cocos2dx 资源合并.

文件合并之前

cocos2dx 资源合并._第1张图片

文件合并之后

cocos2dx 资源合并._第2张图片

吐槽

我们项目比较奇葩, 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 }

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

一堆的控制台弹窗.

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

你可能感兴趣的:(cocos2dx)