JSAPI.cpp 3.9 KB

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