现在的位置: 首页 > 综合 > 正文

cocos2d-x2.1 + cocosbuilder3.0 的自动生成C++类的修改

2013年12月07日 ⁄ 综合 ⁄ 共 9753字 ⁄ 字号 评论关闭

cocosbuilder的ccb文件对应的c++类可以用自动生成c++代码的方式实现快速开发。不过作者写的针对cocos2d-x2.1 + cocosbuilder3.0稍微有点问题,都是cocos2d-x的版本更新太快,修改太大的问题。新版的ccb类bind的方法参考点击打开链接

需要把codeGen稍微改了下就OK了,代码如下:

//
//  CodeGen.h
//  cocos2dCodeGen
//
//  Created by user on 13-4-25.
//  Copyright (c) 2013年 user. All rights reserved.
//

#ifndef __cocos2dCodeGen__CodeGen__
#define __cocos2dCodeGen__CodeGen__

#include <iostream>
#include "utility.h"
#include <vector>

class CodeGen
{
public:
    std::string m_className;                        //要生成的类名
    std::string m_baseClass;                        //生成类的父类
    std::vector<TypeName> m_listAssignMember;       //需要赋值的场景对象
    std::vector<TypeName> m_listCutomProperty;      //需要赋值的自定义变量
    std::vector<std::string> m_listCContorlCallBack;//menu回调函数名
    std::vector<std::string> m_listMenuCallBack;    //control回调函数名
    
    
    void GenerateHeaderFile()
    {
        GenerateClassDec();
        GenerateInterfaceDec();
        GenerateCallBackControlDec();
        GenerateCallBackMenuDec();
        GenerateAssignMemberDec();
        GenerateCustomMemberDec();
        GenerateLayerClassEnd();
        GenerateNodeLeader();
        GenerateEnd();

    }
    void GenerateCppFile()
    {
        GenerateCppHeader();
        GenerateCallBackControl();
        GenerateCallBackMenu();
        GlueMenuCallBack();
        GlueControlCallBack();
        GlueAssignMember();
        GlueCustomMember();
        
    }
    CodeGen(std::ostream& h,std::ostream& c);
private:
    //header file
    void GenerateClassDec();
    void GenerateInterfaceDec();
    void GenerateCallBackControlDec();
    void GenerateCallBackMenuDec();
    void GenerateAssignMemberDec();
    void GenerateCustomMemberDec();
    void GenerateLayerClassEnd();
    void GenerateNodeLeader();
    void GenerateEnd();
    
    //cpp file
    void GenerateCppHeader();
    void GenerateCallBackControl();
    void GenerateCallBackMenu();

    void GlueMenuCallBack();
    void GlueControlCallBack();
    void GlueAssignMember();
    void GlueCustomMember();
    //void GeneateClass();

    std::ostream& m_header;
    std::ostream& m_cpp;


};

#endif /* defined(__cocos2dCodeGen__CodeGen__) */

对应的.mm文件:

//
//  CodeGen.cpp
//  cocos2dCodeGen
//
//  Created by user on 13-4-25.
//  Copyright (c) 2013年 user. All rights reserved.
//

#include "CodeGen.h"
#include <fstream>
#include <sstream>
#include <set>

using namespace std;

//cpp file
std::string m_cppHeader;
std::string m_callBackControl;
std::string m_callBackMenu;
std::string m_glueAssignMember;
std::string m_glueControlCallBack;
std::string m_glueMenuCallBack;
std::string m_glueCustomMember;

//header file
std::string m_classDec;
std::string m_interfaceDec;
std::string m_callBackControlDec;
std::string m_callBackMenuDec;


void string_replace( std::string &strBig, const std::string &strsrc, const std::string &strdst )
{
    std::string::size_type pos = 0;
    std::string::size_type srclen = strsrc.size();
    std::string::size_type dstlen = strdst.size();
    
    while( (pos=strBig.find(strsrc, pos)) != std::string::npos )
    {
        strBig.replace( pos, srclen, strdst );
        pos += dstlen;
    }
} 


