SlideShare a Scribd company logo
1 of 15
Download to read offline
GPG 
1.6 범용 핸들 기반 자원 관리자 
P. 115 - 129 
NHN NEXT 
남현욱
범용 핸들 기반 자원 관리자 
자원 관리의 필요성 
• 자원의 중복 생성 
- 어떤 자원이 이미 생성된 자원이고 하나만 있으면 충분한 경우, 이를 단 하나만 생성하도록 
제어해주는 것이 좋다 
• 자원의 공유 관리 
- 어떤 한 자원이 여러 개체에 의해 사용될 때 이를 관리하지 않으면 댕글링 포인터 등의 문제가 
생긴다. 
• 성능과 안전성 확보 
- 자원의 생성과 해제 시점, 상태를 관리함으로써 성능을 유지하면서 시스템의 안전성을 확보 
할 수 있다.
범용 핸들 기반 자원 관리자 
방법 
핸들(Handle)개념을 이용하자 
메모리 
포인터 
핸들 
관리자 
포인터를 핸들이라는 추상화 층으 
로 한 번 더 감싸서 관리함으로써 
제어하기 힘들고 위험한 포인터를 
직접적으로 건네주지 않는다.
범용 핸들 기반 자원 관리자 
구현 예제 
범용 핸들(Handle)클래스 
가장 간단한 방법은 두 개의 비트필드 요소를 이용하는 것 
-각각 index, magicNumber의 역할을 한다. index는 Handle과 연결된 자원이 무엇인지를 판 
별하는 식별자 역할을 하며, magicNumber는 해당 핸들이 유효한지를 검증하는 역할을 한다. 
핸들은 읽기 전용 
- 핸들은 데이터를 참조하기 위한 값이므로 한 번 생성되면 수정될 일은 거의 없다고 봐도 된다. 
구분을 위한 태그(Tag)의 이용 
-범용적으로 이용되는 클래스기 때문에 서로 다른 자원에 대한 핸들이 서로 타입 구분이 되지 않 
는다. 따라서 이를 구분하기 위한 용도로 태그를 이용한다(코드 참조)
범용 핸들 기반 자원 관리자 
구현 예제 
범용 핸들(Handle)클래스 
template <typename TAG> 
class Handle 
{ 
public: 
Handle() : m_Handle(0) { } 
void Init(unsigned int index); 
unsigned int GetIndex() const; 
unsigned int GetMagic() const; 
unsigned int GetHandle() const; 
bool IsNull () const; 
private: 
union 
{ 
enum 
{ 
MAX_BITS_INDEX = 16, 
MAX_BITS_MAGIC = 16, 
MAX_INDEX = (1 << MAX_BITS_INDEX) - 1, 
MAX_MAGIC = (1 << MAX_BITS_MAGIC) - 1, 
} 
struct 
{ 
unsigned m_Index : MAX_BITS_INDEX; 
unsigned m_Magic : MAX_BITS_MAGIC; 
}; 
unsigned int m_Handle; 
} 
}; 
template <typename TAG> 
void Handle<TAG> ::Init(unsigned int index) 
{ 
static unsigned int s_AutoMagic = index; 
if (++s_AutoMagic > MAX_MAGIC) 
{ 
s_AutoMagic = 1; 
} 
m_Index = index; 
m_Magic = s_AutoMagic; 
}
범용 핸들 기반 자원 관리자 
구현 예제 
범용 핸들(Handle)클래스 
template <typename TAG> 
class Handle 
{ 
public: 
Handle() : m_Handle(0) { } 
void Init(unsigned int index); 
unsigned int GetIndex() const; 
unsigned int GetMagic() const; 
unsigned int GetHandle() const; 
bool IsNull () const; 
private: 
union 
{ 
enum 
{ 
MAX_BITS_INDEX = 16, 
MAX_BITS_MAGIC = 16, 
핸들 구분을 위한 태그. 오로지 구분 만을 위한 목 
적이므로 빈 구조체같은 걸 이용하는게 좋다. 
ex) 
struct TagTexture{}; 
typedef Handle<TagTexture> HTexture; 
HTexture hTexture; 
MAX_INDEX = (1 << MAX_BITS_INDEX) - 1, 
MAX_MAGIC = (1 << MAX_BITS_MAGIC) - 1, 
} 
struct 
{ 
unsigned m_Index : MAX_BITS_INDEX; 
unsigned m_Magic : MAX_BITS_MAGIC; 
}; 
unsigned int m_Handle; 
} 
}; 
template <typename TAG> 
void Handle<TAG> ::Init(unsigned int index) 
{ 
static unsigned int s_AutoMagic = index; 
if (++s_AutoMagic > MAX_MAGIC) 
{ 
s_AutoMagic = 1; 
} 
m_Index = index; 
m_Magic = s_AutoMagic; 
}
범용 핸들 기반 자원 관리자 
구현 예제 
범용 핸들(Handle)클래스 
template <typename TAG> 
class Handle 
{ 
public: 
Handle() : m_Handle(0) { } 
void Init(unsigned int index); 
unsigned int GetIndex() const; 
unsigned int GetMagic() const; 
unsigned int GetHandle() const; 
bool IsNull () const; 
private: 
union 
{ 
enum 
{ 
MAX_BITS_INDEX = 16, 
MAX_BITS_MAGIC = 16, 
MAX_INDEX = (1 << MAX_BITS_INDEX) - 1, 
MAX_MAGIC = (1 << MAX_BITS_MAGIC) - 1, 
} 
struct 
{ 
unsigned m_Index : MAX_BITS_INDEX; 
unsigned m_Magic : MAX_BITS_MAGIC; 
}; 
unsigned int m_Handle; 
} 
}; 
template <typename TAG> 
void Handle<TAG> ::Init(unsigned int index) 
{ 
static unsigned int s_AutoMagic = index; 
if (++s_AutoMagic > MAX_MAGIC) 
{ 
s_AutoMagic = 1; 
} 
m_Index = index; 
m_Magic = s_AutoMagic; 
} 
내부적으로 핸들은 아래와 같은 구조를 지닌다. 
m_Handle 
m_Index m_Magic
범용 핸들 기반 자원 관리자 
구현 예제 
범용 핸들(Handle)클래스 
template <typename TAG> 
class Handle 
{ 
public: 
Handle() : m_Handle(0) { } 
void Init(unsigned int index); 
unsigned int GetIndex() const; 
unsigned int GetMagic() const; 
unsigned int GetHandle() const; 
bool IsNull () const; 
private: 
union 
{ 
enum 
{ 
MAX_BITS_INDEX = 16, 
MAX_BITS_MAGIC = 16, 
MAX_INDEX = (1 << MAX_BITS_INDEX) - 1, 
MAX_MAGIC = (1 << MAX_BITS_MAGIC) - 1, 
} 
struct 
{ 
unsigned m_Index : MAX_BITS_INDEX; 
unsigned m_Magic : MAX_BITS_MAGIC; 
}; 
unsigned int m_Handle; 
} 
}; 
template <typename TAG> 
void Handle<TAG> ::Init(unsigned int index) 
{ 
static unsigned int s_AutoMagic = index; 
if (++s_AutoMagic > MAX_MAGIC) 
{ 
s_AutoMagic = 1; 
} 
m_Index = index; 
m_Magic = s_AutoMagic; 
} 
핸들 클래스는 내부적으로 핸들 값의 저장 
과 매직 넘버를 관리하는 역할만 담당한다. 
실제 핸들을 부여하고 관리하는 작업은 핸 
들 매니저 클래스에서 담당.
범용 핸들 기반 자원 관리자 
구현 예제 
범용 핸들 매니저(HandleMgr)클래스 
핸들 매니저는 자기가 관리하는 자원 정보와 핸들을 관리 
-자원의 정보는 해당 자원에 대한 간단한 데이터들만을 포함한다. 이 데이터가 어떤 메모리의 할 
당이라든지 복잡한 행동을 수행해서는 안된다. 
핸들의 역참조(dereference)를 지원 
- 핸들 값으로부터 그 값이 유효하면 그 핸들이 가리키는 자원의 정보를 돌려주는 기능(역참조) 
을 지원한다.
범용 핸들 기반 자원 관리자 
구현 예제 
범용 핸들 매니저(HandleMgr)클래스 
template<typename DATA, typename HANDLE> 
class HandleMgr 
{ 
private: 
std::vector<DATA> m_UserData; 
std::vector<unsigned int> m_MagicNumbers; 
std::vector<unsigned int> m_FreeSlots; 
public: 
HandleMgr(){} 
~HandleMgr(){} 
DATA* Acquire(HANDLE& handle); 
void Release(HANDLE handle); 
DATA* Dereference(HANDLE handle); 
};
범용 핸들 기반 자원 관리자 
구현 예제 
범용 핸들 매니저(HandleMgr)클래스 
template<typename DATA, typename HANDLE> 
class HandleMgr 
{ 
private: 
std::vector<DATA> m_UserData; 
std::vector<unsigned int> m_MagicNumbers; 
std::vector<unsigned int> m_FreeSlots; 
public: 
HandleMgr(){} 
~HandleMgr(){} 
DATA* Acquire(HANDLE& handle); 
void Release(HANDLE handle); 
DATA* Dereference(HANDLE handle); 
}; 
template<typename DATA, typename HANDLE> 
DATA* HandleMgr <DATA, HANDLE> ::Acquire(HANDLE& handle) 
{ 
unsigned int index; 
if (m_FreeSlots.empty()) 
{ 
index = m_MagicNumbers.size(); 
handle.Init(index); 
m_UserData.push_back(DATA()); 
m_MagicNumbers.push_back(handle.GetMagic()); 
} 
else 
{ 
index = m_FreeSlots.back(); 
handle.Init(index); 
m_FreeSlots.pop_back(); 
m_MagicNumbers[index] = handle.GetMagic(); 
} 
return (m_UserData.begin() + index); 
}
범용 핸들 기반 자원 관리자 
구현 예제 
범용 핸들 매니저(HandleMgr)클래스 
template<typename DATA, typename HANDLE> 
class HandleMgr 
{ 
private: 
std::vector<DATA> m_UserData; 
std::vector<unsigned int> m_MagicNumbers; 
std::vector<unsigned int> m_FreeSlots; 
public: 
HandleMgr(){} 
~HandleMgr(){} 
DATA* Acquire(HANDLE& handle); 
void Release(HANDLE handle); 
DATA* Dereference(HANDLE handle); 
}; 
template<typename DATA, typename HANDLE> 
void HandleMgr <DATA, HANDLE>::Release(HANDLE handle) 
{ 
unsigned int index = handle.GetIndex(); 
m_MagicNumbers[index] = 0; 
m_FreeSlots.push_back(index); 
}
범용 핸들 기반 자원 관리자 
구현 예제 
범용 핸들 매니저(HandleMgr)클래스 
template<typename DATA, typename HANDLE> 
class HandleMgr 
{ 
private: 
std::vector<DATA> m_UserData; 
std::vector<unsigned int> m_MagicNumbers; 
std::vector<unsigned int> m_FreeSlots; 
public: 
HandleMgr(){} 
~HandleMgr(){} 
DATA* Acquire(HANDLE& handle); 
void Release(HANDLE handle); 
DATA* Dereference(HANDLE handle); 
}; 
template<typename DATA, typename HANDLE> 
DATA* HandleMgr <DATA, HANDLE>::Dereference(HANDLE handle) 
{ 
if (handle.IsNull())return (0); 
unsigned int index = handle.GetIndex(); 
if ((index >= m_UserData.size()) || 
(m_MagicNumbers[index] != handle.GetMagic())) 
{ 
return (0); 
} 
return (m_UserData.begin() + index); 
}
범용 핸들 기반 자원 관리자 
구현 예제 
활용 
struct TagFile{}; 
typedef Handle<TagFile> HFile; 
class FileManager 
{ 
private: 
struct FileData 
{ 
std::string m_Name; 
int m_Length; 
}; 
typedef HandleMgr<FileData, HFile> HFileMgr; 
HFileMgr m_Files; 
public: 
FileManager(); 
~FileManager(); 
HFile GetFile(const char* name); 
void DeleteFile(HFile hFile); 
const std::string& GetName(HFile hFile) const 
{ 
return (m_Files.Dereference(hFile)->m_Name); 
} 
int GetLength(HFile hFile) const 
{ 
return 
(m_Files.Dereference(hFile)->m_Length); 
} 
};
범용 핸들 기반 자원 관리자 
끝 
‘ GPG를 공부하자’ 페이스북 페이지 
https://www.facebook.com/gpgstudygogo

