为数据结构添加setProperty和getProperty

来源:岁月联盟 编辑:exp 时间:2012-08-30

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


myProperty.h

[cpp]
// 王智泉 
#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
[cpp] 
#include "myProperty.h" 

myPropertySet.h
[cpp] 
// 王智泉 
// 属性集 
#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

[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
[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