557 lines
16 KiB
C++
557 lines
16 KiB
C++
// X2DRectAllocator.h
|
|
//
|
|
// by Testors , 2005/08/010
|
|
|
|
#pragma once
|
|
|
|
#include "X2DQuadTree.h"
|
|
|
|
namespace X2D
|
|
{
|
|
|
|
template< typename T >
|
|
struct RectAllocator
|
|
{
|
|
typedef Rect<T> Rect;
|
|
typedef Point<T> Point;
|
|
typedef QuadTree< T, Rect, true > QUAD_TREE;
|
|
|
|
RectAllocator( T width, T height ) : m_AllocatedRectTree( width, height )
|
|
{
|
|
FreeRectChunk temp;
|
|
temp.AddFreeRect( Rect( 0, 0, width, height ) );
|
|
m_vChunkList.push_back( temp );
|
|
}
|
|
|
|
~RectAllocator()
|
|
{
|
|
}
|
|
|
|
template< typename F >
|
|
void EnumAllocatedBlock( F & f )
|
|
{
|
|
m_AllocatedRectTree.Enum( f );
|
|
}
|
|
|
|
template< typename F >
|
|
void EnumFreeBlock( F & f )
|
|
{
|
|
std::vector< FreeRectChunk >::iterator it;
|
|
for( it = m_vChunkList.begin(); it != m_vChunkList.end(); ++it ) (*it).EnumFreeBlock( f );
|
|
}
|
|
|
|
bool Alloc( const T & width, const T & height, Point *pPoint )
|
|
{
|
|
std::vector< Point > vPtList;
|
|
std::vector< FreeRectChunk >::iterator it;
|
|
|
|
for( it = m_vChunkList.begin(); it != m_vChunkList.end(); ++it )
|
|
{
|
|
if( (*it).Alloc( width, ( height < 2 ? 2 : height ), m_AllocatedRectTree, pPoint ) ) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void Remove( const Point & pt )
|
|
{
|
|
std::vector< FreeRectChunk >::iterator it;
|
|
|
|
_Rect block;
|
|
block.bFound = false;
|
|
m_AllocatedRectTree.Enum( pt, block );
|
|
|
|
if( !block.bFound ) return;
|
|
|
|
m_AllocatedRectTree.Remove( block.m_rect );
|
|
|
|
for( it = m_vChunkList.begin(); it != m_vChunkList.end(); ++it )
|
|
{
|
|
if( (*it).IsTouchedFreeBlock( block.m_rect ) )
|
|
{
|
|
(*it).AddFreeRect( block.m_rect );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Remove( const Rect & rc )
|
|
{
|
|
std::vector< Rect >::iterator rit;
|
|
std::vector< FreeRectChunk >::iterator it;
|
|
|
|
_RectList block;
|
|
block.bFound = false;
|
|
m_AllocatedRectTree.Enum( rc, block );
|
|
|
|
if( !block.bFound ) return;
|
|
|
|
for( rit = block.m_lstRect.begin(); rit != block.m_lstRect.end(); ++rit )
|
|
{
|
|
Remove( (*rit).GetLeftTop() );
|
|
}
|
|
}
|
|
|
|
private:
|
|
|
|
struct FreeRectChunk
|
|
{
|
|
FreeRectChunk()
|
|
{
|
|
m_bInitialized = false;
|
|
}
|
|
|
|
bool IsTouchedFreeBlock( const Rect & rc )
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool Alloc( const T & width, const T & height, QUAD_TREE & allocatedRectTree, Point *pPoint )
|
|
{
|
|
if( m_rcEffectiveArea.GetWidth() < width ||
|
|
m_rcEffectiveArea.GetHeight() < height ) return false;
|
|
|
|
bool bFound = false;
|
|
|
|
// 딱 맞는놈이 있는지?
|
|
for( std::vector< Rect >::iterator it = m_vFreeRectList.begin(); it != m_vFreeRectList.end(); ++it )
|
|
{
|
|
if( (*it).GetHeight() == height && (*it).GetWidth() == width )
|
|
{
|
|
T x = (*it).GetLeft();
|
|
T y = (*it).GetTop();
|
|
|
|
Rect rc( x, y, width, height );
|
|
if( !INCLUDE( m_rcEffectiveArea, rc ) ) assert( 0 );
|
|
|
|
pPoint->x = x;
|
|
pPoint->y = y;
|
|
|
|
bFound = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 그나마 비슷한 놈이 있는지?
|
|
if( !bFound )
|
|
{
|
|
for( std::vector< Rect >::iterator it = m_vFreeRectList.begin(); it != m_vFreeRectList.end(); ++it )
|
|
{
|
|
if( (*it).GetHeight() == height || (*it).GetWidth() == width )
|
|
{
|
|
T x = (*it).GetLeft();
|
|
T y = (*it).GetTop();
|
|
Rect rc( x, y, width, height );
|
|
|
|
if( !INCLUDE( m_rcEffectiveArea, rc ) ) continue;
|
|
|
|
if( allocatedRectTree.Collision( rc ) ) continue;
|
|
|
|
pPoint->x = x;
|
|
pPoint->y = y;
|
|
|
|
bFound = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( !bFound )
|
|
{
|
|
// 찾아보세~
|
|
for( std::vector< T >::iterator y = m_vYPtList.begin(); y != m_vYPtList.end(); ++y )
|
|
{
|
|
for( std::vector< T >::iterator x = m_vXPtList.begin(); x != m_vXPtList.end(); ++x )
|
|
{
|
|
Rect rc( *x, *y, width, height );
|
|
|
|
if( !INCLUDE( m_rcEffectiveArea, rc ) ) continue;
|
|
|
|
if( allocatedRectTree.Collision( rc ) ) continue;
|
|
|
|
pPoint->x = *x;
|
|
pPoint->y = *y;
|
|
|
|
bFound = true;
|
|
break;
|
|
}
|
|
if( bFound ) break;
|
|
}
|
|
}
|
|
|
|
if( bFound )
|
|
{
|
|
Rect rc( pPoint->x, pPoint->y, width, height );
|
|
RemoveFreeRect( rc );
|
|
allocatedRectTree.Add( rc );
|
|
m_FreeSize -= rc.GetSize();
|
|
}
|
|
|
|
return bFound;
|
|
}
|
|
|
|
template< typename F >
|
|
void EnumFreeBlock( F & f)
|
|
{
|
|
for( std::vector< Rect >::iterator it = m_vFreeRectList.begin(); it != m_vFreeRectList.end(); ++it ) f( *it );
|
|
}
|
|
|
|
void RemoveFreeRect( const Rect & rc )
|
|
{
|
|
std::vector< Rect > vNewFreeRect;
|
|
|
|
for( std::vector< Rect >::iterator it = m_vFreeRectList.begin(); it != m_vFreeRectList.end(); )
|
|
{
|
|
if( !COLLISION( *it, rc ) )
|
|
{
|
|
++it;
|
|
continue;
|
|
}
|
|
|
|
DivideFreeRect( *it, rc, &vNewFreeRect );
|
|
|
|
it = m_vFreeRectList.erase( it );
|
|
}
|
|
|
|
for( std::vector< Rect >::iterator it = vNewFreeRect.begin(); it != vNewFreeRect.end(); ++it ) AddFreeRect( *it );
|
|
//m_vFreeRectList.insert( m_vFreeRectList.end(), vNewFreeRect.begin(), vNewFreeRect.end() );
|
|
|
|
CalcPtList();
|
|
}
|
|
|
|
bool DivideFreeRect( const Rect & rcFree, const Rect & rcArea, std::vector< Rect > * pNewFreeRect )
|
|
{
|
|
// case #0. FreeRect 가 Area 안에 완전히 포함되어 나뉜 결과가 없는경우
|
|
if( INCLUDE( rcArea, rcFree ) ) return false;
|
|
|
|
std::vector< Point > vIncludePtList;
|
|
|
|
if( INCLUDE( rcFree, rcArea.GetLeftTop() ) &&
|
|
rcArea.GetLeft() != rcFree.GetLeft() &&
|
|
rcArea.GetTop() != rcFree.GetTop() ) vIncludePtList.push_back( rcArea.GetLeftTop() );
|
|
|
|
if( INCLUDE( rcFree, rcArea.GetRightTop() ) &&
|
|
rcArea.GetRight() != rcFree.GetRight() &&
|
|
rcArea.GetTop() != rcFree.GetTop() ) vIncludePtList.push_back( rcArea.GetRightTop() );
|
|
|
|
if( INCLUDE( rcFree, rcArea.GetLeftBottom() ) &&
|
|
rcArea.GetLeft() != rcFree.GetLeft() &&
|
|
rcArea.GetBottom() != rcFree.GetBottom() ) vIncludePtList.push_back( rcArea.GetLeftBottom() );
|
|
|
|
if( INCLUDE( rcFree, rcArea.GetRightBottom() ) &&
|
|
rcArea.GetRight() != rcFree.GetRight() &&
|
|
rcArea.GetBottom() != rcFree.GetBottom() ) vIncludePtList.push_back( rcArea.GetRightBottom() );
|
|
|
|
assert( vIncludePtList.size() < 3 );
|
|
|
|
// a1 b1 c1
|
|
// a2 b2 c2
|
|
// a3 b3 c3
|
|
|
|
if( vIncludePtList.size() == 4 )
|
|
{
|
|
// assert( rcArea.GetLeftTop() == rcFree.GetLeftTop() );
|
|
assert( 0 );
|
|
}
|
|
|
|
if( vIncludePtList.size() == 2 )
|
|
{
|
|
// case #1. [a:b:c] 3덩이로 나뉘는 경우
|
|
if( vIncludePtList[0].y == vIncludePtList[1].y )
|
|
{
|
|
if( vIncludePtList[0].x > vIncludePtList[1].x ) std::swap( vIncludePtList[0].x, vIncludePtList[1].x );
|
|
|
|
// case #1-1. [a:b1:c] 3덩이로 나뉘는 경우
|
|
if( rcArea.GetBottom() >= rcFree.GetBottom() )
|
|
{
|
|
Rect a( rcFree.GetLeft(), rcFree.GetTop(), rcArea.GetLeft() - rcFree.GetLeft(), rcFree.GetHeight() );
|
|
Rect b1( rcArea.GetLeft(), rcFree.GetTop(), rcArea.GetWidth(), rcArea.GetBottom() - rcFree.GetTop() );
|
|
Rect c( rcArea.GetRight(), rcFree.GetTop(), rcFree.GetRight() - rcArea.GetRight(), rcFree.GetHeight() );
|
|
if( a.GetSize() ) pNewFreeRect->push_back( a );
|
|
if( b1.GetSize() ) pNewFreeRect->push_back( b1 );
|
|
if( c.GetSize() ) pNewFreeRect->push_back( c );
|
|
return true;
|
|
}
|
|
// case #1-1. [a:b3:c] 3덩이로 나뉘는 경우
|
|
else if( rcArea.GetTop() <= rcFree.GetTop() )
|
|
{
|
|
Rect a( rcFree.GetLeft(), rcFree.GetTop(), rcArea.GetLeft() - rcFree.GetLeft(), rcFree.GetHeight() );
|
|
Rect b3( rcArea.GetLeft(), rcArea.GetBottom(), rcArea.GetWidth(), rcFree.GetBottom() - rcArea.GetBottom() );
|
|
Rect c( rcArea.GetRight(), rcFree.GetTop(), rcFree.GetRight() - rcArea.GetRight(), rcFree.GetHeight() );
|
|
if( a.GetSize() ) pNewFreeRect->push_back( a );
|
|
if( b3.GetSize() ) pNewFreeRect->push_back( b3 );
|
|
if( c.GetSize() ) pNewFreeRect->push_back( c );
|
|
return true;
|
|
}
|
|
else assert( false );
|
|
|
|
return false;
|
|
}
|
|
|
|
// case #2. [1:2:3] 3덩이로 나뉘는 경우
|
|
if( vIncludePtList[0].x == vIncludePtList[1].x )
|
|
{
|
|
if( vIncludePtList[0].y > vIncludePtList[1].y ) std::swap( vIncludePtList[0].y, vIncludePtList[1].y );
|
|
|
|
// case #2-1. [1:a2:3] 3덩이로 나뉘는 경우
|
|
if( rcArea.GetRight() >= rcFree.GetRight() )
|
|
{
|
|
Rect _1( rcFree.GetLeft(), rcFree.GetTop(), rcFree.GetWidth(), rcArea.GetTop() - rcFree.GetTop() );
|
|
Rect _a2( rcFree.GetLeft(), rcArea.GetTop(), rcArea.GetLeft() - rcFree.GetLeft(), rcArea.GetHeight() );
|
|
Rect _3( rcFree.GetLeft(), rcFree.GetTop() + _1.GetHeight() + _a2.GetHeight(), rcFree.GetWidth(), rcFree.GetHeight() - _1.GetHeight() - _a2.GetHeight() );
|
|
if( _1.GetSize() ) pNewFreeRect->push_back( _1 );
|
|
if( _a2.GetSize() ) pNewFreeRect->push_back( _a2 );
|
|
if( _3.GetSize() ) pNewFreeRect->push_back( _3 );
|
|
return true;
|
|
}
|
|
// case #2-1. [1:c2:3] 3덩이로 나뉘는 경우
|
|
else if( rcArea.GetLeft() <= rcFree.GetLeft() )
|
|
{
|
|
Rect _1( rcFree.GetLeft(), rcFree.GetTop(), rcFree.GetWidth(), rcArea.GetTop() - rcFree.GetTop() );
|
|
Rect _c2( rcArea.GetRight(), rcArea.GetTop(), rcFree.GetRight() - rcArea.GetRight(), rcArea.GetHeight() );
|
|
Rect _3( rcFree.GetLeft(), rcFree.GetTop() + _1.GetHeight() + _c2.GetHeight(), rcFree.GetWidth(), rcFree.GetHeight() - _1.GetHeight() - _c2.GetHeight() );
|
|
if( _1.GetSize() ) pNewFreeRect->push_back( _1 );
|
|
if( _c2.GetSize() ) pNewFreeRect->push_back( _c2 );
|
|
if( _3.GetSize() ) pNewFreeRect->push_back( _3 );
|
|
return true;
|
|
}
|
|
else assert( false );
|
|
|
|
return false;
|
|
}
|
|
|
|
assert( false );
|
|
|
|
return false;
|
|
}
|
|
|
|
if( vIncludePtList.size() == 0 )
|
|
{
|
|
//assert( !INCLUDE( rcFree, rcArea ) );
|
|
|
|
// case #3. a 생성
|
|
if( rcArea.GetLeft() > rcFree.GetLeft() )
|
|
{
|
|
pNewFreeRect->push_back( Rect( rcFree.GetLeft(), rcFree.GetTop(), rcArea.GetLeft() - rcFree.GetLeft(), rcFree.GetHeight() ) );
|
|
//return true;
|
|
}
|
|
|
|
// case #4. c 생성
|
|
if( rcArea.GetRight() < rcFree.GetRight() )
|
|
{
|
|
pNewFreeRect->push_back( Rect( rcArea.GetRight(), rcFree.GetTop(), rcFree.GetRight() - rcArea.GetRight(), rcFree.GetHeight() ) );
|
|
//return true;
|
|
}
|
|
|
|
// case #5. 1 생성
|
|
if( rcArea.GetTop() > rcFree.GetTop() )
|
|
{
|
|
pNewFreeRect->push_back( Rect( rcFree.GetLeft(), rcFree.GetTop(), rcFree.GetWidth(), rcArea.GetTop() - rcFree.GetTop() ) );
|
|
//return true;
|
|
}
|
|
|
|
// case #6. 3 생성
|
|
if( rcArea.GetBottom() < rcFree.GetBottom() )
|
|
{
|
|
pNewFreeRect->push_back( Rect( rcFree.GetLeft(), rcArea.GetBottom(), rcFree.GetWidth(), rcFree.GetBottom() - rcArea.GetBottom() ) );
|
|
//return true;
|
|
}
|
|
|
|
// case #5. 한쪽이 완전히 잘려나가 크기가 줄어드는 경우
|
|
return false;
|
|
}
|
|
|
|
assert( vIncludePtList.size() == 1 );
|
|
|
|
if( vIncludePtList[0] == rcArea.GetLeftTop() )
|
|
{
|
|
pNewFreeRect->push_back( Rect( rcFree.GetLeft(), rcFree.GetTop(), rcFree.GetWidth(), rcArea.GetTop() - rcFree.GetTop() ) );
|
|
pNewFreeRect->push_back( Rect( rcFree.GetLeft(), rcArea.GetTop(), rcArea.GetLeft() - rcFree.GetLeft(), rcFree.GetBottom() - rcArea.GetTop() ) );
|
|
return true;
|
|
}
|
|
else if( vIncludePtList[0] == rcArea.GetRightTop() )
|
|
{
|
|
pNewFreeRect->push_back( Rect( rcFree.GetLeft(), rcFree.GetTop(), rcFree.GetWidth(), rcArea.GetTop() - rcFree.GetTop() ) );
|
|
pNewFreeRect->push_back( Rect( rcArea.GetRight(), rcArea.GetTop(), rcFree.GetRight() - rcArea.GetRight(), rcFree.GetBottom() - rcArea.GetTop() ) );
|
|
return true;
|
|
}
|
|
else if( vIncludePtList[0] == rcArea.GetLeftBottom() )
|
|
{
|
|
pNewFreeRect->push_back( Rect( rcFree.GetLeft(), rcFree.GetTop(), rcArea.GetLeft() - rcFree.GetLeft(), rcFree.GetHeight() ) );
|
|
pNewFreeRect->push_back( Rect( rcArea.GetLeft(), rcArea.GetBottom(), rcFree.GetRight() - rcArea.GetLeft(), rcFree.GetBottom() - rcArea.GetBottom() ) );
|
|
return true;
|
|
}
|
|
else if( vIncludePtList[0] == rcArea.GetRightBottom() )
|
|
{
|
|
pNewFreeRect->push_back( Rect( rcArea.GetRight(), rcFree.GetTop(), rcFree.GetRight() - rcArea.GetRight(), rcFree.GetHeight() ) );
|
|
pNewFreeRect->push_back( Rect( rcFree.GetLeft(), rcArea.GetBottom(), rcFree.GetWidth() - ( rcFree.GetRight() - rcArea.GetRight() ), rcFree.GetBottom() - rcArea.GetBottom() ) );
|
|
return true;
|
|
}
|
|
else assert( 0 );
|
|
|
|
// etc. 인접한 2덩이로 나뉘는 경우
|
|
return false;
|
|
}
|
|
|
|
typename std::vector< Rect >::iterator FindJoinableFreeRect( const Rect & rc )
|
|
{
|
|
std::vector< Rect >::iterator it;
|
|
for( it = m_vFreeRectList.begin(); it != m_vFreeRectList.end(); ++it )
|
|
{
|
|
if( ( rc.GetLeft() == (*it).GetLeft() && rc.GetWidth() == (*it).GetWidth() ) )
|
|
{
|
|
if( rc.GetTop() + rc.GetHeight() == (*it).GetTop() ||
|
|
rc.GetTop() == (*it).GetTop() + (*it).GetHeight() ) return it;
|
|
}
|
|
|
|
if( rc.GetTop() == (*it).GetTop() && rc.GetHeight() == (*it).GetHeight() )
|
|
{
|
|
if( rc.GetLeft() + rc.GetWidth() == (*it).GetLeft() ||
|
|
rc.GetLeft() == (*it).GetLeft() + (*it).GetWidth() ) return it;
|
|
|
|
}
|
|
}
|
|
|
|
return it;
|
|
}
|
|
|
|
void AddFreeRect( Rect & rc )
|
|
{
|
|
if( !m_bInitialized )
|
|
{
|
|
m_bInitialized = true;
|
|
m_rcEffectiveArea = rc;
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
if( m_rcEffectiveArea.GetLeft() > rc.GetLeft() ) m_rcEffectiveArea.SetLeft( rc.GetLeft() );
|
|
if( m_rcEffectiveArea.GetRight() < rc.GetRight() ) m_rcEffectiveArea.SetRight( rc.GetRight() );
|
|
if( m_rcEffectiveArea.GetTop() > rc.GetTop() ) m_rcEffectiveArea.SetTop( rc.GetTop() );
|
|
if( m_rcEffectiveArea.GetBottom() < rc.GetBottom() ) m_rcEffectiveArea.SetBottom( rc.GetBottom() );
|
|
*/
|
|
}
|
|
|
|
m_FreeSize += rc.GetSize();
|
|
|
|
#ifndef NO_JOIN_FREE_BOX
|
|
std::vector< Rect >::iterator it;
|
|
while( ( it = FindJoinableFreeRect( rc ) ) != m_vFreeRectList.end() )
|
|
{
|
|
if( rc.GetLeft() == (*it).GetLeft() && rc.GetRight() == (*it).GetRight() )
|
|
{
|
|
// 위에 붙음
|
|
if( rc.GetTop() + rc.GetHeight() == (*it).GetTop() )
|
|
{
|
|
(*it).SetHeight( (*it).GetHeight() + rc.GetHeight() );
|
|
(*it).Move( rc.GetX(), rc.GetY() );
|
|
rc = *it;
|
|
it = m_vFreeRectList.erase(it);
|
|
continue;
|
|
}
|
|
|
|
// 아래에 붙음
|
|
if( rc.GetTop() == (*it).GetTop() + (*it).GetHeight() )
|
|
{
|
|
(*it).SetHeight( (*it).GetHeight() + rc.GetHeight() );
|
|
rc = *it;
|
|
it = m_vFreeRectList.erase(it);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if( rc.GetTop() == (*it).GetTop() && rc.GetBottom() == (*it).GetBottom() )
|
|
{
|
|
// 왼쪽에 붙음
|
|
if( rc.GetLeft() + rc.GetWidth() == (*it).GetLeft() )
|
|
{
|
|
(*it).SetWidth( (*it).GetWidth() + rc.GetWidth() );
|
|
(*it).Move( rc.GetX(), rc.GetY() );
|
|
rc = *it;
|
|
it = m_vFreeRectList.erase(it);
|
|
continue;
|
|
}
|
|
|
|
// 오른쪽에 붙음
|
|
if( rc.GetLeft() == (*it).GetLeft() + (*it).GetWidth() )
|
|
{
|
|
(*it).SetWidth( (*it).GetWidth() + rc.GetWidth() );
|
|
rc = *it;
|
|
it = m_vFreeRectList.erase(it);
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
// }
|
|
#endif // // }
|
|
|
|
for( it = m_vFreeRectList.begin(); it != m_vFreeRectList.end(); ++it )
|
|
{
|
|
if( COLLISION( *it, rc ) )
|
|
{
|
|
assert( 0 );
|
|
}
|
|
}
|
|
m_vFreeRectList.push_back( rc );
|
|
|
|
CalcPtList();
|
|
}
|
|
|
|
void CalcPtList()
|
|
{
|
|
m_FreeSize = 0;
|
|
|
|
std::vector< Rect >::iterator it;
|
|
|
|
m_vXPtList.erase( m_vXPtList.begin(), m_vXPtList.end() );
|
|
m_vYPtList.erase( m_vYPtList.begin(), m_vYPtList.end() );
|
|
|
|
for( it = m_vFreeRectList.begin(); it != m_vFreeRectList.end(); ++it )
|
|
{
|
|
if( std::find( m_vXPtList.begin(), m_vXPtList.end(), (*it).GetLeft() ) == m_vXPtList.end() ) m_vXPtList.push_back( (*it).GetLeft() );
|
|
if( std::find( m_vYPtList.begin(), m_vYPtList.end(), (*it).GetTop() ) == m_vYPtList.end() ) m_vYPtList.push_back( (*it).GetTop() );
|
|
if( std::find( m_vXPtList.begin(), m_vXPtList.end(), (*it).GetRight() + 1 ) == m_vXPtList.end() ) m_vXPtList.push_back( (*it).GetRight() + 1 );
|
|
if( std::find( m_vYPtList.begin(), m_vYPtList.end(), (*it).GetBottom() + 1 ) == m_vYPtList.end() ) m_vYPtList.push_back( (*it).GetBottom() + 1 );
|
|
|
|
m_FreeSize += (*it).GetSize();
|
|
}
|
|
|
|
std::sort( m_vXPtList.begin(), m_vXPtList.end() );
|
|
std::sort( m_vYPtList.begin(), m_vYPtList.end() );
|
|
}
|
|
|
|
bool m_bInitialized;
|
|
std::vector< T > m_vXPtList;
|
|
std::vector< T > m_vYPtList;
|
|
std::vector< Rect > m_vFreeRectList;
|
|
Rect m_rcEffectiveArea;
|
|
T m_FreeSize;
|
|
};
|
|
|
|
QUAD_TREE m_AllocatedRectTree;
|
|
std::vector< FreeRectChunk > m_vChunkList;
|
|
|
|
struct _Rect
|
|
{
|
|
void operator()( const Rect & rc )
|
|
{
|
|
bFound = true;
|
|
m_rect = rc;
|
|
}
|
|
bool bFound;
|
|
Rect m_rect;
|
|
};
|
|
|
|
struct _RectList
|
|
{
|
|
void operator()( const Rect & rc )
|
|
{
|
|
bFound = true;
|
|
m_lstRect.push_back( rc );
|
|
}
|
|
bool bFound;
|
|
std::vector< Rect > m_lstRect;
|
|
};
|
|
};
|
|
|
|
}; // namespace X2D
|