游戏资源及代码生成

一、资源及c++代码生成

这里使用c#.net读写Excel及生成c++代码。

1.Excel读写及生成资源

需要添加Excel组件,暂时没有关闭excel进程的方法。

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Threading.Tasks;
  6 
  7 using System.IO;
  8 
  9 using Excel = Microsoft.Office.Interop.Excel;
 10 using Forms = System.Windows.Forms;
 11 
 12 namespace ResHelper
 13 {
 14     class ExcelHelper
 15     {
 16         private string _filepath;
 17         private Excel.Application _app;               // excel app
 18         private Excel.Workbook _workbook;
 19         private Excel.Worksheet _worksheet;
 20 
 21         public bool Open(string filepath)
 22         {
 23             try
 24             {
 25                 _filepath = filepath;
 26 
 27                 _app = new Excel.Application();
 28                 _workbook = _app.Workbooks.Open(filepath, Type.Missing, Type.Missing, Type.Missing
 29                     , Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing
 30                     , Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
 31                 _worksheet = (Excel.Worksheet)_workbook.Worksheets[1];
 32 
 33             }
 34             catch (System.Exception)
 35             {
 36                 Forms.MessageBox.Show("打开Excel文件失败!");
 37                 return false;
 38             }
 39             finally
 40             {
 41             }
 42             return true;
 43         }
 44 
 45         public bool Create(string filepath)
 46         {
 47             try
 48             {
 49                 _filepath = filepath;
 50                 _app = new Excel.Application();
 51                 _workbook = _app.Workbooks.Open(filepath, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
 52                     Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
 53                     Type.Missing, Type.Missing, Type.Missing);
 54             }
 55             catch (System.Exception)
 56             {
 57                 
 58             }
 59             finally
 60             {
 61             }
 62 
 63             return true;
 64         }
 65 
 66         public string Cells(int row, int col)
 67         {
 68             if (row < 0 || col < 0)
 69             {
 70                 Forms.MessageBox.Show("请输入正确的Excel某项的行号与列号,不能为负数!");
 71             }
 72             return ((Excel.Range)_worksheet.Cells[row][col]).Text.ToString();
 73         }
 74 
 75         public void Cells(int row, int col, string content)
 76         {
 77             if (row < 0 || col < 0)
 78             {
 79                 Forms.MessageBox.Show("请输入正确的Excel某项的行号与列号,不能为负数!");
 80             }
 81             _worksheet.Cells[row, col] = content;
 82         }
 83 
 84         public void Save(string filepath)
 85         {
 86             try
 87             {
 88                 _worksheet.SaveAs(filepath, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
 89                     Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
 90 
 91             }
 92             catch (System.Exception)
 93             {
 94                 
 95             }
 96             finally
 97             {
 98             }
 99 
100         }
101 
102         public void Close()
103         {
104             try
105             {
106                 _app.Workbooks.Close();
107 
108             }
109             catch (System.Exception)
110             {
111 
112             }
113             finally
114             {
115                 _workbook = null;
116                 _worksheet = null;
117                 _app = null;
118                 GC.Collect();
119             }
120             
121         }
122 
123         public void ToRes()
124         {
125             if (string.IsNullOrEmpty(_filepath))
126             {
127                 Forms.MessageBox.Show("没有载入Excel文件!");
128                 return;
129             }
130             string txtpath = _filepath;
131             txtpath = txtpath.Substring(txtpath.LastIndexOf('\\') + 1);
132             txtpath = txtpath.Substring(0,txtpath.LastIndexOf('.') + 1);
133             txtpath += "res";
134             txtpath = "./res/" + txtpath;
135 
136             FileStream file = new FileStream(txtpath, FileMode.Create, FileAccess.Write);
137             try
138             {
139                 int colnum = 0;
140                 string text;
141                 for (int i = 1; i < 100; ++i)
142                 {
143                     text = Cells(i, 1);
144                     if (string.IsNullOrEmpty(text)) break;
145                     colnum += 1;
146                 }
147                 if(colnum<1)
148                 {
149                     Forms.MessageBox.Show("没有列头,数据格式有误!");
150                     return;
151                 }
152                 string line, space = "";
153                 for(int i = 0; i<colnum; ++i)
154                 {
155                     space += "\t";
156                 }
157 
158 
159                 using (StreamWriter writer = new StreamWriter(file))
160                 {
161                     // 从3行开始才是数据 1.是表头 2.是备注
162                     for (int row = 3; row < 10000; ++row)
163                     {
164                         line = "";
165                         for (int col = 1; col <= colnum; ++col)
166                         {
167                             text = Cells(col, row);
168                             if (text.IndexOf('\t', 0) > 0)
169                             {
170                                 Forms.MessageBox.Show("内容中不能含有tab表格符!");
171                                 break;
172                             }
173                             text = text.Replace("\t", ",,");
174                             line += text + "\t";
175                         }
176                         // 从该项开始没有数据
177                         if (line == space) break;
178                         line = line.Substring(0,line.LastIndexOf('\t'));
179                         line += "\n";
180                         int len = line.Length;
181                         writer.Write(line);
182                     }
183 
184                     writer.Flush();
185                     writer.Dispose();
186                     writer.Close();
187                 }
188             }
189             catch (System.Exception e)
190             {
191                 Forms.MessageBox.Show(e.Message);
192                 return;
193             }
194             finally
195             {
196                 file.Dispose();
197                 file.Close();
198             }
199         }
200     }
201 }
View Code

2.c++代码生成

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Threading.Tasks;
  6 
  7 using System.IO;
  8 using System.Windows.Forms;
  9 
 10 struct ADTType
 11 {
 12     public enum EType { i = 0, l, d, c, s, S, t };
 13     private EType _valueType;
 14     private string _valueName;
 15 
 16     public EType ValueType
 17     {
 18         set { _valueType = value; }
 19         get { return _valueType; }
 20     }
 21 
 22     public string ValueName
 23     {
 24         set { _valueName = value; }
 25         get { return _valueName; }
 26     }
 27 }
 28 
 29 
 30 namespace ResHelper
 31 {
 32     class CppHelper
 33     {
 34         FileStream _file;
 35         List<ADTType> _lstValue = new List<ADTType>();
 36 
 37         // 将text解释成类型及变量名
 38         private string GetTypeAndValueName(string text)
 39         {
 40             if (string.IsNullOrEmpty(text)) return null;
 41             string type, name;
 42             
 43             if (text[0] == 'i')
 44             {
 45                 type = "int";
 46                 name = text.Substring(1);
 47 
 48                 ADTType adttype = new ADTType();
 49                 adttype.ValueType = ADTType.EType.i;
 50                 adttype.ValueName = name;
 51                 _lstValue.Add(adttype);
 52 
 53                 return "\t" + type + "\t" + name + ";";
 54             }
 55             else if (text[0] == 'l')
 56             {
 57                 type = "long";
 58                 name = text.Substring(1);
 59 
 60                 ADTType adttype = new ADTType();
 61                 adttype.ValueType = ADTType.EType.l;
 62                 adttype.ValueName = name;
 63                 _lstValue.Add(adttype);
 64 
 65                 return "\t" + type + "\t" + name + ";";
 66             }
 67             else if (text[0] == 'd')
 68             {
 69                 type = "double";
 70                 name = text.Substring(1);
 71 
 72                 ADTType adttype = new ADTType();
 73                 adttype.ValueType = ADTType.EType.d;
 74                 adttype.ValueName = name;
 75                 _lstValue.Add(adttype);
 76 
 77                 return "\t" + type + "\t" + name + ";";
 78             }
 79             else if (text[0] == 'c')
 80             {
 81                 type = "char";
 82                 name = text.Substring(1);
 83 
 84                 ADTType adttype = new ADTType();
 85                 adttype.ValueType = ADTType.EType.c;
 86                 adttype.ValueName = name;
 87                 _lstValue.Add(adttype);
 88 
 89                 return "\t" + type + "\t" + name + ";";
 90             }
 91             else if (text[0] == 's')
 92             {
 93                 type = "char";
 94                 name = text.Substring(1);
 95 
 96                 ADTType adttype = new ADTType();
 97                 adttype.ValueType = ADTType.EType.s;
 98                 adttype.ValueName = name;
 99                 _lstValue.Add(adttype);
100 
101                 return "\t" + type + "\t" + name + "[32];";
102             }
103             else if (text[0] == 'S')
104             {
105                 type = "char";
106                 name = text.Substring(1);
107 
108                 ADTType adttype = new ADTType();
109                 adttype.ValueType = ADTType.EType.S;
110                 adttype.ValueName = name;
111                 _lstValue.Add(adttype);
112 
113                 return "\t" + type + "\t" + name + "[64];";
114             }
115             else if (text[0] == 't')
116             {
117                 type = "char";
118                 name = text.Substring(1);
119 
120                 ADTType adttype = new ADTType();
121                 adttype.ValueType = ADTType.EType.t;
122                 adttype.ValueName = name;
123                 _lstValue.Add(adttype);
124 
125                 return "\t" + type + "\t" + name + "[512];";
126             }
127             else
128             {
129                 string msg = "无法识别的列名:" + text + ",是否没有前缀!";
130                 MessageBox.Show(msg);
131             }
132             return null;
133         }
134 
135         public bool CreateADT(string ADT, string ExcelName)
136         {
137             bool ret = true;
138             _lstValue.Clear();
139             _file = new FileStream("./cpp/"+ADT+".h", FileMode.Create, FileAccess.Write);
140             try
141             {
142                 List<string> lstName = new List<string>();
143                 ExcelHelper helper = new ExcelHelper();
144                 if (!helper.Open(ExcelName)) return false;
145                 using (StreamWriter writer = new StreamWriter(_file))
146                 {
147                     string text, name;
148                     text = "#pragma once";
149                     writer.WriteLine("");
150                     writer.WriteLine(text);
151                     text = "struct " + ADT;
152                     writer.WriteLine(text);
153                     writer.WriteLine("{");
154                     for (int i = 1; i < 100; ++i)
155                     {
156                         name = helper.Cells(i, 1);
157                         foreach (string e in lstName)
158                         {
159                             if (e == name)
160                             {
161                                 string msg = "变量名:" + name + "已存在,不能重复!";
162                                 MessageBox.Show(msg);
163                                 return false;
164                             }
165                         }
166                         lstName.Add(name);
167                         text = GetTypeAndValueName(name);
168                         if (string.IsNullOrEmpty(text)) break;
169                         writer.WriteLine(text);
170                     }
171 
172                     text = "public:";
173                     writer.WriteLine(text);
174                     text = "\tbool operator == (const " + ADT +"& rhs) { return Id == rhs.Id; }";
175                     writer.WriteLine(text);
176                     text = "\texplicit " + ADT + "(int id) { Id = id; }";
177                     writer.WriteLine(text);
178                     text = "\texplicit " + ADT + "(const char* line);";
179                     writer.WriteLine(text);
180                     writer.WriteLine("};");
181                     writer.Flush();
182                     writer.Dispose();
183                     writer.Close();
184                     helper.Close();
185                 }
186                 bool islive = false;
187                 foreach (string e in lstName)
188                 {
189                     if (e == "iId")
190                     {
191                         islive = true;
192                         break;
193                     }
194                 }
195                 if (!islive)
196                 {
197                     string msg = "必须有一个列名为:iId!" ;
198                     MessageBox.Show(msg);
199                     return false;
200                 }
201 
202             }
203             catch (System.Exception e)
204             {
205                 ret = false;
206                 MessageBox.Show(e.Message);
207             }
208             finally
209             {
210                 _file.Dispose();
211                 _file.Close();
212             }
213             return ret;
214         }
215 
216         public bool CreateADTCpp(string ADT, string ExcelName)
217         {
218             bool ret = true;
219             _file = new FileStream("./cpp/" + ADT + ".cpp", FileMode.Create, FileAccess.Write);
220             try
221             {
222                 List<string> lstName = new List<string>();
223                 using (StreamWriter writer = new StreamWriter(_file))
224                 {
225                     string text;
226                     text = "#include \"stdafx.h\"";
227                     writer.WriteLine(text);
228                     text = "#include \"" + ADT + ".h\"";
229                     writer.WriteLine(text);
230                     text = "#include <cstring>";
231                     writer.WriteLine(text);
232                     text = "#include <stdlib.h>";
233                     writer.WriteLine(text);
234                     text = "#include <cassert>";
235                     writer.WriteLine(text);
236                     text = "#include \"../convertion.hpp\"";
237                     writer.WriteLine(text);
238                     text = "static const char split_token_define = '\t';";
239                     writer.WriteLine(text);
240                     text = ADT + "::" + ADT + "(const char* liuxb_line)";
241                     writer.WriteLine(text);
242                     writer.WriteLine("{");
243 
244                     writer.WriteLine("    int liuxb_max_len = strlen(liuxb_line);");
245                     writer.WriteLine("    memset(this, 0 ,sizeof(*this));");
246                     writer.WriteLine("    char liuxb_tmp[512];");
247                     writer.WriteLine("    char* liuxb_text = (char*)liuxb_line;");
248 
249                     foreach (ADTType e in _lstValue)
250                     {
251                         writer.WriteLine("    memset(liuxb_tmp, 0, sizeof(liuxb_tmp));");
252                         writer.WriteLine("    liuxb_text = string_helper::split(liuxb_text, strlen(liuxb_text), split_token_define, liuxb_tmp);");
253                         text = "    " + e.ValueName + " = string_helper::";
254                         if (e.ValueType == ADTType.EType.i)
255                         {
256                             text += "to_int(liuxb_tmp);";
257                             writer.WriteLine(text);
258                         }
259                         else if (e.ValueType == ADTType.EType.l)
260                         {
261                             text += "to_long(liuxb_tmp);";
262                             writer.WriteLine(text);
263                         }
264                         else if (e.ValueType == ADTType.EType.d)
265                         {
266                             text += "to_double(liuxb_tmp);";
267                             writer.WriteLine(text);
268                         }
269                         else
270                         {
271                             text = "    memcpy(&" + e.ValueName + ", liuxb_tmp, sizeof(" + e.ValueName + "));";
272                             writer.WriteLine(text);
273                         }
274                         
275                     }
276                     writer.WriteLine("};");
277                     writer.Flush();
278                     writer.Dispose();
279                     writer.Close();
280                 }
281             }
282             catch (System.Exception e)
283             {
284                 ret = false;
285                 MessageBox.Show(e.Message);
286             }
287             finally
288             {
289                 _file.Dispose();
290                 _file.Close();
291             }
292             return ret;
293         }
294     }
295 }
View Code

二、装载资源的dll

有了上述工具生成res资源及c++数据结构后,再写一个通用的res资源读取的c++ dll工程即可。

1.字符串转换

 1 /*------------------------------------------------------------------
 2 // 著作版权:Copyright (C) liuxb
 3 // 创建时间:[liuxb|20130920]
 4 // 功能描述:字符串转换
 5 //
 6 // 修改时间:
 7 // 修改描述:
 8 // 
 9 //----------------------------------------------------------------*/
10 
11 #pragma once
12 
13 #include <stdlib.h>
14 
15 // 字符串转换
16 struct string_helper
17 {
18     static int to_int(const char* value) { return atoi(value); }
19 
20     static int to_long(const char* value) { return atol(value); }
21 
22     static double to_double(const char* value) { return atof(value); }
23 
24     // 从text中获取以c分隔的前半段字符串并写入buffer
25     // 返回src_text后半段字符串
26     static char* split(char* text, int text_len, char c, char* buffer);
27 };
View Code
 1 #include "stdafx.h"
 2 #include "convertion.hpp"
 3 
 4 #include <string.h>
 5 #include <stdio.h>
 6 
 7 char* string_helper::split(char* text, int text_len, char c, char* buffer)
 8 {
 9     char* end = text; 
10     for(int i = 0; i<text_len; ++i, ++end)
11     {
12         if(end[0] == c)
13         {
14             memcpy(buffer, text, end-text);
15             return end + 1;
16         }
17     }
18     memcpy(buffer, text, text_len);
19     return 0;
20 }
View Code

2.资源容器模板

 1 /*------------------------------------------------------------------
 2 // 著作版权:Copyright (C) liuxb
 3 // 创建时间:[liuxb|20130920]
 4 // 功能描述:读入res资源转换成对象数组
 5 //
 6 // 修改时间:
 7 // 修改描述:
 8 // 
 9 //----------------------------------------------------------------*/
10 
11 #pragma once
12 
13 #include <vector>
14 #include <string>
15 #include <algorithm>
16 #include <fstream>
17 
18 using std::vector;
19 using std::string;
20 
21 // 资源集
22 template<typename Data>
23 class resource_set
24 {
25     typedef vector<Data>                        vdata;
26 public:
27     typedef typename vdata::value_type            value_type;
28     typedef    typename vdata::iterator            iterator;    
29 public:
30     resource_set() 
31     {
32         m_vdata = new vdata;
33     }
34 
35     ~resource_set()
36     {
37         delete m_vdata;
38     }
39 
40 public:
41     // 加载资源
42     bool load_resource(const char* resource_path)
43     {
44         std::ifstream file(resource_path, std::ios::binary);
45         if(!file) return false;
46         string line;
47         while (getline(file, line))
48         {
49             value_type data(line.c_str());
50             m_vdata->push_back(data);
51         }
52         return true;
53     }
54 
55     // 查找资源
56     value_type* find(int id)
57     {
58         value_type data(id);
59         vdata::iterator it = std::find(m_vdata->begin(), m_vdata->end(), data);
60         if(it == m_vdata->end())  return 0;
61         return &(*it);
62     }
63 
64     vdata& datas() { return *m_vdata; }
65     iterator begin() { return m_vdata->begin(); }
66     iterator end() { return m_vdata->end(); }
67 
68 private:
69     vdata*                                m_vdata;
70 };
View Code

3.根据资源数据结构声明具体的资源容器导出类

 1 // 下列 ifdef 块是创建使从 DLL 导出更简单的
 2 // 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 RES_EXPORTS
 3 // 符号编译的。在使用此 DLL 的
 4 // 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
 5 // RES_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
 6 // 符号视为是被导出的。
 7 
 8 #pragma once
 9 
10 #ifdef RES_EXPORTS
11 #define RES_API __declspec(dllexport)
12 #else
13 #define RES_API __declspec(dllimport)
14 #endif
15 
16 #include "resource_set.hpp"
17 
18 #include "adt\npc_talk_dt.h"
19 #include "adt\task_dt.h"
20 
21 
22 class RES_API npc_talk_sc : public resource_set<npc_talk_dt> {};
23 
24 class RES_API task_sc : public resource_set<task_dt> {};
View Code

记得在dllmain.cpp中添加res.h头文件。

posted @ 2013-10-02 01:00  traits  阅读(290)  评论(0编辑  收藏  举报