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__) */
// // 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"; }