DataProxy実装

3063 ワード

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の宣言は1つのリストに置かれており、GetData、SetDataのたびにリストを巡回する必要があります.まだ改善策は考えられていませんが、hashテーブルはもちろんできます.2つのhashテーブルを作ってrttiごとにitemが保存されます.しかし、templateの直接的な解法が望ましい.
==============================================================================
朝起きて少し時間をかけて、上記の効率問題に関する機能を実現しました.現在
GetDataとSetDataはそれぞれ
GetData<0, int>();
およびSetData<0,int>(CHANGED_VALUE);
nameでindexを作るのはテンプレート化できないようです.だからnameのlist検索メカニズムは依然として残っています.