Skip to content

Instantly share code, notes, and snippets.

@darkfall
Created April 18, 2014 14:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save darkfall/11047818 to your computer and use it in GitHub Desktop.
Save darkfall/11047818 to your computer and use it in GitHub Desktop.
Get component test
#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