ClassBinding.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. #include "ClassBinding.h"
  2. #include "Generator.h"
  3. static void generateInstanceGetter(ostream& o, const string& classname, const string& uniquename)
  4. {
  5. o << "static " << classname << "* getInstance(lua_State* state)\n";
  6. o << "{\n";
  7. o << " void* userdata = luaL_checkudata(state, 1, \"" << uniquename << "\");\n";
  8. o << " luaL_argcheck(state, userdata != NULL, 1, \"\'" << uniquename << "\' expected.\");\n";
  9. o << " return (" << classname << "*)((" << LUA_OBJECT << "*)userdata)->instance;\n";
  10. o << "}\n\n";
  11. }
  12. ClassBinding::ClassBinding(string classname, string refId) : classname(classname),
  13. refId(refId), inaccessibleConstructor(false), inaccessibleDestructor(false)
  14. {
  15. // Get the class's name and namespace.
  16. this->classname = Generator::getInstance()->getClassNameAndNamespace(classname, &ns);
  17. // Calculate the unique name for the class.
  18. uniquename = Generator::getUniqueName(this->classname);
  19. }
  20. void ClassBinding::write(string dir, const set<string>& includes, string* bindingNS)
  21. {
  22. // Calculate the constructor string.
  23. size_t index = uniquename.rfind(SCOPE_REPLACEMENT);
  24. string constructorString = "";
  25. string* constructorUniqueName = NULL;
  26. if (index != uniquename.npos && index != uniquename.length())
  27. constructorString += uniquename.substr(index + SCOPE_REPLACEMENT_SIZE);
  28. else
  29. constructorString += uniquename;
  30. // Generate a constructor function if there isn't one
  31. // and the class doesn't have an inaccessible constructor.
  32. FunctionBinding b(classname, uniquename);
  33. b.name = constructorString;
  34. b.returnParam = FunctionBinding::Param(FunctionBinding::Param::TYPE_CONSTRUCTOR, FunctionBinding::Param::KIND_POINTER, refId);
  35. b.type = FunctionBinding::MEMBER_FUNCTION;
  36. b.own = true;
  37. map<string, vector<FunctionBinding> >::iterator iter = bindings.find(b.getFunctionName());
  38. if (iter == bindings.end())
  39. {
  40. if (!inaccessibleConstructor)
  41. {
  42. bindings[b.getFunctionName()].push_back(b);
  43. constructorUniqueName = new string(b.getFunctionName());
  44. }
  45. }
  46. else
  47. {
  48. constructorUniqueName = new string(iter->second[0].getFunctionName());
  49. }
  50. // Calculate the destructor string.
  51. index = uniquename.rfind(SCOPE_REPLACEMENT);
  52. string destructorString = "~";
  53. string* destructorUniqueName = NULL;
  54. if (index != uniquename.npos && index != uniquename.length())
  55. destructorString += uniquename.substr(index + SCOPE_REPLACEMENT_SIZE);
  56. else
  57. destructorString += uniquename;
  58. // Generate a destructor function if there isn't one
  59. // and the class doesn't have an inaccessible destructor
  60. // or the class is derived from Ref.
  61. b = FunctionBinding(classname, uniquename);
  62. b.name = destructorString;
  63. b.returnParam = FunctionBinding::Param(FunctionBinding::Param::TYPE_DESTRUCTOR);
  64. b.type = FunctionBinding::MEMBER_FUNCTION;
  65. iter = bindings.find(b.getFunctionName());
  66. if (iter == bindings.end())
  67. {
  68. if (!inaccessibleDestructor || Generator::getInstance()->isRef(classname))
  69. {
  70. bindings[b.getFunctionName()].push_back(b);
  71. destructorUniqueName = new string(b.getFunctionName());
  72. }
  73. }
  74. else
  75. {
  76. destructorUniqueName = new string(iter->second[0].getFunctionName());
  77. }
  78. // Write out the header.
  79. {
  80. string path = dir + string("lua_") + uniquename + string(".h");
  81. ostringstream o;
  82. if (!o)
  83. {
  84. GP_ERROR("Failed to open file '%s' for generating Lua bindings.", path.c_str());
  85. return;
  86. }
  87. string includeGuard = string("lua_") + uniquename + string("_H_");
  88. transform(includeGuard.begin(), includeGuard.end(), includeGuard.begin(), ::toupper);
  89. o << "#ifndef " << includeGuard << "\n";
  90. o << "#define " << includeGuard << "\n\n";
  91. if (bindingNS)
  92. {
  93. o << "namespace " << *bindingNS << "\n";
  94. o << "{\n\n";
  95. }
  96. o << "// Lua bindings for " << classname << ".\n";
  97. // Write out the binding functions declarations.
  98. iter = bindings.begin();
  99. for (; iter != bindings.end(); iter++)
  100. {
  101. o << "int " << iter->second[0].getFunctionName() << "(lua_State* state);\n";
  102. }
  103. o << "\n";
  104. // Write out the signature of the function used to register the class with Lua.
  105. o << "void luaRegister_" << uniquename << "();\n\n";
  106. if (bindingNS)
  107. o << "}\n\n";
  108. o << "#endif\n";
  109. writeFile(path, o.str());
  110. }
  111. // Write out the implementation.
  112. {
  113. string path = dir + string("lua_") + uniquename + string(".cpp");
  114. ostringstream o;
  115. if (!o)
  116. {
  117. GP_ERROR("Failed to open file '%s' for generating Lua bindings.", path.c_str());
  118. return;
  119. }
  120. o << "#include \"Base.h\"\n";
  121. o << "#include \"ScriptController.h\"\n";
  122. o << "#include \"lua_" << uniquename << ".h\"\n";
  123. // Ensure we include the original class header, even
  124. // if the list of includes doesn't have it.
  125. if (includes.find(include) == includes.end())
  126. o << "#include \"" << include << "\"\n";
  127. for (set<string>::iterator includeIter = includes.begin(); includeIter != includes.end(); includeIter++)
  128. {
  129. o << "#include \"" << *includeIter << "\"\n";
  130. }
  131. o << "\n";
  132. // If the original class is part of a namespace and we aren't generating into that namespace,
  133. // include its member with a 'using' statement.
  134. if (ns.length() > 0 && (!bindingNS || (*bindingNS != ns)))
  135. {
  136. o << "using " << ns << ";\n\n";
  137. }
  138. if (bindingNS)
  139. {
  140. o << "namespace " << *bindingNS << "\n";
  141. o << "{\n\n";
  142. }
  143. // Write out the function used to register the class with Lua.
  144. o << "void luaRegister_" << uniquename << "()\n";
  145. o << "{\n";
  146. // Get the member functions ready to bind.
  147. iter = bindings.begin();
  148. bool hasMembers = false;
  149. for (; iter != bindings.end(); iter++)
  150. {
  151. for (unsigned int i = 0, count = iter->second.size(); i < count; i++)
  152. {
  153. if (iter->second[i].type == FunctionBinding::MEMBER_FUNCTION ||
  154. iter->second[i].type == FunctionBinding::MEMBER_CONSTANT ||
  155. iter->second[i].type == FunctionBinding::MEMBER_VARIABLE)
  156. {
  157. hasMembers = true;
  158. break;
  159. }
  160. }
  161. if (hasMembers)
  162. break;
  163. }
  164. if (hasMembers)
  165. {
  166. o << " const luaL_Reg lua_members[] = \n";
  167. o << " {\n";
  168. iter = bindings.begin();
  169. for (; iter != bindings.end(); iter++)
  170. {
  171. for (unsigned int i = 0, count = iter->second.size(); i < count; i++)
  172. {
  173. if ((iter->second[i].type == FunctionBinding::MEMBER_FUNCTION ||
  174. iter->second[i].type == FunctionBinding::MEMBER_CONSTANT ||
  175. iter->second[i].type == FunctionBinding::MEMBER_VARIABLE) &&
  176. iter->second[i].returnParam.type != FunctionBinding::Param::TYPE_CONSTRUCTOR &&
  177. iter->second[i].returnParam.type != FunctionBinding::Param::TYPE_DESTRUCTOR)
  178. {
  179. o << " {\"" << iter->second[i].name << "\", " << iter->second[i].getFunctionName() << "},\n";
  180. break;
  181. }
  182. }
  183. }
  184. o << " {NULL, NULL}\n";
  185. o << " };\n";
  186. }
  187. else
  188. {
  189. o << " const luaL_Reg* lua_members = NULL;\n";
  190. }
  191. // Get the static functions ready to bind.
  192. iter = bindings.begin();
  193. bool hasStatics = false;
  194. for (; iter != bindings.end(); iter++)
  195. {
  196. for (unsigned int i = 0, count = iter->second.size(); i < count; i++)
  197. {
  198. if (iter->second[i].type == FunctionBinding::STATIC_FUNCTION ||
  199. iter->second[i].type == FunctionBinding::STATIC_CONSTANT ||
  200. iter->second[i].type == FunctionBinding::STATIC_VARIABLE)
  201. {
  202. hasStatics = true;
  203. break;
  204. }
  205. }
  206. if (hasStatics)
  207. break;
  208. }
  209. if (hasStatics)
  210. {
  211. o << " const luaL_Reg lua_statics[] = \n";
  212. o << " {\n";
  213. iter = bindings.begin();
  214. for (; iter != bindings.end(); iter++)
  215. {
  216. for (unsigned int i = 0, count = iter->second.size(); i < count; i++)
  217. {
  218. if (iter->second[i].type == FunctionBinding::STATIC_FUNCTION ||
  219. iter->second[i].type == FunctionBinding::STATIC_CONSTANT ||
  220. iter->second[i].type == FunctionBinding::STATIC_VARIABLE)
  221. {
  222. o << " {\"" << iter->second[i].name << "\", " << iter->second[i].getFunctionName() << "},\n";
  223. break;
  224. }
  225. }
  226. }
  227. o << " {NULL, NULL}\n";
  228. o << " };\n";
  229. }
  230. else
  231. {
  232. o << " const luaL_Reg* lua_statics = NULL;\n";
  233. }
  234. // Output the scope path for the class (used for inner classes).
  235. vector<string> scopePath = Generator::getScopePath(classname, ns);
  236. o << " std::vector<std::string> scopePath;\n";
  237. for (vector<string>::iterator scopeIter = scopePath.begin(); scopeIter != scopePath.end(); scopeIter++)
  238. {
  239. o << " scopePath.push_back(\"" << *scopeIter << "\");\n";
  240. }
  241. // Register the class (its member and static functions and constructor and destructor).
  242. o << "\n gameplay::ScriptUtil::registerClass(\"" << uniquename << "\", lua_members, ";
  243. o << ((constructorUniqueName) ? *constructorUniqueName : "NULL") << ", ";
  244. o << ((destructorUniqueName) ? *destructorUniqueName : "NULL") << ", ";
  245. o << "lua_statics, scopePath);\n";
  246. o << "}\n\n";
  247. // Write out the function used to get the instance for
  248. // calling member functions and variables.
  249. generateInstanceGetter(o, classname, uniquename);
  250. // Write out the binding functions.
  251. iter = bindings.begin();
  252. for (; iter != bindings.end(); iter++)
  253. {
  254. FunctionBinding::write(o, iter->second);
  255. }
  256. if (bindingNS)
  257. o << "}\n";
  258. writeFile(path, o.str());
  259. }
  260. SAFE_DELETE(constructorUniqueName);
  261. SAFE_DELETE(destructorUniqueName);
  262. }