为手头游戏项目写编器,关联编器和游戏中的游戏对象的属性成了一个不小的问题,经过多经改写总算有一个相对好点的方案了,如果大家有更好的解决方案,请指点:
不废话,上代码:
原文地址: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