CPPGenerator.cs 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044
  1. using System;
  2. using System.Text;
  3. using System.IO;
  4. using System.Collections.Generic;
  5. namespace spgen
  6. {
  7. public class CPPGenerator : GeneratorBase
  8. {
  9. static string[] CPP_TYPE_NAMES = new string[]
  10. {
  11. "bool",
  12. "short",
  13. "unsigned short",
  14. "char",
  15. "unsigned char",
  16. "int",
  17. "unsigned int",
  18. "__int64",
  19. "unsigned __int64",
  20. "double",
  21. "float",
  22. "CSimpleStringA",
  23. "CSimpleStringW",
  24. "CBlob", // blob
  25. "CAutoArray<bool>",
  26. "CAutoArray<short>",
  27. "CAutoArray<unsigned short>",
  28. "CAutoArray<char>",
  29. "CAutoArray<unsigned char>",
  30. "CAutoArray<int>",
  31. "CAutoArray<unsigned int>",
  32. "CAutoArray<__int64>",
  33. "CAutoArray<unsigned __int64>",
  34. "CAutoArray<double>",
  35. "CAutoArray<float>",
  36. "CAutoArray<CSimpleStringA>",
  37. "CAutoArray<CSimpleStringW>",
  38. "CAutoArray<CBlob>",
  39. };
  40. static string GetCodeType(ParamType type)
  41. {
  42. return CPP_TYPE_NAMES[(int)type];
  43. }
  44. public override void GenerateCode(string dir, Entity entity, bool inSourceDir)
  45. {
  46. if (!inSourceDir)
  47. dir = Path.Combine(dir, "generate");
  48. if (!Directory.Exists(dir))
  49. Directory.CreateDirectory(dir);
  50. string deffilename = string.Format("{0}_def_g.h", entity.Name);
  51. string deffilepath = Path.Combine(dir, deffilename);
  52. GenerateDef(deffilepath, deffilename, entity);
  53. if (entity.ClassList.Count > 0)
  54. {
  55. string serverfile = string.Format("{0}_server_g.h", entity.Name);
  56. serverfile = Path.Combine(dir, serverfile);
  57. GenerateServer(deffilename, serverfile, entity);
  58. string clientfile = string.Format("{0}_client_g.h", entity.Name);
  59. clientfile = Path.Combine(dir, clientfile);
  60. GenerateClient(deffilename, clientfile, entity);
  61. }
  62. if (entity.MsgList.Count > 0)
  63. {
  64. string msgfile = string.Format("{0}_msg_g.h", entity.Name);
  65. msgfile = Path.Combine(dir, msgfile);
  66. GenerateMsg(msgfile, entity);
  67. }
  68. }
  69. string GetMethodEnumName(Entity entity, EntityClass cls, Method m)
  70. {
  71. return string.Format("{0}_Method_{1}", cls.Name, m.Name);
  72. }
  73. string GetMethodSignatureEnumName(Entity entity, EntityClass cls, Method m)
  74. {
  75. return string.Format("{0}_MethodSignature_{1}", cls.Name, m.Name);
  76. }
  77. void WriteConst(StreamWriter sw, Entity entity)
  78. {
  79. sw.WriteLine("//");
  80. sw.WriteLine("// const goes here");
  81. sw.WriteLine("//");
  82. foreach (ConstItem i in entity.ConstList)
  83. {
  84. WriteLineDefine(sw, entity, i.Name, i.Value.ToString());
  85. }
  86. sw.WriteLine();
  87. }
  88. void WriteLineDefine(StreamWriter sw, Entity entity, string name, string num, bool tryReplace = true)
  89. {
  90. string value = "";
  91. if (tryReplace && entity.defineDic.TryGetValue(name, out value))
  92. {
  93. //success ,judge if len > 3, len > 3, replace the new value; len <=3, must the same
  94. if (value.Length > 3)
  95. num = value;
  96. else
  97. {
  98. if (num != value)
  99. {
  100. Console.WriteLine("sequence changed ,failed!! {0}, {1}", name, num);
  101. Environment.Exit(-1);
  102. }
  103. }
  104. }
  105. sw.WriteLine("#define {0} {1}", name, num);
  106. }
  107. void WriteMethodEnum(StreamWriter sw, Entity entity, EntityClass cls)
  108. {
  109. foreach (Method m in cls.MethodList)
  110. {
  111. if (typeof(Subscribe).IsInstanceOfType(m))
  112. {
  113. Subscribe subscribe = m as Subscribe;
  114. WriteLineDefine(sw, entity, string.Format("{0}_Method_{1}", cls.Name, subscribe.Name), subscribe.Id.ToString());
  115. WriteLineDefine(sw, entity, string.Format("{0}_Method_{1}", cls.Name, subscribe.Cancel.Name), subscribe.Cancel.Id.ToString());
  116. WriteLineDefine(sw, entity, string.Format("{0}_Method_{1}", cls.Name, subscribe.Message.Name), subscribe.Message.Id.ToString());
  117. }
  118. else
  119. {
  120. WriteLineDefine(sw, entity, string.Format("{0}_Method_{1}", cls.Name, m.Name), m.Id.ToString());
  121. }
  122. }
  123. sw.WriteLine();
  124. }
  125. bool WriteLogCode(StreamWriter sw, Entity entity, EntityClass cls)
  126. {
  127. if (!Entity.entityDic.ContainsKey(entity.Name))
  128. return false;
  129. foreach (Method m in cls.MethodList)
  130. {
  131. if (typeof(Subscribe).IsInstanceOfType(m))
  132. {
  133. continue;
  134. }
  135. else
  136. {
  137. if (m.Id > 256) m.Id = 99;
  138. string nameStr = string.Format("{0}_LogCode_{1}", cls.Name, m.Name);
  139. string defineStr = string.Format("\"QLR0402{0}{1}\"", Entity.entityDic[entity.Name], m.Id.ToString("D2"));
  140. WriteLineDefine(sw, entity, nameStr, defineStr, false);
  141. }
  142. }
  143. sw.WriteLine();
  144. return true;
  145. }
  146. void WriteMethodSignatureEnum(StreamWriter sw, Entity entity, EntityClass cls)
  147. {
  148. foreach (Method m in cls.MethodList)
  149. {
  150. if (typeof(Subscribe).IsInstanceOfType(m))
  151. {
  152. Subscribe subscribe = m as Subscribe;
  153. WriteLineDefine(sw, entity, string.Format("{0}_MethodSignature_{1}", cls.Name, subscribe.Name), subscribe.Signature.ToString());
  154. WriteLineDefine(sw, entity, string.Format("{0}_MethodSignature_{1}", cls.Name, subscribe.Cancel.Name), subscribe.Cancel.Signature.ToString());
  155. WriteLineDefine(sw, entity, string.Format("{0}_MethodSignature_{1}", cls.Name, subscribe.Message.Name), subscribe.Message.Signature.ToString());
  156. }
  157. else
  158. {
  159. WriteLineDefine(sw, entity, string.Format("{0}_MethodSignature_{1}", cls.Name, m.Name), m.Signature.ToString());
  160. }
  161. }
  162. sw.WriteLine();
  163. }
  164. void WriteStruct(StreamWriter sw, string name, List<Param> ParamList)
  165. {
  166. sw.WriteLine("struct {0}", name);
  167. sw.WriteLine("{");
  168. foreach (Param i in ParamList)
  169. {
  170. sw.WriteLine("\t{0} {1};", GetCodeType(i.Type), i.Name);
  171. }
  172. sw.WriteLine();
  173. sw.WriteLine("\tvoid Serialize(SpBuffer &Buf)");
  174. sw.WriteLine("\t{");
  175. if (ParamList.Count > 0)
  176. {
  177. sw.Write("\t\tauto & buf = Buf");
  178. foreach (Param i in ParamList)
  179. {
  180. sw.Write(" & {0}", i.Name);
  181. }
  182. sw.WriteLine(";");
  183. }
  184. sw.WriteLine("\t}");
  185. sw.WriteLine("");
  186. sw.WriteLine("};");
  187. }
  188. string GetInfoStructName(Entity entity, EntityClass cls, Method m)
  189. {
  190. return string.Format("{0}_{1}_Info", cls.Name, m.Name);
  191. }
  192. string GetReqStructName(Entity entity, EntityClass cls, Method m)
  193. {
  194. return string.Format("{0}_{1}_Req", cls.Name, m.Name);
  195. }
  196. string GetAnsStructName(Entity entity, EntityClass cls, Method m)
  197. {
  198. return string.Format("{0}_{1}_Ans", cls.Name, m.Name);
  199. }
  200. string GetSubStructName(Entity entity, EntityClass cls, Method m)
  201. {
  202. return string.Format("{0}_{1}_Sub", cls.Name, m.Name);
  203. }
  204. void WriteMethodParam(StreamWriter sw, Entity entity, EntityClass cls)
  205. {
  206. foreach (Method m in cls.MethodList)
  207. {
  208. if (typeof(Oneway).IsInstanceOfType(m))
  209. {
  210. Oneway oneway = m as Oneway;
  211. string iname = GetInfoStructName(entity, cls, m);
  212. WriteStruct(sw, iname, oneway.InfoParamList);
  213. sw.WriteLine();
  214. }
  215. else if (typeof(Twoway).IsInstanceOfType(m))
  216. {
  217. Twoway twoway = m as Twoway;
  218. string reqname = GetReqStructName(entity, cls, m);
  219. WriteStruct(sw, reqname, twoway.ReqParamList);
  220. sw.WriteLine();
  221. string ansname = GetAnsStructName(entity, cls, m);
  222. WriteStruct(sw, ansname, twoway.ResParamList);
  223. sw.WriteLine();
  224. }
  225. else if (typeof(Subscribe).IsInstanceOfType(m))
  226. {
  227. Subscribe subscribe = m as Subscribe;
  228. string subname = GetSubStructName(entity, cls, m);
  229. WriteStruct(sw, subname, subscribe.SubParamList);
  230. sw.WriteLine();
  231. string canname = GetInfoStructName(entity, cls, subscribe.Cancel);
  232. WriteStruct(sw, canname, subscribe.Cancel.InfoParamList);
  233. sw.WriteLine();
  234. string msgname = GetInfoStructName(entity, cls, subscribe.Message);
  235. WriteStruct(sw, msgname, subscribe.Message.InfoParamList);
  236. sw.WriteLine();
  237. }
  238. else
  239. {
  240. throw new Exception("unknown");
  241. }
  242. }
  243. }
  244. void GenerateDef(string file, string file_name, Entity entity)
  245. {
  246. using (StreamWriter sw = new StreamWriter(file, false, Encoding.GetEncoding("gb2312")))
  247. {
  248. string guard_marco = string.Format("__{0}", file_name.Replace('.', '_').ToUpper());
  249. sw.WriteLine("#ifndef " + guard_marco);
  250. sw.WriteLine("#define " + guard_marco);
  251. sw.WriteLine();
  252. sw.WriteLine("#pragma once");
  253. sw.WriteLine();
  254. sw.WriteLine("// This code is generated by spgen tool!");
  255. sw.WriteLine();
  256. sw.WriteLine("#include \"SpHelper.h\"");
  257. sw.WriteLine();
  258. sw.WriteLine("namespace {0} {{", entity.Name);
  259. WriteConst(sw, entity);
  260. foreach (EntityClass cls in entity.ClassList)
  261. {
  262. WriteMethodEnum(sw, entity, cls);
  263. WriteMethodSignatureEnum(sw, entity, cls);
  264. WriteLogCode(sw, entity, cls);
  265. WriteMethodParam(sw, entity, cls);
  266. sw.WriteLine();
  267. sw.WriteLine("///////////////////////////");
  268. sw.WriteLine();
  269. }
  270. sw.WriteLine("}} // namespace {0}", entity.Name);
  271. sw.WriteLine();
  272. sw.WriteLine(string.Format("#endif // {0}", guard_marco));
  273. }
  274. }
  275. void WriteServerConstructor(StreamWriter sw, Entity entity, EntityClass cls)
  276. {
  277. sw.WriteLine("\t{0}()", GetServerClassName(entity, cls));
  278. sw.WriteLine("\t{");
  279. sw.WriteLine("\t\t/// override by user");
  280. sw.WriteLine("\t}");
  281. sw.WriteLine();
  282. }
  283. void WriteServerDestructor(StreamWriter sw, Entity entity, EntityClass cls)
  284. {
  285. sw.WriteLine("\tvirtual ~{0}()", GetServerClassName(entity, cls));
  286. sw.WriteLine("\t{");
  287. sw.WriteLine("\t\t/// override by user");
  288. sw.WriteLine("\t}");
  289. sw.WriteLine();
  290. }
  291. void WriteSeverIsExclusive(StreamWriter sw, Entity entity, EntityClass cls)
  292. {
  293. sw.WriteLine("\tvirtual bool IsExclusive() {{ return {0}; }}", cls.Exclusive.ToString().ToLower());
  294. sw.WriteLine();
  295. }
  296. void WriteServerGetMessageAttr(StreamWriter sw, Entity entity, EntityClass cls)
  297. {
  298. sw.WriteLine("\tvirtual ErrorCodeEnum GetMessageAttr(DWORD dwMessageID, DWORD dwSignature, bool &bOverlap)");
  299. sw.WriteLine("\t{");
  300. sw.WriteLine("\t\tErrorCodeEnum Error = Error_Succeed;");
  301. sw.WriteLine("\t\tswitch (dwMessageID) {");
  302. foreach (Method m in cls.MethodList)
  303. {
  304. sw.WriteLine("\t\tcase {0}:", GetMethodEnumName(entity, cls, m));
  305. sw.WriteLine("\t\t\tif (dwSignature == {0}) {{", GetMethodSignatureEnumName(entity, cls, m));
  306. sw.WriteLine("\t\t\t\tbOverlap = {0};", m.Overlap.ToString().ToLower());
  307. sw.WriteLine("\t\t\t} else {");
  308. sw.WriteLine("\t\t\t\tError = Error_MethodSignatureFailed;");
  309. sw.WriteLine("\t\t\t}");
  310. sw.WriteLine("\t\t\tbreak;");
  311. if (typeof(Subscribe).IsInstanceOfType(m))
  312. {
  313. Subscribe subscribe = m as Subscribe;
  314. sw.WriteLine("\t\tcase {0}:", GetMethodEnumName(entity, cls, subscribe.Cancel));
  315. sw.WriteLine("\t\t\tif (dwSignature == {0}) {{", GetMethodSignatureEnumName(entity, cls, subscribe.Cancel));
  316. sw.WriteLine("\t\t\t\tbOverlap = {0};", subscribe.Cancel.Overlap.ToString().ToLower());
  317. sw.WriteLine("\t\t\t} else {");
  318. sw.WriteLine("\t\t\t\tError = Error_MethodSignatureFailed;");
  319. sw.WriteLine("\t\t\t}");
  320. sw.WriteLine("\t\t\tbreak;");
  321. }
  322. }
  323. sw.WriteLine("\t\tdefault:");
  324. sw.WriteLine("\t\t\tError = Error_MethodNotFound;");
  325. sw.WriteLine("\t\t\tbreak;");
  326. sw.WriteLine("\t\t}");
  327. sw.WriteLine("\t\treturn Error;");
  328. sw.WriteLine("\t}");
  329. sw.WriteLine();
  330. }
  331. void WriteServerCheckMessageSignature(StreamWriter sw, Entity entity, EntityClass cls)
  332. {
  333. sw.WriteLine("\tint CheckMessageSignature(DWORD dwMessageID, DWORD dwSignature)");
  334. sw.WriteLine("\t{");
  335. sw.WriteLine("\t\tErrorCodeEnum Error = Error_Succeed;");
  336. sw.WriteLine("\t\tswitch (dwMessageID) {");
  337. foreach (Method m in cls.MethodList)
  338. {
  339. sw.WriteLine("\t\tcase {0}:", GetMethodEnumName(entity, cls, m));
  340. sw.WriteLine("\t\t\tif (dwSignature != {0}) {{", GetMethodSignatureEnumName(entity, cls, m));
  341. sw.WriteLine("\t\t\t\tError = Error_MethodSignatureFailed;");
  342. sw.WriteLine("\t\t\t}");
  343. sw.WriteLine("\t\t\tbreak;");
  344. // gen cancel method signature check
  345. if (typeof(Subscribe).IsInstanceOfType(m))
  346. {
  347. Subscribe subscribe = m as Subscribe;
  348. sw.WriteLine("\t\tcase {0}:", GetMethodEnumName(entity, cls, subscribe.Cancel));
  349. sw.WriteLine("\t\t\tif (dwSignature != {0}) {{", GetMethodSignatureEnumName(entity, cls, subscribe.Cancel));
  350. sw.WriteLine("\t\t\t\tError = Error_MethodSignatureFailed;");
  351. sw.WriteLine("\t\t\t}");
  352. sw.WriteLine("\t\t\tbreak;");
  353. }
  354. }
  355. sw.WriteLine("\t\tdefault:");
  356. sw.WriteLine("\t\t\tError = Error_MethodNotFound;");
  357. sw.WriteLine("\t\t\tbreak;");
  358. sw.WriteLine("\t\t}");
  359. sw.WriteLine("\t\treturn Error;");
  360. sw.WriteLine("\t}");
  361. sw.WriteLine();
  362. }
  363. void WriteServerIsSessionOverlap(StreamWriter sw, Entity entity, EntityClass cls)
  364. {
  365. sw.WriteLine("\tvirtual bool IsSessionOverlap() {{ return {0}; }}", cls.Overlap.ToString().ToLower());
  366. sw.WriteLine();
  367. }
  368. void WriteServerOnewayHandler(StreamWriter sw, Entity entity, EntityClass cls, Oneway oneway)
  369. {
  370. sw.WriteLine("\tvirtual void Handle_{0}(SpOnewayCallContext<{1}>::Pointer ctx)", oneway.Name, GetInfoStructName(entity, cls, oneway));
  371. sw.WriteLine("\t{");
  372. sw.WriteLine("\t/// override by user");
  373. sw.WriteLine("\t}");
  374. sw.WriteLine("");
  375. }
  376. void WriteServerTwowayHandler(StreamWriter sw, Entity entity, EntityClass cls, Twoway twoway)
  377. {
  378. sw.WriteLine("\tvirtual void Handle_{0}(SpReqAnsContext<{1}, {2}>::Pointer ctx)", twoway.Name, GetReqStructName(entity, cls, twoway), GetAnsStructName(entity, cls, twoway));
  379. sw.WriteLine("\t{");
  380. sw.WriteLine("\t/// override by user");
  381. sw.WriteLine("\t}");
  382. sw.WriteLine("");
  383. }
  384. void WriteServerSubscibeHandler(StreamWriter sw, Entity entity, EntityClass cls, Subscribe subscribe)
  385. {
  386. // subscribe
  387. sw.WriteLine("\tvirtual void Handle_{0}(SpSubscribeContext<{1}, {2}>::Pointer ctx)", subscribe.Name, GetSubStructName(entity, cls, subscribe), GetInfoStructName(entity, cls, subscribe.Message));
  388. sw.WriteLine("\t{");
  389. sw.WriteLine("\t/// override by user");
  390. sw.WriteLine("\t}");
  391. sw.WriteLine("");
  392. // cancel
  393. sw.WriteLine("\tvirtual void Handle_{0}(SpOnewayCallContext<{1}>::Pointer ctx)", subscribe.Cancel.Name, GetInfoStructName(entity, cls, subscribe.Cancel));
  394. sw.WriteLine("\t{");
  395. sw.WriteLine("\t/// override by user");
  396. sw.WriteLine("\t}");
  397. sw.WriteLine("");
  398. }
  399. void WriteServerOnRequest(StreamWriter sw, Entity entity, EntityClass cls)
  400. {
  401. sw.WriteLine("\tvirtual void OnRequest(CSmartPointer<ITransactionContext> pTransactionContext)");
  402. sw.WriteLine("\t{");
  403. sw.WriteLine("\t\tCAutoBuffer Buf;");
  404. sw.WriteLine("\t\tDWORD dwMessageID;");
  405. sw.WriteLine("\t\tDWORD dwMessageSignature;");
  406. sw.WriteLine("\t\tErrorCodeEnum Error = pTransactionContext->GetReceiveBuffer(dwMessageID, dwMessageSignature, Buf);");
  407. sw.WriteLine("\t\tif (Error == Error_Succeed) {");
  408. sw.WriteLine("#ifdef DEBUG");
  409. sw.WriteLine("\t\t\tassert(CheckMessageSignature(dwMessageID, dwMessageSignature) == Error_Succeed);");
  410. sw.WriteLine("#else");
  411. sw.WriteLine("\t\t\tif (CheckMessageSignature(dwMessageID, dwMessageSignature) != Error_Succeed) {");
  412. sw.WriteLine("\t\t\t\tpTransactionContext->SendAnswer(Error_MethodSignatureFailed);");
  413. sw.WriteLine("\t\t\t\treturn;");
  414. sw.WriteLine("\t\t\t}");
  415. sw.WriteLine("#endif");
  416. //sw.WriteLine("\t\tEntityResource::clearLink();");
  417. sw.WriteLine("\t\t\tswitch (dwMessageID) {");
  418. foreach (Method m in cls.MethodList)
  419. {
  420. if (typeof(Oneway).IsInstanceOfType(m))
  421. {
  422. Oneway oneway = m as Oneway;
  423. sw.WriteLine("\t\t\t\tcase {0}:", GetMethodEnumName(entity, cls, m));
  424. sw.WriteLine("\t\t\t\t\t{");
  425. sw.WriteLine("\t\t\t\t\t\tSpOnewayCallContext<{0}>::Pointer ctx;", GetInfoStructName(entity, cls, m));
  426. sw.WriteLine("\t\t\t\t\t\tctx.Attach(new SpOnewayCallContext<{0}>());", GetInfoStructName(entity, cls, m));
  427. sw.WriteLine("\t\t\t\t\t\tSpBuffer2Object(Buf, ctx->Info);");
  428. sw.WriteLine("\t\t\t\t\t\tpTransactionContext->GetLinkContext(ctx->link);");
  429. sw.WriteLine("\t\t\t\t\t\tEntityResource::setLink(ctx->link);");
  430. sw.WriteLine("\t\t\t\t\t\tHandle_{0}(ctx);", m.Name);
  431. sw.WriteLine("\t\t\t\t\t}");
  432. sw.WriteLine("\t\t\t\t\tbreak;");
  433. }
  434. else if (typeof(Twoway).IsInstanceOfType(m))
  435. {
  436. Twoway twoway = m as Twoway;
  437. sw.WriteLine("\t\t\t\tcase {0}:", GetMethodEnumName(entity, cls, m));
  438. sw.WriteLine("\t\t\t\t\t{");
  439. sw.WriteLine("\t\t\t\t\t\tSpReqAnsContext<{0},{1}>::Pointer ctx;", GetReqStructName(entity, cls, m), GetAnsStructName(entity, cls, m));
  440. sw.WriteLine("\t\t\t\t\t\tctx.Attach(new SpReqAnsContext<{0},{1}>(pTransactionContext));", GetReqStructName(entity, cls, m), GetAnsStructName(entity, cls, m));
  441. sw.WriteLine("\t\t\t\t\t\tSpBuffer2Object(Buf, ctx->Req);");
  442. sw.WriteLine("\t\t\t\t\t\tpTransactionContext->GetLinkContext(ctx->link);");
  443. sw.WriteLine("\t\t\t\t\t\tEntityResource::setLink(ctx->link);");
  444. sw.WriteLine("\t\t\t\t\t\tHandle_{0}(ctx);", m.Name);
  445. sw.WriteLine("\t\t\t\t\t}");
  446. sw.WriteLine("\t\t\t\t\tbreak;");
  447. }
  448. else if (typeof(Subscribe).IsInstanceOfType(m))
  449. {
  450. Subscribe subscribe = m as Subscribe;
  451. sw.WriteLine("\t\t\t\tcase {0}:", GetMethodEnumName(entity, cls, m));
  452. sw.WriteLine("\t\t\t\t\t{");
  453. sw.WriteLine("\t\t\t\t\t\tSpSubscribeContext<{0},{1}>::Pointer ctx;", GetSubStructName(entity, cls, m), GetInfoStructName(entity, cls, subscribe.Message));
  454. sw.WriteLine("\t\t\t\t\t\tctx.Attach(new SpSubscribeContext<{0},{1}>(pTransactionContext));", GetSubStructName(entity, cls, m), GetInfoStructName(entity, cls, subscribe.Message));
  455. sw.WriteLine("\t\t\t\t\t\tSpBuffer2Object(Buf, ctx->Req);");
  456. sw.WriteLine("\t\t\t\t\t\tHandle_{0}(ctx);", m.Name);
  457. sw.WriteLine("\t\t\t\t\t}");
  458. sw.WriteLine("\t\t\t\t\tbreak;");
  459. sw.WriteLine("\t\t\t\tcase {0}:", GetMethodEnumName(entity, cls, subscribe.Cancel));
  460. sw.WriteLine("\t\t\t\t\t{");
  461. sw.WriteLine("\t\t\t\t\t\tSpOnewayCallContext<{0}>::Pointer ctx;", GetInfoStructName(entity, cls, subscribe.Cancel));
  462. sw.WriteLine("\t\t\t\t\t\tctx.Attach(new SpOnewayCallContext<{0}>());", GetInfoStructName(entity, cls, subscribe.Cancel));
  463. sw.WriteLine("\t\t\t\t\t\tSpBuffer2Object(Buf, ctx->Info);");
  464. sw.WriteLine("\t\t\t\t\t\tHandle_{0}(ctx);", subscribe.Cancel.Name);
  465. sw.WriteLine("\t\t\t\t\t}");
  466. sw.WriteLine("\t\t\t\t\tbreak;");
  467. }
  468. else
  469. {
  470. throw new Exception("unknown method!");
  471. }
  472. }
  473. sw.WriteLine("\t\t\t\tdefault:");
  474. sw.WriteLine("\t\t\t\t\tassert(0);");
  475. sw.WriteLine("\t\t\t\t\tbreak;");
  476. sw.WriteLine("\t\t\t}");
  477. sw.WriteLine("\t\t\t");
  478. sw.WriteLine("\t\t} else {");
  479. sw.WriteLine("\t\t\tpTransactionContext->SendAnswer(Error);");
  480. sw.WriteLine("\t\t}");
  481. sw.WriteLine("\t}");
  482. sw.WriteLine("");
  483. }
  484. string GetServerClassName(Entity entity, EntityClass cls)
  485. {
  486. return string.Format("{0}_ServerSessionBase", cls.Name);
  487. }
  488. void WriteClassServer(StreamWriter sw, Entity entity, EntityClass cls)
  489. {
  490. sw.WriteLine("class {0} : public CServerSessionBase", GetServerClassName(entity, cls));
  491. sw.WriteLine("{");
  492. sw.WriteLine("public:");
  493. WriteServerConstructor(sw, entity, cls);
  494. WriteServerDestructor(sw, entity, cls);
  495. WriteSeverIsExclusive(sw, entity, cls);
  496. WriteServerIsSessionOverlap(sw, entity, cls);
  497. WriteServerGetMessageAttr(sw, entity, cls);
  498. WriteServerCheckMessageSignature(sw, entity, cls);
  499. foreach (Method m in cls.MethodList)
  500. {
  501. if (typeof(Oneway).IsInstanceOfType(m))
  502. {
  503. WriteServerOnewayHandler(sw, entity, cls, m as Oneway);
  504. }
  505. else if (typeof(Twoway).IsInstanceOfType(m))
  506. {
  507. WriteServerTwowayHandler(sw, entity, cls, m as Twoway);
  508. }
  509. else if (typeof(Subscribe).IsInstanceOfType(m))
  510. {
  511. WriteServerSubscibeHandler(sw, entity, cls, m as Subscribe);
  512. }
  513. else
  514. {
  515. throw new Exception("unknown method!");
  516. }
  517. }
  518. WriteServerOnRequest(sw, entity, cls);
  519. sw.WriteLine("};");
  520. sw.WriteLine();
  521. }
  522. void GenerateServer(string deffilename, string file, Entity entity)
  523. {
  524. string file_name = System.IO.Path.GetFileName(file);
  525. using (StreamWriter sw = new StreamWriter(file, false, Encoding.GetEncoding("gb2312")))
  526. {
  527. string guard_marco = string.Format("__{0}", file_name.Replace('.', '_').ToUpper());
  528. sw.WriteLine();
  529. sw.WriteLine("#ifndef " + guard_marco);
  530. sw.WriteLine("#define " + guard_marco);
  531. sw.WriteLine();
  532. sw.WriteLine("#pragma once");
  533. sw.WriteLine();
  534. sw.WriteLine("// This code is generated by spgen tool!");
  535. sw.WriteLine();
  536. sw.WriteLine("#include \"{0}\"", deffilename);
  537. sw.WriteLine();
  538. sw.WriteLine("namespace {0} {{", entity.Name);
  539. foreach (EntityClass cls in entity.ClassList)
  540. {
  541. WriteClassServer(sw, entity, cls);
  542. sw.WriteLine();
  543. sw.WriteLine("///////////////////////////");
  544. sw.WriteLine();
  545. }
  546. sw.WriteLine("}} // namespace {0}", entity.Name);
  547. sw.WriteLine(string.Format("#endif // {0}", guard_marco));
  548. }
  549. }
  550. void WriteClientOneway(StreamWriter sw, Entity entity, EntityClass cls, Oneway oneway)
  551. {
  552. string iname = GetInfoStructName(entity, cls, oneway);
  553. if (oneway.InfoParamList.Count > 0)
  554. {
  555. sw.WriteLine("\tErrorCodeEnum {0}({1} &Info)", oneway.Name, iname);
  556. sw.WriteLine("\t{");
  557. sw.WriteLine("\t\tCSmartPointer<IClientSessionFunction> pFunc = GetFunction();");
  558. sw.WriteLine("\t\tif (m_context.checkEmpty())");
  559. sw.WriteLine("\t\t{");
  560. sw.WriteLine("\t\t\tm_context.AutoGenerate();");
  561. sw.WriteLine("\t\t\tDbgToBeidou(m_context, m_pEntityBase != NULL ? m_pEntityBase->GetEntityName() : \"\")();");
  562. sw.WriteLine("\t\t\tm_context = m_context.upgradeLink();");
  563. sw.WriteLine("\t\t}");
  564. sw.WriteLine("\t\tCAutoBuffer Buf = SpObject2Buffer(Info);");
  565. sw.WriteLine("\t\tauto ret = pFunc->OnewayCall({0}, {1}, Buf, m_context);", GetMethodEnumName(entity, cls, oneway), GetMethodSignatureEnumName(entity, cls, oneway));
  566. sw.WriteLine("\t\tm_context.clear();");
  567. sw.WriteLine("\t\treturn ret;");
  568. sw.WriteLine("\t}");
  569. }
  570. else
  571. {
  572. sw.WriteLine("\tErrorCodeEnum {0}()", oneway.Name);
  573. sw.WriteLine("\t{");
  574. sw.WriteLine("\t\tCSmartPointer<IClientSessionFunction> pFunc = GetFunction();");
  575. sw.WriteLine("\t\tif (m_context.checkEmpty())");
  576. sw.WriteLine("\t\t{");
  577. sw.WriteLine("\t\t\tm_context.AutoGenerate();");
  578. sw.WriteLine("\t\t\tDbgToBeidou(m_context, m_pEntityBase != NULL ? m_pEntityBase->GetEntityName() : \"\")();");
  579. sw.WriteLine("\t\t\tm_context = m_context.upgradeLink();");
  580. sw.WriteLine("\t\t}");
  581. sw.WriteLine("\t\tauto ret = pFunc->OnewayCall({0}, {1}, m_context);", GetMethodEnumName(entity, cls, oneway), GetMethodSignatureEnumName(entity, cls, oneway));
  582. sw.WriteLine("\t\tm_context.clear();");
  583. sw.WriteLine("\t\treturn ret;");
  584. sw.WriteLine("\t}");
  585. }
  586. sw.WriteLine();
  587. }
  588. void WriteClientTwoway(StreamWriter sw, Entity entity, EntityClass cls, Twoway twoway)
  589. {
  590. // async
  591. sw.WriteLine("\tErrorCodeEnum {0}({1} &Req, CSmartPointer<IAsynWaitSp> &spAsyncWait, DWORD dwTimeout)", twoway.Name, GetReqStructName(entity, cls, twoway));
  592. sw.WriteLine("\t{");
  593. sw.WriteLine("\t\tCSmartPointer<IClientSessionFunction> pFunc = GetFunction();");
  594. sw.WriteLine("\t\tCAutoBuffer Buf = SpObject2Buffer(Req);");
  595. sw.WriteLine("\t\tif (m_context.checkEmpty())");
  596. sw.WriteLine("\t\t{");
  597. sw.WriteLine("\t\t\tm_context.AutoGenerate();");
  598. sw.WriteLine("\t\t\tDbgToBeidou(m_context, m_pEntityBase != NULL ? m_pEntityBase->GetEntityName() : \"\")();");
  599. sw.WriteLine("\t\t\tm_context = m_context.upgradeLink();");
  600. sw.WriteLine("\t\t}");
  601. sw.WriteLine("\t\tauto ret = pFunc->AsyncRequest({0}, {1}, Buf, spAsyncWait, m_context, dwTimeout);", GetMethodEnumName(entity, cls, twoway), GetMethodSignatureEnumName(entity, cls, twoway));
  602. sw.WriteLine("\t\tm_context.clear();");
  603. sw.WriteLine("\t\treturn ret;");
  604. sw.WriteLine("\t}");
  605. // sync
  606. sw.WriteLine("\tErrorCodeEnum {0}({1} &Req, {2} &Ans, DWORD dwTimeout)", twoway.Name, GetReqStructName(entity, cls, twoway), GetAnsStructName(entity, cls, twoway));
  607. sw.WriteLine("\t{");
  608. sw.WriteLine("\t\tCSmartPointer<IAsynWaitSp> spAsyncWait;");
  609. sw.WriteLine("\t\tErrorCodeEnum Error = {0}(Req, spAsyncWait, dwTimeout);", twoway.Name);
  610. sw.WriteLine("\t\tif (Error == Error_Succeed) {");
  611. sw.WriteLine("\t\t\tbool bEnd = false;");
  612. sw.WriteLine("\t\t\tError = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwTimeout);");
  613. sw.WriteLine("\t\t\tLOG_ASSERT(Error || bEnd);");
  614. sw.WriteLine("\t\t}");
  615. sw.WriteLine("\t\treturn Error;");
  616. sw.WriteLine("\t}");
  617. // sync with user error + buf
  618. sw.WriteLine("\tErrorCodeEnum {0}({1} &Req, {2} &Ans, DWORD dwTimeout, DWORD &dwUserError, CSimpleString &str)", twoway.Name, GetReqStructName(entity, cls, twoway), GetAnsStructName(entity, cls, twoway));
  619. sw.WriteLine("\t{");
  620. sw.WriteLine("\t\tCSmartPointer<IAsynWaitSp> spAsyncWait;");
  621. sw.WriteLine("\t\tErrorCodeEnum Error = {0}(Req, spAsyncWait, dwTimeout);", twoway.Name);
  622. sw.WriteLine("\t\tif (Error == Error_Succeed) {");
  623. sw.WriteLine("\t\t\tbool bEnd = false;");
  624. sw.WriteLine("\t\t\tError = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, str, dwTimeout);");
  625. sw.WriteLine("\t\t\tLOG_ASSERT(Error || bEnd);");
  626. sw.WriteLine("\t\t}");
  627. sw.WriteLine("\t\treturn Error;");
  628. sw.WriteLine("\t}");
  629. // sync with user error
  630. sw.WriteLine("\tErrorCodeEnum {0}({1} &Req, {2} &Ans, DWORD dwTimeout, DWORD &dwUserError)", twoway.Name, GetReqStructName(entity, cls, twoway), GetAnsStructName(entity, cls, twoway));
  631. sw.WriteLine("\t{");
  632. sw.WriteLine("\t\tCSmartPointer<IAsynWaitSp> spAsyncWait;");
  633. sw.WriteLine("\t\tErrorCodeEnum Error = {0}(Req, spAsyncWait, dwTimeout);", twoway.Name);
  634. sw.WriteLine("\t\tif (Error == Error_Succeed) {");
  635. sw.WriteLine("\t\t\tbool bEnd = false;");
  636. sw.WriteLine("\t\t\tCSimpleString str;");
  637. sw.WriteLine("\t\t\tError = SpWaitAnswerObject(spAsyncWait, Ans, bEnd, dwUserError, str, dwTimeout);");
  638. sw.WriteLine("\t\t\tLOG_ASSERT(Error || bEnd);");
  639. sw.WriteLine("\t\t}");
  640. sw.WriteLine("\t\treturn Error;");
  641. sw.WriteLine("\t}");
  642. sw.WriteLine();
  643. }
  644. void WriteClientSubscribe(StreamWriter sw, Entity entity, EntityClass cls, Subscribe subscribe)
  645. {
  646. sw.WriteLine("\tErrorCodeEnum {0}({1} &Req, CSmartPointer<IAsynWaitSp> &spAsyncWait)", subscribe.Name, GetSubStructName(entity, cls, subscribe));
  647. sw.WriteLine("\t{");
  648. sw.WriteLine("\t\tCSmartPointer<IClientSessionFunction> pFunc = GetFunction();");
  649. sw.WriteLine("\t\tCAutoBuffer Buf = SpObject2Buffer(Req);");
  650. sw.WriteLine("\t\tErrorCodeEnum Error = pFunc->AsyncRequest({0}, {1}, Buf, spAsyncWait, -1);", GetMethodEnumName(entity, cls, subscribe), GetMethodSignatureEnumName(entity, cls, subscribe));
  651. sw.WriteLine("\t\treturn Error;");
  652. sw.WriteLine("\t}");
  653. sw.WriteLine("\tErrorCodeEnum {0}({1} &Req, ICallbackListener *pCallback,IReleasable *pData = NULL)", subscribe.Name, GetSubStructName(entity, cls, subscribe));
  654. sw.WriteLine("\t{");
  655. sw.WriteLine("\t\tCSmartPointer<IAsynWaitSp> spAsyncWait;");
  656. sw.WriteLine("\t\tErrorCodeEnum Error = {0}(Req, spAsyncWait);", subscribe.Name);
  657. sw.WriteLine("\t\tif (Error == Error_Succeed) {");
  658. sw.WriteLine("\t\t\tspAsyncWait->SetCallback(pCallback, pData);");
  659. sw.WriteLine("\t\t}");
  660. sw.WriteLine("\t\treturn Error;");
  661. sw.WriteLine("\t}");
  662. sw.WriteLine("\tErrorCodeEnum {0}({1} &Req, IReleasable *pData = NULL)", subscribe.Name, GetSubStructName(entity, cls, subscribe));
  663. sw.WriteLine("\t{");
  664. sw.WriteLine("\t\treturn {0}(Req, this, pData);", subscribe.Name);
  665. sw.WriteLine("\t}");
  666. if (subscribe.Cancel.InfoParamList.Count > 0)
  667. {
  668. sw.WriteLine("\tErrorCodeEnum {0}({1} &CancelInfo)", subscribe.Cancel.Name, GetInfoStructName(entity, cls, subscribe.Cancel));
  669. sw.WriteLine("\t{");
  670. sw.WriteLine("\t\tCSmartPointer<IClientSessionFunction> pFunc = GetFunction();");
  671. sw.WriteLine("\t\tCAutoBuffer Buf = SpObject2Buffer(CancelInfo);");
  672. sw.WriteLine("\t\treturn pFunc->OnewayCall({0}, {1}, Buf);", GetMethodEnumName(entity, cls, subscribe.Cancel), GetMethodSignatureEnumName(entity, cls, subscribe.Cancel));
  673. sw.WriteLine("\t}");
  674. }
  675. else
  676. {
  677. sw.WriteLine("\tErrorCodeEnum {0}({1} &CancelInfo)", subscribe.Cancel.Name, GetInfoStructName(entity, cls, subscribe.Cancel));
  678. sw.WriteLine("\t{");
  679. sw.WriteLine("\t\tCSmartPointer<IClientSessionFunction> pFunc = GetFunction();");
  680. sw.WriteLine("\t\treturn pFunc->OnewayCall({0}, {1});", GetMethodEnumName(entity, cls, subscribe.Cancel), GetMethodSignatureEnumName(entity, cls, subscribe.Cancel));
  681. sw.WriteLine("\t}");
  682. }
  683. sw.WriteLine("\tvirtual void OnMessage(ErrorCodeEnum Error, {0} &Msg, CSmartPointer<IReleasable> pData)", GetInfoStructName(entity, cls, subscribe.Message));
  684. sw.WriteLine("\t{");
  685. sw.WriteLine("\t\t/// implement by user");
  686. sw.WriteLine("\t}");
  687. sw.WriteLine();
  688. }
  689. void WriteOnAnswer(StreamWriter sw, Entity entity, EntityClass cls)
  690. {
  691. sw.WriteLine("private:");
  692. sw.WriteLine("\tvirtual void OnAnswer(CSmartPointer<IAsynWaitSp> pAsynWaitSp)");
  693. sw.WriteLine("\t{");
  694. sw.WriteLine("\t\tCAutoBuffer Buf;");
  695. sw.WriteLine("\t\tbool bEnd;");
  696. sw.WriteLine("\t\tCSmartPointer<IReleasable> pData;");
  697. sw.WriteLine("\t\tErrorCodeEnum Error = pAsynWaitSp->AsyncGetAnswer(Buf, bEnd);");
  698. sw.WriteLine("\t\tDWORD dwMessageId = pAsynWaitSp->GetMessageID();");
  699. sw.WriteLine("\t\tCSmartPointer<ICallbackListener> pCallbackListener;");
  700. sw.WriteLine("\t\tpAsynWaitSp->GetCallback(pCallbackListener, pData);");
  701. sw.WriteLine("\t\t");
  702. sw.WriteLine("\t\tswitch (dwMessageId) {");
  703. foreach (Method m in cls.MethodList)
  704. {
  705. if (typeof(Subscribe).IsInstanceOfType(m))
  706. {
  707. Subscribe subscribe = m as Subscribe;
  708. sw.WriteLine("\t\tcase {0}:", GetMethodEnumName(entity, cls, subscribe));
  709. sw.WriteLine("\t\t\tif (Error) {");
  710. sw.WriteLine("\t\t\t\t{0} Msg;", GetInfoStructName(entity, cls, subscribe.Message));
  711. sw.WriteLine("\t\t\t\tOnMessage(Error, Msg, pData);");
  712. sw.WriteLine("\t\t\t} else {");
  713. sw.WriteLine("\t\t\t\t{0} Msg;", GetInfoStructName(entity, cls, subscribe.Message));
  714. sw.WriteLine("\t\t\t\tSpBuffer2Object(Buf, Msg);");
  715. sw.WriteLine("\t\t\t\tOnMessage(Error, Msg, pData);");
  716. sw.WriteLine("\t\t\t}");
  717. sw.WriteLine("\t\t\tbreak;");
  718. }
  719. }
  720. sw.WriteLine("\t\tdefault:");
  721. sw.WriteLine("\t\t\tassert(0);");
  722. sw.WriteLine("\t\t\tbreak;");
  723. sw.WriteLine("\t\t}");
  724. sw.WriteLine("\t\t");
  725. sw.WriteLine("\t\t");
  726. sw.WriteLine("\t}");
  727. sw.WriteLine();
  728. }
  729. bool HasSubscribe(EntityClass cls)
  730. {
  731. foreach (Method m in cls.MethodList)
  732. {
  733. if (typeof(Subscribe).IsInstanceOfType(m))
  734. return true;
  735. }
  736. return false;
  737. }
  738. void WriteClientConstructor(StreamWriter sw, Entity entity, EntityClass cls)
  739. {
  740. sw.WriteLine("\texplicit {0}(CEntityBase *pEntity) : m_pEntityBase(pEntity), m_bSysManaged(false) {{}}", GetClientClassName(entity, cls));
  741. sw.WriteLine();
  742. }
  743. void WriteOperatorContext(StreamWriter sw, Entity entity, EntityClass cls)
  744. {
  745. sw.WriteLine("\t{0}* operator () (const linkContext &curLink) ", GetClientClassName(entity, cls));
  746. sw.WriteLine("\t{");
  747. sw.WriteLine("\t\tm_context = curLink;");
  748. sw.WriteLine("\t\treturn this;");
  749. sw.WriteLine("\t}");
  750. sw.WriteLine();
  751. }
  752. void WriteClientDestructor(StreamWriter sw, Entity entity, EntityClass cls)
  753. {
  754. sw.WriteLine("protected:");
  755. sw.WriteLine("\tvirtual ~{0}()", GetClientClassName(entity, cls));
  756. sw.WriteLine("\t{");
  757. sw.WriteLine("\t\t/// override by user");
  758. sw.WriteLine("\t}");
  759. sw.WriteLine("public:");
  760. sw.WriteLine();
  761. }
  762. void WriteClientConnect(StreamWriter sw, Entity entity, EntityClass cls)
  763. {
  764. sw.WriteLine("\tvoid OnConnectSucceed()");
  765. sw.WriteLine("\t{");
  766. sw.WriteLine("\t\tbSessionClosed = false;");
  767. sw.WriteLine("\t}");
  768. sw.WriteLine("\tvoid OnClose(ErrorCodeEnum)");
  769. sw.WriteLine("\t{");
  770. sw.WriteLine("\t\tDbg(\"session closed.\");");
  771. sw.WriteLine("\t\tbSessionClosed = true;");
  772. sw.WriteLine("\t}");
  773. sw.WriteLine("\tbool QuerySessionClosed()");
  774. sw.WriteLine("\t{");
  775. sw.WriteLine("\t\treturn bSessionClosed;");
  776. sw.WriteLine("\t}");
  777. sw.WriteLine("\tErrorCodeEnum Connect(CSmartPointer<IAsynWaitSp> &spAsyncWait)");
  778. sw.WriteLine("\t{");
  779. sw.WriteLine("\t\tCSmartPointer<IEntityFunction> pFunc = m_pEntityBase->GetFunction();");
  780. sw.WriteLine("\t\tErrorCodeEnum Error = pFunc->ConnectRemoteEntity(this, \"{0}\", \"{1}\", spAsyncWait);", entity.Name, cls.Name);
  781. sw.WriteLine("\t\tif (Error == Error_Succeed) {");
  782. sw.WriteLine("\t\t\tm_bSysManaged = true;");
  783. sw.WriteLine("\t\t\tbSessionClosed = false;");
  784. sw.WriteLine("\t\t}");
  785. sw.WriteLine("\t\treturn Error;");
  786. sw.WriteLine("\t}");
  787. sw.WriteLine("\tErrorCodeEnum Connect()");
  788. sw.WriteLine("\t{");
  789. sw.WriteLine("\t\tCSmartPointer<IAsynWaitSp> spAsyncWait;");
  790. sw.WriteLine("\t\tErrorCodeEnum Error = Connect(spAsyncWait);");
  791. sw.WriteLine("\t\tif (Error == Error_Succeed) {");
  792. sw.WriteLine("\t\t\tError = spAsyncWait->WaitAnswer();");
  793. sw.WriteLine("\t\t}");
  794. sw.WriteLine("\t\treturn Error;");
  795. sw.WriteLine("\t}");
  796. sw.WriteLine();
  797. }
  798. string GetClientClassName(Entity entity, EntityClass cls)
  799. {
  800. return string.Format("{0}_ClientBase", cls.Name);
  801. }
  802. void WriteSafeDelete(StreamWriter sw, Entity entity, EntityClass cls)
  803. {
  804. sw.WriteLine("");
  805. sw.WriteLine("\tbool SafeDelete()");
  806. sw.WriteLine("\t{");
  807. sw.WriteLine("\t\tif (!m_bSysManaged) {");
  808. sw.WriteLine("\t\t\tdelete this;");
  809. sw.WriteLine("\t\t}");
  810. sw.WriteLine("\t\treturn m_bSysManaged;");
  811. sw.WriteLine("\t}");
  812. sw.WriteLine("");
  813. }
  814. void WriteClassClient(StreamWriter sw, Entity entity, EntityClass cls)
  815. {
  816. string clsname = GetClientClassName(entity, cls);
  817. bool bHasSub = HasSubscribe(cls);
  818. if (bHasSub)
  819. sw.WriteLine("class {0} : public CClientSessionBase, public ICallbackListener {{ ", clsname);
  820. else
  821. sw.WriteLine("class {0} : public CClientSessionBase {{", clsname);
  822. sw.WriteLine("public:");
  823. WriteClientConstructor(sw, entity, cls);
  824. WriteOperatorContext(sw, entity, cls);
  825. WriteClientDestructor(sw, entity, cls);
  826. WriteClientConnect(sw, entity, cls);
  827. foreach (Method m in cls.MethodList)
  828. {
  829. if (typeof(Oneway).IsInstanceOfType(m))
  830. {
  831. WriteClientOneway(sw, entity, cls, m as Oneway);
  832. }
  833. else if (typeof(Twoway).IsInstanceOfType(m))
  834. {
  835. WriteClientTwoway(sw, entity, cls, m as Twoway);
  836. }
  837. else if (typeof(Subscribe).IsInstanceOfType(m))
  838. {
  839. WriteClientSubscribe(sw, entity, cls, m as Subscribe);
  840. }
  841. else
  842. {
  843. throw new Exception("unknown");
  844. }
  845. }
  846. WriteSafeDelete(sw, entity, cls);
  847. if (bHasSub)
  848. {
  849. WriteOnAnswer(sw, entity, cls);
  850. }
  851. sw.WriteLine("protected:");
  852. sw.WriteLine("\tbool m_bSysManaged;");
  853. sw.WriteLine("\tCEntityBase *m_pEntityBase;");
  854. sw.WriteLine("\tlinkContext m_context;");
  855. sw.WriteLine("\tbool bSessionClosed;");
  856. sw.WriteLine("};");
  857. }
  858. void GenerateClient(string deffilename, string file, Entity entity)
  859. {
  860. string file_name = System.IO.Path.GetFileName(file);
  861. using (StreamWriter sw = new StreamWriter(file, false, Encoding.GetEncoding("gb2312")))
  862. {
  863. string guard_marco = string.Format("__{0}", file_name.Replace('.', '_').ToUpper());
  864. sw.WriteLine();
  865. sw.WriteLine("#ifndef " + guard_marco);
  866. sw.WriteLine("#define " + guard_marco);
  867. sw.WriteLine();
  868. sw.WriteLine("#pragma once");
  869. sw.WriteLine();
  870. sw.WriteLine("// This code is generated by spgen tool!");
  871. sw.WriteLine();
  872. sw.WriteLine("#include \"{0}\"", deffilename);
  873. sw.WriteLine();
  874. sw.WriteLine("namespace {0} {{", entity.Name);
  875. foreach (EntityClass cls in entity.ClassList)
  876. {
  877. WriteClassClient(sw, entity, cls);
  878. sw.WriteLine();
  879. sw.WriteLine("///////////////////////////");
  880. sw.WriteLine();
  881. }
  882. sw.WriteLine("}} // namespace {0}", entity.Name);
  883. sw.WriteLine(string.Format("#endif // {0}", guard_marco));
  884. }
  885. }
  886. string GetMsgDefName(EntityMsg msg)
  887. {
  888. return string.Format("eMsg_{0}", msg.Name);
  889. }
  890. string GetMsgSigDefName(EntityMsg msg)
  891. {
  892. return string.Format("eMsgSig_{0}", msg.Name);
  893. }
  894. void WriteMsgDef(StreamWriter sw, Entity entity)
  895. {
  896. int i = 0;
  897. foreach (EntityMsg msg in entity.MsgList)
  898. {
  899. WriteLineDefine(sw, entity, GetMsgDefName(msg), i.ToString());
  900. i++;
  901. }
  902. sw.WriteLine();
  903. foreach (EntityMsg msg in entity.MsgList)
  904. {
  905. WriteLineDefine(sw, entity, GetMsgSigDefName(msg), msg.Signature.ToString());
  906. }
  907. sw.WriteLine();
  908. }
  909. #if false
  910. void WriteMsgReceiverBase(StreamWriter sw, Entity entity)
  911. {
  912. sw.WriteLine();
  913. sw.WriteLine("struct ReceiverBase : public IBroadcastListener {");
  914. foreach (EntityMsg msg in entity.MsgList)
  915. {
  916. sw.WriteLine("\tvirtual void Handle_{0}({0} &Event) = 0;", msg.Name);
  917. }
  918. sw.WriteLine("\tvirtual void OnBroadcastEvent(const char *pszEntityName,DWORD dwMessageId, DWORD dwMessageSignature,CAutoBuffer Buffer)");
  919. sw.WriteLine("\t{");
  920. sw.WriteLine("\t\tswitch(dwMessageId) {");
  921. foreach (EntityMsg msg in entity.MsgList)
  922. {
  923. sw.WriteLine("\t\tcase {0}:", GetMsgDefName(msg));
  924. sw.WriteLine("\t\t\t{");
  925. sw.WriteLine("\t\t\t\tif (dwMessageSignature == {0}) {{", GetMsgSigDefName(msg));
  926. sw.WriteLine("\t\t\t\t\t{0} Event;", msg.Name);
  927. sw.WriteLine("\t\t\t\t\tErrorCodeEnum Error = SpBuffer2Object<{0}>(Buffer, Event);", msg.Name);
  928. sw.WriteLine("\t\t\t\t\tif (Error == Error_Succeed) {");
  929. sw.WriteLine("\t\t\t\t\t\tHandle_{0}(Event);", msg.Name);
  930. sw.WriteLine("\t\t\t\t\t}");
  931. sw.WriteLine("\t\t\t\t} else {");
  932. sw.WriteLine("\t\t\t\t\tLOG_TRACE(\"sig mismatch, %d\", dwMessageId);");
  933. sw.WriteLine("\t\t\t\t}");
  934. sw.WriteLine("\t\t\t}");
  935. sw.WriteLine("\t\t\tbreak;");
  936. }
  937. sw.WriteLine("\t\tdefault:");
  938. sw.WriteLine("\t\t\tLOG_TRACE(\"ignore event! %d\", dwMessageId);");
  939. sw.WriteLine("\t\t}");
  940. sw.WriteLine("\t}");
  941. sw.WriteLine("};");
  942. sw.WriteLine();
  943. }
  944. #endif
  945. void GenerateMsg(string msgfile, Entity entity)
  946. {
  947. string file_name = System.IO.Path.GetFileName(msgfile);
  948. using (StreamWriter sw = new StreamWriter(msgfile, false, Encoding.GetEncoding("gb2312")))
  949. {
  950. string guard_marco = string.Format("__{0}", file_name.Replace('.', '_').ToUpper());
  951. sw.WriteLine();
  952. sw.WriteLine("#ifndef " + guard_marco);
  953. sw.WriteLine("#define " + guard_marco);
  954. sw.WriteLine();
  955. sw.WriteLine("#pragma once");
  956. sw.WriteLine();
  957. sw.WriteLine("// This code is generated by spgen tool!");
  958. sw.WriteLine();
  959. sw.WriteLine("#include \"SpHelper.h\"");
  960. sw.WriteLine();
  961. sw.WriteLine("namespace {0} {{", entity.Name);
  962. WriteMsgDef(sw, entity);
  963. foreach (EntityMsg msg in entity.MsgList)
  964. {
  965. WriteStruct(sw, msg.Name, msg.InfoParamList);
  966. sw.WriteLine();
  967. sw.WriteLine("///////////////////////////");
  968. sw.WriteLine();
  969. }
  970. sw.WriteLine("}} // namespace {0}", entity.Name);
  971. sw.WriteLine(string.Format("#endif // {0}", guard_marco));
  972. }
  973. }
  974. }
  975. }