DataProxy实现

写了一个小东西,用于实现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查找机制依旧保留。

你可能感兴趣的:(D语言)