00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef __LeapUtil_h__
00010 #define __LeapUtil_h__
00011
00012 #include "Leap.h"
00013
00014
00015 #if defined(_MSC_VER) && (_MSC_VER < 1600)
00016 typedef __int8 int8_t;
00017 typedef __int16 int16_t;
00018 typedef unsigned __int8 uint8_t;
00019 typedef unsigned __int16 uint16_t;
00020 #endif
00021
00022 namespace LeapUtil {
00023
00030
00039
00040 static const float kfPi = Leap::PI;
00041 static const float kf2Pi = kfPi + kfPi;
00042 static const float kfHalfPi = kfPi * 0.5f;
00043 static const float kfEpsilon = 0.00001f;
00044
00045 template<typename T>
00046 T Min( T lhs, T rhs )
00047 {
00048 return lhs < rhs ? lhs : rhs;
00049 }
00050
00051 template<typename T>
00052 T Max( T lhs, T rhs )
00053 {
00054 return lhs > rhs ? lhs : rhs;
00055 }
00056
00057 template<typename T>
00058 T Clamp( T inVal, T minVal, T maxVal )
00059 {
00060 return (inVal < minVal) ? minVal : ((inVal > maxVal) ? maxVal : inVal);
00061 }
00062
00064 template<typename InterpType, typename ParamType>
00065 InterpType Linterp( InterpType a, InterpType b, ParamType t )
00066 {
00067 return a + static_cast<InterpType>((b - a) * t);
00068 }
00069
00071 template<class Vec2>
00072 Leap::Vector FromVector2( const Vec2& vIn, float fZ = 0.0f )
00073 {
00074 return Leap::Vector( static_cast<float>(vIn.x), static_cast<float>(vIn.y), fZ );
00075 }
00076
00078 template<class Vec3>
00079 Leap::Vector FromVector3( const Vec3& vIn )
00080 {
00081 return Leap::Vector( static_cast<float>(vIn.x), static_cast<float>(vIn.y), static_cast<float>(vIn.z) );
00082 }
00083
00084 inline bool IsNearZero( float fVal )
00085 {
00086 return fabs(fVal) <= kfEpsilon;
00087 }
00088
00089 inline bool IsNearZero( const Leap::Vector& vVec )
00090 {
00091 return IsNearZero(vVec.x) && IsNearZero(vVec.y) && IsNearZero(vVec.z);
00092 }
00093
00095 template<typename T>
00096 inline bool IsNearEqual( const T& a, const T& b )
00097 {
00098 return IsNearZero( a - b );
00099 }
00100
00102 inline Leap::Matrix ExtractRotation( const Leap::Matrix& mtxTransform )
00103 {
00104 return Leap::Matrix( mtxTransform.xBasis, mtxTransform.yBasis, mtxTransform.zBasis );
00105 }
00106
00108 inline Leap::Matrix RotationInverse( const Leap::Matrix& mtxRot )
00109 {
00110 return Leap::Matrix( Leap::Vector( mtxRot.xBasis.x, mtxRot.yBasis.x, mtxRot.zBasis.x ),
00111 Leap::Vector( mtxRot.xBasis.y, mtxRot.yBasis.y, mtxRot.zBasis.y ),
00112 Leap::Vector( mtxRot.xBasis.z, mtxRot.yBasis.z, mtxRot.zBasis.z ) );
00113 }
00114
00117 inline Leap::Matrix RigidInverse( const Leap::Matrix& mtxTransform )
00118 {
00119 Leap::Matrix rigidInverse = RotationInverse( mtxTransform );
00120 rigidInverse.origin = rigidInverse.transformDirection( -mtxTransform.origin );
00121 return rigidInverse;
00122 }
00123
00124 inline Leap::Vector ComponentWiseMin( const Leap::Vector& vLHS, const Leap::Vector& vRHS )
00125 {
00126 return Leap::Vector( Min( vLHS.x, vRHS.x ), Min( vLHS.y, vRHS.y ), Min( vLHS.z, vRHS.z ) );
00127 }
00128
00129 inline Leap::Vector ComponentWiseMax( const Leap::Vector& vLHS, const Leap::Vector& vRHS )
00130 {
00131 return Leap::Vector( Max( vLHS.x, vRHS.x ), Max( vLHS.y, vRHS.y ), Max( vLHS.z, vRHS.z ) );
00132 }
00133
00134 inline Leap::Vector ComponentWiseScale( const Leap::Vector& vLHS, const Leap::Vector& vRHS )
00135 {
00136 return Leap::Vector( vLHS.x * vRHS.x, vLHS.y * vRHS.y, vLHS.z * vRHS.z );
00137 }
00138
00139 inline Leap::Vector ComponentWiseReciprocal( const Leap::Vector& vVec )
00140 {
00141 return Leap::Vector( 1.0f/vVec.x, 1.0f/vVec.y, 1.0f/vVec.z );
00142 }
00143
00144 inline float MinComponent( const Leap::Vector& vVec )
00145 {
00146 return Min( vVec.x, Min( vVec.y, vVec.z ) );
00147 }
00148
00149 inline float MaxComponent( const Leap::Vector& vVec )
00150 {
00151 return Max( vVec.x, Max( vVec.y, vVec.z ) );
00152 }
00153
00155 inline float Heading( const Leap::Vector& vVec )
00156 {
00157 return atan2f( vVec.z, vVec.x );
00158 }
00159
00161 inline float Elevation( const Leap::Vector& vVec )
00162 {
00163 return atan2f( vVec.y, sqrtf(vVec.z * vVec.z + vVec.x * vVec.x) );
00164 }
00165
00168 inline Leap::Vector CartesianToSpherical( const Leap::Vector& vCartesian )
00169 {
00170 return Leap::Vector( vCartesian.magnitude(), Heading(vCartesian), Elevation(vCartesian) );
00171 }
00172
00174 inline Leap::Vector NormalizeSpherical( const Leap::Vector& vSpherical )
00175 {
00176 float fHeading = vSpherical.y;
00177 float fElevation = vSpherical.z;
00178
00179 for ( ; fElevation <= -kfPi; fElevation += kf2Pi );
00180 for ( ; fElevation > kfPi; fElevation -= kf2Pi );
00181
00182 if ( fabs(fElevation) > kfHalfPi )
00183 {
00184 fHeading += kfPi;
00185 fElevation = fElevation > 0 ? (kfPi - fElevation) : -(kfPi + fElevation);
00186 }
00187
00188 for ( ; fHeading <= -kfPi; fHeading += kf2Pi );
00189 for ( ; fHeading > kfPi; fHeading -= kf2Pi );
00190
00191 return Leap::Vector( 1, fHeading, fElevation );
00192 }
00193
00196 inline Leap::Vector SphericalToCartesian( const Leap::Vector& vSpherical )
00197 {
00198 const float fMagnitude = vSpherical.x;
00199 const float fCosHeading = cosf( vSpherical.y );
00200 const float fSinHeading = sinf( vSpherical.y );
00201 const float fCosElevation = cosf( vSpherical.z );
00202 const float fSinElevation = sinf( vSpherical.z );
00203
00204 return Leap::Vector( fCosHeading * fCosElevation * fMagnitude,
00205 fSinElevation * fMagnitude,
00206 fSinHeading * fCosElevation * fMagnitude);
00207 }
00208
00209 inline const char* BoolToStr( uint32_t bVal )
00210 {
00211 return bVal ? "On" : "Off";
00212 }
00213
00214 template<int _HistoryLength=256>
00215 class RollingAverage
00216 {
00217 public:
00218 enum
00219 {
00220 kHistoryLength = _HistoryLength
00221 };
00222
00223 public:
00224 RollingAverage() { Reset(); }
00225
00226 void Reset()
00227 {
00228 m_uiCurIndex = 0;
00229 m_fNumSamples = 0.0f;
00230 m_fSum = 0.0f;
00231 m_fAverage = 0.0f;
00232 for ( int i = 0; i < kHistoryLength; m_afSamples[i++] = 0.0f );
00233 }
00234
00235 float AddSample( float fSample )
00236 {
00237 m_fNumSamples = Min( (m_fNumSamples + 1.0f), static_cast<float>(kHistoryLength) );
00238 m_fSum -= m_afSamples[m_uiCurIndex];
00239 m_fSum += fSample;
00240 m_fAverage = m_fSum * (1.0f/m_fNumSamples);
00241
00242 m_afSamples[m_uiCurIndex] = fSample;
00243
00244 m_uiCurIndex = static_cast<uint32_t>((m_uiCurIndex + 1) % kHistoryLength);
00245
00246 return m_fAverage;
00247 }
00248
00249 float GetAverage() const { return m_fAverage; }
00250 float GetSum() const { return m_fSum; }
00251 uint32_t GetNumSamples() const { return static_cast<uint32_t>(m_fNumSamples); }
00252
00254 float operator[](uint32_t uiIdx) const { return m_afSamples[(m_uiCurIndex + uiIdx) % kHistoryLength]; }
00255
00256 private:
00257 uint32_t m_uiCurIndex;
00258 float m_fNumSamples;
00259 float m_fSum;
00260 float m_fAverage;
00261 float m_afSamples[kHistoryLength];
00262 };
00263
00271 class Camera
00272 {
00273 public:
00274 Camera()
00275 : m_fOrbitDistance(-1.0f),
00276 m_fMaxOrbitLatitude( LeapUtil::kfPi * 0.375f ),
00277 m_fNearClip( 0.1f ),
00278 m_fFarClip( 128.0f ),
00279 m_fVerticalFOVDegrees( 40.0f ),
00280 m_fAspectRatio( 4.0f/3.0f )
00281 {}
00282
00284 const Leap::Matrix& GetPOV() const { return m_mtxPOV; }
00285
00286 void SetPOV( const Leap::Matrix& mtxPOV ) { m_mtxPOV = mtxPOV; }
00287
00290 Leap::Matrix GetView() const { return LeapUtil::RigidInverse(m_mtxPOV); }
00291
00293 const Leap::Vector& GetPosition() const { return m_mtxPOV.origin; }
00294
00295 void SetPosition( const Leap::Vector& vPos ) { m_mtxPOV.origin = vPos; }
00296
00298 Leap::Matrix GetRotation() const { return LeapUtil::ExtractRotation(m_mtxPOV); }
00299
00300 void SetRotation( const Leap::Vector& vAxis, float fRadians ) { m_mtxPOV.setRotation( vAxis, fRadians ); }
00301
00302 void SetRotation( const Leap::Matrix& mtxRot )
00303 {
00304 m_mtxPOV.xBasis = mtxRot.xBasis;
00305 m_mtxPOV.yBasis = mtxRot.yBasis;
00306 m_mtxPOV.zBasis = mtxRot.zBasis;
00307 }
00308
00310 void SetPOVLookAt( const Leap::Vector& vCameraPosition, const Leap::Vector& vTarget, Leap::Vector vUp = Leap::Vector::yAxis() );
00311
00313 void SetRotationLookAt( const Leap::Vector& vTarget, const Leap::Vector& vUp = Leap::Vector::yAxis() )
00314 {
00315 SetPOVLookAt( m_mtxPOV.origin, vTarget, vUp );
00316 }
00317
00319 void Move( const Leap::Vector& vDeltaPos )
00320 {
00321 m_mtxPOV.origin += vDeltaPos;
00322 }
00323
00325 void Rotate( const Leap::Matrix& mtxRotation )
00326 {
00327 m_mtxPOV = m_mtxPOV * LeapUtil::ExtractRotation(mtxRotation);
00328 }
00329
00330 void Rotate( const Leap::Vector& vAxis, float fRadians )
00331 {
00332 m_mtxPOV = m_mtxPOV * Leap::Matrix( vAxis, fRadians );
00333 }
00334
00336 const Leap::Vector& GetOrbitTarget() const
00337 {
00338 return m_vOrbitTarget;
00339 }
00340
00341 void SetOrbitTarget( const Leap::Vector& vOrbitTarget)
00342 {
00343 m_vOrbitTarget = vOrbitTarget;
00344 updateOrbitDistance();
00345 }
00346
00352 void RotateOrbit( float fDeltaMagnitude, float fDeltaLongitude, float fDeltaLatitude );
00353
00356 float GetMaxOrbitLatitude() const
00357 {
00358 return m_fMaxOrbitLatitude;
00359 }
00360
00361 void SetMaxOrbitLatitude( float fMaxOrbitLatitude )
00362 {
00363 m_fMaxOrbitLatitude = fMaxOrbitLatitude;
00364 }
00365
00368 float CalcViewDepth( const Leap::Vector& vPos ) const
00369 {
00370 return m_mtxPOV.zBasis.dot( m_mtxPOV.origin - vPos );
00371 }
00372
00374
00375 void OnMouseWheel( float fDeltaZ );
00376
00377 void OnMouseDown( const Leap::Vector& vMousePos );
00378
00379 void OnMouseMoveOrbit( const Leap::Vector& vMousePos );
00380
00381 float GetNearClip() const { return m_fNearClip; }
00382
00383 float GetFarClip() const { return m_fFarClip; }
00384
00385 void SetNearClip( float fNearClip ) { m_fNearClip = Max( 0.01f, fNearClip ); }
00386
00387 void SetFarClip( float fFarClip ) { m_fFarClip = fFarClip; }
00388
00389 void SetClipPlanes( float fNearClip, float fFarClip )
00390 {
00391 SetNearClip( fNearClip );
00392 SetFarClip( fFarClip );
00393 }
00394
00395 float GetVerticalFOVDegrees() const { return m_fVerticalFOVDegrees; }
00396
00397 void SetVerticalFOVDegrees( float fFOV ) { m_fVerticalFOVDegrees = fFOV; }
00398
00399 float GetAspectRatio() const { return m_fAspectRatio; }
00400
00401 void SetAspectRatio( float fAspectRatio ) { m_fAspectRatio = fAspectRatio; }
00402
00403 private:
00404 void updateOrbitDistance()
00405 {
00406 float fOrbitDistance = (m_vOrbitTarget - m_mtxPOV.origin).magnitude();
00407
00408 if ( !IsNearZero( fOrbitDistance - m_fOrbitDistance ) )
00409 {
00410 m_fOrbitDistance = fOrbitDistance;
00411 }
00412 }
00413
00414 private:
00415 Leap::Matrix m_mtxPOV;
00416 Leap::Vector m_vLastMousePos;
00417 Leap::Vector m_vOrbitTarget;
00418 float m_fOrbitDistance;
00419 float m_fMaxOrbitLatitude;
00420 float m_fNearClip;
00421 float m_fFarClip;
00422 float m_fVerticalFOVDegrees;
00423 float m_fAspectRatio;
00424 };
00425
00426
00428 class ScrollMomentum {
00429 public:
00430 ScrollMomentum()
00431 : m_vDirection(Leap::Vector::yAxis()),
00432 m_fScrollSize(512.0f),
00433 m_fSpeed(0),
00434 m_fMinSpeed(0.125f),
00435 m_fDrag(0.4f),
00436 m_fDragPower(2.0f),
00437 m_fFixedTimeStep(1.0f/60.0f),
00438 m_fPendingDeltaTime(0.0f)
00439 {}
00440
00445 const Leap::Vector& getPosition() const { return m_vPosition; }
00446 void setPosition( const Leap::Vector& vPosition ) { m_vPosition = vPosition; }
00447
00451 const Leap::Vector& getDirection() const { return m_vDirection; }
00452 void setDirection( const Leap::Vector& vDirection ) { m_vDirection = vDirection.normalized(); }
00453
00462 float getScrollSize() const { return m_fScrollSize; }
00463 void setScrollSize( float fScrollSize ) { m_fScrollSize = (fScrollSize > 0.0f ? fScrollSize : 1.0f); }
00464
00471 float getSpeed() const { return m_fSpeed; }
00472 void setSpeed( float fSpeed ) { m_fSpeed = fSpeed; }
00473
00478 float getMinSpeed() const { return m_fMinSpeed; }
00479 void setMinSpeed( float fMinSpeed ) { m_fMinSpeed = fabs(fMinSpeed); }
00480
00485 float getFixedTimeStep() const { return m_fMinSpeed; }
00486 void setFixedTimeStep( float fFixedTimeStep ) { m_fFixedTimeStep = fabs(fFixedTimeStep); }
00487
00491 float getDrag() const { return m_fDrag; }
00492 void setDrag( float fDrag ) { m_fDrag = fabs(fDrag); }
00493
00498 float getDragPower() const { return m_fDragPower; }
00499 void setDragPower( float fDragPower ) { m_fDragPower = fDragPower; }
00500
00503 const Leap::Vector getVelocity() const { return m_vDirection * m_fSpeed; }
00504
00507 void setVelocity( const Leap::Vector& vDirection, float fSpeed )
00508 {
00509 setDirection( vDirection );
00510 setSpeed( fSpeed );
00511 }
00512
00519 void update( float fDeltaTimeSeconds )
00520 {
00521 if ( fDeltaTimeSeconds <= 0.0f )
00522 {
00523 return;
00524 }
00525
00526 if ( fabs(m_fSpeed) > m_fMinSpeed )
00527 {
00528 if ( m_fDrag > 0 )
00529 {
00530
00531
00532 const float fMinScrollSpeed = m_fMinSpeed / m_fScrollSize;
00533
00534 const float fScrollScale = (m_fSpeed < 0.0f ? -1.0f : 1.0f) * m_fScrollSize;
00535
00536 float fScrollSpeed = m_fSpeed / fScrollScale;
00537
00538
00539 fDeltaTimeSeconds += m_fPendingDeltaTime;
00540
00541
00542 for ( ; fDeltaTimeSeconds >= m_fFixedTimeStep; fDeltaTimeSeconds -= m_fFixedTimeStep )
00543 {
00544 const float fDragForce = powf( fScrollSpeed, m_fDragPower ) * m_fDrag;
00545
00546
00547 fScrollSpeed -= fDragForce * m_fFixedTimeStep;
00548
00549
00550 if ( fScrollSpeed <= fMinScrollSpeed )
00551 {
00552 m_fSpeed = 0.0f;
00553 fDeltaTimeSeconds = 0.0f;
00554 break;
00555 }
00556
00557
00558 m_fSpeed = fScrollSpeed * fScrollScale;
00559
00560
00561 m_vPosition += m_vDirection * (m_fFixedTimeStep * m_fSpeed);
00562 }
00563
00564
00565 m_fPendingDeltaTime = fDeltaTimeSeconds;
00566 }
00567 else
00568 {
00569
00570 m_vPosition += m_vDirection * ((m_fPendingDeltaTime + fDeltaTimeSeconds) * m_fSpeed);
00571 m_fPendingDeltaTime = 0.0f;
00572 }
00573 }
00574 else
00575 {
00576
00577 m_fSpeed = 0.0f;
00578 m_fPendingDeltaTime = 0.0f;
00579 }
00580 }
00581
00582 protected:
00583 Leap::Vector m_vPosition;
00584 Leap::Vector m_vDirection;
00585 float m_fScrollSize;
00586 float m_fSpeed;
00587 float m_fMinSpeed;
00588 float m_fDrag;
00589 float m_fDragPower;
00590 float m_fFixedTimeStep;
00591 float m_fPendingDeltaTime;
00592 };
00593
00594
00596 template<typename T>
00597 class SmartInstanceDestructor
00598 {
00599 public:
00600 static void Destroy( T* pPointer ) { delete pPointer; }
00601 };
00602
00604 template<typename T>
00605 class SmartArrayDestructor
00606 {
00607 public:
00608 static void Destroy( T* pPointer ) { delete[] pPointer; }
00609 };
00610
00624 template< typename T,
00625 class Destructor = SmartInstanceDestructor<T>,
00626 unsigned int ManagedPointerPoolSize = 512 >
00627 class SmartPointer
00628 {
00629 public:
00630 enum { kManagedPointerPoolSize = ManagedPointerPoolSize };
00631
00632 typedef T ManagedType;
00633
00634 private:
00635
00636 struct ManagedPointerEntry
00637 {
00638 ManagedType* m_pPointer;
00639 uint32_t m_uiRefCount;
00640 };
00641
00642
00643
00644
00645 struct ManagedPointerPool
00646 {
00647 enum { kPoolSize = kManagedPointerPoolSize, kDeadPointer = 0xdeadbea7 };
00648
00649 ManagedPointerPool()
00650 : m_uiNextFree(0),
00651 m_uiNumAllocated(0)
00652 {
00653 for ( uint32_t i = 0; i < static_cast<uint32_t>(kPoolSize); i++ )
00654 {
00655 m_aEntryPool[i].m_pPointer = reinterpret_cast<ManagedType*>(kDeadPointer);
00656 m_aEntryPool[i].m_uiRefCount = i + 1;
00657 }
00658 }
00659
00660
00661 ManagedPointerEntry* allocEntry( ManagedType* pPointer )
00662 {
00663 ManagedPointerEntry* pEntry = NULL;
00664
00665
00666
00667
00668
00669
00670
00671 pEntry = findEntry( pPointer );
00672
00673 if ( pEntry )
00674 {
00675
00676 pEntry->m_uiRefCount++;
00677 }
00678 else if ( (m_uiNextFree < kPoolSize) && pPointer )
00679 {
00680
00681 pEntry = m_aEntryPool + m_uiNextFree;
00682
00683
00684
00685 m_uiNextFree = pEntry->m_uiRefCount;
00686
00687
00688 pEntry->m_pPointer = pPointer;
00689 pEntry->m_uiRefCount = 1;
00690
00691
00692 m_uiNumAllocated++;
00693 }
00694
00695 return pEntry;
00696 }
00697
00698
00699 void freeEntry( ManagedPointerEntry* pEntry )
00700 {
00701
00702 const uint32_t entryIndex = static_cast<uint32_t>(pEntry - m_aEntryPool);
00703
00704
00705 if ( (entryIndex < kPoolSize) &&
00706 (m_uiNumAllocated != 0) &&
00707 (pEntry->m_pPointer != reinterpret_cast<ManagedType*>(kDeadPointer)) )
00708 {
00709
00710 pEntry->m_pPointer = NULL;
00711
00712
00713 pEntry->m_uiRefCount = m_uiNextFree;
00714 m_uiNextFree = entryIndex;
00715
00716
00717 m_uiNumAllocated--;
00718 }
00719 }
00720
00721
00722
00723 ManagedPointerEntry* findEntry( const ManagedType* pPointer )
00724 {
00725
00726 if ( pPointer && (pPointer != reinterpret_cast<ManagedType*>(kDeadPointer)) )
00727 {
00728
00729
00730 for ( uint32_t i = 0, j = 0; j < m_uiNumAllocated && i < static_cast<uint32_t>(kPoolSize); i++ )
00731 {
00732
00733 if ( m_aEntryPool[i].m_pPointer != reinterpret_cast<ManagedType*>(kDeadPointer) )
00734 {
00735
00736 if ( m_aEntryPool[i].m_pPointer == pPointer )
00737 {
00738 return m_aEntryPool + i;
00739 }
00740
00741
00742 j++;
00743 }
00744 }
00745 }
00746
00747 return NULL;
00748 }
00749
00750
00751 uint32_t getNumAllocated() const { return m_uiNumAllocated; }
00752
00753
00754 uint32_t getNumFree() const { return static_cast<uint32_t>(kPoolSize) - m_uiNumAllocated; }
00755
00756
00757 ManagedPointerEntry m_aEntryPool[kPoolSize];
00758
00759
00760 uint32_t m_uiNextFree;
00761
00762
00763 uint32_t m_uiNumAllocated;
00764 };
00765
00766
00767 static ManagedPointerPool& s_pool()
00768 {
00769 static ManagedPointerPool _s_pool;
00770 return _s_pool;
00771 }
00772
00774 void refInc()
00775 {
00776 if ( m_pManagedPointer )
00777 {
00778 m_pManagedPointer->m_uiRefCount++;
00779 }
00780 }
00781
00785 void refDec()
00786 {
00787 if ( m_pManagedPointer )
00788 {
00789 if ( m_pManagedPointer->m_uiRefCount )
00790 {
00791 m_pManagedPointer->m_uiRefCount--;
00792 }
00793
00794 if ( !m_pManagedPointer->m_uiRefCount )
00795 {
00796 Destructor::Destroy(m_pManagedPointer->m_pPointer);
00797 s_pool().freeEntry(m_pManagedPointer);
00798 }
00799
00800 m_pManagedPointer = NULL;
00801 }
00802 }
00803
00804 public:
00806 SmartPointer()
00807 : m_pManagedPointer(NULL)
00808 {
00809 }
00810
00816 explicit SmartPointer( ManagedType* pManaged )
00817 : m_pManagedPointer( s_pool().allocEntry( pManaged ) )
00818 {
00819 }
00820
00822 SmartPointer( const SmartPointer& rhs )
00823 : m_pManagedPointer( rhs.m_pManagedPointer )
00824 {
00825 refInc();
00826 }
00827
00830 const SmartPointer& operator =( const SmartPointer& rhs )
00831 {
00832 if ( m_pManagedPointer != rhs.m_pManagedPointer )
00833 {
00834 refDec();
00835 m_pManagedPointer = rhs.m_pManagedPointer;
00836 refInc();
00837 }
00838
00839 return *this;
00840 }
00841
00843 ~SmartPointer()
00844 {
00845 refDec();
00846 }
00847
00850 ManagedType* GetPointer() const { return m_pManagedPointer ? m_pManagedPointer->m_pPointer : NULL; }
00851
00853 uint32_t GetRefCount() const { return m_pManagedPointer ? m_pManagedPointer->m_uiRefCount : 0u; }
00854
00856 operator ManagedType*() const { return GetPointer(); }
00857
00858 ManagedType* operator ->() const { return GetPointer(); }
00859
00861 operator bool() const { return m_pManagedPointer != NULL; }
00862
00863 bool operator !() const { return !m_pManagedPointer; }
00864
00865 bool operator ==( const ManagedType* pPointer ) const { return GetPointer() == pPointer; }
00866
00867 bool operator !=( const ManagedType* pPointer ) const { return GetPointer() != pPointer; }
00868
00869 bool operator ==( const SmartPointer& rhs ) const { return m_pManagedPointer == rhs.m_pManagedPointer; }
00870
00871 bool operator !=( const SmartPointer& rhs ) const { return m_pManagedPointer != rhs.m_pManagedPointer; }
00872
00876 void Release()
00877 {
00878 refDec();
00879 }
00880
00882 static const SmartPointer& Null()
00883 {
00884 static SmartPointer _s_null;
00885 return _s_null;
00886 }
00887
00889 static bool IsManaged( const ManagedType* pPointer )
00890 {
00891 return s_pool().findEntry( pPointer ) != NULL;
00892 }
00893
00896 static uint32_t GetNumManagedPointers() { return s_pool().getNumAllocated(); }
00897
00898 private:
00899 ManagedPointerEntry* m_pManagedPointer;
00900 };
00901
00902 }
00903
00904 #endif // __LeapUtil_h__