好记性不如铅笔头

C && C++, cocos2dx, 编程

cocos2dx-Lua学习笔记:CCLuaValue

最近在学习cocos2dx和Lua的交互,这里笔记下学习心得。

CONTENTS

备注:

1 作者对于Lua的使用较少,纯粹从使用出发,对它的理解较浅,可能有错误,还请路过的各位大牛多多指正。
2 本笔记代码部分参考cocos2dx2.2.3代码,代码版权归原作者所有。
3 由于作者时间,经验,能力有限,笔记可能不完整,以后随用随补充吧。

CCLuaValue.h/cpp:

NS_CC_BEGIN

typedef int LUA_FUNCTION;
typedef int LUA_TABLE;
typedef int LUA_STRING;

class CCLuaValue;

//注意这里定义了CCLuaValueDict类型,其实就是一个hashmap。
typedef std::map<std::string, CCLuaValue>   CCLuaValueDict;
typedef CCLuaValueDict::const_iterator      CCLuaValueDictIterator;

//注意这里定义了CCLuaValueArray类型,其实就是一个list。	
typedef std::list<CCLuaValue>               CCLuaValueArray;
typedef CCLuaValueArray::const_iterator     CCLuaValueArrayIterator;

//定义了CCLuaValue支持的数据类型
typedef enum {
    CCLuaValueTypeInt,
    CCLuaValueTypeFloat,
    CCLuaValueTypeBoolean,
    CCLuaValueTypeString,
    CCLuaValueTypeDict,
    CCLuaValueTypeArray,
    CCLuaValueTypeCCObject
} CCLuaValueType;

//通过union来定义存储方式,可以简化大量的存储变量。
typedef union {
    int                 intValue;
    float               floatValue;
    bool                booleanValue;
    std::string*        stringValue;
    CCLuaValueDict*     dictValue;
    CCLuaValueArray*    arrayValue;
    CCObject*           ccobjectValue;
} CCLuaValueField;

/** Lua support for cocos2d-x
 *  @js NA
 *  @lua NA
 */
class CCLuaValue
{
public:
	//各种静态工具类方法,直接返回一个CCLuaValue实例。
    static const CCLuaValue intValue(const int intValue);
    static const CCLuaValue floatValue(const float floatValue);
    static const CCLuaValue booleanValue(const bool booleanValue);
    static const CCLuaValue stringValue(const char* stringValue);
    static const CCLuaValue stringValue(const std::string& stringValue);
    static const CCLuaValue dictValue(const CCLuaValueDict& dictValue);
    static const CCLuaValue arrayValue(const CCLuaValueArray& arrayValue);
    static const CCLuaValue ccobjectValue(CCObject* ccobjectValue, const char* objectTypename);
    static const CCLuaValue ccobjectValue(CCObject* ccobjectValue, const std::string& objectTypename);
    
    //默认构造函数,默认类型为int,名称为NULL,值为NULL
    CCLuaValue(void)
    : m_type(CCLuaValueTypeInt)
    , m_ccobjectType(NULL)
    {
        memset(&m_field, 0, sizeof(m_field));
    }
    CCLuaValue(const CCLuaValue& rhs);
    CCLuaValue& operator=(const CCLuaValue& rhs);
    ~CCLuaValue(void);
    
    //各种get
    const CCLuaValueType getType(void) const {
        return m_type;
    } 
    const std::string& getCCObjectTypename(void) const {
        return *m_ccobjectType;
    }
    
    //返回不同类型的值,因为存储结构为union,因此可以直接返回。    
    int intValue(void) const {
        return m_field.intValue;
    }   
    float floatValue(void) const {
        return m_field.floatValue;
    }
    bool booleanValue(void) const {
        return m_field.booleanValue;
    }
    const std::string& stringValue(void) const {
        return *m_field.stringValue;
    }
    const CCLuaValueDict& dictValue(void) const {
        return *m_field.dictValue;
    }
    const CCLuaValueArray& arrayValue(void) const {
        return *m_field.arrayValue;
    }
    CCObject* ccobjectValue(void) const {
        return m_field.ccobjectValue;
    }
   
private:
    CCLuaValueField m_field;//定义了存储值
    CCLuaValueType  m_type;	//定义了存储类型
    std::string*    m_ccobjectType;//定义了名称,这里只有在自定义类型中才有意义。
    
    void copy(const CCLuaValue& rhs);
};

NS_CC_END

//===========================================================

NS_CC_BEGIN