More Related Content

Viewers also liked

[0604 석재호]광택성사전필터링
[0604 석재호]광택성사전필터링[0604 석재호]광택성사전필터링
[0604 석재호]광택성사전필터링Jaeho Seok
 
[12 0210] gpg 2.3.7 전략적 판단 기법
[12 0210] gpg 2.3.7 전략적 판단 기법[12 0210] gpg 2.3.7 전략적 판단 기법
[12 0210] gpg 2.3.7 전략적 판단 기법SeungMin Yang
 
[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규ChangKyu Song
 
[NDC2014] 반응적 라이브 개발
[NDC2014] 반응적 라이브 개발[NDC2014] 반응적 라이브 개발
[NDC2014] 반응적 라이브 개발ChangKyu Song
 
GPG Study 4.3 카메라 제어기법
GPG Study 4.3 카메라 제어기법GPG Study 4.3 카메라 제어기법
GPG Study 4.3 카메라 제어기법연우 김
 
Windows system - memory개념잡기
Windows system - memory개념잡기Windows system - memory개념잡기
Windows system - memory개념잡기ChangKyu Song
 
GPG 1.2 템플릿 메타프로그래밍을 이용한 빠른 수학 연산
GPG 1.2 템플릿 메타프로그래밍을 이용한 빠른 수학 연산GPG 1.2 템플릿 메타프로그래밍을 이용한 빠른 수학 연산
GPG 1.2 템플릿 메타프로그래밍을 이용한 빠른 수학 연산Taeung Ra
 
Gpg gems1 1.3
Gpg gems1 1.3Gpg gems1 1.3
Gpg gems1 1.3david nc
 

Viewers also liked (11)

Gpg study1.8
Gpg study1.8Gpg study1.8
Gpg study1.8
 
[0604 석재호]광택성사전필터링
[0604 석재호]광택성사전필터링[0604 석재호]광택성사전필터링
[0604 석재호]광택성사전필터링
 
[12 0210] gpg 2.3.7 전략적 판단 기법
[12 0210] gpg 2.3.7 전략적 판단 기법[12 0210] gpg 2.3.7 전략적 판단 기법
[12 0210] gpg 2.3.7 전략적 판단 기법
 
GPG 1권 4.12 VIPM
GPG 1권 4.12 VIPMGPG 1권 4.12 VIPM
GPG 1권 4.12 VIPM
 
[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규
 
[NDC2014] 반응적 라이브 개발
[NDC2014] 반응적 라이브 개발[NDC2014] 반응적 라이브 개발
[NDC2014] 반응적 라이브 개발
 
GPG Study 4.3 카메라 제어기법
GPG Study 4.3 카메라 제어기법GPG Study 4.3 카메라 제어기법
GPG Study 4.3 카메라 제어기법
 
Gpg study5.5
Gpg study5.5Gpg study5.5
Gpg study5.5
 
Windows system - memory개념잡기
Windows system - memory개념잡기Windows system - memory개념잡기
Windows system - memory개념잡기
 
GPG 1.2 템플릿 메타프로그래밍을 이용한 빠른 수학 연산
GPG 1.2 템플릿 메타프로그래밍을 이용한 빠른 수학 연산GPG 1.2 템플릿 메타프로그래밍을 이용한 빠른 수학 연산
GPG 1.2 템플릿 메타프로그래밍을 이용한 빠른 수학 연산
 
Gpg gems1 1.3
Gpg gems1 1.3Gpg gems1 1.3
Gpg gems1 1.3
 

More from Sehyeon Nam

Game programing gems 4.17
Game programing gems 4.17Game programing gems 4.17
Game programing gems 4.17Sehyeon Nam
 
Game programing gems 4.11
Game programing gems 4.11Game programing gems 4.11
Game programing gems 4.11Sehyeon Nam
 
Game programing gems 1.11
Game programing gems 1.11Game programing gems 1.11
Game programing gems 1.11Sehyeon Nam
 
Game programing gems 1.10
Game programing gems 1.10Game programing gems 1.10
Game programing gems 1.10Sehyeon Nam
 
Game programing gems 3.4 3.6
Game programing gems 3.4 3.6Game programing gems 3.4 3.6
Game programing gems 3.4 3.6Sehyeon Nam
 
Hexagrid Draw by NHN NEXT Seo Dong Yu
Hexagrid Draw by NHN NEXT Seo Dong YuHexagrid Draw by NHN NEXT Seo Dong Yu
Hexagrid Draw by NHN NEXT Seo Dong YuSehyeon Nam
 
아르카스톤 기획
아르카스톤 기획아르카스톤 기획
아르카스톤 기획Sehyeon Nam
 
[GPG 스터디] 1.4 게임프로그래밍에서의 STL 활용
[GPG 스터디] 1.4 게임프로그래밍에서의 STL 활용 [GPG 스터디] 1.4 게임프로그래밍에서의 STL 활용
[GPG 스터디] 1.4 게임프로그래밍에서의 STL 활용 Sehyeon Nam
 
[GPG 스터디] 1.2 템플릿 메타프로그래밍을 이용한 빠른 수학 연산
[GPG 스터디] 1.2 템플릿 메타프로그래밍을 이용한 빠른 수학 연산 [GPG 스터디] 1.2 템플릿 메타프로그래밍을 이용한 빠른 수학 연산
[GPG 스터디] 1.2 템플릿 메타프로그래밍을 이용한 빠른 수학 연산 Sehyeon Nam
 
[GPG 스터디] 1.1 객체지향적 프로그래밍과 설계기법
[GPG 스터디] 1.1 객체지향적 프로그래밍과 설계기법[GPG 스터디] 1.1 객체지향적 프로그래밍과 설계기법
[GPG 스터디] 1.1 객체지향적 프로그래밍과 설계기법Sehyeon Nam
 
[GPG스터디] 1.0 데이터 주도적 설계의 마법
[GPG스터디] 1.0 데이터 주도적 설계의 마법[GPG스터디] 1.0 데이터 주도적 설계의 마법
[GPG스터디] 1.0 데이터 주도적 설계의 마법Sehyeon Nam
 
Ec++ 3,4 summary
Ec++ 3,4 summaryEc++ 3,4 summary
Ec++ 3,4 summarySehyeon Nam
 
Ec++ c 1,2 surmary
Ec++ c 1,2 surmaryEc++ c 1,2 surmary
Ec++ c 1,2 surmarySehyeon Nam
 

More from Sehyeon Nam (14)

Game programing gems 4.17
Game programing gems 4.17Game programing gems 4.17
Game programing gems 4.17
 
Game programing gems 4.11
Game programing gems 4.11Game programing gems 4.11
Game programing gems 4.11
 
Game programing gems 1.11
Game programing gems 1.11Game programing gems 1.11
Game programing gems 1.11
 
Game programing gems 1.10
Game programing gems 1.10Game programing gems 1.10
Game programing gems 1.10
 
Game programing gems 3.4 3.6
Game programing gems 3.4 3.6Game programing gems 3.4 3.6
Game programing gems 3.4 3.6
 
Hexagrid Draw by NHN NEXT Seo Dong Yu
Hexagrid Draw by NHN NEXT Seo Dong YuHexagrid Draw by NHN NEXT Seo Dong Yu
Hexagrid Draw by NHN NEXT Seo Dong Yu
 
아르카스톤 기획
아르카스톤 기획아르카스톤 기획
아르카스톤 기획
 
[GPG 스터디] 1.4 게임프로그래밍에서의 STL 활용
[GPG 스터디] 1.4 게임프로그래밍에서의 STL 활용 [GPG 스터디] 1.4 게임프로그래밍에서의 STL 활용
[GPG 스터디] 1.4 게임프로그래밍에서의 STL 활용
 
[GPG 스터디] 1.2 템플릿 메타프로그래밍을 이용한 빠른 수학 연산
[GPG 스터디] 1.2 템플릿 메타프로그래밍을 이용한 빠른 수학 연산 [GPG 스터디] 1.2 템플릿 메타프로그래밍을 이용한 빠른 수학 연산
[GPG 스터디] 1.2 템플릿 메타프로그래밍을 이용한 빠른 수학 연산
 
[GPG 스터디] 1.1 객체지향적 프로그래밍과 설계기법
[GPG 스터디] 1.1 객체지향적 프로그래밍과 설계기법[GPG 스터디] 1.1 객체지향적 프로그래밍과 설계기법
[GPG 스터디] 1.1 객체지향적 프로그래밍과 설계기법
 
[GPG스터디] 1.0 데이터 주도적 설계의 마법
[GPG스터디] 1.0 데이터 주도적 설계의 마법[GPG스터디] 1.0 데이터 주도적 설계의 마법
[GPG스터디] 1.0 데이터 주도적 설계의 마법
 
Ec++ 3,4 summary
Ec++ 3,4 summaryEc++ 3,4 summary
Ec++ 3,4 summary
 
Ec++ c 1,2 surmary
Ec++ c 1,2 surmaryEc++ c 1,2 surmary
Ec++ c 1,2 surmary
 
D2 ppt
D2 pptD2 ppt
D2 ppt
 

[GPG 스터디] 1.6 범용 핸들 기반 자원 관리자

  • 1. GPG 1.6 범용 핸들 기반 자원 관리자 P. 115 - 129 NHN NEXT 남현욱
  • 2. 범용 핸들 기반 자원 관리자 자원 관리의 필요성 • 자원의 중복 생성 - 어떤 자원이 이미 생성된 자원이고 하나만 있으면 충분한 경우, 이를 단 하나만 생성하도록 제어해주는 것이 좋다 • 자원의 공유 관리 - 어떤 한 자원이 여러 개체에 의해 사용될 때 이를 관리하지 않으면 댕글링 포인터 등의 문제가 생긴다. • 성능과 안전성 확보 - 자원의 생성과 해제 시점, 상태를 관리함으로써 성능을 유지하면서 시스템의 안전성을 확보 할 수 있다.
  • 3. 범용 핸들 기반 자원 관리자 방법 핸들(Handle)개념을 이용하자 메모리 포인터 핸들 관리자 포인터를 핸들이라는 추상화 층으 로 한 번 더 감싸서 관리함으로써 제어하기 힘들고 위험한 포인터를 직접적으로 건네주지 않는다.
  • 4. 범용 핸들 기반 자원 관리자 구현 예제 범용 핸들(Handle)클래스 가장 간단한 방법은 두 개의 비트필드 요소를 이용하는 것 -각각 index, magicNumber의 역할을 한다. index는 Handle과 연결된 자원이 무엇인지를 판 별하는 식별자 역할을 하며, magicNumber는 해당 핸들이 유효한지를 검증하는 역할을 한다. 핸들은 읽기 전용 - 핸들은 데이터를 참조하기 위한 값이므로 한 번 생성되면 수정될 일은 거의 없다고 봐도 된다. 구분을 위한 태그(Tag)의 이용 -범용적으로 이용되는 클래스기 때문에 서로 다른 자원에 대한 핸들이 서로 타입 구분이 되지 않 는다. 따라서 이를 구분하기 위한 용도로 태그를 이용한다(코드 참조)
  • 5. 범용 핸들 기반 자원 관리자 구현 예제 범용 핸들(Handle)클래스 template <typename TAG> class Handle { public: Handle() : m_Handle(0) { } void Init(unsigned int index); unsigned int GetIndex() const; unsigned int GetMagic() const; unsigned int GetHandle() const; bool IsNull () const; private: union { enum { MAX_BITS_INDEX = 16, MAX_BITS_MAGIC = 16, MAX_INDEX = (1 << MAX_BITS_INDEX) - 1, MAX_MAGIC = (1 << MAX_BITS_MAGIC) - 1, } struct { unsigned m_Index : MAX_BITS_INDEX; unsigned m_Magic : MAX_BITS_MAGIC; }; unsigned int m_Handle; } }; template <typename TAG> void Handle<TAG> ::Init(unsigned int index) { static unsigned int s_AutoMagic = index; if (++s_AutoMagic > MAX_MAGIC) { s_AutoMagic = 1; } m_Index = index; m_Magic = s_AutoMagic; }
  • 6. 범용 핸들 기반 자원 관리자 구현 예제 범용 핸들(Handle)클래스 template <typename TAG> class Handle { public: Handle() : m_Handle(0) { } void Init(unsigned int index); unsigned int GetIndex() const; unsigned int GetMagic() const; unsigned int GetHandle() const; bool IsNull () const; private: union { enum { MAX_BITS_INDEX = 16, MAX_BITS_MAGIC = 16, 핸들 구분을 위한 태그. 오로지 구분 만을 위한 목 적이므로 빈 구조체같은 걸 이용하는게 좋다. ex) struct TagTexture{}; typedef Handle<TagTexture> HTexture; HTexture hTexture; MAX_INDEX = (1 << MAX_BITS_INDEX) - 1, MAX_MAGIC = (1 << MAX_BITS_MAGIC) - 1, } struct { unsigned m_Index : MAX_BITS_INDEX; unsigned m_Magic : MAX_BITS_MAGIC; }; unsigned int m_Handle; } }; template <typename TAG> void Handle<TAG> ::Init(unsigned int index) { static unsigned int s_AutoMagic = index; if (++s_AutoMagic > MAX_MAGIC) { s_AutoMagic = 1; } m_Index = index; m_Magic = s_AutoMagic; }
  • 7. 범용 핸들 기반 자원 관리자 구현 예제 범용 핸들(Handle)클래스 template <typename TAG> class Handle { public: Handle() : m_Handle(0) { } void Init(unsigned int index); unsigned int GetIndex() const; unsigned int GetMagic() const; unsigned int GetHandle() const; bool IsNull () const; private: union { enum { MAX_BITS_INDEX = 16, MAX_BITS_MAGIC = 16, MAX_INDEX = (1 << MAX_BITS_INDEX) - 1, MAX_MAGIC = (1 << MAX_BITS_MAGIC) - 1, } struct { unsigned m_Index : MAX_BITS_INDEX; unsigned m_Magic : MAX_BITS_MAGIC; }; unsigned int m_Handle; } }; template <typename TAG> void Handle<TAG> ::Init(unsigned int index) { static unsigned int s_AutoMagic = index; if (++s_AutoMagic > MAX_MAGIC) { s_AutoMagic = 1; } m_Index = index; m_Magic = s_AutoMagic; } 내부적으로 핸들은 아래와 같은 구조를 지닌다. m_Handle m_Index m_Magic
  • 8. 범용 핸들 기반 자원 관리자 구현 예제 범용 핸들(Handle)클래스 template <typename TAG> class Handle { public: Handle() : m_Handle(0) { } void Init(unsigned int index); unsigned int GetIndex() const; unsigned int GetMagic() const; unsigned int GetHandle() const; bool IsNull () const; private: union { enum { MAX_BITS_INDEX = 16, MAX_BITS_MAGIC = 16, MAX_INDEX = (1 << MAX_BITS_INDEX) - 1, MAX_MAGIC = (1 << MAX_BITS_MAGIC) - 1, } struct { unsigned m_Index : MAX_BITS_INDEX; unsigned m_Magic : MAX_BITS_MAGIC; }; unsigned int m_Handle; } }; template <typename TAG> void Handle<TAG> ::Init(unsigned int index) { static unsigned int s_AutoMagic = index; if (++s_AutoMagic > MAX_MAGIC) { s_AutoMagic = 1; } m_Index = index; m_Magic = s_AutoMagic; } 핸들 클래스는 내부적으로 핸들 값의 저장 과 매직 넘버를 관리하는 역할만 담당한다. 실제 핸들을 부여하고 관리하는 작업은 핸 들 매니저 클래스에서 담당.
  • 9. 범용 핸들 기반 자원 관리자 구현 예제 범용 핸들 매니저(HandleMgr)클래스 핸들 매니저는 자기가 관리하는 자원 정보와 핸들을 관리 -자원의 정보는 해당 자원에 대한 간단한 데이터들만을 포함한다. 이 데이터가 어떤 메모리의 할 당이라든지 복잡한 행동을 수행해서는 안된다. 핸들의 역참조(dereference)를 지원 - 핸들 값으로부터 그 값이 유효하면 그 핸들이 가리키는 자원의 정보를 돌려주는 기능(역참조) 을 지원한다.
  • 10. 범용 핸들 기반 자원 관리자 구현 예제 범용 핸들 매니저(HandleMgr)클래스 template<typename DATA, typename HANDLE> class HandleMgr { private: std::vector<DATA> m_UserData; std::vector<unsigned int> m_MagicNumbers; std::vector<unsigned int> m_FreeSlots; public: HandleMgr(){} ~HandleMgr(){} DATA* Acquire(HANDLE& handle); void Release(HANDLE handle); DATA* Dereference(HANDLE handle); };
  • 11. 범용 핸들 기반 자원 관리자 구현 예제 범용 핸들 매니저(HandleMgr)클래스 template<typename DATA, typename HANDLE> class HandleMgr { private: std::vector<DATA> m_UserData; std::vector<unsigned int> m_MagicNumbers; std::vector<unsigned int> m_FreeSlots; public: HandleMgr(){} ~HandleMgr(){} DATA* Acquire(HANDLE& handle); void Release(HANDLE handle); DATA* Dereference(HANDLE handle); }; template<typename DATA, typename HANDLE> DATA* HandleMgr <DATA, HANDLE> ::Acquire(HANDLE& handle) { unsigned int index; if (m_FreeSlots.empty()) { index = m_MagicNumbers.size(); handle.Init(index); m_UserData.push_back(DATA()); m_MagicNumbers.push_back(handle.GetMagic()); } else { index = m_FreeSlots.back(); handle.Init(index); m_FreeSlots.pop_back(); m_MagicNumbers[index] = handle.GetMagic(); } return (m_UserData.begin() + index); }
  • 12. 범용 핸들 기반 자원 관리자 구현 예제 범용 핸들 매니저(HandleMgr)클래스 template<typename DATA, typename HANDLE> class HandleMgr { private: std::vector<DATA> m_UserData; std::vector<unsigned int> m_MagicNumbers; std::vector<unsigned int> m_FreeSlots; public: HandleMgr(){} ~HandleMgr(){} DATA* Acquire(HANDLE& handle); void Release(HANDLE handle); DATA* Dereference(HANDLE handle); }; template<typename DATA, typename HANDLE> void HandleMgr <DATA, HANDLE>::Release(HANDLE handle) { unsigned int index = handle.GetIndex(); m_MagicNumbers[index] = 0; m_FreeSlots.push_back(index); }
  • 13. 범용 핸들 기반 자원 관리자 구현 예제 범용 핸들 매니저(HandleMgr)클래스 template<typename DATA, typename HANDLE> class HandleMgr { private: std::vector<DATA> m_UserData; std::vector<unsigned int> m_MagicNumbers; std::vector<unsigned int> m_FreeSlots; public: HandleMgr(){} ~HandleMgr(){} DATA* Acquire(HANDLE& handle); void Release(HANDLE handle); DATA* Dereference(HANDLE handle); }; template<typename DATA, typename HANDLE> DATA* HandleMgr <DATA, HANDLE>::Dereference(HANDLE handle) { if (handle.IsNull())return (0); unsigned int index = handle.GetIndex(); if ((index >= m_UserData.size()) || (m_MagicNumbers[index] != handle.GetMagic())) { return (0); } return (m_UserData.begin() + index); }
  • 14. 범용 핸들 기반 자원 관리자 구현 예제 활용 struct TagFile{}; typedef Handle<TagFile> HFile; class FileManager { private: struct FileData { std::string m_Name; int m_Length; }; typedef HandleMgr<FileData, HFile> HFileMgr; HFileMgr m_Files; public: FileManager(); ~FileManager(); HFile GetFile(const char* name); void DeleteFile(HFile hFile); const std::string& GetName(HFile hFile) const { return (m_Files.Dereference(hFile)->m_Name); } int GetLength(HFile hFile) const { return (m_Files.Dereference(hFile)->m_Length); } };
  • 15. 범용 핸들 기반 자원 관리자 끝 ‘ GPG를 공부하자’ 페이스북 페이지 https://www.facebook.com/gpgstudygogo