标签:
GUIReader分析(1): 1、GUIReader用于cocostudio所做UI界面导出json的解析, 并生成对应的UI元素。 GUIReader* GUIReader::shareReader() { if (!sharedReader) { sharedReader = new GUIReader(); } return sharedReader; } 2、主要函数: cocos2d::ui::Widget* widgetFromJsonFile(const char* fileName); -----源码-->>> //解析json文件 cocos2d::ui::Widget* GUIReader::widgetFromJsonFile(const char *fileName) { unsigned char *pBytes = NULL; std::string jsonpath; rapidjson::Document jsonDict; //获取json文件的全路径 jsonpath = CCFileUtils::sharedFileUtils()->fullPathForFilename(fileName); int pos = jsonpath.find_last_of('/'); m_strFilePath = jsonpath.substr(0,pos+1); unsigned long size = 0; //读取json文件 pBytes = CCFileUtils::sharedFileUtils()->getFileData(jsonpath.c_str(),"r" , &size); if(NULL == pBytes || strcmp((const char*)pBytes, "") == 0) { printf("read json file[%s] error!\n", fileName); return NULL; } CCData *data = new CCData(pBytes, size); std::string load_str = std::string((const char *)data->getBytes(), data->getSize() ); CC_SAFE_DELETE(data); //解析json文件内容 jsonDict.Parse<0>(load_str.c_str()); if (jsonDict.HasParseError()) { CCLOG("GetParseError %s\n",jsonDict.GetParseError()); } cocos2d::ui::Widget* widget = NULL; //DICTOOL获取json信息的工具类#define DICTOOL DictionaryHelper::shareHelper() //得到json文件的版本,即使用那个版本的cocostudio做的 const char* fileVersion = DICTOOL->getStringValue_json(jsonDict, "version"); WidgetPropertiesReader * pReader = NULL; if (fileVersion) { //根据不同的版本去掉用不同的解析类,如 "version": "1.6.0.0", versionInteger = 1600 //所以我们这里使用WidgetPropertiesReader0300 int versionInteger = getVersionInteger(fileVersion); if (versionInteger < 250) { pReader = new WidgetPropertiesReader0250(); widget = pReader->createWidget(jsonDict, m_strFilePath.c_str(), fileName); } else { pReader = new WidgetPropertiesReader0300(); widget = pReader->createWidget(jsonDict, m_strFilePath.c_str(), fileName); } } else { pReader = new WidgetPropertiesReader0250(); widget = pReader->createWidget(jsonDict, m_strFilePath.c_str(), fileName); } CC_SAFE_DELETE(pReader); CC_SAFE_DELETE_ARRAY(pBytes); return widget; } 3、WidgetPropertiesReader0300类的分析: 3.1、 //jsonDict -- 解析后的json数据 //m_strFilePath -- json文件所在目录的全路径,不包含json文件名 //fileName -- json文件名 createWidget(jsonDict, m_strFilePath.c_str(), fileName)方法: ----->>>> /*0.3.0.0~1.0.0.0*/ 这里有点疑惑,看到这个注释我以为WidgetPropertiesReader0300用来解析0.3.0.0~1.0.0.0的版本, //但是我调试了下,想我上面分析的那样,我是用cocostudio的版本是1.6.0.0, //"version": "1.6.0.0", versionInteger = 1600,大于250,所以使用的是WidgetPropertiesReader0300解析。 //所以忽略这个注释。 cocos2d::ui::Widget* WidgetPropertiesReader0300::createWidget(const rapidjson::Value& data, const char* fullPath, const char* fileName) { m_strFilePath = fullPath; /*如果我们在制作界面的过程中使用了.plist问价,那么生成的json文件中会有 textures 字段,如下所示: "textures": [ "hero.plist" ] */ int texturesCount = DICTOOL->getArrayCount_json(data, "textures"); //.plist文件,用CCSpriteFrameCache加载,路径为json文件的全路径目录部分 + "xx.plist" for (int i=0; i<texturesCount; i++) { const char* file = DICTOOL->getStringValueFromArray_json(data, "textures", i); std::string tp = fullPath; tp.append(file); CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(tp.c_str()); } /* "designHeight": 640, "designWidth": 960, */ float fileDesignWidth = DICTOOL->getFloatValue_json(data, "designWidth"); float fileDesignHeight = DICTOOL->getFloatValue_json(data, "designHeight"); if (fileDesignWidth <= 0 || fileDesignHeight <= 0) { printf("Read design size error!\n"); CCSize winSize = CCDirector::sharedDirector()->getWinSize(); GUIReader::shareReader()->storeFileDesignSize(fileName, winSize); } else { GUIReader::shareReader()->storeFileDesignSize(fileName, CCSizeMake(fileDesignWidth, fileDesignHeight)); } /* "widgetTree": { "classname": "Panel", "name": null, "children": [ */ //解析UI树,生成UI const rapidjson::Value& widgetTree = DICTOOL->getSubDictionary_json(data, "widgetTree"); cocos2d::ui::Widget* widget = widgetFromJsonDictionary(widgetTree); /* *********temp********* */ if (widget->getContentSize().equals(CCSizeZero)) { widget->setSize(CCSizeMake(fileDesignWidth, fileDesignHeight)); } /* ********************** */ // widget->setFileDesignSize(CCSizeMake(fileDesignWidth, fileDesignHeight)); const rapidjson::Value& actions = DICTOOL->getSubDictionary_json(data, "animation"); /* *********temp********* */ // ActionManager::shareManager()->releaseActions(); /* ********************** */ CCLOG("file name == [%s]",fileName); CCObject* rootWidget = (CCObject*) widget; ActionManager::shareManager()->initWithDictionary(fileName,actions,rootWidget); return widget; } ------>>>> widgetFromJsonDictionary: //根据json文件生成UI树 cocos2d::ui::Widget* WidgetPropertiesReader0300::widgetFromJsonDictionary(const rapidjson::Value& data) { //获取类名,如: "classname": "Panel" const char* classname = DICTOOL->getStringValue_json(data, "classname"); const rapidjson::Value& uiOptions = DICTOOL->getSubDictionary_json(data, "options"); //根据类名创建不同的对象,在GUIReader构造函数中,注册了很多类的创建函数。 /* 在GUIReader::GUIReader() { ObjectFactory* factoryCreate = ObjectFactory::getInstance(); factoryCreate->registerType(CREATE_CLASS_WIDGET_READER_INFO(ButtonReader)); ....... factoryCreate->registerType(CREATE_CLASS_GUI_INFO(Button)); ............. } */ cocos2d::ui::Widget* widget = ObjectFactory::getInstance()->createGUI(classname); // create widget reader to parse properties of widget // 得到不同UI元素的对应的不同解析类,如ButtonReader,CheckBoxReader等等 std::string readerName = getWidgetReaderClassName(classname); WidgetReaderProtocol* reader = this->createWidgetReaderProtocol(readerName); if (reader) { // widget parse with widget reader setPropsForAllWidgetFromJsonDictionary(reader, widget, uiOptions); } else { // 1st., custom widget parse properties of parent widget with parent widget reader // 自定义控件 readerName = this->getWidgetReaderClassName(widget); reader = this->createWidgetReaderProtocol(readerName); if (reader && widget) { setPropsForAllWidgetFromJsonDictionary(reader, widget, uiOptions); // 2nd., custom widget parse with custom reader const char* customProperty = DICTOOL->getStringValue_json(uiOptions, "customProperty"); rapidjson::Document customJsonDict; customJsonDict.Parse<0>(customProperty); if (customJsonDict.HasParseError()) { CCLOG("GetParseError %s\n", customJsonDict.GetParseError()); } setPropsForAllCustomWidgetFromJsonDictionary(classname, widget, customJsonDict); }else{ CCLOG("Widget or WidgetReader doesn't exists!!! Please check your json file."); } } //遍历子节点UI树,生成整个UI树,最终返回根节点 int childrenCount = DICTOOL->getArrayCount_json(data, "children"); for (int i = 0; i < childrenCount; i++) { const rapidjson::Value& subData = DICTOOL->getDictionaryFromArray_json(data, "children", i); cocos2d::ui::Widget* child = widgetFromJsonDictionary(subData); if (child) { PageView* pageView = dynamic_cast<PageView*>(widget); if (pageView) { pageView->addPage(static_cast<Layout*>(child)); } else { ListView* listView = dynamic_cast<ListView*>(widget); if (listView) { listView->pushBackCustomItem(child); } else { widget->addChild(child); } } } } return widget; }
标签:
原文地址:http://blog.csdn.net/tianxiawuzhei/article/details/45674735