cocos2dx 资源合并.

文件合并之前

文件合并之后

吐槽

我们项目比较奇葩, ui用cocostudio做, 这项光荣的任务由美术接手.

这个美术是个新手, 经过我长时间的观察, 她似乎不用怎么画画. 至少在很长一段时间里, 她很悠闲, 只管拼UI即可.

这是我们客户端噩梦的源头.

她不懂需求, 任何ui, 只要截图下来符合策划草图就算完成任务.

因此, 什么层次结构, 什么命名规范, 统统没有.

程序接手过来的ui自己要从头到尾翻新一遍, 甚至比重做花的时间更长.

于是, 一个伟大的决定诞生了, 我把她的活一起做了, 摆脱了厄运, 让我事倍功半.

两周以后, 她说她太闲了, 又把活接了过去, 从此厄运continue..

她把每一个ui都新建一个工程, 可以看到合并前有多个目录, 容量达到500M.

而且, 同一个文件, 在不同的目录就可能是不同的名字, 总之错乱不堪, 一塌糊涂.

她的杰作, 导致apk远远过150m, 直逼200m.

就在策划, 美术大呼, 节省资源的同时, 他们依然没有意识到问题出在哪里.

随着他们的呼声越来越高, 资源也越来越大.

卧槽, 彻底服了.

实际行动

终于, 我忍无可忍了, 决定要彻底优化一次资源.

由于资源文件太乱, 根本无从下手, 于是我订好了目录结构, 统一了文件名, 把这个活交给了美术.

这个事情很容易完成, 因为他们只要整理文件就OK, 至于ui资源里指定的文件路径, 都是由程序各自去修改.

所以, 这个工作量是相当的小, 我以为美术一周内怎么也可以做完了...

2个月以后, 美术把文件整理好了.

然后我把文件合并了, 有效资源居然只有22m.