//各种工具函数,快捷构造出CCLuaValue的实例
const CCLuaValue CCLuaValue::intValue(const int intValue)
{
    CCLuaValue value;
    value.m_type = CCLuaValueTypeInt;
    value.m_field.intValue = intValue;
    return value;
}
const CCLuaValue CCLuaValue::floatValue(const float floatValue)
{
    CCLuaValue value;
    value.m_type = CCLuaValueTypeFloat;
    value.m_field.floatValue = floatValue;
    return value;
}
const CCLuaValue CCLuaValue::booleanValue(const bool booleanValue)
{
    CCLuaValue value;
    value.m_type = CCLuaValueTypeBoolean;
    value.m_field.booleanValue = booleanValue;
    return value;
}
const CCLuaValue CCLuaValue::stringValue(const char* stringValue)
{
    CCLuaValue value;
    value.m_type = CCLuaValueTypeString;
    //注意这里重新拷贝了一份,这样就和入参没有关系了
    value.m_field.stringValue = new std::string(stringValue ? stringValue : "");
    return value;
}
const CCLuaValue CCLuaValue::stringValue(const std::string& stringValue)
{
    CCLuaValue value;
    value.m_type = CCLuaValueTypeString;
    //注意这里重新拷贝了一份,这样就和入参没有关系了
    value.m_field.stringValue = new std::string(stringValue);
    return value;
}
const CCLuaValue CCLuaValue::dictValue(const CCLuaValueDict& dictValue)
{
    CCLuaValue value;
    value.m_type = CCLuaValueTypeDict;
    //注意这里重新拷贝了一份,这样就和入参没有关系了
    value.m_field.dictValue = new CCLuaValueDict(dictValue);
    return value;
}
const CCLuaValue CCLuaValue::arrayValue(const CCLuaValueArray& arrayValue)
{
    CCLuaValue value;
    value.m_type = CCLuaValueTypeArray;
    //注意这里重新拷贝了一份,这样就和入参没有关系了
    value.m_field.arrayValue = new CCLuaValueArray(arrayValue);
    return value;
}
//注意这里包装了自定义类型,需要传入一个名称。
const CCLuaValue CCLuaValue::ccobjectValue(CCObject* ccobjectValue, const char* objectTypename)
{
    CCLuaValue value;
    value.m_type = CCLuaValueTypeCCObject;
    value.m_field.ccobjectValue = ccobjectValue;
    ccobjectValue->retain();//retain一次
    //注意这里重新拷贝了一份,这样就和入参没有关系了
    value.m_ccobjectType = new std::string(objectTypename);
    return value;
}
const CCLuaValue CCLuaValue::ccobjectValue(CCObject* ccobjectValue, const std::string& objectTypename)
{
    return CCLuaValue::ccobjectValue(ccobjectValue, objectTypename.c_str());
}

CCLuaValue::CCLuaValue(const CCLuaValue& rhs)
{
    copy(rhs);
}

CCLuaValue& CCLuaValue::operator=(const CCLuaValue& rhs)
{
    if (this != &rhs) copy(rhs);
    return *this;
}
//析构函数,删掉申请的内存
CCLuaValue::~CCLuaValue(void)
{
    if (m_type == CCLuaValueTypeString)
    {
        delete m_field.stringValue;
    }
    else if (m_type == CCLuaValueTypeDict)
    {
        delete m_field.dictValue;
    }
    else if (m_type == CCLuaValueTypeArray)
    {
        delete m_field.arrayValue;
    }
    else if (m_type == CCLuaValueTypeCCObject)
    {
        m_field.ccobjectValue->release();
        delete m_ccobjectType;
    }
}
//拷贝构造函数的实现为深拷贝,内存也重新申请一次。
void CCLuaValue::copy(const CCLuaValue& rhs)
{
    memcpy(&m_field, &rhs.m_field, sizeof(m_field));
    m_type = rhs.m_type;
    if (m_type == CCLuaValueTypeString)
    {
        m_field.stringValue = new std::string(*rhs.m_field.stringValue);
    }
    else if (m_type == CCLuaValueTypeDict)
    {
        m_field.dictValue = new CCLuaValueDict(*rhs.m_field.dictValue);
    }
    else if (m_type == CCLuaValueTypeArray)
    {
        m_field.arrayValue = new CCLuaValueArray(*rhs.m_field.arrayValue);
    }
    else if (m_type == CCLuaValueTypeCCObject)
    {
        m_field.ccobjectValue = rhs.m_field.ccobjectValue;
        m_field.ccobjectValue->retain();
        m_ccobjectType = new std::string(*rhs.m_ccobjectType);
    }
}

NS_CC_END

 

发表评论

18 − 4 =

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据