JSBModule.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  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. namespace ToolCore
  13. {
  14. JSBModule::JSBModule(Context* context, JSBPackage* package) : Object(context),
  15. package_(package)
  16. {
  17. }
  18. JSBModule::~JSBModule()
  19. {
  20. }
  21. void JSBModule::PreprocessHeaders()
  22. {
  23. for (unsigned i = 0; i < headers_.Size(); i++)
  24. {
  25. headers_[i]->VisitPreprocess();
  26. }
  27. }
  28. void JSBModule::VisitHeaders()
  29. {
  30. for (unsigned i = 0; i < headers_.Size(); i++)
  31. {
  32. headers_[i]->VisitHeader();
  33. }
  34. // validate that all classes found
  35. for (unsigned i = 0; i < classnames_.Size(); i++)
  36. {
  37. JSBClass* cls = GetClass(classnames_[i]);
  38. if (!cls)
  39. {
  40. ErrorExit(ToString("Module class not found %s", classnames_[i].CString()));
  41. }
  42. }
  43. ProcessOverloads();
  44. }
  45. void JSBModule::ProcessOverloads()
  46. {
  47. // overloads
  48. JSONValue root = moduleJSON_->GetRoot();
  49. JSONValue overloads = root.GetChild("overloads");
  50. if (overloads.IsObject())
  51. {
  52. Vector<String> childNames = overloads.GetChildNames();
  53. for (unsigned j = 0; j < childNames.Size(); j++)
  54. {
  55. String classname = childNames.At(j);
  56. JSBClass* klass = GetClass(classname);
  57. if (!klass)
  58. {
  59. ErrorExit("Bad overload klass");
  60. }
  61. JSONValue classoverloads = overloads.GetChild(classname);
  62. Vector<String> functionNames = classoverloads.GetChildNames();
  63. for (unsigned k = 0; k < functionNames.Size(); k++)
  64. {
  65. JSONValue sig = classoverloads.GetChild(functionNames[k]);
  66. if (!sig.IsArray())
  67. {
  68. ErrorExit("Bad overload defintion");
  69. }
  70. Vector<String> values;
  71. for (unsigned x = 0; x < sig.GetSize(); x++)
  72. {
  73. values.Push(sig.GetString(x));
  74. }
  75. JSBFunctionOverride* fo = new JSBFunctionOverride(functionNames[k], values);
  76. klass->AddFunctionOverride(fo);
  77. }
  78. }
  79. }
  80. }
  81. void JSBModule::ScanHeaders()
  82. {
  83. JSBind* jsbind = GetSubsystem<JSBind>();
  84. FileSystem* fs = GetSubsystem<FileSystem>();
  85. const String& sourceRoot = jsbind->GetSourceRootFolder();
  86. for (unsigned i = 0; i < sourceDirs_.Size(); i++)
  87. {
  88. const String& dir = sourceRoot + sourceDirs_[i] + "/";
  89. Vector<String> fileNames;
  90. fs->ScanDir(fileNames, dir, "*.h", SCAN_FILES, false);
  91. for (unsigned k = 0; k < fileNames.Size(); k++)
  92. {
  93. String filepath = dir + fileNames[k];
  94. SharedPtr<JSBHeader> header(new JSBHeader(context_, this, filepath));
  95. // Parse the C++ header
  96. header->Parse();
  97. headers_.Push(header);
  98. }
  99. }
  100. }
  101. JSBClass* JSBModule::GetClass(const String& name)
  102. {
  103. if (classes_.Contains(name))
  104. return classes_[name];
  105. return 0;
  106. }
  107. void JSBModule::RegisterClass(String name)
  108. {
  109. String nativeName = name;
  110. if (classnames_.Contains(name))
  111. {
  112. if (classRenames_.Contains(name))
  113. {
  114. name = classRenames_[name];
  115. }
  116. if (JSBPackage::GetClassAllPackages(nativeName))
  117. {
  118. ErrorExit(ToString("Class collision: %s", name.CString()));
  119. }
  120. JSBClass* cls = new JSBClass(context_, this, name, nativeName);
  121. classes_[nativeName] = cls;
  122. LOGINFOF("Registered Class: %s", cls->GetName().CString());
  123. }
  124. }
  125. void JSBModule::RegisterEnum(JSBEnum* jenum)
  126. {
  127. if (JSBPackage::GetClassAllPackages(jenum->GetName()))
  128. {
  129. ErrorExit(ToString("Enum collision: %s", jenum->GetName().CString()));
  130. }
  131. enums_[jenum->GetName()] = jenum;
  132. LOGINFOF("Registered Enum: %s", jenum->GetName().CString());
  133. }
  134. JSBEnum* JSBModule::GetEnum(const String& name)
  135. {
  136. if (enums_.Contains(name))
  137. {
  138. return enums_[name];
  139. }
  140. return 0;
  141. }
  142. bool JSBModule::ContainsConstant(const String& constantName)
  143. {
  144. return constants_.Contains(constantName);
  145. }
  146. void JSBModule::RegisterConstant(const String& constantName)
  147. {
  148. // MAX_CASCADE_SPLITS is defined differently for desktop/mobile
  149. if (constantName == "MAX_CASCADE_SPLITS" && JSBPackage::ContainsConstantAllPackages(constantName))
  150. {
  151. return;
  152. }
  153. if (JSBPackage::ContainsConstantAllPackages(constantName))
  154. {
  155. ErrorExit(ToString("Constant collision: %s", constantName.CString()));
  156. }
  157. constants_.Push(constantName);
  158. }
  159. bool JSBModule::Load(const String& jsonFilename)
  160. {
  161. LOGINFOF("Loading Module: %s", jsonFilename.CString());
  162. SharedPtr<File> jsonFile(new File(context_, jsonFilename));
  163. if (!jsonFile->IsOpen())
  164. {
  165. LOGERRORF("Unable to open module json: %s", jsonFilename.CString());
  166. return false;
  167. }
  168. moduleJSON_ = new JSONFile(context_);
  169. if (!moduleJSON_->BeginLoad(*jsonFile))
  170. {
  171. LOGERRORF("Unable to parse module json: %s", jsonFilename.CString());
  172. return false;
  173. }
  174. JSONValue root = moduleJSON_->GetRoot();
  175. name_ = root.GetString("name");
  176. JSONValue classes = root.GetChild("classes");
  177. for (unsigned i = 0; i < classes.GetSize(); i++)
  178. {
  179. classnames_.Push(classes.GetString(i));
  180. }
  181. JSONValue classes_rename = root.GetChild("classes_rename");
  182. if (classes_rename.IsObject())
  183. {
  184. Vector<String> childNames = classes_rename.GetValueNames();
  185. for (unsigned j = 0; j < childNames.Size(); j++)
  186. {
  187. String classname = childNames.At(j);
  188. String crename = classes_rename.GetString(classname);
  189. classRenames_[classname] = crename;
  190. }
  191. }
  192. JSONValue sources = root.GetChild("sources");
  193. for (unsigned i = 0; i < sources.GetSize(); i++)
  194. {
  195. sourceDirs_.Push(sources.GetString(i));
  196. }
  197. if (name_ == "Graphics")
  198. {
  199. #ifdef _MSC_VER
  200. if (JSBind::PLATFORM == "ANDROID" || JSBind::PLATFORM == "WEB")
  201. {
  202. sourceDirs_.Push("Source/Atomic/Graphics/OpenGL");
  203. }
  204. else
  205. {
  206. #ifdef ATOMIC_D3D11
  207. sourceDirs_.Push("Source/Atomic/Graphics/Direct3D11");
  208. #else
  209. sourceDirs_.Push("Source/Atomic/Graphics/Direct3D9");
  210. #endif
  211. }
  212. #else
  213. sourceDirs_.Push("Source/Atomic/Graphics/OpenGL");
  214. #endif
  215. }
  216. ScanHeaders();
  217. return true;
  218. }
  219. }