ASResult.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137
  1. // Copyright (c) 2008-2023 the Urho3D project
  2. // License: MIT
  3. #include "ASResult.h"
  4. #include "Tuning.h"
  5. #include "Utils.h"
  6. #include <fstream>
  7. #include <cassert>
  8. #include <unordered_map>
  9. #include <memory>
  10. using namespace std;
  11. extern string _sourceDir;
  12. namespace ASBindingGenerator
  13. {
  14. ASGeneratedFile_WithRegistrationFunction::ASGeneratedFile_WithRegistrationFunction(const string& outputFilePath, const string& functionName)
  15. {
  16. outputFilePath_ = outputFilePath;
  17. functionName_ = functionName;
  18. }
  19. // ============================================================================
  20. void ASGeneratedFile_Members::Save()
  21. {
  22. ofstream out(outputFilePath_);
  23. out <<
  24. "// DO NOT EDIT. This file is generated\n"
  25. "\n"
  26. "#include \"../Precompiled.h\"\n"
  27. "#include \"../AngelScript/APITemplates.h\"\n"
  28. "\n"
  29. "#include \"../AngelScript/Generated_Includes.h\"\n"
  30. "#include \"../AngelScript/Manual.h\"\n"
  31. "\n"
  32. "namespace Urho3D\n"
  33. "{\n"
  34. "\n"
  35. << glue_.str() <<
  36. "void " << functionName_ << "(asIScriptEngine* engine)\n"
  37. "{\n"
  38. << reg_.str() <<
  39. "}\n"
  40. "\n"
  41. "}\n";
  42. }
  43. // ============================================================================
  44. ASGeneratedFile_Templates::ASGeneratedFile_Templates(const string& outputFilePath)
  45. {
  46. outputFilePath_ = outputFilePath;
  47. }
  48. void ASGeneratedFile_Templates::Save()
  49. {
  50. ofstream out(outputFilePath_);
  51. out <<
  52. "// DO NOT EDIT. This file is generated\n"
  53. "\n"
  54. "#pragma once\n"
  55. "\n"
  56. "#include \"../Precompiled.h\"\n"
  57. "#include \"../AngelScript/APITemplates.h\"\n"
  58. "\n"
  59. "#include \"../AngelScript/Generated_Includes.h\"\n"
  60. "\n"
  61. "#include \"../AngelScript/Manual.h\"\n"
  62. "\n"
  63. "namespace Urho3D\n"
  64. "{\n"
  65. "\n"
  66. << glue_.str()
  67. << reg_.str() <<
  68. "}\n";
  69. }
  70. bool ProcessedEnum::operator <(const ProcessedEnum& rhs) const
  71. {
  72. if (insideDefine_ != rhs.insideDefine_)
  73. return insideDefine_ < rhs.insideDefine_;
  74. return name_ < rhs.name_;
  75. }
  76. bool ProcessedGlobalFunction::operator <(const ProcessedGlobalFunction& rhs) const
  77. {
  78. if (insideDefine_ != rhs.insideDefine_)
  79. return insideDefine_ < rhs.insideDefine_;
  80. if (name_ != rhs.name_)
  81. return name_ < rhs.name_;
  82. // Overloads with the same name may exist
  83. if (comment_ != rhs.comment_)
  84. return comment_ < rhs.comment_;
  85. // Different specializations of the same template and aliases have the same comment
  86. return registration_ < rhs.registration_;
  87. }
  88. bool ProcessedGlobalVariable::operator <(const ProcessedGlobalVariable& rhs) const
  89. {
  90. if (insideDefine_ != rhs.insideDefine_)
  91. return insideDefine_ < rhs.insideDefine_;
  92. return name_ < rhs.name_;
  93. }
  94. bool ProcessedClass::operator <(const ProcessedClass& rhs) const
  95. {
  96. if (inherianceDeep_ != rhs.inherianceDeep_)
  97. return inherianceDeep_ < rhs.inherianceDeep_;
  98. if (insideDefine_ != rhs.insideDefine_)
  99. return insideDefine_ < rhs.insideDefine_;
  100. return name_ < rhs.name_;
  101. }
  102. bool MemberRegistrationError::operator <(const MemberRegistrationError& rhs) const
  103. {
  104. if (name_ != rhs.name_)
  105. return name_ < rhs.name_;
  106. return comment_ < rhs.comment_;
  107. }
  108. namespace Result
  109. {
  110. vector<ProcessedEnum> enums_;
  111. // Write result to Generated_Enums.cpp
  112. static void SaveEnums()
  113. {
  114. sort(enums_.begin(), enums_.end());
  115. ofstream ofs(_sourceDir + "/Source/Urho3D/AngelScript/Generated_Enums.cpp");
  116. ofs <<
  117. "// DO NOT EDIT. This file is generated\n"
  118. "\n"
  119. "// We need register all enums before registration of any functions because functions can use any enums\n"
  120. "\n"
  121. "#include \"../Precompiled.h\"\n"
  122. "#include \"../AngelScript/APITemplates.h\"\n"
  123. "\n"
  124. "#include \"../AngelScript/Generated_Includes.h\"\n"
  125. "\n"
  126. "namespace Urho3D\n"
  127. "{\n"
  128. "\n";
  129. for (const ProcessedEnum& processedEnum : enums_)
  130. {
  131. if (!processedEnum.glue_.size())
  132. continue;
  133. if (!processedEnum.insideDefine_.empty())
  134. ofs << "#ifdef " << processedEnum.insideDefine_ << "\n";
  135. ofs << "// " << processedEnum.comment_ << "\n";
  136. for (const string& glue : processedEnum.glue_)
  137. ofs << glue << "\n";
  138. if (!processedEnum.insideDefine_.empty())
  139. ofs << "#endif\n";
  140. ofs << "\n";
  141. }
  142. ofs <<
  143. "void ASRegisterGeneratedEnums(asIScriptEngine* engine)\n"
  144. "{\n";
  145. bool isFirst = true;
  146. string openedDefine;
  147. for (const ProcessedEnum& processedEnum : enums_)
  148. {
  149. if (processedEnum.insideDefine_ != openedDefine && !openedDefine.empty())
  150. {
  151. ofs << "#endif\n";
  152. openedDefine.clear();
  153. }
  154. if (!isFirst)
  155. ofs << "\n";
  156. if (processedEnum.insideDefine_ != openedDefine && !processedEnum.insideDefine_.empty())
  157. {
  158. ofs << "#ifdef " << processedEnum.insideDefine_ << "\n";
  159. openedDefine = processedEnum.insideDefine_;
  160. }
  161. ofs << " // " << processedEnum.comment_ << "\n";
  162. for (const string& registration : processedEnum.registration_)
  163. ofs << " " << registration << "\n";
  164. isFirst = false;
  165. }
  166. if (!openedDefine.empty())
  167. ofs << "#endif\n";
  168. ofs <<
  169. "}\n"
  170. "\n"
  171. "}\n";
  172. }
  173. // ============================================================================
  174. vector<ProcessedGlobalFunction> globalFunctions_;
  175. // Write result to Generated_GlobalFunctions.cpp
  176. static void SaveGlobalFunctions()
  177. {
  178. sort(globalFunctions_.begin(), globalFunctions_.end());
  179. ofstream ofs(_sourceDir + "/Source/Urho3D/AngelScript/Generated_GlobalFunctions.cpp");
  180. ofs <<
  181. "// DO NOT EDIT. This file is generated\n"
  182. "\n"
  183. "#include \"../Precompiled.h\"\n"
  184. "#include \"../AngelScript/APITemplates.h\"\n"
  185. "\n"
  186. "#include \"../AngelScript/Generated_Includes.h\"\n"
  187. "\n"
  188. "namespace Urho3D\n"
  189. "{\n"
  190. "\n";
  191. for (const ProcessedGlobalFunction& globalFunction : globalFunctions_)
  192. {
  193. if (globalFunction.glue_.empty())
  194. continue;
  195. if (!globalFunction.insideDefine_.empty())
  196. ofs << "#ifdef " << globalFunction.insideDefine_ << "\n";
  197. ofs << "// " << globalFunction.comment_ << "\n";
  198. ofs << globalFunction.glue_ << "\n";
  199. if (!globalFunction.insideDefine_.empty())
  200. ofs << "#endif\n";
  201. ofs << "\n";
  202. }
  203. ofs <<
  204. "void ASRegisterGeneratedGlobalFunctions(asIScriptEngine* engine)\n"
  205. "{\n";
  206. bool isFirst = true;
  207. string openedDefine;
  208. string lastComment;
  209. for (const ProcessedGlobalFunction& globalFunction : globalFunctions_)
  210. {
  211. if (globalFunction.insideDefine_ != openedDefine && !openedDefine.empty())
  212. {
  213. ofs << "#endif\n";
  214. openedDefine.clear();
  215. }
  216. if (!isFirst && lastComment != globalFunction.comment_)
  217. ofs << "\n";
  218. if (globalFunction.insideDefine_ != openedDefine && !globalFunction.insideDefine_.empty())
  219. {
  220. ofs << "#ifdef " << globalFunction.insideDefine_ << "\n";
  221. openedDefine = globalFunction.insideDefine_;
  222. }
  223. if (lastComment != globalFunction.comment_)
  224. ofs << " // " << globalFunction.comment_ << "\n";
  225. ofs << " " << globalFunction.registration_ << "\n";
  226. isFirst = false;
  227. lastComment = globalFunction.comment_;
  228. }
  229. if (!openedDefine.empty())
  230. ofs << "#endif\n";
  231. ofs <<
  232. "}\n"
  233. "\n"
  234. "}\n";
  235. }
  236. // ============================================================================
  237. vector<ProcessedGlobalVariable> globalVariables_;
  238. // Write result to Generated_GlobalVariables.cpp
  239. static void SaveGlobalVariables()
  240. {
  241. sort(globalVariables_.begin(), globalVariables_.end());
  242. ofstream ofs(_sourceDir + "/Source/Urho3D/AngelScript/Generated_GlobalVariables.cpp");
  243. ofs <<
  244. "// DO NOT EDIT. This file is generated\n"
  245. "\n"
  246. "#include \"../Precompiled.h\"\n"
  247. "#include \"../AngelScript/APITemplates.h\"\n"
  248. "\n"
  249. "#include \"../AngelScript/Generated_Includes.h\"\n"
  250. "\n"
  251. "// Some headers could re-define M_PI, ensure that it's undefined\n"
  252. "#undef M_PI\n"
  253. "\n"
  254. "namespace Urho3D\n"
  255. "{\n"
  256. "\n"
  257. "void ASRegisterGeneratedGlobalVariables(asIScriptEngine* engine)\n"
  258. "{\n";
  259. bool isFirst = true;
  260. string openedDefine;
  261. string lastComment;
  262. for (const ProcessedGlobalVariable& globalVariable : globalVariables_)
  263. {
  264. if (globalVariable.insideDefine_ != openedDefine && !openedDefine.empty())
  265. {
  266. ofs << "#endif\n";
  267. openedDefine.clear();
  268. }
  269. if (!isFirst && lastComment != globalVariable.comment_)
  270. ofs << "\n";
  271. if (globalVariable.insideDefine_ != openedDefine && !globalVariable.insideDefine_.empty())
  272. {
  273. ofs << "#ifdef " << globalVariable.insideDefine_ << "\n";
  274. openedDefine = globalVariable.insideDefine_;
  275. }
  276. if (lastComment != globalVariable.comment_)
  277. ofs << " // " << globalVariable.comment_ << "\n";
  278. ofs << " " << globalVariable.registration_ << "\n";
  279. isFirst = false;
  280. lastComment = globalVariable.comment_;
  281. }
  282. if (!openedDefine.empty())
  283. ofs << "#endif\n";
  284. ofs <<
  285. "}\n"
  286. "\n"
  287. "}\n";
  288. }
  289. // ============================================================================
  290. vector<ProcessedClass> classes_;
  291. // Write result to Generated_ObjectTypes.cpp
  292. static void SaveObjectTypes()
  293. {
  294. ofstream ofs(_sourceDir + "/Source/Urho3D/AngelScript/Generated_ObjectTypes.cpp");
  295. ofs <<
  296. "// DO NOT EDIT. This file is generated\n"
  297. "\n"
  298. "// We need register all types before registration of any functions because functions can use any types\n"
  299. "\n"
  300. "#include \"../Precompiled.h\"\n"
  301. "#include \"../AngelScript/APITemplates.h\"\n"
  302. "\n"
  303. "#include \"../AngelScript/Generated_Includes.h\"\n"
  304. "\n"
  305. "namespace Urho3D\n"
  306. "{\n"
  307. "\n"
  308. "void ASRegisterGeneratedObjectTypes(asIScriptEngine* engine)\n"
  309. "{\n";
  310. string openedDefine;
  311. bool isFirst = true;
  312. for (const ProcessedClass& processedClass : classes_)
  313. {
  314. if (processedClass.insideDefine_ != openedDefine && !openedDefine.empty())
  315. {
  316. ofs << "#endif\n";
  317. openedDefine.clear();
  318. }
  319. if (!isFirst)
  320. ofs << "\n";
  321. if (processedClass.insideDefine_ != openedDefine && !processedClass.insideDefine_.empty())
  322. {
  323. ofs << "#ifdef " << processedClass.insideDefine_ << "\n";
  324. openedDefine = processedClass.insideDefine_;
  325. }
  326. ofs
  327. << " // " << processedClass.comment_ << "\n"
  328. << " " << processedClass.objectTypeRegistration_ << "\n";
  329. isFirst = false;
  330. }
  331. if (!openedDefine.empty())
  332. ofs << "#endif\n";
  333. ofs <<
  334. "}\n"
  335. "\n"
  336. "}\n";
  337. }
  338. // Write result to Generated_DefaultConstructors.cpp
  339. static void SaveDefaultConstructors()
  340. {
  341. ofstream ofs(_sourceDir + "/Source/Urho3D/AngelScript/Generated_DefaultConstructors.cpp");
  342. ofs <<
  343. "// DO NOT EDIT. This file is generated\n"
  344. "\n"
  345. "// We need register default constructors before any members to allow using in Array<type>\n"
  346. "\n"
  347. "#include \"../Precompiled.h\"\n"
  348. "#include \"../AngelScript/APITemplates.h\"\n"
  349. "\n"
  350. "#include \"../AngelScript/Generated_Includes.h\"\n"
  351. "\n"
  352. "namespace Urho3D\n"
  353. "{\n";
  354. string openedDefine;
  355. for (const ProcessedClass& processedClass : classes_)
  356. {
  357. if (!processedClass.defaultConstructor_)
  358. continue;
  359. if (processedClass.defaultConstructor_->glue_.empty())
  360. continue;
  361. if (processedClass.insideDefine_ != openedDefine && !openedDefine.empty())
  362. {
  363. ofs << "\n#endif\n";
  364. openedDefine.clear();
  365. }
  366. ofs << "\n";
  367. if (processedClass.insideDefine_ != openedDefine && !processedClass.insideDefine_.empty())
  368. {
  369. ofs << "#ifdef " << processedClass.insideDefine_ << "\n\n";
  370. openedDefine = processedClass.insideDefine_;
  371. }
  372. ofs <<
  373. "// " << processedClass.defaultConstructor_->comment_ << "\n" <<
  374. processedClass.defaultConstructor_->glue_;
  375. }
  376. if (!openedDefine.empty())
  377. {
  378. ofs << "\n#endif\n";
  379. openedDefine.clear();
  380. }
  381. ofs <<
  382. "\n"
  383. "void ASRegisterGeneratedDefaultConstructors(asIScriptEngine* engine)\n"
  384. "{\n";
  385. bool isFirst = true;
  386. for (const ProcessedClass& processedClass : classes_)
  387. {
  388. if (!processedClass.defaultConstructor_)
  389. continue;
  390. if (processedClass.noBind_)
  391. continue;
  392. if (processedClass.insideDefine_ != openedDefine && !openedDefine.empty())
  393. {
  394. ofs << "#endif\n";
  395. openedDefine.clear();
  396. }
  397. if (!isFirst)
  398. ofs << "\n";
  399. if (processedClass.insideDefine_ != openedDefine && !processedClass.insideDefine_.empty())
  400. {
  401. ofs << "#ifdef " << processedClass.insideDefine_ << "\n";
  402. openedDefine = processedClass.insideDefine_;
  403. }
  404. ofs <<
  405. " // " << processedClass.defaultConstructor_->comment_ << "\n" <<
  406. " " << processedClass.defaultConstructor_->registration_ << "\n";
  407. isFirst = false;
  408. }
  409. if (!openedDefine.empty())
  410. ofs << "#endif\n";
  411. ofs <<
  412. "}\n"
  413. "\n"
  414. "}\n";
  415. }
  416. // Write result to Generated_Classes.cpp
  417. static void SaveGeneratedClasses()
  418. {
  419. ofstream ofs(_sourceDir + "/Source/Urho3D/AngelScript/Generated_Classes.cpp");
  420. ofs <<
  421. "// DO NOT EDIT. This file is generated\n"
  422. "\n"
  423. "#include \"../Precompiled.h\"\n"
  424. "#include \"../AngelScript/APITemplates.h\"\n"
  425. "\n"
  426. "#include \"../AngelScript/Generated_Includes.h\"\n"
  427. "#include \"../AngelScript/Generated_Members.h\"\n"
  428. "#include \"../AngelScript/Manual.h\"\n"
  429. "\n"
  430. "namespace Urho3D\n"
  431. "{\n";
  432. string openedDefine;
  433. for (ProcessedClass& processedClass : classes_)
  434. {
  435. if (processedClass.noBind_)
  436. continue;
  437. if (processedClass.insideDefine_ != openedDefine && !openedDefine.empty())
  438. {
  439. ofs << "\n#endif // def " << openedDefine << "\n";
  440. openedDefine.clear();
  441. }
  442. ofs << "\n";
  443. if (processedClass.insideDefine_ != openedDefine && !processedClass.insideDefine_.empty())
  444. {
  445. ofs << "#ifdef " << processedClass.insideDefine_ << "\n\n";
  446. openedDefine = processedClass.insideDefine_;
  447. }
  448. if (processedClass.destructor_ && !processedClass.destructor_->glue_.empty())
  449. {
  450. ofs <<
  451. "// " << processedClass.destructor_->comment_ << "\n"
  452. << processedClass.destructor_->glue_ <<
  453. "\n";
  454. }
  455. for (const SpecialMethodRegistration& nonDefaultConstructor : processedClass.nonDefaultConstructors_)
  456. {
  457. ofs <<
  458. "// " << nonDefaultConstructor.comment_ << "\n"
  459. << nonDefaultConstructor.glue_ <<
  460. "\n";
  461. }
  462. for (const Registration& personalMethod : processedClass.personalMethods_)
  463. {
  464. if (personalMethod.glue_.size())
  465. {
  466. ofs <<
  467. "// " << personalMethod.comment_ << "\n"
  468. << personalMethod.glue_ <<
  469. "\n";
  470. }
  471. }
  472. for (const Registration& personalStaticMethod : processedClass.personalStaticMethods_)
  473. {
  474. if (personalStaticMethod.glue_.size())
  475. {
  476. ofs <<
  477. "// " << personalStaticMethod.comment_ << "\n"
  478. << personalStaticMethod.glue_ <<
  479. "\n";
  480. }
  481. }
  482. ofs <<
  483. "// " << processedClass.comment_ << "\n"
  484. "static void Register_" << processedClass.name_ << "(asIScriptEngine* engine)\n"
  485. "{\n";
  486. bool needGap = false;
  487. sort(processedClass.unregisteredSpecialMethods_.begin(), processedClass.unregisteredSpecialMethods_.end());
  488. for (const MemberRegistrationError& regError : processedClass.unregisteredSpecialMethods_)
  489. {
  490. ofs <<
  491. " // " << regError.comment_ << "\n"
  492. " // " << regError.message_ << "\n";
  493. needGap = true;
  494. }
  495. if (needGap && processedClass.nonDefaultConstructors_.size())
  496. ofs << '\n';
  497. for (const SpecialMethodRegistration& nonDefaultConstructor : processedClass.nonDefaultConstructors_)
  498. {
  499. ofs <<
  500. " // " << nonDefaultConstructor.comment_ << "\n"
  501. " " << nonDefaultConstructor.registration_ << "\n";
  502. needGap = true;
  503. }
  504. if (processedClass.destructor_)
  505. {
  506. if (needGap)
  507. ofs << '\n';
  508. ofs <<
  509. " // " << processedClass.destructor_->comment_ << "\n"
  510. " " << processedClass.destructor_->registration_ << "\n";
  511. needGap = true;
  512. }
  513. if (needGap && processedClass.subclassRegistrations_.size())
  514. ofs << '\n';
  515. for (const string& subclassRegistration : processedClass.subclassRegistrations_)
  516. {
  517. ofs << " " << subclassRegistration << '\n';
  518. needGap = true;
  519. }
  520. if (needGap)
  521. ofs << '\n';
  522. ofs <<
  523. " RegisterMembers_" << processedClass.name_ << "<" << processedClass.name_ << ">(engine, \"" << processedClass.name_ << "\");\n"
  524. "\n"
  525. " #ifdef REGISTER_CLASS_MANUAL_PART_" << processedClass.name_ << "\n"
  526. " REGISTER_CLASS_MANUAL_PART_" << processedClass.name_ << "();\n"
  527. " #endif\n";
  528. for (const MemberRegistrationError& unregisteredPersonalMethod : processedClass.unregisteredPersonalMethods_)
  529. {
  530. ofs <<
  531. "\n"
  532. " // " << unregisteredPersonalMethod.comment_ << "\n"
  533. " // " << unregisteredPersonalMethod.message_ << "\n";
  534. needGap = true;
  535. }
  536. for (const Registration& perosnalMethod : processedClass.personalMethods_)
  537. {
  538. ofs <<
  539. "\n"
  540. " // " << perosnalMethod.comment_ << "\n";
  541. for (const string& reg : perosnalMethod.registration_)
  542. ofs << " " << reg << '\n';
  543. }
  544. for (const MemberRegistrationError& unregisteredPersonalStaticMethod : processedClass.unregisteredPersonalStaticMethods_)
  545. {
  546. ofs <<
  547. "\n"
  548. " // " << unregisteredPersonalStaticMethod.comment_ << "\n"
  549. " // " << unregisteredPersonalStaticMethod.message_ << "\n";
  550. needGap = true;
  551. }
  552. for (const Registration& perosnalStaticMethod : processedClass.personalStaticMethods_)
  553. {
  554. ofs <<
  555. "\n"
  556. " // " << perosnalStaticMethod.comment_ << "\n";
  557. for (const string& reg : perosnalStaticMethod.registration_)
  558. ofs << " " << reg << '\n';
  559. }
  560. if (processedClass.additionalLines_.size())
  561. ofs << '\n';
  562. for (string str : processedClass.additionalLines_)
  563. ofs << str << '\n';
  564. ofs << "}\n";
  565. }
  566. if (!openedDefine.empty())
  567. {
  568. ofs << "\n#endif // def " << openedDefine << "\n";
  569. openedDefine.clear();
  570. }
  571. ofs <<
  572. "\n"
  573. "void ASRegisterGeneratedClasses(asIScriptEngine* engine)\n"
  574. "{\n";
  575. bool isFirst = true;
  576. for (const ProcessedClass& processedClass : classes_)
  577. {
  578. if (processedClass.noBind_)
  579. continue;
  580. if (processedClass.insideDefine_ != openedDefine && !openedDefine.empty())
  581. {
  582. ofs << "#endif\n";
  583. openedDefine.clear();
  584. }
  585. if (processedClass.insideDefine_ != openedDefine && !processedClass.insideDefine_.empty())
  586. {
  587. if (!isFirst)
  588. ofs << "\n";
  589. ofs << "#ifdef " << processedClass.insideDefine_ << "\n";
  590. openedDefine = processedClass.insideDefine_;
  591. }
  592. ofs << " Register_" << processedClass.name_ << "(engine);\n";
  593. isFirst = false;
  594. }
  595. if (!openedDefine.empty())
  596. ofs << "#endif\n";
  597. ofs <<
  598. "}\n"
  599. "\n"
  600. "}\n";
  601. }
  602. struct MemberCppFile
  603. {
  604. ofstream ofs_;
  605. string openedDefine_;
  606. bool needGap_ = false;
  607. MemberCppFile(const string& dirName)
  608. {
  609. string fileName = _sourceDir + "/Source/Urho3D/AngelScript/Generated_Members_" + dirName + ".cpp";
  610. ofs_ = ofstream(fileName);
  611. ofs_ <<
  612. "// DO NOT EDIT. This file is generated\n"
  613. "\n"
  614. "#include \"../Precompiled.h\"\n"
  615. "#include \"../AngelScript/APITemplates.h\"\n"
  616. "\n"
  617. "#include \"../AngelScript/Generated_Includes.h\"\n"
  618. "#include \"../AngelScript/Generated_ClassMembers.h\"\n"
  619. "#include \"../AngelScript/Manual.h\"\n"
  620. "\n"
  621. "namespace Urho3D\n"
  622. "{\n";
  623. }
  624. };
  625. unordered_map<string, shared_ptr<MemberCppFile>> memberCppFiles_;
  626. shared_ptr<MemberCppFile> GetMemberCppFile(const string& dirName)
  627. {
  628. auto it = memberCppFiles_.find(dirName);
  629. if (it == memberCppFiles_.end())
  630. {
  631. auto newElement = memberCppFiles_.emplace(dirName, make_shared<MemberCppFile>(dirName));
  632. it = newElement.first;
  633. }
  634. return (*it).second;
  635. }
  636. // Write result to GeneratedClassMembers.cpp and GeneratedClassMembers.h // TODO change comment
  637. static void SaveClassMembers()
  638. {
  639. ofstream ofsH = ofstream(_sourceDir + "/Source/Urho3D/AngelScript/Generated_Members.h");
  640. ofsH <<
  641. "// DO NOT EDIT. This file is generated\n"
  642. "\n"
  643. "#pragma once\n"
  644. "\n"
  645. "#include \"../AngelScript/APITemplates.h\"\n"
  646. "\n"
  647. "#include \"../AngelScript/Generated_Includes.h\"\n"
  648. "#include \"../AngelScript/Manual.h\"\n"
  649. "\n"
  650. "namespace Urho3D\n"
  651. "{\n";
  652. string openedDefine;
  653. for (const ProcessedClass& processedClass : classes_)
  654. {
  655. if (processedClass.insideDefine_ != openedDefine && !openedDefine.empty())
  656. {
  657. ofsH <<
  658. "\n"
  659. "#endif // def " << openedDefine << "\n";
  660. openedDefine.clear();
  661. }
  662. if (processedClass.insideDefine_ != openedDefine && !processedClass.insideDefine_.empty())
  663. {
  664. ofsH <<
  665. "\n"
  666. "#ifdef " << processedClass.insideDefine_ << "\n";
  667. openedDefine = processedClass.insideDefine_;
  668. }
  669. for (const Registration& method : processedClass.templateMethods_)
  670. {
  671. if (method.glue_.size())
  672. {
  673. ofsH <<
  674. "\n"
  675. "// " << method.comment_ << "\n"
  676. << method.glue_;
  677. }
  678. }
  679. for (const Registration& staticMethod : processedClass.templateStaticMethods_)
  680. {
  681. if (staticMethod.glue_.size())
  682. {
  683. ofsH <<
  684. "\n"
  685. "// " << staticMethod.comment_ << "\n"
  686. << staticMethod.glue_;
  687. }
  688. }
  689. ofsH <<
  690. "\n"
  691. "// " << processedClass.comment_ << "\n"
  692. "template <class T> void RegisterMembers_" << processedClass.name_ << "(asIScriptEngine* engine, const char* className)\n"
  693. "{\n";
  694. bool needGap = false;
  695. if (processedClass.baseClassNames_.size())
  696. {
  697. for (const string& baseClassName : processedClass.baseClassNames_)
  698. ofsH << " RegisterMembers_" << baseClassName << "<T>(engine, className);\n";
  699. needGap = true;
  700. }
  701. if (needGap && processedClass.unregisteredTemplateMethods_.size())
  702. ofsH << '\n';
  703. for (const MemberRegistrationError& unregisteredTemplateMethod : processedClass.unregisteredTemplateMethods_)
  704. {
  705. ofsH <<
  706. " // " << unregisteredTemplateMethod.comment_ << "\n"
  707. " // " << unregisteredTemplateMethod.message_ << "\n";
  708. needGap = true;
  709. }
  710. for (const Registration& method : processedClass.templateMethods_)
  711. {
  712. if (needGap)
  713. ofsH << '\n';
  714. ofsH << " // " << method.comment_ << '\n';
  715. for (const string& registration : method.registration_)
  716. ofsH << " " << registration << '\n';
  717. needGap = true;
  718. }
  719. if (needGap && processedClass.unregisteredTemplateStaticMethods_.size())
  720. ofsH << '\n';
  721. for (const MemberRegistrationError& unregisteredTemplateStaticMethod : processedClass.unregisteredTemplateStaticMethods_)
  722. {
  723. ofsH <<
  724. " // " << unregisteredTemplateStaticMethod.comment_ << "\n"
  725. " // " << unregisteredTemplateStaticMethod.message_ << "\n";
  726. needGap = true;
  727. }
  728. for (const Registration& staticMethod : processedClass.templateStaticMethods_)
  729. {
  730. if (needGap)
  731. ofsH << '\n';
  732. ofsH << " // " << staticMethod.comment_ << '\n';
  733. for (const string& registration : staticMethod.registration_)
  734. ofsH << " " << registration << '\n';
  735. needGap = true;
  736. }
  737. if (needGap && processedClass.unregisteredTemplateFields_.size())
  738. ofsH << '\n';
  739. for (const MemberRegistrationError& unregisteredTemplateField : processedClass.unregisteredTemplateFields_)
  740. {
  741. ofsH <<
  742. " // " << unregisteredTemplateField.comment_ << "\n"
  743. " // " << unregisteredTemplateField.message_ << "\n";
  744. needGap = true;
  745. }
  746. for (const Registration& field : processedClass.templateFields_)
  747. {
  748. if (needGap)
  749. ofsH << '\n';
  750. ofsH << " // " << field.comment_ << '\n';
  751. for (const string& registration : field.registration_)
  752. ofsH << " " << registration << '\n';
  753. needGap = true;
  754. }
  755. if (needGap && processedClass.unregisteredTemplateStaticFields_.size())
  756. ofsH << '\n';
  757. for (const MemberRegistrationError& unregisteredTemplateStaticField : processedClass.unregisteredTemplateStaticFields_)
  758. {
  759. ofsH <<
  760. " // " << unregisteredTemplateStaticField.comment_ << "\n"
  761. " // " << unregisteredTemplateStaticField.message_ << "\n";
  762. needGap = true;
  763. }
  764. for (const Registration& field : processedClass.templateStaticFields_)
  765. {
  766. if (needGap)
  767. ofsH << '\n';
  768. ofsH << " // " << field.comment_ << '\n';
  769. for (const string& registration : field.registration_)
  770. ofsH << " " << registration << '\n';
  771. needGap = true;
  772. }
  773. if (needGap)
  774. ofsH << '\n';
  775. ofsH <<
  776. " #ifdef REGISTER_MEMBERS_MANUAL_PART_" << processedClass.name_ << "\n"
  777. " REGISTER_MEMBERS_MANUAL_PART_" << processedClass.name_ << "();\n"
  778. " #endif\n";
  779. ofsH << "}\n";
  780. }
  781. if (!openedDefine.empty())
  782. {
  783. ofsH <<
  784. "\n"
  785. "#endif // def " << openedDefine << "\n";
  786. openedDefine.clear();
  787. }
  788. ofsH <<
  789. "\n"
  790. "} // namespace Urho3D\n";
  791. }
  792. static void SaveClasses()
  793. {
  794. sort(classes_.begin(), classes_.end());
  795. SaveObjectTypes();
  796. SaveDefaultConstructors();
  797. SaveGeneratedClasses();
  798. SaveClassMembers();
  799. }
  800. // ============================================================================
  801. // List of all required header files
  802. static vector<string> headers_;
  803. // Discarded header files for statistic
  804. static vector<string> ignoredHeaders_;
  805. // Add header to lists if not added yet
  806. void AddHeader(const string& headerFile)
  807. {
  808. if (IsIgnoredHeader(headerFile))
  809. {
  810. if (!CONTAINS(ignoredHeaders_, headerFile))
  811. ignoredHeaders_.push_back(headerFile);
  812. }
  813. else
  814. {
  815. if (!CONTAINS(headers_, headerFile))
  816. headers_.push_back(headerFile);
  817. }
  818. }
  819. // Write result to Generated_Includes.h
  820. static void SaveIncludes()
  821. {
  822. sort(headers_.begin(), headers_.end());
  823. sort(ignoredHeaders_.begin(), ignoredHeaders_.end());
  824. ofstream ofs(_sourceDir + "/Source/Urho3D/AngelScript/Generated_Includes.h");
  825. ofs <<
  826. "// DO NOT EDIT. This file is generated\n"
  827. "\n"
  828. "#pragma once\n"
  829. "\n";
  830. string openedDefine;
  831. bool isFirst = true;
  832. for (const string& header : headers_)
  833. {
  834. string insideDefine = InsideDefine(header);
  835. if (insideDefine != openedDefine)
  836. {
  837. if (!openedDefine.empty())
  838. {
  839. ofs << "#endif\n";
  840. openedDefine.clear();
  841. }
  842. if (!isFirst) // First include can be guarded. Avoid print \n before it
  843. ofs << "\n";
  844. if (!insideDefine.empty())
  845. {
  846. ofs << "#ifdef " << insideDefine << "\n";
  847. openedDefine = insideDefine;
  848. }
  849. }
  850. ofs << "#include \"" << header << "\"\n";
  851. isFirst = false;
  852. }
  853. if (!openedDefine.empty())
  854. {
  855. ofs << "#endif\n";
  856. openedDefine.clear();
  857. }
  858. if (headers_.size() > 0)
  859. ofs << "\n";
  860. if (ignoredHeaders_.size() > 0)
  861. ofs << "// Ignored headers\n\n";
  862. isFirst = true;
  863. for (const string& header : ignoredHeaders_)
  864. {
  865. string insideDefine = InsideDefine(header);
  866. if (insideDefine != openedDefine)
  867. {
  868. if (!openedDefine.empty())
  869. {
  870. ofs << "//#endif\n";
  871. openedDefine.clear();
  872. }
  873. if (!isFirst) // First include can be guarded. Avoid print \n before it
  874. ofs << "\n";
  875. if (!insideDefine.empty())
  876. {
  877. ofs << "//#ifdef " << insideDefine << "\n";
  878. openedDefine = insideDefine;
  879. }
  880. }
  881. ofs << "//#include \"" << header << "\"\n";
  882. isFirst = false;
  883. }
  884. if (!openedDefine.empty())
  885. ofs << "//#endif\n";
  886. }
  887. }
  888. void SaveResult()
  889. {
  890. Result::SaveEnums();
  891. Result::SaveGlobalFunctions();
  892. Result::SaveGlobalVariables();
  893. Result::SaveClasses();
  894. Result::SaveIncludes();
  895. }
  896. }