码迷,mamicode.com
首页 > 其他好文 > 详细

cocostudio: GUIReader分析(1)

时间:2015-05-12 21:01:43      阅读:433      评论:0      收藏:0      [点我收藏+]

标签:

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;
}

cocostudio: GUIReader分析(1)

标签:

原文地址:http://blog.csdn.net/tianxiawuzhei/article/details/45674735

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!