写了一个小东西,用于实现DataProxy机制,暂时还处于试验阶段:
class TestDataObjectDeclaration : public Test
{
public:
TestDataObjectDeclaration();
public:
virtual bool RunTest();
};
const int DEFAULT_VALUE_OF_BASE_X = 4;
const int DEFAULT_VALUE_OF_X = 5;
class MyBaseObject
{
public:
MyBaseObject() : _x(DEFAULT_VALUE_OF_BASE_X)
{}
public:
int _x;
};
class MyDataObject : public MyBaseObject, public archer::oi::DataObject<MyDataObject, MyActionProxy>
{
public:
MyDataObject() : _x(DEFAULT_VALUE_OF_X)
{}
public:
int _x;
public:
const type_info& func()
{ return ((const archer::oi::rtti_derived_class<MyDataObject>&) this->GetRuntimeTypeInfo()).typeidof(); }
};
DECLARE_RTTI(MyDataObject)
DECLARE_SIMPLE_RTTI_ITEM_OF_BASE(MyDataObject, MyBaseObject, _x, int, 0, "b_x")
DECLARE_SIMPLE_RTTI_ITEM(MyDataObject, _x, int, 1, "x")
END_DECLARE_RTTI
TestDataObjectDeclaration::TestDataObjectDeclaration() : Test("testDataObjectDeclaration") {}
bool TestDataObjectDeclaration::RunTest()
{
MyDataObject obj = MyDataObject();
char buffer[256];
sprintf(buffer, "size of MyDataObject: [%d]", sizeof(MyDataObject));
this->PromptMessage(buffer);
if (!AssertEquals(std::string(obj.func().name()), std::string("class MyDataObject"), "Get wrong type id from rtti."))
return false;
if (!AssertEquals(DEFAULT_VALUE_OF_X, obj.GetData<int>(1), "Failed to get data by rtti."))
return false;
if (!AssertEquals(DEFAULT_VALUE_OF_BASE_X, obj.GetData<int>(0), "Failed to get data of base class by rtti."))
return false;
const int CHANGED_VALUE = 10;
obj.SetData<int>(1, CHANGED_VALUE);
obj.SetData<int>(0, CHANGED_VALUE);
if (!AssertEquals(CHANGED_VALUE, obj.GetData<int>(1), "Failed to set data by rtti."))
return false;
if (!AssertEquals(CHANGED_VALUE, obj.GetData<int>(0), "Failed to set data of base class by rtti."))
return false;
return true;
}
优点是用户类MyDataObject的代码侵入很少,DataObject类可以用于多继承。data member的调用已经很类似于script语言了,GetData,SetData还可以按name查找。
缺点是data member必须为public,以及类似script语言的效率低的问题。目前rtti中,data member的声明是放在一个列表里,每次GetData, SetData时需要对列表遍历。还没有想到什么改进的办法,hash表当然是可以的,弄两个hash表把每个rtti_item存起来。但更希望有template直接的解法。
==============================================================================
早上起来花了点时间,把上面提的关于效率问题的功能实现了。现在
GetData和SetData分别变成了
GetData<0, int>();
和SetData<0, int>(CHANGED_VALUE);
而用name做index似乎是无法模板化的。所以name的list查找机制依旧保留。