CPPGenerator.cs 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043
  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_t",
  19. "u__int64_t",
  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_t>",
  33. "CAutoArray<u__int64_t>",
  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\tbSessionClosed = true;");
  771. sw.WriteLine("\t}");
  772. sw.WriteLine("\tbool QuerySessionClosed()");
  773. sw.WriteLine("\t{");
  774. sw.WriteLine("\t\treturn bSessionClosed;");
  775. sw.WriteLine("\t}");
  776. sw.WriteLine("\tErrorCodeEnum Connect(CSmartPointer<IAsynWaitSp> &spAsyncWait)");
  777. sw.WriteLine("\t{");
  778. sw.WriteLine("\t\tCSmartPointer<IEntityFunction> pFunc = m_pEntityBase->GetFunction();");
  779. sw.WriteLine("\t\tErrorCodeEnum Error = pFunc->ConnectRemoteEntity(this, \"{0}\", \"{1}\", spAsyncWait);", entity.Name, cls.Name);
  780. sw.WriteLine("\t\tif (Error == Error_Succeed) {");
  781. sw.WriteLine("\t\t\tm_bSysManaged = true;");
  782. sw.WriteLine("\t\t\tbSessionClosed = false;");
  783. sw.WriteLine("\t\t}");
  784. sw.WriteLine("\t\treturn Error;");
  785. sw.WriteLine("\t}");
  786. sw.WriteLine("\tErrorCodeEnum Connect()");
  787. sw.WriteLine("\t{");
  788. sw.WriteLine("\t\tCSmartPointer<IAsynWaitSp> spAsyncWait;");
  789. sw.WriteLine("\t\tErrorCodeEnum Error = Connect(spAsyncWait);");
  790. sw.WriteLine("\t\tif (Error == Error_Succeed) {");
  791. sw.WriteLine("\t\t\tError = spAsyncWait->WaitAnswer();");
  792. sw.WriteLine("\t\t}");
  793. sw.WriteLine("\t\treturn Error;");
  794. sw.WriteLine("\t}");
  795. sw.WriteLine();
  796. }
  797. string GetClientClassName(Entity entity, EntityClass cls)
  798. {
  799. return string.Format("{0}_ClientBase", cls.Name);
  800. }
  801. void WriteSafeDelete(StreamWriter sw, Entity entity, EntityClass cls)
  802. {
  803. sw.WriteLine("");
  804. sw.WriteLine("\tbool SafeDelete()");
  805. sw.WriteLine("\t{");
  806. sw.WriteLine("\t\tif (!m_bSysManaged) {");
  807. sw.WriteLine("\t\t\tdelete this;");
  808. sw.WriteLine("\t\t}");
  809. sw.WriteLine("\t\treturn m_bSysManaged;");
  810. sw.WriteLine("\t}");
  811. sw.WriteLine("");
  812. }
  813. void WriteClassClient(StreamWriter sw, Entity entity, EntityClass cls)
  814. {
  815. string clsname = GetClientClassName(entity, cls);
  816. bool bHasSub = HasSubscribe(cls);
  817. if (bHasSub)
  818. sw.WriteLine("class {0} : public CClientSessionBase, public ICallbackListener {{ ", clsname);
  819. else
  820. sw.WriteLine("class {0} : public CClientSessionBase {{", clsname);
  821. sw.WriteLine("public:");
  822. WriteClientConstructor(sw, entity, cls);
  823. WriteOperatorContext(sw, entity, cls);
  824. WriteClientDestructor(sw, entity, cls);
  825. WriteClientConnect(sw, entity, cls);
  826. foreach (Method m in cls.MethodList)
  827. {
  828. if (typeof(Oneway).IsInstanceOfType(m))
  829. {
  830. WriteClientOneway(sw, entity, cls, m as Oneway);
  831. }
  832. else if (typeof(Twoway).IsInstanceOfType(m))
  833. {
  834. WriteClientTwoway(sw, entity, cls, m as Twoway);
  835. }
  836. else if (typeof(Subscribe).IsInstanceOfType(m))
  837. {
  838. WriteClientSubscribe(sw, entity, cls, m as Subscribe);
  839. }
  840. else
  841. {
  842. throw new Exception("unknown");
  843. }
  844. }
  845. WriteSafeDelete(sw, entity, cls);
  846. if (bHasSub)
  847. {
  848. WriteOnAnswer(sw, entity, cls);
  849. }
  850. sw.WriteLine("protected:");
  851. sw.WriteLine("\tbool m_bSysManaged;");
  852. sw.WriteLine("\tCEntityBase *m_pEntityBase;");
  853. sw.WriteLine("\tlinkContext m_context;");
  854. sw.WriteLine("\tbool bSessionClosed;");
  855. sw.WriteLine("};");
  856. }
  857. void GenerateClient(string deffilename, string file, Entity entity)
  858. {
  859. string file_name = System.IO.Path.GetFileName(file);
  860. using (StreamWriter sw = new StreamWriter(file, false, Encoding.GetEncoding("gb2312")))
  861. {
  862. string guard_marco = string.Format("__{0}", file_name.Replace('.', '_').ToUpper());
  863. sw.WriteLine();
  864. sw.WriteLine("#ifndef " + guard_marco);
  865. sw.WriteLine("#define " + guard_marco);
  866. sw.WriteLine();
  867. sw.WriteLine("#pragma once");
  868. sw.WriteLine();
  869. sw.WriteLine("// This code is generated by spgen tool!");
  870. sw.WriteLine();
  871. sw.WriteLine("#include \"{0}\"", deffilename);
  872. sw.WriteLine();
  873. sw.WriteLine("namespace {0} {{", entity.Name);
  874. foreach (EntityClass cls in entity.ClassList)
  875. {
  876. WriteClassClient(sw, entity, cls);
  877. sw.WriteLine();
  878. sw.WriteLine("///////////////////////////");
  879. sw.WriteLine();
  880. }
  881. sw.WriteLine("}} // namespace {0}", entity.Name);
  882. sw.WriteLine(string.Format("#endif // {0}", guard_marco));
  883. }
  884. }
  885. string GetMsgDefName(EntityMsg msg)
  886. {
  887. return string.Format("eMsg_{0}", msg.Name);
  888. }
  889. string GetMsgSigDefName(EntityMsg msg)
  890. {
  891. return string.Format("eMsgSig_{0}", msg.Name);
  892. }
  893. void WriteMsgDef(StreamWriter sw, Entity entity)
  894. {
  895. int i = 0;
  896. foreach (EntityMsg msg in entity.MsgList)
  897. {
  898. WriteLineDefine(sw, entity, GetMsgDefName(msg), i.ToString());
  899. i++;
  900. }
  901. sw.WriteLine();
  902. foreach (EntityMsg msg in entity.MsgList)
  903. {
  904. WriteLineDefine(sw, entity, GetMsgSigDefName(msg), msg.Signature.ToString());
  905. }
  906. sw.WriteLine();
  907. }
  908. #if false
  909. void WriteMsgReceiverBase(StreamWriter sw, Entity entity)
  910. {
  911. sw.WriteLine();
  912. sw.WriteLine("struct ReceiverBase : public IBroadcastListener {");
  913. foreach (EntityMsg msg in entity.MsgList)
  914. {
  915. sw.WriteLine("\tvirtual void Handle_{0}({0} &Event) = 0;", msg.Name);
  916. }
  917. sw.WriteLine("\tvirtual void OnBroadcastEvent(const char *pszEntityName,DWORD dwMessageId, DWORD dwMessageSignature,CAutoBuffer Buffer)");
  918. sw.WriteLine("\t{");
  919. sw.WriteLine("\t\tswitch(dwMessageId) {");
  920. foreach (EntityMsg msg in entity.MsgList)
  921. {
  922. sw.WriteLine("\t\tcase {0}:", GetMsgDefName(msg));
  923. sw.WriteLine("\t\t\t{");
  924. sw.WriteLine("\t\t\t\tif (dwMessageSignature == {0}) {{", GetMsgSigDefName(msg));
  925. sw.WriteLine("\t\t\t\t\t{0} Event;", msg.Name);
  926. sw.WriteLine("\t\t\t\t\tErrorCodeEnum Error = SpBuffer2Object<{0}>(Buffer, Event);", msg.Name);
  927. sw.WriteLine("\t\t\t\t\tif (Error == Error_Succeed) {");
  928. sw.WriteLine("\t\t\t\t\t\tHandle_{0}(Event);", msg.Name);
  929. sw.WriteLine("\t\t\t\t\t}");
  930. sw.WriteLine("\t\t\t\t} else {");
  931. sw.WriteLine("\t\t\t\t\tLOG_TRACE(\"sig mismatch, %d\", dwMessageId);");
  932. sw.WriteLine("\t\t\t\t}");
  933. sw.WriteLine("\t\t\t}");
  934. sw.WriteLine("\t\t\tbreak;");
  935. }
  936. sw.WriteLine("\t\tdefault:");
  937. sw.WriteLine("\t\t\tLOG_TRACE(\"ignore event! %d\", dwMessageId);");
  938. sw.WriteLine("\t\t}");
  939. sw.WriteLine("\t}");
  940. sw.WriteLine("};");
  941. sw.WriteLine();
  942. }
  943. #endif
  944. void GenerateMsg(string msgfile, Entity entity)
  945. {
  946. string file_name = System.IO.Path.GetFileName(msgfile);
  947. using (StreamWriter sw = new StreamWriter(msgfile, false, Encoding.GetEncoding("gb2312")))
  948. {
  949. string guard_marco = string.Format("__{0}", file_name.Replace('.', '_').ToUpper());
  950. sw.WriteLine();
  951. sw.WriteLine("#ifndef " + guard_marco);
  952. sw.WriteLine("#define " + guard_marco);
  953. sw.WriteLine();
  954. sw.WriteLine("#pragma once");
  955. sw.WriteLine();
  956. sw.WriteLine("// This code is generated by spgen tool!");
  957. sw.WriteLine();
  958. sw.WriteLine("#include \"SpHelper.h\"");
  959. sw.WriteLine();
  960. sw.WriteLine("namespace {0} {{", entity.Name);
  961. WriteMsgDef(sw, entity);
  962. foreach (EntityMsg msg in entity.MsgList)
  963. {
  964. WriteStruct(sw, msg.Name, msg.InfoParamList);
  965. sw.WriteLine();
  966. sw.WriteLine("///////////////////////////");
  967. sw.WriteLine();
  968. }
  969. sw.WriteLine("}} // namespace {0}", entity.Name);
  970. sw.WriteLine(string.Format("#endif // {0}", guard_marco));
  971. }
  972. }
  973. }
  974. }