Created
April 18, 2014 14:46
-
-
Save darkfall/11047818 to your computer and use it in GitHub Desktop.
Get component test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <vector> | |
#include <set> | |
struct TypeDescriptor { | |
TypeDescriptor* parent; | |
const char* name; | |
typedef std::set<TypeDescriptor*> ChildList; | |
ChildList children; | |
}; | |
class CBase { | |
public: | |
size_t _size; | |
TypeDescriptor* _typeDescriptor; | |
CBase(): _size(0), _typeDescriptor(0) { | |
} | |
}; | |
#define BUILD_TYPE_DESCRIPTOR(T) \ | |
if(_size < sizeof(T)) { \ | |
_size = sizeof(T); \ | |
_typeDescriptor = &Type; \ | |
_typeDescriptor->name = #T; \ | |
}\ | |
#define BUILD_TYPE_DESCRIPTOR_2(T, Base) \ | |
if(_size < sizeof(T)) { \ | |
_size = sizeof(T); \ | |
_typeDescriptor = &Type; \ | |
_typeDescriptor->name = #T; \ | |
_typeDescriptor->parent = &Base::Type; \ | |
Base::Type.children.insert(&Type); \ | |
}\ | |
class Component: public virtual CBase { | |
public: | |
static TypeDescriptor Type; | |
Component() { | |
BUILD_TYPE_DESCRIPTOR(Component); | |
} | |
}; | |
class C1: public virtual Component { | |
public: | |
static TypeDescriptor Type; | |
C1() { | |
BUILD_TYPE_DESCRIPTOR_2(C1, Component); | |
} | |
}; | |
class C2: public virtual Component { | |
public: | |
static TypeDescriptor Type; | |
C2() { | |
BUILD_TYPE_DESCRIPTOR_2(C2, Component); | |
} | |
}; | |
class C3: public virtual C1 { | |
public: | |
static TypeDescriptor Type; | |
C3() { | |
BUILD_TYPE_DESCRIPTOR_2(C3, C1); | |
} | |
}; | |
class C4: public virtual C2 { | |
public: | |
static TypeDescriptor Type; | |
C4() { | |
BUILD_TYPE_DESCRIPTOR_2(C4, C2); | |
} | |
}; | |
class C5: public virtual C3 { | |
public: | |
static TypeDescriptor Type; | |
C5() { | |
BUILD_TYPE_DESCRIPTOR_2(C5, C3); | |
} | |
}; | |
TypeDescriptor Component::Type; | |
TypeDescriptor C1::Type; | |
TypeDescriptor C2::Type; | |
TypeDescriptor C3::Type; | |
TypeDescriptor C4::Type; | |
TypeDescriptor C5::Type; | |
template<typename T> | |
void dump(const std::vector<T*>& l, bool dumpChild=false) { | |
for(auto c: l) { | |
printf("%s, Size = %d\t", c->_typeDescriptor->name, c->_size); | |
if(c->_typeDescriptor->parent) { | |
printf("(Parent = %s)", c->_typeDescriptor->parent->name); | |
} | |
printf("\n"); | |
if(dumpChild) { | |
for(auto ci: c->_typeDescriptor->children) { | |
printf("\t%s\n", ci->name); | |
} | |
} | |
} | |
} | |
template<typename T> | |
std::vector<T*> GetComponent(const std::vector<Component*> cl) { | |
TypeDescriptor* pt = &T::Type; | |
std::vector<T*> result; | |
for(auto c: cl) { | |
TypeDescriptor* ct = c->_typeDescriptor; | |
if(ct == pt) { | |
result.push_back(reinterpret_cast<T*>(c)); | |
} | |
else { | |
// reverse | |
TypeDescriptor* parent = c->_typeDescriptor->parent; | |
while(parent) { | |
if(parent == pt) { | |
result.push_back(reinterpret_cast<T*>(c)); | |
break; | |
} | |
parent = parent->parent; | |
} | |
} | |
} | |
return result; | |
} | |
int main() | |
{ | |
std::vector<Component*> components; | |
components.push_back(new C3()); | |
components.push_back(new C2()); | |
components.push_back(new C1()); | |
components.push_back(new C4()); | |
components.push_back(new C5()); | |
components.push_back(new Component()); | |
dump(components); | |
{ | |
printf("\n\nGet Component (C3):\n"); | |
auto aaa = GetComponent<C3>(components); | |
dump(aaa); | |
} | |
{ | |
printf("\n\nGet Component (C2):\n"); | |
auto aaa = GetComponent<C2>(components); | |
dump(aaa); | |
} | |
{ | |
printf("\n\nGet Component (C1):\n"); | |
auto aaa = GetComponent<C1>(components); | |
dump(aaa); | |
} | |
getchar(); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment