JSBModule.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. #include <Atomic/IO/Log.h>
  2. #include <Atomic/IO/File.h>
  3. #include <Atomic/IO/FileSystem.h>
  4. #include <Atomic/Resource/JSONFile.h>
  5. #include "Atomic/Core/ProcessUtils.h"
  6. #include "JSBind.h"
  7. #include "JSBPackage.h"
  8. #include "JSBModule.h"
  9. #include "JSBHeader.h"
  10. #include "JSBClass.h"
  11. #include "JSBEnum.h"
  12. #include "JSBModuleWriter.h"
  13. #include "JSBType.h"
  14. namespace ToolCore
  15. {
  16. JSBModule::JSBModule(Context* context, JSBPackage* package) : Object(context),
  17. package_(package)
  18. {
  19. }
  20. JSBModule::~JSBModule()
  21. {
  22. }
  23. Vector<SharedPtr<JSBClass>> JSBModule::GetClasses()
  24. {
  25. return classes_.Values();
  26. }
  27. Vector<SharedPtr<JSBEnum>> JSBModule::GetEnums()
  28. {
  29. return enums_.Values();
  30. }
  31. void JSBModule::PreprocessHeaders()
  32. {
  33. for (unsigned i = 0; i < headers_.Size(); i++)
  34. {
  35. headers_[i]->VisitPreprocess();
  36. }
  37. }
  38. void JSBModule::VisitHeaders()
  39. {
  40. for (unsigned i = 0; i < headers_.Size(); i++)
  41. {
  42. headers_[i]->VisitHeader();
  43. }
  44. // validate that all classes found
  45. for (unsigned i = 0; i < classnames_.Size(); i++)
  46. {
  47. JSBClass* cls = GetClass(classnames_[i]);
  48. if (!cls)
  49. {
  50. ErrorExit(ToString("Module class not found %s", classnames_[i].CString()));
  51. }
  52. }
  53. ProcessOverloads();
  54. ProcessExcludes();
  55. ProcessTypeScriptDecl();
  56. ProcessHaxeDecl();
  57. }
  58. void JSBModule::PreprocessClasses()
  59. {
  60. HashMap<StringHash, SharedPtr<JSBClass> >::Iterator itr;
  61. for (itr = classes_.Begin(); itr != classes_.End(); itr++)
  62. {
  63. itr->second_->Preprocess();
  64. }
  65. }
  66. void JSBModule::ProcessClasses()
  67. {
  68. HashMap<StringHash, SharedPtr<JSBClass> >::Iterator itr;
  69. for (itr = classes_.Begin(); itr != classes_.End(); itr++)
  70. {
  71. itr->second_->Process();
  72. }
  73. }
  74. void JSBModule::PostProcessClasses()
  75. {
  76. HashMap<StringHash, SharedPtr<JSBClass> >::Iterator itr;
  77. for (itr = classes_.Begin(); itr != classes_.End(); itr++)
  78. {
  79. itr->second_->PostProcess();
  80. }
  81. }
  82. void JSBModule::ProcessOverloads()
  83. {
  84. // overloads
  85. JSONValue root = moduleJSON_->GetRoot();
  86. JSONValue overloads = root.GetChild("overloads");
  87. if (overloads.IsObject())
  88. {
  89. Vector<String> childNames = overloads.GetChildNames();
  90. for (unsigned j = 0; j < childNames.Size(); j++)
  91. {
  92. String classname = childNames.At(j);
  93. JSBClass* klass = GetClass(classname);
  94. if (!klass)
  95. {
  96. ErrorExit("Bad overload klass");
  97. }
  98. JSONValue classoverloads = overloads.GetChild(classname);
  99. Vector<String> functionNames = classoverloads.GetChildNames();
  100. for (unsigned k = 0; k < functionNames.Size(); k++)
  101. {
  102. JSONValue sig = classoverloads.GetChild(functionNames[k]);
  103. if (!sig.IsArray())
  104. {
  105. ErrorExit("Bad overload defintion");
  106. }
  107. Vector<String> values;
  108. for (unsigned x = 0; x < sig.GetSize(); x++)
  109. {
  110. values.Push(sig.GetString(x));
  111. }
  112. JSBFunctionSignature* fo = new JSBFunctionSignature(functionNames[k], values);
  113. klass->AddFunctionOverride(fo);
  114. }
  115. }
  116. }
  117. }
  118. void JSBModule::ProcessExcludes()
  119. {
  120. // excludes
  121. JSONValue root = moduleJSON_->GetRoot();
  122. JSONValue excludes = root.GetChild("excludes");
  123. if (excludes.IsObject())
  124. {
  125. Vector<String> childNames = excludes.GetChildNames();
  126. for (unsigned j = 0; j < childNames.Size(); j++)
  127. {
  128. String classname = childNames.At(j);
  129. JSBClass* klass = GetClass(classname);
  130. if (!klass)
  131. {
  132. ErrorExit("Bad exclude klass");
  133. }
  134. JSONValue classexcludes = excludes.GetChild(classname);
  135. Vector<String> functionNames = classexcludes.GetChildNames();
  136. for (unsigned k = 0; k < functionNames.Size(); k++)
  137. {
  138. JSONValue sig = classexcludes.GetChild(functionNames[k]);
  139. if (!sig.IsArray())
  140. {
  141. ErrorExit("Bad exclude defintion");
  142. }
  143. Vector<String> values;
  144. for (unsigned x = 0; x < sig.GetSize(); x++)
  145. {
  146. values.Push(sig.GetString(x));
  147. }
  148. JSBFunctionSignature* fe = new JSBFunctionSignature(functionNames[k], values);
  149. klass->AddFunctionExclude(fe);
  150. }
  151. }
  152. }
  153. }
  154. void JSBModule::ProcessTypeScriptDecl()
  155. {
  156. // TypeScript declarations
  157. JSONValue root = moduleJSON_->GetRoot();
  158. JSONValue decl = root.GetChild("typescript_decl");
  159. if (decl.IsObject())
  160. {
  161. Vector<String> childNames = decl.GetChildNames();
  162. for (unsigned j = 0; j < childNames.Size(); j++)
  163. {
  164. String classname = childNames.At(j);
  165. JSBClass* klass = GetClass(classname);
  166. if (!klass)
  167. {
  168. ErrorExit("Bad TypeScript decl klass");
  169. }
  170. JSONValue classdecl = decl.GetChild(classname);
  171. for (unsigned k = 0; k < classdecl.GetSize(); k++)
  172. {
  173. klass->AddTypeScriptDecl(classdecl.GetString(k));
  174. }
  175. }
  176. }
  177. }
  178. void JSBModule::ProcessHaxeDecl()
  179. {
  180. // Haxe declarations
  181. JSONValue root = moduleJSON_->GetRoot();
  182. JSONValue decl = root.GetChild("haxe_decl");
  183. if (decl.IsObject())
  184. {
  185. Vector<String> childNames = decl.GetChildNames();
  186. for (unsigned j = 0; j < childNames.Size(); j++)
  187. {
  188. String classname = childNames.At(j);
  189. JSBClass* klass = GetClass(classname);
  190. if (!klass)
  191. {
  192. ErrorExit("Bad Haxe decl class");
  193. }
  194. JSONValue classdecl = decl.GetChild(classname);
  195. for (unsigned k = 0; k < classdecl.GetSize(); k++)
  196. {
  197. klass->AddHaxeDecl(classdecl.GetString(k));
  198. }
  199. }
  200. }
  201. }
  202. void JSBModule::ScanHeaders()
  203. {
  204. JSBind* jsbind = GetSubsystem<JSBind>();
  205. FileSystem* fs = GetSubsystem<FileSystem>();
  206. const String& sourceRoot = jsbind->GetSourceRootFolder();
  207. for (unsigned i = 0; i < sourceDirs_.Size(); i++)
  208. {
  209. const String& dir = sourceRoot + sourceDirs_[i] + "/";
  210. Vector<String> fileNames;
  211. fs->ScanDir(fileNames, dir, "*.h", SCAN_FILES, false);
  212. for (unsigned k = 0; k < fileNames.Size(); k++)
  213. {
  214. String filepath = dir + fileNames[k];
  215. SharedPtr<JSBHeader> header(new JSBHeader(context_, this, filepath));
  216. // Parse the C++ header
  217. header->Parse();
  218. headers_.Push(header);
  219. }
  220. }
  221. }
  222. JSBClass* JSBModule::GetClass(const String& name)
  223. {
  224. if (classes_.Contains(name))
  225. return classes_[name];
  226. return 0;
  227. }
  228. void JSBModule::RegisterClass(String name)
  229. {
  230. String nativeName = name;
  231. if (classnames_.Contains(name))
  232. {
  233. if (classRenames_.Contains(name))
  234. {
  235. name = classRenames_[name];
  236. }
  237. if (JSBPackage::GetClassAllPackages(nativeName))
  238. {
  239. ErrorExit(ToString("Class collision: %s", name.CString()));
  240. }
  241. JSBClass* cls = new JSBClass(context_, this, name, nativeName);
  242. classes_[nativeName] = cls;
  243. package_->RegisterClass(cls);
  244. }
  245. }
  246. void JSBModule::RegisterEnum(JSBEnum* jenum)
  247. {
  248. if (JSBPackage::GetClassAllPackages(jenum->GetName()))
  249. {
  250. ErrorExit(ToString("Enum collision: %s", jenum->GetName().CString()));
  251. }
  252. enums_[jenum->GetName()] = jenum;
  253. }
  254. JSBEnum* JSBModule::GetEnum(const String& name)
  255. {
  256. if (enums_.Contains(name))
  257. {
  258. return enums_[name];
  259. }
  260. return 0;
  261. }
  262. bool JSBModule::ContainsConstant(const String& constantName)
  263. {
  264. return constants_.Contains(constantName);
  265. }
  266. void JSBModule::RegisterConstant(const String& constantName, unsigned type)
  267. {
  268. // MAX_CASCADE_SPLITS is defined differently for desktop/mobile
  269. if (constantName == "MAX_CASCADE_SPLITS" && JSBPackage::ContainsConstantAllPackages(constantName))
  270. {
  271. return;
  272. }
  273. if (JSBPackage::ContainsConstantAllPackages(constantName))
  274. {
  275. ErrorExit(ToString("Constant collision: %s", constantName.CString()));
  276. }
  277. constants_[constantName] = new JSBPrimitiveType(type);
  278. }
  279. bool JSBModule::Load(const String& jsonFilename)
  280. {
  281. JSBind* jsbind = GetSubsystem<JSBind>();
  282. LOGINFOF("Loading Module: %s", jsonFilename.CString());
  283. SharedPtr<File> jsonFile(new File(context_, jsonFilename));
  284. if (!jsonFile->IsOpen())
  285. {
  286. LOGERRORF("Unable to open module json: %s", jsonFilename.CString());
  287. return false;
  288. }
  289. moduleJSON_ = new JSONFile(context_);
  290. if (!moduleJSON_->BeginLoad(*jsonFile))
  291. {
  292. LOGERRORF("Unable to parse module json: %s", jsonFilename.CString());
  293. return false;
  294. }
  295. JSONValue root = moduleJSON_->GetRoot();
  296. name_ = root.GetString("name");
  297. JSONValue requires = root.GetChild("requires");
  298. if (requires.IsArray())
  299. {
  300. for (unsigned j = 0; j < requires.GetSize(); j++)
  301. {
  302. requirements_.Push(requires.GetString(j));
  303. }
  304. }
  305. JSONValue classes = root.GetChild("classes");
  306. for (unsigned i = 0; i < classes.GetSize(); i++)
  307. {
  308. classnames_.Push(classes.GetString(i));
  309. }
  310. JSONValue classes_rename = root.GetChild("classes_rename");
  311. if (classes_rename.IsObject())
  312. {
  313. Vector<String> childNames = classes_rename.GetValueNames();
  314. for (unsigned j = 0; j < childNames.Size(); j++)
  315. {
  316. String classname = childNames.At(j);
  317. String crename = classes_rename.GetString(classname);
  318. classRenames_[classname] = crename;
  319. }
  320. }
  321. JSONValue includes = root.GetChild("includes");
  322. if (includes.IsArray())
  323. {
  324. for (unsigned j = 0; j < includes.GetSize(); j++)
  325. {
  326. includes_.Push(includes.GetString(j));
  327. }
  328. }
  329. JSONValue sources = root.GetChild("sources");
  330. for (unsigned i = 0; i < sources.GetSize(); i++)
  331. {
  332. sourceDirs_.Push(sources.GetString(i));
  333. }
  334. if (name_ == "Graphics")
  335. {
  336. #ifdef _MSC_VER
  337. if (jsbind->GetPlatform() == "ANDROID" || jsbind->GetPlatform() == "WEB")
  338. {
  339. sourceDirs_.Push("Source/Atomic/Graphics/OpenGL");
  340. }
  341. else
  342. {
  343. #ifdef ATOMIC_D3D11
  344. sourceDirs_.Push("Source/Atomic/Graphics/Direct3D11");
  345. #else
  346. sourceDirs_.Push("Source/Atomic/Graphics/Direct3D9");
  347. #endif
  348. }
  349. #else
  350. sourceDirs_.Push("Source/Atomic/Graphics/OpenGL");
  351. #endif
  352. }
  353. ScanHeaders();
  354. return true;
  355. }
  356. void JSBModule::GenerateSource(const String& outPath)
  357. {
  358. JSBModuleWriter writer(this);
  359. writer.GenerateSource(source_);
  360. String filepath = outPath + "/JSModule" + name_ + ".cpp";
  361. File file(context_);
  362. file.Open(filepath, FILE_WRITE);
  363. file.Write(source_.CString(), source_.Length());
  364. file.Close();
  365. }
  366. }