游戏资源及代码生成

一、资源及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头文件。

你可能感兴趣的:(代码生成)