std::string ReadTemplateFromDic(const std::string& fileName,NSDictionary * templateCppCode)
{
    
    return std::string(
            [ [templateCppCode objectForKey: [NSString stringWithFormat:@"%s",fileName.c_str()]] UTF8String]
                       );

}
CodeGen::CodeGen(std::ostream& h,std::ostream& c)
:m_header(h),m_cpp(c)
{
    //read header dec
    //read
    if (m_cppHeader == "") {
        NSString *codeTemplatePath = [[NSBundle mainBundle] pathForResource:@"codeTemplateCpp" ofType:@"plist"];
        NSDictionary * templateCppCode = [NSDictionary dictionaryWithContentsOfFile:codeTemplatePath];
        
        
        m_classDec = ReadTemplateFromDic("ClassDec.txt",templateCppCode);
        m_interfaceDec = ReadTemplateFromDic("InterfaceDec.txt",templateCppCode);
        m_callBackControlDec = ReadTemplateFromDic("CallBackCControlDec.txt",templateCppCode);
        m_callBackMenuDec = ReadTemplateFromDic("CallBackMenuDec.txt",templateCppCode);
        
        m_glueMenuCallBack = ReadTemplateFromDic("GlueMenuCallBack.txt",templateCppCode);
        m_glueCustomMember = ReadTemplateFromDic("GlueCustomMember.txt",templateCppCode);
        m_cppHeader = ReadTemplateFromDic("CppHeader.txt",templateCppCode);
        m_glueAssignMember = ReadTemplateFromDic("GlueAssignMember.txt",templateCppCode);
        m_glueControlCallBack = ReadTemplateFromDic("GlueControlCallBack.txt",templateCppCode );
        m_callBackControl = ReadTemplateFromDic("CallBackControl.txt",templateCppCode);
        m_callBackMenu = ReadTemplateFromDic("CallBackMenu.txt",templateCppCode); 
    }

    
}
void CodeGen::GlueAssignMember()
{
    m_cpp << "// glue assigned member here ;\n";
    std::string glueBegin = m_glueAssignMember;
    string_replace(glueBegin, "%class_name%", m_className);
    m_cpp << glueBegin ;
    for (const TypeName& item : m_listAssignMember)
    {
        m_cpp << "\tCCB_MEMBERVARIABLEASSIGNER_GLUE(this," << "\"" << item.name << "\"," << item.type << "*," << "this->" << item.name << ");\n";
    }
    m_cpp << "\treturn false;\n";
    m_cpp << "}\n";
}

void CodeGen::GlueCustomMember()
{
    m_cpp << "// glue custom member here ;\n";
    std::string glueBegin = m_glueCustomMember;
    string_replace(glueBegin, "%class_name%", m_className);
    m_cpp << glueBegin ;
    for (const TypeName& item : m_listCutomProperty)
    {
        m_cpp << "\t\tif (0 == strcmp(pMemberVariableName, \"" << item.name << "\")){\n";
        m_cpp << "\t\t\t"<<item.name<< " = ";
        if (item.type == "string" || item.type == "std::string")
        {
            m_cpp << "pCCBValue->getStringValue();\n";
        }
        else if(item.type == "int")
        {
            m_cpp << "pCCBValue->getIntValue();\n";
        }
        else if(item.type == "float")
        {
            m_cpp << "pCCBValue->getFloatValue();\n";
        }
        else if(item.type == "bool")
        {
            m_cpp << "pCCBValue->getBoolValue();\n";
        }
        else
        {
            m_cpp << "0;\n";
        }
        m_cpp << "\t\t\treturn true;\n";
        m_cpp << "\t\t}\n";
    }
    m_cpp << "\t}\n";
    m_cpp << "\treturn false;\n";
    m_cpp << "}\n\n";
}

void CodeGen::GlueControlCallBack()
{
    m_cpp << "// glue control button call back  here ;\n";
    std::string glueBegin = m_glueControlCallBack;
    string_replace(glueBegin, "%class_name%", m_className);
    m_cpp << glueBegin ;
    for (const std::string& item : m_listCContorlCallBack)
    {
        m_cpp << "\tCCB_SELECTORRESOLVER_CCCONTROL_GLUE(this," << "\"" << item << "\"," << m_className << "::" << item << ");\n";
    }
    m_cpp << "\treturn false;\n";
    m_cpp << "}\n\n";
}
void CodeGen::GlueMenuCallBack()
{
    m_cpp << "// glue menu callback here ;\n";
    std::string glueBegin = m_glueMenuCallBack;
    string_replace(glueBegin, "%class_name%", m_className);
    m_cpp << glueBegin ;
    for (const std::string& item : m_listMenuCallBack)
    {
        m_cpp << "\tCCB_SELECTORRESOLVER_CCMENUITEM_GLUE(this," << "\"" << item << "\"," << m_className << "::" << item << ");\n";
    }
    m_cpp << "\treturn false;\n";
    m_cpp << "}\n\n";
}



void CodeGen::GenerateCppHeader()
{
    std::string cppHeader = m_cppHeader;
    string_replace(cppHeader, "%class_name%", m_className);
    m_cpp << cppHeader;
}

void CodeGen::GenerateCallBackControl()
{
    m_cpp << "//control button call back  here ;\n";
    for(const std::string& fName : m_listCContorlCallBack)
    {
        std::string callBackImpli = m_callBackControl;
        string_replace(callBackImpli, "%class_name%", m_className);
        string_replace(callBackImpli, "%control_call%", fName);
        m_cpp << callBackImpli ;

    }
    m_cpp << "// end control call back\n\n";
}
void CodeGen::GenerateCallBackMenu()
{
    m_cpp << "// menu call back   here ;\n";
    for(const std::string& fName : m_listMenuCallBack)
    {
        std::string callBackImpli = m_callBackMenu;
        string_replace(callBackImpli, "%class_name%", m_className);
        string_replace(callBackImpli, "%menu_call%", fName);
        m_cpp << callBackImpli;
    }
    m_cpp << "// end menu call back\n\n";
}

