为数据结构添加setProperty和getProperty

为手头游戏项目写编器,关联编器和游戏中的游戏对象的属性成了一个不小的问题,经过多经改写总算有一个相对好点的方案了,如果大家有更好的解决方案,请指点:

不废话,上代码:

原文地址:http://blog.csdn.net/wzq9706/article/details/7924881


myProperty.h

// 王智泉
#ifndef __myProperty__H__
#define __myProperty__H__
#include <string>
#include <vector>

// @注意: 以下的宏只能在CPP文件中使用

/* 定义一个属性
@param ownerClass: 宿主类
@param propertyName: 属性名 
@param bindVar: 邦定的变量
@param defaultVal: 默认值
@param describe: 描述
**/
// =================================================================
#define myDEF_PROPERTY(ownerClass, propertyName, bindVar, describe)\
class  ownerClass##bindVar##Pty : public myProperty\
{\
public:\
	ownerClass##bindVar##Pty():myProperty(propertyName, describe){}\
	virtual void setter(myPropertySet* owner, const std::string& val)\
	{\
	str2val(val, &(static_cast<ownerClass*>(owner)->##bindVar));\
	}\
	virtual std::string getter(const myPropertySet* owner)\
	{\
	return val2str(static_cast<const ownerClass*>(owner)->##bindVar);\
	}\
	virtual std::string getValueType(const myPropertySet* owner)\
	{\
	return getvalType( static_cast<const ownerClass*>(owner)->##bindVar );\
	}\
};\
	static ownerClass##bindVar##Pty s_pty##ownerClass##bindVar;

// 清空属性可能的值
#define myClearPropertyPossVals(ownerClass, bindVar)\
	 s_pty##ownerClass##bindVar._possibleVal.clear();

// 为属性增加可选的值
#define myAddPropertyPossVal(ownerClass, bindVar, possibleVal)\
	 s_pty##ownerClass##bindVar._possibleVal.push_back(possibleVal);

/* 注册属性
@param ownerClass: 类名
@param propertyName: 属性名
**/
#define myRegisterProperty(ownerClass, bindVar)\
	registerProperty_impl(&s_pty##ownerClass##bindVar);\
	s_pty##ownerClass##bindVar._defaultVal = s_pty##ownerClass##bindVar.val2str(bindVar);



// 属性类
// =====================================================================
class myPropertySet;
class  myProperty
{
public:

	/* 构造函数
	@param name: 属性名
	@param valType: 数据类型
	@param describe: 描述
	**/
	myProperty(const std::string& name, const std::string& describe)
	: _name(name)
	, _describe(describe)
	{}

	virtual ~myProperty(){}

	/* 设置属性
	@param owner: 该属性的宿主(myPorpertySet的子类)
	@param val: 该属性对应的值
	**/
	virtual void setter(myPropertySet* owner, const std::string& val) = 0;

	/* 获得属性
	@param owner: 该属性的宿主(myPorpertySet的子类)
	**/
	virtual std::string getter(const myPropertySet* owner) = 0;

	/* 获得属性的数据类型
	@param owner: 宿主
	@return: 返回数据类型的名称(int, float, bool, string, ...)
	**/
	virtual std::string getValueType(const myPropertySet* owner) = 0;

public:

	// 将字符串转化成其它类型
	void str2val(const std::string& str, int* val) { *val = atoi(str.c_str());}
	void str2val(const std::string& str, float* val){ *val = (float)atof(str.c_str()); }
	void str2val(const std::string& str, bool* val){ *val = str == "TRUE"; }
	void str2val(const std::string& str, std::string* val){ *val = str; }

	// 奖其它类型转化成字符串
	std::string val2str(int val) {char str[128] = {0}; sprintf(str, "%d", val); return str; }
	std::string val2str(float val) {char str[128] = {0}; sprintf(str, "%.2f", val); return str; }
	std::string val2str(bool val) { return val ? "TRUE" : "FALSE"; }
	std::string val2str(const std::string& val){ return val; }
	std::string val2str(double val){ return val2str((float)val); }

	// 获得属性的数据类型
	std::string getvalType(int val) {return "int";}
	std::string getvalType(float val) {return "float";}
	std::string getvalType(bool val) {return "bool";}
	std::string getvalType(std::string val) {return "string";}


public:

	std::string _name;							// 属性的名称
	std::string _defaultVal;					// 默认值
	std::string _describe;						// 描述
	std::vector<std::string> _possibleVal;		// 可用的值
};

#endif

myProperty.cpp

#include "myProperty.h"

myPropertySet.h

// 王智泉
// 属性集
#ifndef __myPropertySet__H__
#define __myPropertySet__H__
#include <string>
#include <map>

// 关闭自动排序(还未用)
template<class T>
struct DisableCompare
{
	bool operator()(const T& lhs, const T& rhs)  const
	{
		return true;
	}

	bool operator<(const T& rhs)  const
	{
		return true;
	}
};

// 属性集
// ======================================================================
class myProperty;
class  myPropertySet
{
public:

	typedef std::map<std::string, myProperty*> PropertyList;

	myPropertySet(void);

	virtual ~myPropertySet(void);

	/* 注册属性
	@param pty: 属性
	**/
	void registerProperty_impl(myProperty* pty);

	/* 设置属性
	@param name: 属性名
	@param val:	属性值
	**/
	void setProperty(const std::string& name, const std::string& val);

	/* 获得属性值信息
	@param name: 属性名
	@return: 返回属性名对应的值
	**/
	std::string getProperty(const std::string& name) const;

	/* 获得属性
	@param name: 属性名
	@return: 返回属性名对应的属性指针
	*/
	myProperty* getPropertyPtr(const std::string& name);

	/* 获得指定属性的数据类型
	@param name:  属性名
	@return: 返回指定属性的数据类型
	**/
	std::string getPropertyValueType(const std::string& name) const;

public:

	PropertyList _ptysList;
};


#endif


myPropertySet.cpp


#include "myPropertySet.h"
#include "myProperty.h"
#include <assert.h>

// ================================================================
myPropertySet::myPropertySet(void)
{
}

// ================================================================
myPropertySet::~myPropertySet(void)
{
}

// ================================================================
void myPropertySet::registerProperty_impl(myProperty * pty)
{
	_ptysList[pty->_name] = pty;
}

// ================================================================
void myPropertySet::setProperty(const std::string& name, const std::string& val)
{
	myPropertySet::PropertyList::iterator pos = _ptysList.find(name);
	if (pos != _ptysList.end())
	{
		pos->second->setter(this, val);
	}
}

// ================================================================
std::string myPropertySet::getProperty(const std::string& name) const
{
	myPropertySet::PropertyList::const_iterator pos = _ptysList.find(name);
	assert(pos != _ptysList.end());
	return pos->second->getter(this);
}

// ================================================================
myProperty* myPropertySet::getPropertyPtr(const std::string& name)
{
	myPropertySet::PropertyList::const_iterator pos = _ptysList.find(name);
	if (pos != _ptysList.end())
		return pos->second;
	return NULL;
}

// ================================================================
std::string myPropertySet::getPropertyValueType(const std::string& name) const
{
	myPropertySet::PropertyList::const_iterator pos = _ptysList.find(name);
	assert(pos != _ptysList.end());
	return pos->second->getValueType(this);
}

myMain.cpp

// 王智泉
#include "myPropertySet.h"
#include "myProperty.h"
#include <iostream>

class myTest : public myPropertySet
{
public:

	myTest();
	int _intVal;
	float _floatVal;
	std::string _strVal;
	bool _boolVal;
};

// 定义属性
myDEF_PROPERTY(myTest, "IntValue", _intVal, "这是整型");
myDEF_PROPERTY(myTest, "FloatValue", _floatVal, "这是浮点型");
myDEF_PROPERTY(myTest, "StringValue", _strVal, "这是字符串");
myDEF_PROPERTY(myTest, "BOOLValue", _boolVal, "这是布尔型");

myTest::myTest()
{
	// 注册属性,一定人先调用myDEF_PROPERTY定义对应的属性
	myRegisterProperty(myTest, _intVal);
	myRegisterProperty(myTest, _floatVal);
	myRegisterProperty(myTest, _strVal);
	myRegisterProperty(myTest, _boolVal);
}

int main()
{
	myTest test;
	test.setProperty("IntValue", "10");
	test.setProperty("FloatValue", "10");
	test.setProperty("StringValue", "我叫王智泉,哈哈....");
	test.setProperty("BOOLValue", "TRUE");
	std::cout << "IntValue:" << test._intVal  << "\nFloatValue:" << test._floatVal << "\nStringValue:" << test._strVal << "\nBOOLValue:" << test._boolVal << std::endl;

	test._intVal = 100;
	test._floatVal = 100.0f;
	test._strVal = "Are you a programming monkey?";
	test._boolVal = false;
	std::cout << "\nIntValue:" << test.getProperty("IntValue")  << "\nFloatValue:" << test.getProperty("FloatValue") << "\nStringValue:" << test.getProperty("StringValue") << "\nBOOLValue:" << test.getProperty("BOOLValue") << std::endl;
	return 0;
}

输出结果:

IntValue:10
FloatValue:10
StringValue:我叫王智泉,哈哈....
BOOLValue:1


IntValue:100
FloatValue:100.00
StringValue:Are you a programming monkey?
BOOLValue:FALSE

原文地址:https://www.cnblogs.com/iapp/p/3631785.html