|
|
@@ -22,6 +22,7 @@
|
|
|
|
|
|
#include <Atomic/Core/Context.h>
|
|
|
#include <Atomic/Resource/ResourceCache.h>
|
|
|
+#include <Atomic/Script/ScriptVector.h>
|
|
|
|
|
|
#include "JSAPI.h"
|
|
|
#include "JSVM.h"
|
|
|
@@ -47,658 +48,756 @@
|
|
|
namespace Atomic
|
|
|
{
|
|
|
|
|
|
-void js_class_get_prototype(duk_context* ctx, const char* package, const char *classname)
|
|
|
-{
|
|
|
- duk_get_global_string(ctx, package);
|
|
|
- duk_get_prop_string(ctx, -1, classname);
|
|
|
- duk_get_prop_string(ctx, -1, "prototype");
|
|
|
- duk_remove(ctx, -2); // remove class object
|
|
|
- duk_remove(ctx, -2); // remove Atomic object
|
|
|
-}
|
|
|
+ void js_class_get_prototype(duk_context* ctx, const char* package, const char *classname)
|
|
|
+ {
|
|
|
+ duk_get_global_string(ctx, package);
|
|
|
+ duk_get_prop_string(ctx, -1, classname);
|
|
|
+ duk_get_prop_string(ctx, -1, "prototype");
|
|
|
+ duk_remove(ctx, -2); // remove class object
|
|
|
+ duk_remove(ctx, -2); // remove Atomic object
|
|
|
+ }
|
|
|
|
|
|
-void js_class_get_constructor(duk_context* ctx, const char* package, const char *classname)
|
|
|
-{
|
|
|
- duk_get_global_string(ctx, package);
|
|
|
- duk_get_prop_string(ctx, -1, classname);
|
|
|
- duk_remove(ctx, -2); // remove package
|
|
|
-}
|
|
|
+ void js_class_get_constructor(duk_context* ctx, const char* package, const char *classname)
|
|
|
+ {
|
|
|
+ duk_get_global_string(ctx, package);
|
|
|
+ duk_get_prop_string(ctx, -1, classname);
|
|
|
+ duk_remove(ctx, -2); // remove package
|
|
|
+ }
|
|
|
|
|
|
-void js_constructor_basecall(duk_context* ctx, const char* package, const char* baseclass)
|
|
|
-{
|
|
|
- int top = duk_get_top(ctx);
|
|
|
- duk_get_global_string(ctx, package);
|
|
|
- duk_get_prop_string(ctx, -1, baseclass);
|
|
|
- assert(duk_is_function(ctx, -1));
|
|
|
- duk_push_this(ctx);
|
|
|
- duk_call_method(ctx, 0);
|
|
|
- duk_pop_n(ctx, 2);
|
|
|
- assert (top == duk_get_top(ctx));
|
|
|
-}
|
|
|
+ void js_constructor_basecall(duk_context* ctx, const char* package, const char* baseclass)
|
|
|
+ {
|
|
|
+ int top = duk_get_top(ctx);
|
|
|
+ duk_get_global_string(ctx, package);
|
|
|
+ duk_get_prop_string(ctx, -1, baseclass);
|
|
|
+ assert(duk_is_function(ctx, -1));
|
|
|
+ duk_push_this(ctx);
|
|
|
+ duk_call_method(ctx, 0);
|
|
|
+ duk_pop_n(ctx, 2);
|
|
|
+ assert(top == duk_get_top(ctx));
|
|
|
+ }
|
|
|
|
|
|
-void js_class_declare_internal(JSVM* vm, void* uniqueClassID, const char* package, const char* classname, duk_c_function constructor)
|
|
|
-{
|
|
|
- duk_context* ctx = vm->GetJSContext();
|
|
|
+ void js_class_declare_internal(JSVM* vm, void* uniqueClassID, const char* package, const char* classname, duk_c_function constructor)
|
|
|
+ {
|
|
|
+ duk_context* ctx = vm->GetJSContext();
|
|
|
|
|
|
- // uniqueClassID must be non-null
|
|
|
- assert(uniqueClassID);
|
|
|
+ // uniqueClassID must be non-null
|
|
|
+ assert(uniqueClassID);
|
|
|
|
|
|
- // stash a lookup from the uniqueID to the package and class name
|
|
|
+ // stash a lookup from the uniqueID to the package and class name
|
|
|
|
|
|
- duk_push_heap_stash(ctx);
|
|
|
- duk_push_pointer(ctx, uniqueClassID);
|
|
|
+ duk_push_heap_stash(ctx);
|
|
|
+ duk_push_pointer(ctx, uniqueClassID);
|
|
|
|
|
|
- duk_push_object(ctx);
|
|
|
- duk_push_string(ctx, package);
|
|
|
- duk_put_prop_index(ctx, -2, 0);
|
|
|
- duk_push_string(ctx, classname);
|
|
|
- duk_put_prop_index(ctx, -2, 1);
|
|
|
+ duk_push_object(ctx);
|
|
|
+ duk_push_string(ctx, package);
|
|
|
+ duk_put_prop_index(ctx, -2, 0);
|
|
|
+ duk_push_string(ctx, classname);
|
|
|
+ duk_put_prop_index(ctx, -2, 1);
|
|
|
|
|
|
- // store class object into uniqueClassID key
|
|
|
- duk_put_prop(ctx, -3);
|
|
|
+ // store class object into uniqueClassID key
|
|
|
+ duk_put_prop(ctx, -3);
|
|
|
|
|
|
- // pop heap stash
|
|
|
- duk_pop(ctx);
|
|
|
+ // pop heap stash
|
|
|
+ duk_pop(ctx);
|
|
|
|
|
|
- // store the constructor
|
|
|
- duk_get_global_string(ctx, package);
|
|
|
- duk_push_c_function(ctx, constructor, DUK_VARARGS);
|
|
|
- duk_put_prop_string(ctx, -2, classname);
|
|
|
- duk_pop(ctx);
|
|
|
-}
|
|
|
+ // store the constructor
|
|
|
+ duk_get_global_string(ctx, package);
|
|
|
+ duk_push_c_function(ctx, constructor, DUK_VARARGS);
|
|
|
+ duk_put_prop_string(ctx, -2, classname);
|
|
|
+ duk_pop(ctx);
|
|
|
+ }
|
|
|
|
|
|
-void js_class_push_propertyobject(JSVM* vm, const char* package, const char* classname)
|
|
|
-{
|
|
|
- duk_context* ctx = vm->GetJSContext();
|
|
|
- String pname;
|
|
|
- pname.AppendWithFormat("__%s__Properties", classname);
|
|
|
-
|
|
|
- duk_get_global_string(ctx, package);
|
|
|
- duk_push_object(ctx);
|
|
|
- duk_dup(ctx, -1);
|
|
|
- duk_put_prop_string(ctx, -3, pname.CString());
|
|
|
- duk_remove(ctx, -2); // remove Atomic object
|
|
|
-}
|
|
|
+ void js_class_push_propertyobject(JSVM* vm, const char* package, const char* classname)
|
|
|
+ {
|
|
|
+ duk_context* ctx = vm->GetJSContext();
|
|
|
+ String pname;
|
|
|
+ pname.AppendWithFormat("__%s__Properties", classname);
|
|
|
|
|
|
-void js_setup_prototype(JSVM* vm, const char* package, const char* classname, const char* basePackage, const char* basename, bool hasProperties)
|
|
|
-{
|
|
|
- duk_context* ctx = vm->GetJSContext();
|
|
|
+ duk_get_global_string(ctx, package);
|
|
|
+ duk_push_object(ctx);
|
|
|
+ duk_dup(ctx, -1);
|
|
|
+ duk_put_prop_string(ctx, -3, pname.CString());
|
|
|
+ duk_remove(ctx, -2); // remove Atomic object
|
|
|
+ }
|
|
|
|
|
|
- String pname;
|
|
|
- pname.AppendWithFormat("__%s__Properties", classname);
|
|
|
+ void js_setup_prototype(JSVM* vm, const char* package, const char* classname, const char* basePackage, const char* basename, bool hasProperties)
|
|
|
+ {
|
|
|
+ duk_context* ctx = vm->GetJSContext();
|
|
|
|
|
|
- int top = duk_get_top(ctx);
|
|
|
+ String pname;
|
|
|
+ pname.AppendWithFormat("__%s__Properties", classname);
|
|
|
|
|
|
- duk_get_global_string(ctx,package);
|
|
|
- duk_get_prop_string(ctx, -1, classname);
|
|
|
- assert(duk_is_c_function(ctx, -1));
|
|
|
+ int top = duk_get_top(ctx);
|
|
|
|
|
|
- if (!strlen(basename))
|
|
|
- {
|
|
|
- // prototype
|
|
|
- duk_push_object(ctx);
|
|
|
- duk_dup(ctx, -2); // AObject constructor function
|
|
|
- duk_put_prop_string(ctx, -2, "constructor");
|
|
|
- duk_put_prop_string(ctx, -2, "prototype");
|
|
|
+ duk_get_global_string(ctx, package);
|
|
|
+ duk_get_prop_string(ctx, -1, classname);
|
|
|
+ assert(duk_is_c_function(ctx, -1));
|
|
|
|
|
|
- duk_pop_n(ctx, 2);
|
|
|
+ if (!strlen(basename))
|
|
|
+ {
|
|
|
+ // prototype
|
|
|
+ duk_push_object(ctx);
|
|
|
+ duk_dup(ctx, -2); // AObject constructor function
|
|
|
+ duk_put_prop_string(ctx, -2, "constructor");
|
|
|
+ duk_put_prop_string(ctx, -2, "prototype");
|
|
|
|
|
|
- assert (top == duk_get_top(ctx));
|
|
|
+ duk_pop_n(ctx, 2);
|
|
|
|
|
|
- return;
|
|
|
+ assert(top == duk_get_top(ctx));
|
|
|
|
|
|
- }
|
|
|
-
|
|
|
- // prototype
|
|
|
- duk_get_global_string(ctx, "Object");
|
|
|
- duk_get_prop_string(ctx, -1, "create");
|
|
|
+ return;
|
|
|
|
|
|
- assert(duk_is_function(ctx, -1));
|
|
|
+ }
|
|
|
|
|
|
- duk_remove(ctx, -2); // remove Object
|
|
|
+ // prototype
|
|
|
+ duk_get_global_string(ctx, "Object");
|
|
|
+ duk_get_prop_string(ctx, -1, "create");
|
|
|
|
|
|
- duk_get_global_string(ctx, basePackage);
|
|
|
- duk_get_prop_string(ctx, -1, basename);
|
|
|
- assert(duk_is_function(ctx, -1));
|
|
|
- duk_get_prop_string(ctx, -1, "prototype");
|
|
|
+ assert(duk_is_function(ctx, -1));
|
|
|
|
|
|
- assert(duk_is_object(ctx, -1));
|
|
|
+ duk_remove(ctx, -2); // remove Object
|
|
|
|
|
|
- duk_remove(ctx, -2); // remove basename
|
|
|
+ duk_get_global_string(ctx, basePackage);
|
|
|
+ duk_get_prop_string(ctx, -1, basename);
|
|
|
+ assert(duk_is_function(ctx, -1));
|
|
|
+ duk_get_prop_string(ctx, -1, "prototype");
|
|
|
|
|
|
- int numargs = 1;
|
|
|
- if (hasProperties)
|
|
|
- {
|
|
|
- duk_get_global_string(ctx, package);
|
|
|
- duk_get_prop_string(ctx, -1, pname.CString());
|
|
|
assert(duk_is_object(ctx, -1));
|
|
|
- duk_remove(ctx, -2);
|
|
|
- duk_remove(ctx, -3); // remove package
|
|
|
- numargs++;
|
|
|
- }
|
|
|
- else
|
|
|
- duk_remove(ctx, -2); // remove package
|
|
|
|
|
|
- duk_call(ctx, numargs);
|
|
|
+ duk_remove(ctx, -2); // remove basename
|
|
|
|
|
|
- assert(duk_is_object(ctx, -1));
|
|
|
+ int numargs = 1;
|
|
|
+ if (hasProperties)
|
|
|
+ {
|
|
|
+ duk_get_global_string(ctx, package);
|
|
|
+ duk_get_prop_string(ctx, -1, pname.CString());
|
|
|
+ assert(duk_is_object(ctx, -1));
|
|
|
+ duk_remove(ctx, -2);
|
|
|
+ duk_remove(ctx, -3); // remove package
|
|
|
+ numargs++;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ duk_remove(ctx, -2); // remove package
|
|
|
|
|
|
- duk_dup(ctx, -2);
|
|
|
- duk_put_prop_string(ctx, -2, "constructor");
|
|
|
+ duk_call(ctx, numargs);
|
|
|
|
|
|
- //duk_dup(ctx, -1);
|
|
|
- duk_put_prop_string(ctx, -2, "prototype");
|
|
|
+ assert(duk_is_object(ctx, -1));
|
|
|
|
|
|
- // pop the classname object
|
|
|
- duk_pop(ctx);
|
|
|
+ duk_dup(ctx, -2);
|
|
|
+ duk_put_prop_string(ctx, -2, "constructor");
|
|
|
|
|
|
- // pop the Atomic Object
|
|
|
- duk_pop(ctx);
|
|
|
+ //duk_dup(ctx, -1);
|
|
|
+ duk_put_prop_string(ctx, -2, "prototype");
|
|
|
|
|
|
- assert (top == duk_get_top(ctx));
|
|
|
-}
|
|
|
+ // pop the classname object
|
|
|
+ duk_pop(ctx);
|
|
|
|
|
|
+ // pop the Atomic Object
|
|
|
+ duk_pop(ctx);
|
|
|
|
|
|
-// When subscribing to native event, this method will be called
|
|
|
-// to provide the event meta data (type and callback)
|
|
|
-static int js_push_native_event_metadata(duk_context* ctx) {
|
|
|
+ assert(top == duk_get_top(ctx));
|
|
|
+ }
|
|
|
|
|
|
- duk_push_current_function(ctx);
|
|
|
|
|
|
- duk_push_object(ctx);
|
|
|
- duk_get_prop_string(ctx, -2, "_eventType");
|
|
|
- duk_put_prop_string(ctx, -2, "_eventType");
|
|
|
- duk_dup(ctx, 0);
|
|
|
- duk_put_prop_string(ctx, -2, "_callback");
|
|
|
+ // When subscribing to native event, this method will be called
|
|
|
+ // to provide the event meta data (type and callback)
|
|
|
+ static int js_push_native_event_metadata(duk_context* ctx) {
|
|
|
|
|
|
- return 1;
|
|
|
-}
|
|
|
+ duk_push_current_function(ctx);
|
|
|
|
|
|
-void js_define_native_event(duk_context* ctx, const String& eventType, const String &eventName)
|
|
|
-{
|
|
|
- // push c function which takes 1 argument, the callback
|
|
|
- duk_push_c_function(ctx, js_push_native_event_metadata, 1);
|
|
|
+ duk_push_object(ctx);
|
|
|
+ duk_get_prop_string(ctx, -2, "_eventType");
|
|
|
+ duk_put_prop_string(ctx, -2, "_eventType");
|
|
|
+ duk_dup(ctx, 0);
|
|
|
+ duk_put_prop_string(ctx, -2, "_callback");
|
|
|
|
|
|
- // store the event type in the function object
|
|
|
- duk_push_string(ctx, eventType.CString());
|
|
|
- duk_put_prop_string(ctx, -2, "_eventType");
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
|
|
|
- // store to module object
|
|
|
- duk_put_prop_string(ctx, -2, eventName.CString());
|
|
|
+ void js_define_native_event(duk_context* ctx, const String& eventType, const String &eventName)
|
|
|
+ {
|
|
|
+ // push c function which takes 1 argument, the callback
|
|
|
+ duk_push_c_function(ctx, js_push_native_event_metadata, 1);
|
|
|
|
|
|
-}
|
|
|
+ // store the event type in the function object
|
|
|
+ duk_push_string(ctx, eventType.CString());
|
|
|
+ duk_put_prop_string(ctx, -2, "_eventType");
|
|
|
|
|
|
-void js_object_to_variantmap(duk_context* ctx, int objIdx, VariantMap &v)
|
|
|
-{
|
|
|
- v.Clear();
|
|
|
+ // store to module object
|
|
|
+ duk_put_prop_string(ctx, -2, eventName.CString());
|
|
|
|
|
|
- duk_enum(ctx, objIdx, DUK_ENUM_OWN_PROPERTIES_ONLY);
|
|
|
+ }
|
|
|
|
|
|
- while (duk_next(ctx, -1 /*enum_index*/, 1 /*get_value*/)) {
|
|
|
+ void js_object_to_variantmap(duk_context* ctx, int objIdx, VariantMap &v)
|
|
|
+ {
|
|
|
+ v.Clear();
|
|
|
|
|
|
- /* [ ... enum key ] */
|
|
|
+ duk_enum(ctx, objIdx, DUK_ENUM_OWN_PROPERTIES_ONLY);
|
|
|
|
|
|
- const char* key = duk_to_string(ctx, -2);
|
|
|
+ while (duk_next(ctx, -1 /*enum_index*/, 1 /*get_value*/)) {
|
|
|
|
|
|
- if (duk_is_number(ctx, -1)) {
|
|
|
+ /* [ ... enum key ] */
|
|
|
|
|
|
- v[key] = (float) duk_to_number(ctx, -1);
|
|
|
+ const char* key = duk_to_string(ctx, -2);
|
|
|
|
|
|
- } else if (duk_is_boolean(ctx, -1)) {
|
|
|
+ if (duk_is_number(ctx, -1)) {
|
|
|
|
|
|
- v[key] = duk_to_boolean(ctx, -1) ? true : false;
|
|
|
+ v[key] = (float)duk_to_number(ctx, -1);
|
|
|
|
|
|
- }
|
|
|
- else if (duk_is_string(ctx, -1)) {
|
|
|
+ }
|
|
|
+ else if (duk_is_boolean(ctx, -1)) {
|
|
|
|
|
|
- v[key] = duk_to_string(ctx, -1);
|
|
|
+ v[key] = duk_to_boolean(ctx, -1) ? true : false;
|
|
|
|
|
|
- } else if (duk_get_heapptr(ctx, -1)) {
|
|
|
+ }
|
|
|
+ else if (duk_is_string(ctx, -1)) {
|
|
|
|
|
|
- v[key] = js_to_class_instance<Object>(ctx, -1, 0);
|
|
|
+ v[key] = duk_to_string(ctx, -1);
|
|
|
|
|
|
- }
|
|
|
+ }
|
|
|
+ else if (duk_get_heapptr(ctx, -1)) {
|
|
|
|
|
|
- duk_pop_2(ctx); /* pop_key & value*/
|
|
|
- }
|
|
|
+ v[key] = js_to_class_instance<Object>(ctx, -1, 0);
|
|
|
|
|
|
- duk_pop(ctx); /* pop enum object */
|
|
|
+ }
|
|
|
|
|
|
-}
|
|
|
+ duk_pop_2(ctx); /* pop_key & value*/
|
|
|
+ }
|
|
|
|
|
|
-duk_bool_t js_check_is_buffer_and_get_data(duk_context* ctx, duk_idx_t idx, void** data, duk_size_t* size)
|
|
|
-{
|
|
|
- void* temp;
|
|
|
- if (duk_is_buffer(ctx, idx))
|
|
|
+ duk_pop(ctx); /* pop enum object */
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ duk_bool_t js_check_is_buffer_and_get_data(duk_context* ctx, duk_idx_t idx, void** data, duk_size_t* size)
|
|
|
{
|
|
|
- temp = duk_get_buffer_data(ctx, idx, size);
|
|
|
- if (data)
|
|
|
+ void* temp;
|
|
|
+ if (duk_is_buffer(ctx, idx))
|
|
|
{
|
|
|
- *data = temp;
|
|
|
+ temp = duk_get_buffer_data(ctx, idx, size);
|
|
|
+ if (data)
|
|
|
+ {
|
|
|
+ *data = temp;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
}
|
|
|
- return true;
|
|
|
- }
|
|
|
- if (!(duk_is_object(ctx, idx) &&
|
|
|
- duk_has_prop_string(ctx, idx, "length") &&
|
|
|
- duk_has_prop_string(ctx, idx, "byteLength") &&
|
|
|
- duk_has_prop_string(ctx, idx, "byteOffset") &&
|
|
|
- duk_has_prop_string(ctx, idx, "BYTES_PER_ELEMENT")))
|
|
|
- {
|
|
|
- if (data)
|
|
|
+ if (!(duk_is_object(ctx, idx) &&
|
|
|
+ duk_has_prop_string(ctx, idx, "length") &&
|
|
|
+ duk_has_prop_string(ctx, idx, "byteLength") &&
|
|
|
+ duk_has_prop_string(ctx, idx, "byteOffset") &&
|
|
|
+ duk_has_prop_string(ctx, idx, "BYTES_PER_ELEMENT")))
|
|
|
{
|
|
|
- *data = nullptr;
|
|
|
+ if (data)
|
|
|
+ {
|
|
|
+ *data = nullptr;
|
|
|
+ }
|
|
|
+ if (size)
|
|
|
+ {
|
|
|
+ *size = 0;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
}
|
|
|
- if (size)
|
|
|
+ temp = duk_require_buffer_data(ctx, idx, size);
|
|
|
+ if (data)
|
|
|
{
|
|
|
- *size = 0;
|
|
|
+ *data = temp;
|
|
|
}
|
|
|
- return false;
|
|
|
+ return true;
|
|
|
}
|
|
|
- temp = duk_require_buffer_data(ctx, idx, size);
|
|
|
- if (data)
|
|
|
+
|
|
|
+ void js_push_default_variant(duk_context* ctx, VariantType variantType, Variant& value)
|
|
|
{
|
|
|
- *data = temp;
|
|
|
- }
|
|
|
- return true;
|
|
|
-}
|
|
|
+ value = Variant::EMPTY;
|
|
|
+
|
|
|
+ switch (variantType)
|
|
|
+ {
|
|
|
|
|
|
-void js_to_variant(duk_context* ctx, int variantIdx, Variant &v, VariantType variantType)
|
|
|
-{
|
|
|
- v.Clear();
|
|
|
+ case VAR_NONE:
|
|
|
+ break;
|
|
|
|
|
|
- // convert to abs index
|
|
|
- if (variantIdx < 0)
|
|
|
- variantIdx = duk_get_top(ctx) + variantIdx;
|
|
|
+ case VAR_INT:
|
|
|
+ value = 0;
|
|
|
+ break;
|
|
|
|
|
|
- if (duk_is_boolean(ctx, variantIdx))
|
|
|
- {
|
|
|
- v = duk_to_boolean(ctx, variantIdx) ? true : false;
|
|
|
- return;
|
|
|
- }
|
|
|
+ case VAR_BOOL:
|
|
|
+ value = false;
|
|
|
+ break;
|
|
|
|
|
|
- if (duk_is_string(ctx, variantIdx))
|
|
|
- {
|
|
|
- v = duk_to_string(ctx, variantIdx);
|
|
|
- return;
|
|
|
- }
|
|
|
+ case VAR_FLOAT:
|
|
|
+ value = 0.0f;
|
|
|
+ break;
|
|
|
|
|
|
- if (duk_is_number(ctx, variantIdx))
|
|
|
- {
|
|
|
- v = (float) duk_to_number(ctx, variantIdx);
|
|
|
- return;
|
|
|
- }
|
|
|
+ case VAR_VECTOR2:
|
|
|
+ value = Vector2::ZERO;
|
|
|
+ break;
|
|
|
|
|
|
- if (duk_is_pointer(ctx, variantIdx))
|
|
|
- {
|
|
|
- v = (RefCounted*) duk_get_pointer(ctx, variantIdx);
|
|
|
- return;
|
|
|
+ case VAR_VECTOR3:
|
|
|
+ value = Vector3::ZERO;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case VAR_VECTOR4:
|
|
|
+ value = Vector4::ZERO;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case VAR_QUATERNION:
|
|
|
+ value = Quaternion::IDENTITY;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case VAR_COLOR:
|
|
|
+ value = Color::WHITE;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case VAR_STRING:
|
|
|
+ value = "";
|
|
|
+ break;
|
|
|
+
|
|
|
+ case VAR_INTRECT:
|
|
|
+ value = IntRect::ZERO;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case VAR_INTVECTOR2:
|
|
|
+ value = IntVector2::ZERO;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case VAR_DOUBLE:
|
|
|
+ // set float here too, so standard edits work
|
|
|
+ value = 0.0f;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ js_push_variant(ctx, value);
|
|
|
}
|
|
|
|
|
|
- if (duk_is_array(ctx, variantIdx))
|
|
|
+ void js_to_variant(duk_context* ctx, int variantIdx, Variant &v, VariantType variantType)
|
|
|
{
|
|
|
- if (duk_get_length(ctx, variantIdx) == 2)
|
|
|
+ v.Clear();
|
|
|
+
|
|
|
+ // convert to abs index
|
|
|
+ if (variantIdx < 0)
|
|
|
+ variantIdx = duk_get_top(ctx) + variantIdx;
|
|
|
+
|
|
|
+ if (duk_is_boolean(ctx, variantIdx))
|
|
|
{
|
|
|
- Vector2 v2;
|
|
|
- duk_get_prop_index(ctx, variantIdx, 0);
|
|
|
- v2.x_ = duk_to_number(ctx, -1);
|
|
|
- duk_get_prop_index(ctx, variantIdx, 1);
|
|
|
- v2.y_ = duk_to_number(ctx, -1);
|
|
|
- duk_pop_n(ctx, 2);
|
|
|
- v = v2;
|
|
|
+ v = duk_to_boolean(ctx, variantIdx) ? true : false;
|
|
|
return;
|
|
|
}
|
|
|
- else if (duk_get_length(ctx, variantIdx) == 3)
|
|
|
+
|
|
|
+ if (duk_is_string(ctx, variantIdx))
|
|
|
{
|
|
|
- Vector3 v3;
|
|
|
- duk_get_prop_index(ctx, variantIdx, 0);
|
|
|
- v3.x_ = duk_to_number(ctx, -1);
|
|
|
- duk_get_prop_index(ctx, variantIdx, 1);
|
|
|
- v3.y_ = duk_to_number(ctx, -1);
|
|
|
- duk_get_prop_index(ctx, variantIdx, 2);
|
|
|
- v3.z_ = duk_to_number(ctx, -1);
|
|
|
- duk_pop_n(ctx, 3);
|
|
|
- v = v3;
|
|
|
+ v = duk_to_string(ctx, variantIdx);
|
|
|
return;
|
|
|
}
|
|
|
- else if (duk_get_length(ctx, variantIdx) == 4)
|
|
|
+
|
|
|
+ if (duk_is_number(ctx, variantIdx))
|
|
|
{
|
|
|
- Vector4 v4;
|
|
|
- duk_get_prop_index(ctx, variantIdx, 0);
|
|
|
- v4.x_ = duk_to_number(ctx, -1);
|
|
|
- duk_get_prop_index(ctx, variantIdx, 1);
|
|
|
- v4.y_ = duk_to_number(ctx, -1);
|
|
|
- duk_get_prop_index(ctx, variantIdx, 2);
|
|
|
- v4.z_ = duk_to_number(ctx, -1);
|
|
|
- duk_get_prop_index(ctx, variantIdx, 3);
|
|
|
- v4.w_ = duk_to_number(ctx, -1);
|
|
|
- duk_pop_n(ctx, 4);
|
|
|
- v = v4;
|
|
|
+ v = (float)duk_to_number(ctx, variantIdx);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ if (duk_is_pointer(ctx, variantIdx))
|
|
|
+ {
|
|
|
+ v = (RefCounted*)duk_get_pointer(ctx, variantIdx);
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- {
|
|
|
- void* bufferData;
|
|
|
- duk_size_t bufferSize;
|
|
|
- if (js_check_is_buffer_and_get_data(ctx, variantIdx, &bufferData, &bufferSize))
|
|
|
+ if (duk_is_array(ctx, variantIdx))
|
|
|
{
|
|
|
- // copy the buffer into the variant
|
|
|
- v.SetBuffer(bufferData, (unsigned)bufferSize);
|
|
|
+ if (duk_get_length(ctx, variantIdx) == 2)
|
|
|
+ {
|
|
|
+ Vector2 v2;
|
|
|
+ duk_get_prop_index(ctx, variantIdx, 0);
|
|
|
+ v2.x_ = duk_to_number(ctx, -1);
|
|
|
+ duk_get_prop_index(ctx, variantIdx, 1);
|
|
|
+ v2.y_ = duk_to_number(ctx, -1);
|
|
|
+ duk_pop_n(ctx, 2);
|
|
|
+ v = v2;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ else if (duk_get_length(ctx, variantIdx) == 3)
|
|
|
+ {
|
|
|
+ Vector3 v3;
|
|
|
+ duk_get_prop_index(ctx, variantIdx, 0);
|
|
|
+ v3.x_ = duk_to_number(ctx, -1);
|
|
|
+ duk_get_prop_index(ctx, variantIdx, 1);
|
|
|
+ v3.y_ = duk_to_number(ctx, -1);
|
|
|
+ duk_get_prop_index(ctx, variantIdx, 2);
|
|
|
+ v3.z_ = duk_to_number(ctx, -1);
|
|
|
+ duk_pop_n(ctx, 3);
|
|
|
+ v = v3;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ else if (duk_get_length(ctx, variantIdx) == 4)
|
|
|
+ {
|
|
|
+ Vector4 v4;
|
|
|
+ duk_get_prop_index(ctx, variantIdx, 0);
|
|
|
+ v4.x_ = duk_to_number(ctx, -1);
|
|
|
+ duk_get_prop_index(ctx, variantIdx, 1);
|
|
|
+ v4.y_ = duk_to_number(ctx, -1);
|
|
|
+ duk_get_prop_index(ctx, variantIdx, 2);
|
|
|
+ v4.z_ = duk_to_number(ctx, -1);
|
|
|
+ duk_get_prop_index(ctx, variantIdx, 3);
|
|
|
+ v4.w_ = duk_to_number(ctx, -1);
|
|
|
+ duk_pop_n(ctx, 4);
|
|
|
+ v = v4;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
return;
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- // object check after array and buffer object check
|
|
|
- if (duk_is_object(ctx, variantIdx))
|
|
|
- {
|
|
|
- if (variantType == VAR_RESOURCEREFLIST)
|
|
|
{
|
|
|
- ResourceRefList refList;
|
|
|
+ void* bufferData;
|
|
|
+ duk_size_t bufferSize;
|
|
|
+ if (js_check_is_buffer_and_get_data(ctx, variantIdx, &bufferData, &bufferSize))
|
|
|
+ {
|
|
|
+ // copy the buffer into the variant
|
|
|
+ v.SetBuffer(bufferData, (unsigned)bufferSize);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- duk_get_prop_string(ctx, variantIdx, "typeName");
|
|
|
- refList.type_ = duk_to_string(ctx, -1);
|
|
|
+ // object check after array and buffer object check
|
|
|
+ if (duk_is_object(ctx, variantIdx))
|
|
|
+ {
|
|
|
+ if (variantType == VAR_RESOURCEREFLIST)
|
|
|
+ {
|
|
|
+ ResourceRefList refList;
|
|
|
|
|
|
- duk_get_prop_string(ctx, variantIdx, "resources");
|
|
|
- int length = duk_get_length(ctx, -1);
|
|
|
+ duk_get_prop_string(ctx, variantIdx, "typeName");
|
|
|
+ refList.type_ = duk_to_string(ctx, -1);
|
|
|
|
|
|
- for (int i = 0; i < length; i++) {
|
|
|
+ duk_get_prop_string(ctx, variantIdx, "resources");
|
|
|
+ int length = duk_get_length(ctx, -1);
|
|
|
|
|
|
- duk_get_prop_index(ctx, -1, i);
|
|
|
+ for (int i = 0; i < length; i++) {
|
|
|
|
|
|
- Resource* resource = NULL;
|
|
|
+ duk_get_prop_index(ctx, -1, i);
|
|
|
|
|
|
- if (duk_is_object(ctx, -1))
|
|
|
- {
|
|
|
- resource = js_to_class_instance<Resource>(ctx, -1, 0);
|
|
|
+ Resource* resource = NULL;
|
|
|
|
|
|
- }
|
|
|
+ if (duk_is_object(ctx, -1))
|
|
|
+ {
|
|
|
+ resource = js_to_class_instance<Resource>(ctx, -1, 0);
|
|
|
|
|
|
- if (resource) {
|
|
|
- refList.names_.Push(resource->GetName());
|
|
|
+ }
|
|
|
+
|
|
|
+ if (resource) {
|
|
|
+ refList.names_.Push(resource->GetName());
|
|
|
+ }
|
|
|
+ else
|
|
|
+ refList.names_.Push(String::EMPTY);
|
|
|
+
|
|
|
+ duk_pop(ctx);
|
|
|
}
|
|
|
- else
|
|
|
- refList.names_.Push(String::EMPTY);
|
|
|
|
|
|
- duk_pop(ctx);
|
|
|
- }
|
|
|
+ duk_pop_n(ctx, 2);
|
|
|
|
|
|
- duk_pop_n(ctx, 2);
|
|
|
+ v = refList;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ RefCounted* o = js_to_class_instance<RefCounted>(ctx, variantIdx, 0);
|
|
|
+ if (o)
|
|
|
+ v = o;
|
|
|
+ }
|
|
|
|
|
|
- v = refList;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- RefCounted* o = js_to_class_instance<RefCounted>(ctx, variantIdx, 0);
|
|
|
- if (o)
|
|
|
- v = o;
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
- return;
|
|
|
- }
|
|
|
|
|
|
+ }
|
|
|
|
|
|
-}
|
|
|
+ // variant map Proxy getter, so we can convert access to string based
|
|
|
+ // member lookup, to string hash on the fly
|
|
|
|
|
|
-// variant map Proxy getter, so we can convert access to string based
|
|
|
-// member lookup, to string hash on the fly
|
|
|
+ static int variantmap_property_get(duk_context* ctx)
|
|
|
+ {
|
|
|
+ // targ, key, recv
|
|
|
|
|
|
-static int variantmap_property_get(duk_context* ctx)
|
|
|
-{
|
|
|
- // targ, key, recv
|
|
|
+ if (duk_is_string(ctx, 1))
|
|
|
+ {
|
|
|
+ StringHash key = duk_to_string(ctx, 1);
|
|
|
+ duk_get_prop_index(ctx, 0, (unsigned)key.Value());
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
|
|
|
- if (duk_is_string(ctx, 1))
|
|
|
- {
|
|
|
- StringHash key = duk_to_string(ctx, 1);
|
|
|
- duk_get_prop_index(ctx, 0, (unsigned) key.Value());
|
|
|
+ duk_push_undefined(ctx);
|
|
|
return 1;
|
|
|
+
|
|
|
}
|
|
|
|
|
|
- duk_push_undefined(ctx);
|
|
|
- return 1;
|
|
|
+ // removes all keys from the variant map proxy target, REGARDLESS of key given for delete
|
|
|
+ // see (lengthy) note in JSEventDispatcher::EndSendEvent
|
|
|
+ static int variantmap_property_deleteproperty(duk_context* ctx)
|
|
|
+ {
|
|
|
+ // deleteProperty: function (targ, key)
|
|
|
|
|
|
-}
|
|
|
+ duk_enum(ctx, 0, DUK_ENUM_OWN_PROPERTIES_ONLY);
|
|
|
|
|
|
-// removes all keys from the variant map proxy target, REGARDLESS of key given for delete
|
|
|
-// see (lengthy) note in JSEventDispatcher::EndSendEvent
|
|
|
-static int variantmap_property_deleteproperty(duk_context* ctx)
|
|
|
-{
|
|
|
- // deleteProperty: function (targ, key)
|
|
|
+ while (duk_next(ctx, -1, 0)) {
|
|
|
+ duk_del_prop(ctx, 0);
|
|
|
+ }
|
|
|
|
|
|
- duk_enum(ctx, 0, DUK_ENUM_OWN_PROPERTIES_ONLY);
|
|
|
+ duk_push_boolean(ctx, 1);
|
|
|
+ return 1;
|
|
|
|
|
|
- while (duk_next(ctx, -1, 0)) {
|
|
|
- duk_del_prop(ctx, 0);
|
|
|
}
|
|
|
|
|
|
- duk_push_boolean(ctx, 1);
|
|
|
- return 1;
|
|
|
|
|
|
-}
|
|
|
+ void js_push_variantmap(duk_context* ctx, const VariantMap &vmap)
|
|
|
+ {
|
|
|
|
|
|
+ // setup proxy so we can map string
|
|
|
+ duk_get_global_string(ctx, "Proxy");
|
|
|
|
|
|
-void js_push_variantmap(duk_context* ctx, const VariantMap &vmap)
|
|
|
-{
|
|
|
+ duk_push_object(ctx);
|
|
|
|
|
|
- // setup proxy so we can map string
|
|
|
- duk_get_global_string(ctx, "Proxy");
|
|
|
+ VariantMap::ConstIterator itr = vmap.Begin();
|
|
|
|
|
|
- duk_push_object(ctx);
|
|
|
+ while (itr != vmap.End()) {
|
|
|
|
|
|
- VariantMap::ConstIterator itr = vmap.Begin();
|
|
|
+ js_push_variant(ctx, itr->second_);
|
|
|
|
|
|
- while (itr != vmap.End()) {
|
|
|
|
|
|
- js_push_variant(ctx, itr->second_);
|
|
|
+ if (duk_is_undefined(ctx, -1)) {
|
|
|
|
|
|
+ duk_pop(ctx);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ duk_put_prop_index(ctx, -2, (unsigned)itr->first_.Value());
|
|
|
+ }
|
|
|
|
|
|
- if (duk_is_undefined(ctx, -1)) {
|
|
|
+ itr++;
|
|
|
|
|
|
- duk_pop(ctx);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- duk_put_prop_index(ctx, -2, (unsigned) itr->first_.Value());
|
|
|
}
|
|
|
|
|
|
- itr++;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- // setup property handler
|
|
|
- duk_push_object(ctx);
|
|
|
- duk_push_c_function(ctx, variantmap_property_get, 3);
|
|
|
- duk_put_prop_string(ctx, -2, "get");
|
|
|
- duk_push_c_function(ctx, variantmap_property_deleteproperty, 2);
|
|
|
- duk_put_prop_string(ctx, -2, "deleteProperty");
|
|
|
-
|
|
|
- duk_new(ctx, 2);
|
|
|
+ // setup property handler
|
|
|
+ duk_push_object(ctx);
|
|
|
+ duk_push_c_function(ctx, variantmap_property_get, 3);
|
|
|
+ duk_put_prop_string(ctx, -2, "get");
|
|
|
+ duk_push_c_function(ctx, variantmap_property_deleteproperty, 2);
|
|
|
+ duk_put_prop_string(ctx, -2, "deleteProperty");
|
|
|
|
|
|
+ duk_new(ctx, 2);
|
|
|
|
|
|
-}
|
|
|
|
|
|
-void js_push_variant(duk_context *ctx, const Variant& v)
|
|
|
-{
|
|
|
- switch (v.GetType())
|
|
|
- {
|
|
|
- case VAR_NONE:
|
|
|
- duk_push_undefined(ctx);
|
|
|
- break;
|
|
|
-
|
|
|
- case VAR_VOIDPTR:
|
|
|
- duk_push_null(ctx);
|
|
|
- break;
|
|
|
+ }
|
|
|
|
|
|
- case VAR_PTR:
|
|
|
+ void js_push_variant(duk_context *ctx, const Variant& v, int arrayIndex)
|
|
|
{
|
|
|
- RefCounted* ref = v.GetPtr();
|
|
|
-
|
|
|
- // if we're null or don't have any refs, return null
|
|
|
- if (!ref || !ref->Refs())
|
|
|
+ switch (v.GetType())
|
|
|
{
|
|
|
- duk_push_null(ctx);
|
|
|
+ case VAR_NONE:
|
|
|
+ duk_push_undefined(ctx);
|
|
|
break;
|
|
|
- }
|
|
|
|
|
|
- // check that class is supported
|
|
|
- duk_push_heap_stash(ctx);
|
|
|
- duk_push_pointer(ctx, (void*)ref->GetClassID());
|
|
|
- duk_get_prop(ctx, -2);
|
|
|
+ case VAR_VOIDPTR:
|
|
|
+ duk_push_null(ctx);
|
|
|
+ break;
|
|
|
|
|
|
- if (!duk_is_object(ctx, -1))
|
|
|
+ case VAR_PTR:
|
|
|
{
|
|
|
- duk_pop_2(ctx);
|
|
|
- duk_push_undefined(ctx);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- duk_pop_2(ctx);
|
|
|
- js_push_class_object_instance(ctx, ref);
|
|
|
- }
|
|
|
+ RefCounted* ref = v.GetPtr();
|
|
|
|
|
|
- } break;
|
|
|
+ // if we're null or don't have any refs, return null
|
|
|
+ if (!ref || !ref->Refs())
|
|
|
+ {
|
|
|
+ duk_push_null(ctx);
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- case VAR_RESOURCEREF:
|
|
|
- {
|
|
|
- const ResourceRef& resourceRef(v.GetResourceRef());
|
|
|
- ResourceCache* cache = JSVM::GetJSVM(ctx)->GetContext()->GetSubsystem<ResourceCache>();
|
|
|
- Resource* resource = cache->GetResource(resourceRef.type_, resourceRef.name_);
|
|
|
- js_push_class_object_instance(ctx, resource);
|
|
|
- } break;
|
|
|
+ // check that class is supported
|
|
|
+ duk_push_heap_stash(ctx);
|
|
|
+ duk_push_pointer(ctx, (void*)ref->GetClassID());
|
|
|
+ duk_get_prop(ctx, -2);
|
|
|
|
|
|
- case VAR_RESOURCEREFLIST:
|
|
|
- {
|
|
|
+ if (!duk_is_object(ctx, -1))
|
|
|
+ {
|
|
|
+ duk_pop_2(ctx);
|
|
|
+ duk_push_undefined(ctx);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ duk_pop_2(ctx);
|
|
|
+ js_push_class_object_instance(ctx, ref);
|
|
|
+ }
|
|
|
|
|
|
- const ResourceRefList& resourceRefList(v.GetResourceRefList());
|
|
|
- const Context* context = JSVM::GetJSVM(ctx)->GetContext();
|
|
|
+ } break;
|
|
|
|
|
|
- duk_push_object(ctx);
|
|
|
- duk_push_string(ctx, context->GetTypeName(resourceRefList.type_).CString());
|
|
|
- duk_put_prop_string(ctx, -2, "typeName");
|
|
|
+ case VAR_RESOURCEREF:
|
|
|
+ {
|
|
|
+ const ResourceRef& resourceRef(v.GetResourceRef());
|
|
|
+ ResourceCache* cache = JSVM::GetJSVM(ctx)->GetContext()->GetSubsystem<ResourceCache>();
|
|
|
+ Resource* resource = cache->GetResource(resourceRef.type_, resourceRef.name_);
|
|
|
+ js_push_class_object_instance(ctx, resource);
|
|
|
+ } break;
|
|
|
|
|
|
- duk_push_array(ctx);
|
|
|
+ case VAR_RESOURCEREFLIST:
|
|
|
+ {
|
|
|
|
|
|
- ResourceCache* cache = context->GetSubsystem<ResourceCache>();
|
|
|
+ const ResourceRefList& resourceRefList(v.GetResourceRefList());
|
|
|
+ const Context* context = JSVM::GetJSVM(ctx)->GetContext();
|
|
|
|
|
|
- for (unsigned i = 0; i < resourceRefList.names_.Size(); i++) {
|
|
|
+ duk_push_object(ctx);
|
|
|
+ duk_push_string(ctx, context->GetTypeName(resourceRefList.type_).CString());
|
|
|
+ duk_put_prop_string(ctx, -2, "typeName");
|
|
|
|
|
|
- Resource* resource = cache->GetResource(resourceRefList.type_, resourceRefList.names_[i]);
|
|
|
- js_push_class_object_instance(ctx, resource);
|
|
|
- duk_put_prop_index(ctx, -2, i);
|
|
|
- }
|
|
|
+ duk_push_array(ctx);
|
|
|
|
|
|
- duk_put_prop_string(ctx, -2, "resources");
|
|
|
+ ResourceCache* cache = context->GetSubsystem<ResourceCache>();
|
|
|
|
|
|
- } break;
|
|
|
+ for (unsigned i = 0; i < resourceRefList.names_.Size(); i++) {
|
|
|
|
|
|
- case VAR_BOOL:
|
|
|
- duk_push_boolean(ctx, v.GetBool() ? 1 : 0);
|
|
|
- break;
|
|
|
+ Resource* resource = cache->GetResource(resourceRefList.type_, resourceRefList.names_[i]);
|
|
|
+ js_push_class_object_instance(ctx, resource);
|
|
|
+ duk_put_prop_index(ctx, -2, i);
|
|
|
+ }
|
|
|
|
|
|
- case VAR_INT:
|
|
|
- duk_push_number(ctx, v.GetInt());
|
|
|
- break;
|
|
|
+ duk_put_prop_string(ctx, -2, "resources");
|
|
|
|
|
|
- case VAR_FLOAT:
|
|
|
- duk_push_number(ctx, v.GetFloat());
|
|
|
- break;
|
|
|
+ } break;
|
|
|
|
|
|
- case VAR_STRING:
|
|
|
- {
|
|
|
- const String& string(v.GetString());
|
|
|
- duk_push_lstring(ctx, string.CString(), string.Length());
|
|
|
- } break;
|
|
|
+ case VAR_BOOL:
|
|
|
+ duk_push_boolean(ctx, v.GetBool() ? 1 : 0);
|
|
|
+ break;
|
|
|
|
|
|
- case VAR_BUFFER:
|
|
|
- {
|
|
|
- const PODVector<unsigned char>& buffer(v.GetBuffer()); // The braces are to scope this reference.
|
|
|
- duk_push_fixed_buffer(ctx, buffer.Size());
|
|
|
- duk_push_buffer_object(ctx, -1, 0, buffer.Size(), DUK_BUFOBJ_UINT8ARRAY);
|
|
|
- duk_replace(ctx, -2);
|
|
|
- unsigned char* data = (unsigned char*)duk_require_buffer_data(ctx, -1, (duk_size_t*)nullptr);
|
|
|
- memcpy(data, buffer.Buffer(), buffer.Size());
|
|
|
- } break;
|
|
|
-
|
|
|
- case VAR_VECTOR2:
|
|
|
- {
|
|
|
- const Vector2& vector2(v.GetVector2());
|
|
|
- duk_push_array(ctx);
|
|
|
- duk_push_number(ctx, vector2.x_);
|
|
|
- duk_put_prop_index(ctx, -2, 0);
|
|
|
- duk_push_number(ctx, vector2.y_);
|
|
|
- duk_put_prop_index(ctx, -2, 1);
|
|
|
- } break;
|
|
|
+ case VAR_INT:
|
|
|
+ duk_push_number(ctx, v.GetInt());
|
|
|
+ break;
|
|
|
|
|
|
- case VAR_INTVECTOR2:
|
|
|
- {
|
|
|
- const IntVector2& intVector2(v.GetIntVector2());
|
|
|
- duk_push_array(ctx);
|
|
|
- duk_push_number(ctx, intVector2.x_);
|
|
|
- duk_put_prop_index(ctx, -2, 0);
|
|
|
- duk_push_number(ctx, intVector2.y_);
|
|
|
- duk_put_prop_index(ctx, -2, 1);
|
|
|
- } break;
|
|
|
+ case VAR_FLOAT:
|
|
|
+ duk_push_number(ctx, v.GetFloat());
|
|
|
+ break;
|
|
|
|
|
|
- case VAR_VECTOR3:
|
|
|
- {
|
|
|
- const Vector3& vector3(v.GetVector3());
|
|
|
- duk_push_array(ctx);
|
|
|
- duk_push_number(ctx, vector3.x_);
|
|
|
- duk_put_prop_index(ctx, -2, 0);
|
|
|
- duk_push_number(ctx, vector3.y_);
|
|
|
- duk_put_prop_index(ctx, -2, 1);
|
|
|
- duk_push_number(ctx, vector3.z_);
|
|
|
- duk_put_prop_index(ctx, -2, 2);
|
|
|
- } break;
|
|
|
+ case VAR_DOUBLE:
|
|
|
+ duk_push_number(ctx, v.GetFloat());
|
|
|
+ break;
|
|
|
|
|
|
- case VAR_QUATERNION:
|
|
|
- {
|
|
|
- const Vector3& vector3(v.GetQuaternion().EulerAngles());
|
|
|
- duk_push_array(ctx);
|
|
|
- duk_push_number(ctx, vector3.x_);
|
|
|
- duk_put_prop_index(ctx, -2, 0);
|
|
|
- duk_push_number(ctx, vector3.y_);
|
|
|
- duk_put_prop_index(ctx, -2, 1);
|
|
|
- duk_push_number(ctx, vector3.z_);
|
|
|
- duk_put_prop_index(ctx, -2, 2);
|
|
|
- } break;
|
|
|
+ case VAR_STRING:
|
|
|
+ {
|
|
|
+ const String& string(v.GetString());
|
|
|
+ duk_push_lstring(ctx, string.CString(), string.Length());
|
|
|
+ } break;
|
|
|
|
|
|
- case VAR_COLOR:
|
|
|
- {
|
|
|
- const Color& color(v.GetColor());
|
|
|
- duk_push_array(ctx);
|
|
|
- duk_push_number(ctx, color.r_);
|
|
|
- duk_put_prop_index(ctx, -2, 0);
|
|
|
- duk_push_number(ctx, color.g_);
|
|
|
- duk_put_prop_index(ctx, -2, 1);
|
|
|
- duk_push_number(ctx, color.b_);
|
|
|
- duk_put_prop_index(ctx, -2, 2);
|
|
|
- duk_push_number(ctx, color.a_);
|
|
|
- duk_put_prop_index(ctx, -2, 3);
|
|
|
- } break;
|
|
|
+ case VAR_BUFFER:
|
|
|
+ {
|
|
|
+ const PODVector<unsigned char>& buffer(v.GetBuffer()); // The braces are to scope this reference.
|
|
|
+ duk_push_fixed_buffer(ctx, buffer.Size());
|
|
|
+ duk_push_buffer_object(ctx, -1, 0, buffer.Size(), DUK_BUFOBJ_UINT8ARRAY);
|
|
|
+ duk_replace(ctx, -2);
|
|
|
+ unsigned char* data = (unsigned char*)duk_require_buffer_data(ctx, -1, (duk_size_t*)nullptr);
|
|
|
+ memcpy(data, buffer.Buffer(), buffer.Size());
|
|
|
+ } break;
|
|
|
+
|
|
|
+ case VAR_VECTOR2:
|
|
|
+ {
|
|
|
+ const Vector2& vector2(v.GetVector2());
|
|
|
+ duk_push_array(ctx);
|
|
|
+ duk_push_number(ctx, vector2.x_);
|
|
|
+ duk_put_prop_index(ctx, -2, 0);
|
|
|
+ duk_push_number(ctx, vector2.y_);
|
|
|
+ duk_put_prop_index(ctx, -2, 1);
|
|
|
+ } break;
|
|
|
+
|
|
|
+ case VAR_INTVECTOR2:
|
|
|
+ {
|
|
|
+ const IntVector2& intVector2(v.GetIntVector2());
|
|
|
+ duk_push_array(ctx);
|
|
|
+ duk_push_number(ctx, intVector2.x_);
|
|
|
+ duk_put_prop_index(ctx, -2, 0);
|
|
|
+ duk_push_number(ctx, intVector2.y_);
|
|
|
+ duk_put_prop_index(ctx, -2, 1);
|
|
|
+ } break;
|
|
|
+
|
|
|
+ case VAR_VECTOR3:
|
|
|
+ {
|
|
|
+ const Vector3& vector3(v.GetVector3());
|
|
|
+ duk_push_array(ctx);
|
|
|
+ duk_push_number(ctx, vector3.x_);
|
|
|
+ duk_put_prop_index(ctx, -2, 0);
|
|
|
+ duk_push_number(ctx, vector3.y_);
|
|
|
+ duk_put_prop_index(ctx, -2, 1);
|
|
|
+ duk_push_number(ctx, vector3.z_);
|
|
|
+ duk_put_prop_index(ctx, -2, 2);
|
|
|
+ } break;
|
|
|
+
|
|
|
+ case VAR_QUATERNION:
|
|
|
+ {
|
|
|
+ const Vector3& vector3(v.GetQuaternion().EulerAngles());
|
|
|
+ duk_push_array(ctx);
|
|
|
+ duk_push_number(ctx, vector3.x_);
|
|
|
+ duk_put_prop_index(ctx, -2, 0);
|
|
|
+ duk_push_number(ctx, vector3.y_);
|
|
|
+ duk_put_prop_index(ctx, -2, 1);
|
|
|
+ duk_push_number(ctx, vector3.z_);
|
|
|
+ duk_put_prop_index(ctx, -2, 2);
|
|
|
+ } break;
|
|
|
+
|
|
|
+ case VAR_COLOR:
|
|
|
+ {
|
|
|
+ const Color& color(v.GetColor());
|
|
|
+ duk_push_array(ctx);
|
|
|
+ duk_push_number(ctx, color.r_);
|
|
|
+ duk_put_prop_index(ctx, -2, 0);
|
|
|
+ duk_push_number(ctx, color.g_);
|
|
|
+ duk_put_prop_index(ctx, -2, 1);
|
|
|
+ duk_push_number(ctx, color.b_);
|
|
|
+ duk_put_prop_index(ctx, -2, 2);
|
|
|
+ duk_push_number(ctx, color.a_);
|
|
|
+ duk_put_prop_index(ctx, -2, 3);
|
|
|
+ } break;
|
|
|
+
|
|
|
+ case VAR_VECTOR4:
|
|
|
+ {
|
|
|
+ const Vector4& vector4(v.GetVector4());
|
|
|
+ duk_push_array(ctx);
|
|
|
+ duk_push_number(ctx, vector4.x_);
|
|
|
+ duk_put_prop_index(ctx, -2, 0);
|
|
|
+ duk_push_number(ctx, vector4.y_);
|
|
|
+ duk_put_prop_index(ctx, -2, 1);
|
|
|
+ duk_push_number(ctx, vector4.z_);
|
|
|
+ duk_put_prop_index(ctx, -2, 2);
|
|
|
+ duk_push_number(ctx, vector4.w_);
|
|
|
+ duk_put_prop_index(ctx, -2, 3);
|
|
|
+ } break;
|
|
|
+
|
|
|
+ case VAR_VARIANTVECTOR:
|
|
|
+ {
|
|
|
+ const VariantVector& vector(v.GetVariantVector());
|
|
|
+
|
|
|
+ // if we don't specify an array index, wrap and push the vector (EXPENSIVE!)
|
|
|
+ if (arrayIndex == -1)
|
|
|
+ {
|
|
|
+ SharedPtr<ScriptVector> scriptVector(new ScriptVector());
|
|
|
+ scriptVector->AdaptFromVector(vector);
|
|
|
+ js_push_class_object_instance(ctx, scriptVector);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (arrayIndex < 0 || arrayIndex >= vector.Size())
|
|
|
+ {
|
|
|
+ duk_push_undefined(ctx);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // recursively push the variant
|
|
|
+ js_push_variant(ctx, vector[arrayIndex]);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- case VAR_VECTOR4:
|
|
|
- {
|
|
|
- const Vector4& vector4(v.GetVector4());
|
|
|
- duk_push_array(ctx);
|
|
|
- duk_push_number(ctx, vector4.x_);
|
|
|
- duk_put_prop_index(ctx, -2, 0);
|
|
|
- duk_push_number(ctx, vector4.y_);
|
|
|
- duk_put_prop_index(ctx, -2, 1);
|
|
|
- duk_push_number(ctx, vector4.z_);
|
|
|
- duk_put_prop_index(ctx, -2, 2);
|
|
|
- duk_push_number(ctx, vector4.w_);
|
|
|
- duk_put_prop_index(ctx, -2, 3);
|
|
|
- } break;
|
|
|
+ } break;
|
|
|
|
|
|
- default:
|
|
|
- duk_push_undefined(ctx);
|
|
|
- break;
|
|
|
- }
|
|
|
+ default:
|
|
|
+ duk_push_undefined(ctx);
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
|
|
|
-}
|
|
|
+ }
|
|
|
|
|
|
|
|
|
}
|