源码

  1 #include <Windows.h>
  2 #include <windowsx.h>
  3
  4 #include <string>
  5 #include <memory>
  6 #include <utility>
  7 #include <vector>
  8 #include <fstream>
  9 #include <list>
 10 #include <iterator>
 11 #include <functional>
 12 #include <iostream>
 13 #include <thread>
 14 #include <regex>
 15
 16 #define LOG(param)    {std::wcout << param << std::endl;}
 17
 18 size_t getFileSize(std::wifstream &ifile)
 19 {
 20     ifile.seekg(0, std::ios::end);
 21     auto pos = (size_t)ifile.tellg();
 22     ifile.seekg(0, std::ios::beg);
 23     return pos;
 24 }
 25
 26 //    获得目录.
 27 inline std::wstring getDirectoryName(const std::wstring &fullName)
 28 {
 29     auto pos = fullName.find_last_of(L‘\\‘);
 30     return pos != std::wstring::npos ? fullName.substr(0, pos) : L"";
 31 }
 32 //    获得文件名.
 33 inline std::wstring getFileName(const std::wstring &fullName)
 34 {
 35     auto pos = fullName.find_last_of(L‘\\‘);
 36     return pos != std::wstring::npos ? fullName.substr(pos + 1) : L"";
 37 }
 38 //    获取后缀.
 39 inline std::wstring getFileExtName(const std::wstring &fullName)
 40 {
 41     auto pos = fullName.find_last_of(L‘.‘);
 42     return pos != std::wstring::npos ? fullName.substr(pos + 1) : L"";
 43 }
 44
 45 class Project {
 46 public:
 47     std::wstring directoryName;
 48     std::wstring directoryPath;
 49     std::wstring jsonPath;
 50     std::wstring projectName;
 51     std::vector<std::wstring> jsonList;
 52 };
 53
 54 bool handleFileList(const std::wstring &rootDirectory, const std::wstring &outDirectory, const std::vector<std::wstring> &fileList)
 55 {
 56     auto result = false;
 57     LOG("handleFileList");
 58     std::vector<Project> projectList;
 59
 60     {
 61         Project project;
 62         for (auto &fullName : fileList)
 63         {
 64             auto directoryPath = getDirectoryName(fullName);
 65             auto fileName = getFileName(fullName);
 66             auto extName = getFileExtName(fileName);
 67
 68             if (extName == L"ui" && directoryPath != project.directoryPath)
 69             {
 70                 //    记录路径.
 71                 if (!project.directoryPath.empty())
 72                 {
 73                     projectList.push_back(project);
 74                 }
 75                 project = Project();
 76                 project.directoryPath = directoryPath;
 77                 project.directoryName = getFileName(directoryPath);
 78                 project.jsonPath = directoryPath + L"\\Json";
 79             }
 80
 81             //    记录项目文件名.
 82             if (extName == L"ui")
 83             { project.projectName = fileName; }
 84
 85             //    记录项目的json文件名.
 86             if ( getFileName(directoryPath) == L"Json" && extName == L"json")
 87             {
 88                 project.jsonList.push_back(fileName);
 89             }
 90         }
 91     }
 92
 93     //    生产新的项目.
 94     {
 95         //    cat json file.
 96         std::wstring jsonList;
 97
 98         CreateDirectory( (outDirectory + L"\\Json").c_str(), nullptr );
 99         CopyFile(L"null_project\\Json\\null_project_1.json", (outDirectory + L"\\Json\\null_project_1.json").c_str(), FALSE);
100
101         for (auto &project : projectList)
102         {
103             for (auto &json : project.jsonList)
104             {
105                 auto name = project.directoryName + L"_" + json;
106                 auto inName = project.jsonPath + L"\\" + json;
107                 auto outName = outDirectory + L"\\Json\\" + name;
108                 auto copy = CopyFile(inName.c_str(), outName.c_str(), FALSE);
109                 jsonList.append(L"<string>" + name + L"</string>\n");
110                 LOG(L"copy " << inName << L", " << outName << L" | " << copy);
111             }
112             LOG(L"copy resources.");
113             wchar_t commandLine[1024] = { 0 };
114             auto inName = project.directoryPath + L"\\Resources";
115             auto outName = outDirectory + L"\\Resources";
116             wsprintf(commandLine, L"/c xcopy %s\\*.* %s\\ /E /Y", inName.c_str(), outName.c_str());
117             ShellExecute(nullptr, L"open", L"cmd", commandLine, nullptr, SW_SHOW);
118         }
119
120         do {
121             //    写入 project.
122             std::wifstream ifile(L"null_project\\null_project.xml.ui", std::ios::binary | std::ios::in);
123             if (!ifile)
124             {
125                 break;
126             }
127             auto fileSize = getFileSize(ifile);
128             auto templateBuffer = std::wstring(fileSize, L‘\0‘);
129             ifile.read(&templateBuffer[0], fileSize);
130             ifile.close();
131
132             auto writeStr = std::regex_replace(
133                 templateBuffer, std::wregex(L"JsonList_Replace"), jsonList);
134             std::wfstream ofile(outDirectory + L"\\project.xml.ui", std::ios::binary | std::ios::out);
135             ofile.write(writeStr.c_str(), writeStr.size());
136             ofile.close();
137         } while (0);
138
139
140
141         result = true;
142     }
143     return result;
144 }
145
146 bool run(const std::wstring &rootDirectory, const std::wstring &outDirectory)
147 {
148     auto result = false;
149
150     do {
151         {
152             wchar_t commadBuffer[256];
153             wsprintf(commadBuffer,
154                      L"/c "
155                      L"%c:&"
156                      L"cd %s&"
157                      L"del config.txt&"
158                      L"for /R %%i in (*) do (echo %%i>>%s\\config.txt)",
159                      rootDirectory[0], rootDirectory.c_str(), rootDirectory.c_str());
160             ShellExecute(nullptr, L"open", L"cmd", commadBuffer, nullptr, SW_SHOW);
161             LOG(L"Wait 10 Seconds...");
162             std::this_thread::sleep_for(std::chrono::milliseconds(10000));
163         }
164
165         //    打开文件
166         std::wifstream ifile(rootDirectory + L"\\config.txt");
167
168         //    读取文件列表.
169         std::vector<std::wstring> fileList;
170         if (ifile)
171         {
172             LOG(L"open config.txt.");
173             do {
174                 std::wstring fileName;
175                 std::getline(ifile, fileName);
176                 fileList.push_back(fileName);
177             } while (!ifile.eof());
178             ifile.close();
179             LOG(L"init file list.");
180         }
181
182         if (!fileList.empty())
183         {
184             result = handleFileList(rootDirectory, outDirectory, fileList);
185         }
186     } while (0);
187
188     return result;
189 }
190
191 int main()
192 {
193     std::locale::global(std::locale("chs"));
194
195     std::wifstream ifile(L"config.txt");
196     if (ifile)
197     {
198         std::wstring rootDirectory = L"X:\\Output\\office\\UI\\11月新版UI";
199         std::wstring outDirectory = L"X:\\Output\\test_out";
200         std::getline(ifile, rootDirectory);
201         std::getline(ifile, outDirectory);
202
203         std::wcout
204             << L"rootDirectory: " << rootDirectory << L"\n"
205             << L"outDirectory: " << outDirectory << std::endl;
206         std::wcout << (run(rootDirectory, outDirectory) ? L"done." : L"failed.");
207     }
208     std::wcout << L"\n===========================end.===========================\n";
209     std::cin.get();
210     return 0;
211 }

思路比较简单, 效果看起来很高端有没有.

一堆的控制台弹窗.

好久没写博客了, 今天坐一会标题党.

时间: 2024-11-05 06:25:54

cocos2dx 资源合并.的相关文章

