JSAPI.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
  2. // Please see LICENSE.md in repository root for license information
  3. // https://github.com/AtomicGameEngine/AtomicGameEngine
  4. #include "JSAPI.h"
  5. #include "JSVM.h"
  6. /*
  7. // script can new an instance
  8. // script can get an engine ptr back (which may be to a previously script new'd instance)
  9. // script should always get the same JS Object back which means a lookup table (strong ref)
  10. // we can look directly at the tval (exposed from duktape internals) to see if the reference count is 1
  11. // script owned
  12. // new'd script side, script holds a RefCounted reference
  13. // native owned
  14. // native script classes not derived from refcounted
  15. // if not inherited from RefCounted can script access?
  16. // if so, script side will always need to delete?
  17. */
  18. namespace Atomic
  19. {
  20. void js_class_get_prototype(duk_context* ctx, const char* classname)
  21. {
  22. duk_get_global_string(ctx, "Atomic");
  23. duk_get_prop_string(ctx, -1, classname);
  24. duk_get_prop_string(ctx, -1, "prototype");
  25. duk_remove(ctx, -2); // remove class object
  26. duk_remove(ctx, -2); // remove Atomic object
  27. }
  28. void js_constructor_basecall(duk_context* ctx, const char* baseclass)
  29. {
  30. int top = duk_get_top(ctx);
  31. duk_get_global_string(ctx, "Atomic");
  32. duk_get_prop_string(ctx, -1, baseclass);
  33. assert(duk_is_function(ctx, -1));
  34. duk_push_this(ctx);
  35. duk_call_method(ctx, 0);
  36. duk_pop_n(ctx, 2);
  37. assert (top == duk_get_top(ctx));
  38. }
  39. void js_class_declare(JSVM* vm, const char* classname, duk_c_function constructor)
  40. {
  41. duk_context* ctx = vm->GetJSContext();
  42. duk_get_global_string(ctx, "Atomic");
  43. duk_push_c_function(ctx, constructor, DUK_VARARGS);
  44. duk_put_prop_string(ctx, -2, classname);
  45. duk_pop(ctx);
  46. }
  47. void js_class_push_propertyobject(JSVM* vm, const char* classname)
  48. {
  49. duk_context* ctx = vm->GetJSContext();
  50. String pname;
  51. pname.AppendWithFormat("__%s__Properties", classname);
  52. duk_get_global_string(ctx, "Atomic");
  53. duk_push_object(ctx);
  54. duk_dup(ctx, -1);
  55. duk_put_prop_string(ctx, -3, pname.CString());
  56. duk_remove(ctx, -2); // remove Atomic object
  57. }
  58. void js_setup_prototype(JSVM* vm, const char* classname, const char* basename, bool hasProperties)
  59. {
  60. duk_context* ctx = vm->GetJSContext();
  61. String pname;
  62. pname.AppendWithFormat("__%s__Properties", classname);
  63. int top = duk_get_top(ctx);
  64. duk_get_global_string(ctx, "Atomic");
  65. duk_get_prop_string(ctx, -1, classname);
  66. assert(duk_is_c_function(ctx, -1));
  67. if (!strlen(basename))
  68. {
  69. // prototype
  70. duk_push_object(ctx);
  71. duk_dup(ctx, -2); // AObject constructor function
  72. duk_put_prop_string(ctx, -2, "constructor");
  73. duk_put_prop_string(ctx, -2, "prototype");
  74. duk_pop_n(ctx, 2);
  75. assert (top == duk_get_top(ctx));
  76. return;
  77. }
  78. // prototype
  79. duk_get_global_string(ctx, "Object");
  80. duk_get_prop_string(ctx, -1, "create");
  81. assert(duk_is_function(ctx, -1));
  82. duk_remove(ctx, -2); // remove Object
  83. duk_get_global_string(ctx, "Atomic");
  84. duk_get_prop_string(ctx, -1, basename);
  85. assert(duk_is_function(ctx, -1));
  86. duk_get_prop_string(ctx, -1, "prototype");
  87. assert(duk_is_object(ctx, -1));
  88. duk_remove(ctx, -2); // remove basename
  89. int numargs = 1;
  90. if (hasProperties)
  91. {
  92. duk_get_prop_string(ctx, -2, pname.CString());
  93. assert(duk_is_object(ctx, -1));
  94. duk_remove(ctx, -3); // remove Atomic
  95. numargs++;
  96. }
  97. else
  98. duk_remove(ctx, -2); // remove Atomic
  99. duk_call(ctx, numargs);
  100. assert(duk_is_object(ctx, -1));
  101. duk_dup(ctx, -2);
  102. duk_put_prop_string(ctx, -2, "constructor");
  103. //duk_dup(ctx, -1);
  104. duk_put_prop_string(ctx, -2, "prototype");
  105. // pop the classname object
  106. duk_pop(ctx);
  107. // pop the Atomic Object
  108. duk_pop(ctx);
  109. assert (top == duk_get_top(ctx));
  110. }
  111. }