JSClassWriter.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. //
  2. // Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
  3. // LICENSE: Atomic Game Engine Editor and Tools EULA
  4. // Please see LICENSE_ATOMIC_EDITOR_AND_TOOLS.md in repository root for
  5. // license information: https://github.com/AtomicGameEngine/AtomicGameEngine
  6. //
  7. #include <Atomic/IO/FileSystem.h>
  8. #include "../JSBind.h"
  9. #include "../JSBModule.h"
  10. #include "../JSBPackage.h"
  11. #include "../JSBEnum.h"
  12. #include "../JSBClass.h"
  13. #include "../JSBFunction.h"
  14. #include "JSClassWriter.h"
  15. #include "JSFunctionWriter.h"
  16. namespace ToolCore
  17. {
  18. JSClassWriter::JSClassWriter(JSBClass *klass) : JSBClassWriter(klass)
  19. {
  20. }
  21. void JSClassWriter::WriteFunctions(String& source)
  22. {
  23. for (unsigned i = 0; i < klass_->functions_.Size(); i++)
  24. {
  25. JSBFunction* function = klass_->functions_.At(i);
  26. if (function->Skip())
  27. continue;
  28. if (function->IsDestructor())
  29. continue;
  30. JSFunctionWriter writer(function);
  31. writer.GenerateSource(source);
  32. }
  33. }
  34. void JSClassWriter::GenerateSource(String& sourceOut)
  35. {
  36. String source = "";
  37. if (klass_->IsNumberArray())
  38. return;
  39. WriteFunctions(source);
  40. String packageName = klass_->GetModule()->GetPackage()->GetName();
  41. source.AppendWithFormat("static void jsb_class_define_%s(JSVM* vm)\n{\n", klass_->GetName().CString());
  42. source.Append("duk_context* ctx = vm->GetJSContext();\n");
  43. GenerateStaticFunctionsSource(source, packageName);
  44. GenerateNonStaticFunctionsSource(source, packageName);
  45. source.Append("}\n");
  46. sourceOut += source;
  47. }
  48. void JSClassWriter::GenerateStaticFunctionsSource(String& source, String& packageName)
  49. {
  50. // Store function on both the constructor and prototype
  51. // so can access static functions from both the class constructor and an instance
  52. source.AppendWithFormat("js_class_get_constructor(ctx, \"%s\", \"%s\");\n", packageName.CString(), klass_->GetName().CString());
  53. source.AppendWithFormat("js_class_get_prototype(ctx, \"%s\", \"%s\");\n", packageName.CString(), klass_->GetName().CString());
  54. for (unsigned i = 0; i < klass_->functions_.Size(); i++)
  55. {
  56. JSBFunction* function = klass_->functions_.At(i);
  57. if (function->Skip())
  58. continue;
  59. if (function->IsConstructor() || function->IsDestructor())
  60. continue;
  61. if (!function->IsStatic())
  62. continue;
  63. if (function->FirstDefaultParameter() != -1)
  64. {
  65. source.AppendWithFormat("duk_push_c_function(ctx, jsb_class_%s_%s, DUK_VARARGS);\n", klass_->GetName().CString(), function->GetName().CString());
  66. }
  67. else
  68. {
  69. source.AppendWithFormat("duk_push_c_function(ctx, jsb_class_%s_%s, %i);\n", klass_->GetName().CString(), function->GetName().CString(), (int)function->GetParameters().Size());
  70. }
  71. String scriptName = function->GetName();
  72. scriptName[0] = tolower(scriptName[0]);
  73. source.Append("duk_dup(ctx, -1);\n");
  74. source.AppendWithFormat("duk_put_prop_string(ctx, -3, \"%s\");\n", scriptName.CString());
  75. source.AppendWithFormat("duk_put_prop_string(ctx, -3, \"%s\");\n", scriptName.CString());
  76. }
  77. source.Append("duk_pop_2(ctx);\n");
  78. }
  79. void JSClassWriter::GenerateNonStaticFunctionsSource(String& source, String& packageName)
  80. {
  81. source.AppendWithFormat("js_class_get_prototype(ctx, \"%s\", \"%s\");\n", packageName.CString(), klass_->GetName().CString());
  82. for (unsigned i = 0; i < klass_->functions_.Size(); i++)
  83. {
  84. JSBFunction* function = klass_->functions_.At(i);
  85. if (function->Skip())
  86. continue;
  87. if (function->IsConstructor() || function->IsDestructor())
  88. continue;
  89. if (function->IsStatic())
  90. continue;
  91. if (function->FirstDefaultParameter() != -1)
  92. {
  93. source.AppendWithFormat("duk_push_c_function(ctx, jsb_class_%s_%s, DUK_VARARGS);\n", klass_->GetName().CString(), function->GetName().CString());
  94. }
  95. else
  96. {
  97. source.AppendWithFormat("duk_push_c_function(ctx, jsb_class_%s_%s, %i);\n", klass_->GetName().CString(), function->GetName().CString(), (int)function->GetParameters().Size());
  98. }
  99. String scriptName = function->GetName();
  100. scriptName[0] = tolower(scriptName[0]);
  101. source.AppendWithFormat("duk_put_prop_string(ctx, -2, \"%s\");\n", scriptName.CString());
  102. }
  103. source.Append("duk_pop(ctx);\n");
  104. }
  105. }