前端性能优化篇—资源合并与压缩减少HTTP请求

资源合并与压缩减少HTTP请求的概要 资源合并与压缩减少HTTP请求主要的两个优化点是减少HTTP请求的数量和减少请求资源的大小 http协议是无状态的应用层协议,意味着每次http请求都需要建立通信链路.进行数据传输,而在服务器端,每个http都需要启动独立的线程去处理. 这些通信和服务的开销都很昂贵,减少http请求的数量和减少请求资源的大小可有效提高访问性能 减少http的主要手段是合并CSS.合并JavaScript.合并图片.将浏览器一次访问需要的javascript和CSS合并成一个

[cocos2d-x] 资源json的载入过程

这块代码主要是文件CCSGUIReader   CCSGUIReader 的作用是解析json组合成用户需要的UIWiget对象. 实例: Widget* m_uiRoot = cocostudio::GUIReader::shareReader()->widgetFromJsonFile("fruit_ui_1.json"); -> 往下面走 return widgetFromJsonDocument(jsonDict, fileName, NULL); jsonDict

仿淘宝 css,js 等静态资源合并压缩输出的 jsp 脚本 combo.jsp

原文:仿淘宝 css,js 等静态资源合并压缩输出的 jsp 脚本 combo.jsp 源代码下载地址:http://www.zuidaima.com/share/1550463482612736.htm 仿淘宝 css,js 等静态资源合并压缩输出的 jsp 脚本 自己在项目中有用到,用于脚本合并输出 , 使用示例: <link rel="stylesheet" type="text/css" href="http://www.zuidaima.c

资源合并fis-postpackager-simple插件的使用

FIS默认只会进行文件打包,不会对页面中的静态资源引用进行替换,这时可以利用fis-postpackager-simple插件进行资源替换. 安装: npm install -g fis-postpackager-simple 开启: // fis-conf.js fis.config.set('modules.postpackager', 'simple'); 设置打包规则: 规则:fis.config.set('pack', {'?.js':[] , '?.css':[]}); //fis-

Nginx资源合并优化模块nginx-http-concat

此模块是nginx的第三方模块nginx-http-concat,此模块可以合并资源,节约带宽和节约请求响应时间 下载地址 git clone git://github.com/alibaba/nginx-http-concat.git 官网解释 https://github.com/alibaba/nginx-http-concat 首先将此模块编译进nginx里 /usr/local/nginx/sbin/nginx -V nginx version: nginx/1.13.9 built

前端资源合并

连接数的概念 连接数也是所谓的请求数, 每个资源都会从客服端独立发一个请求到服务端(当然重复的不算, 这些资源包括css,js,img等) 连接数多带来的问题 因为每一个连接数都要经历一个"漫长的过程", 要发送TCP请求, 然后什么DNS解析成IP, 各种连, 各种多, 然而人要知道每个连接都(可能)有cookie, Header请求头, Respose响应头等信息, 而即使这些数据再小, 也吃不住量大吧? 比如你的静态资源cookie有100个字, 你的页面有10个css, 50个

cocos2dx资源加载机制(同步/异步)

首先cocos2dx里的资源,有png,plist(pvr),exportjson(json)大致这三类,我们也从这3类去研究相应的加载代码. 本次代码分析基于: cocos2dx3.2 1.png png格式的资源,从sprite作为一个切入口来分析,一般Sprite的创建如下 Sprite* Sprite::create(const std::string& filename) 参数filename,是图片资源的路径. 内部调用的initWithFile Sprite *sprite = n

web站点优化之使用tengine搭建静态资源服务器和静态资源合并加载案例剖析

在一个项目还是单体架构的时候,所有的js,css,image都会在一个web网站上,看起来并没有什么问题,比如下面这样: 但是当web网站流量起来的时候,这个单体架构必须要进行横向扩展,而在原来的架构中静态资源这羊毛是出在单体架构这头羊身上,所以横向多少 个单体,就有多少个静态资源文件夹,比如下面这样的架构. 那这种架构有什么问题呢? 总的来说会有如下二个问题: 1.   浏览器对单一域名的请求有并发限制. 在同一个域名下,一般来说有js,css,img,media,html等等静态资源,如果资

cocos2dx资源和脚本加密quick-lua3.3final

一.资源加密 版本号:Quick-Cocos2d-x 3.3 Final 调试工具:xCode 工程创建的时候选择的拷贝源码. 项目结构如图: 这个功能七月大神在很早之前就已经实现了,但是在3.3版本中有几个小BUG,可能很多人不知道一直卡住了.我就在这儿从头到尾的流程都讲一次. 道理很简单 主要就只用到quick-src/extra/approols/下面的HelperFunc这个类. 我只做了图片的加密,plist未做.道理一样.我就只说图片的吧. 第一步 1.  由于cocos现在统一了资