void CodeGen::GenerateClassDec()
{
    std::string classDec = m_classDec;
    string_replace(classDec, "%class_name%", m_className);
    string_replace(classDec, "%base_class%", m_baseClass);
    m_header<< classDec<<"\n";
    
    //initialize member or custom member
    for (const TypeName& item :m_listAssignMember) {
        if (item.type == "string" || item.type == "std::string") {
            continue;
        }
        m_header <<"\t," << item.name << "(0)\n";
    }
    for (const TypeName& item :m_listCutomProperty) {
        if (item.type == "string" || item.type == "std::string") {
            continue;
        }
        m_header <<"\t," << item.name << "(0)\n";
    }
    
    m_header << "{}\n";
    
    //generate loader
    if (m_baseClass == "CCNode") {
        m_header << "CREATE_FUNC("<< m_className << ");\n\n";
    }
    else if(m_baseClass == "CCLayer")
    {
        m_header << "CREATE_FUNC("<< m_className << ");\n\n";
    }
}
void CodeGen::GenerateInterfaceDec()
{
    m_header << "\n//virtual function from base !\n";
    m_header << m_interfaceDec;
}
void CodeGen::GenerateCallBackControlDec()
{
    m_header << "\n //control call back function;\n";
    m_header << "protected:" << std::endl;
    for (auto iter = m_listCContorlCallBack.cbegin(); iter != m_listCContorlCallBack.cend(); ++iter) {
        std::string call_control = m_callBackControlDec;
        string_replace(call_control, "%control_call%", *iter);
        m_header << call_control;
    }
}
void CodeGen::GenerateCallBackMenuDec()
{
    m_header << "\n // menu call back fuction \n";
    m_header << "protected:" << std::endl;
    for (auto iter = m_listMenuCallBack.cbegin(); iter != m_listMenuCallBack.cend(); ++iter) {
        std::string call_menu = m_callBackMenuDec;
        string_replace(call_menu, "%menu_call%", *iter);
        m_header << call_menu;
    }
}
void CodeGen::GenerateCustomMemberDec()
{
    m_header << "\n //custom member list \n";
    m_header << "protected:" << std::endl;
    for (const TypeName& item :m_listCutomProperty) {
        m_header << "\t"<< item.type << "\t\t" << item.name << ";\n";
    }
}
const static std::set<std::string> cocos2dClass =
{
    "CCNode",
    "CCSprite",
    "CCLayer",
    "CCLayerColor",
    "CCLayerGradient",
    "CCMenu",
    "CCLabelBMFont",
    "CCLabelTTF",
    "CCParticleSystem",
    "CCParticleSystemQuad",
    "CCParticleSystemPoint",
    "CCMenuItemImage",
    "CCBFile",
    "CCScale9Sprite",
    "CCControl",
    "CCControlButton",
    "CCScrollView",
};
const static std::set<std::string> extensionClass=
{
    "CCBFile",
    "CCScale9Sprite",
    "CCControl",
    "CCControlButton",
    "CCScrollView",
  
};

void CodeGen::GenerateAssignMemberDec()
{
    m_header << "\n //member will assigned form ccbi file\n";
    m_header << "protected:" << std::endl;
    for (const TypeName& item :m_listAssignMember) {
        m_header << "\t";
        if (cocos2dClass.find(item.type) != cocos2dClass.end()) {
            m_header<<"cocos2d::";
        }
        if (extensionClass.find(item.type) != extensionClass.end()) {
            m_header <<"extension::";
        }
        m_header<< item.type << "*\t\t" << item.name << ";\n";
    }
}

void CodeGen::GenerateLayerClassEnd()
{
    m_header << "};\n";
}

void CodeGen::GenerateNodeLeader()
{
    std::string classHeader = "class %class_name%Loader: public cocos2d::extension::CCLayerLoader {";
    string_replace(classHeader, "%class_name%", m_className);
    m_header << classHeader << "\n";
    m_header << "public:\n";
    m_header << "\tvirtual bool init(){ return true; }\n";
    std::string staticNewObjc = "\tCCB_STATIC_NEW_AUTORELEASE_OBJECT_WITH_INIT_METHOD(%class_name%Loader, loader);";
    std::string virtualRewriteObjc = "\tCCB_VIRTUAL_NEW_AUTORELEASE_CREATECCNODE_METHOD(%class_name%);";
    string_replace(staticNewObjc, "%class_name%", m_className);
    string_replace(virtualRewriteObjc, "%class_name%", m_className);
    m_header << staticNewObjc << "\n";
    m_header << virtualRewriteObjc << "\n";
    m_header << "};";
}

void CodeGen::GenerateEnd()
{
    m_header << "\n#endif\n";
}

抱歉!评论已关闭.