Skip to content

Commit

Permalink
feat: generate index accessor of primitive types (if available)
Browse files Browse the repository at this point in the history
  • Loading branch information
ialex32x committed Jul 5, 2024
1 parent 1b877bf commit 44b929c
Show file tree
Hide file tree
Showing 10 changed files with 95 additions and 14 deletions.
4 changes: 4 additions & 0 deletions bridge-v8/jsb_bridge_module_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,10 @@ namespace jsb
constexpr static Variant::Type TYPE = GetTypeInfo<T>::VARIANT_TYPE;
v8::Local<v8::Object> class_info_obj = v8::Object::New(isolate);
set_field(isolate, context, class_info_obj, "name", Variant::get_type_name(TYPE));
if (Variant::has_indexing(TYPE))
{
set_field(isolate, context, class_info_obj, "element_type", Variant::get_indexed_element_type(TYPE));
}

// constructors
{
Expand Down
67 changes: 67 additions & 0 deletions bridge-v8/jsb_primitive_bindings_reflect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,66 @@ namespace jsb
getset.setter_func(p_self, &value);
}

static void _set_indexed(const v8::FunctionCallbackInfo<v8::Value>& info)
{
v8::Isolate* isolate = info.GetIsolate();
v8::Local<v8::Context> context = isolate->GetCurrentContext();
jsb_check(info.This().As<v8::Object>()->InternalFieldCount() == IF_VariantFieldCount);
const Variant::Type element_type = Variant::get_indexed_element_type(TYPE);
if (info.Length() != 2
|| !info[0]->IsInt32()
|| !Realm::can_convert_strict(isolate, context, info[1], element_type))
{
jsb_throw(isolate, "bad params");
return;
}
const int32_t index = info[0].As<v8::Int32>()->Value();
Variant value;
if (!Realm::js_to_gd_var(isolate, context, info[1], element_type, value))
{
jsb_throw(isolate, "bad value");
return;
}
bool r_valid, r_oob;
Variant* self = (Variant*) info.This().As<v8::Object>()->GetAlignedPointerFromInternalField(IF_Pointer);
self->set_indexed(index, value, r_valid, r_oob);
if (!r_valid || r_oob)
{
jsb_throw(isolate, "invalid or out of bound");
return;
}
}

static void _get_indexed(const v8::FunctionCallbackInfo<v8::Value>& info)
{
v8::Isolate* isolate = info.GetIsolate();
v8::Local<v8::Context> context = isolate->GetCurrentContext();
jsb_check(info.This().As<v8::Object>()->InternalFieldCount() == IF_VariantFieldCount);
const Variant::Type element_type = Variant::get_indexed_element_type(TYPE);
if (info.Length() != 1
|| !info[0]->IsInt32())
{
jsb_throw(isolate, "bad params");
return;
}
const int32_t index = info[0].As<v8::Int32>()->Value();
bool r_valid, r_oob;
const Variant* self = (Variant*) info.This().As<v8::Object>()->GetAlignedPointerFromInternalField(IF_Pointer);
const Variant value = self->get_indexed(index, r_valid, r_oob);
if (!r_valid || r_oob)
{
jsb_throw(isolate, "invalid or out of bound");
return;
}
v8::Local<v8::Value> r_val;
if (!Realm::gd_var_to_js(isolate, context, value, element_type, r_val))
{
jsb_throw(isolate, "bad translation");
return;
}
info.GetReturnValue().Set(r_val);
}

static void _instance_method(const v8::FunctionCallbackInfo<v8::Value>& info)
{
v8::Isolate* isolate = info.GetIsolate();
Expand Down Expand Up @@ -468,6 +528,13 @@ namespace jsb
}
}

// indexed accessor
if (Variant::has_indexing(TYPE))
{
prototype_template->Set(V8Helper::to_string(p_env.isolate, "set_indexed"), v8::FunctionTemplate::New(p_env.isolate, _set_indexed));
prototype_template->Set(V8Helper::to_string(p_env.isolate, "get_indexed"), v8::FunctionTemplate::New(p_env.isolate, _get_indexed));
}

// methods
{
List<StringName> methods;
Expand Down
2 changes: 2 additions & 0 deletions scripts/godot-typings/godot.minimal.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ declare module "godot-jsb" {

interface PrimitiveClassInfo extends BasicClassInfo {
name: string;
// valid only if has_indexing
element_type?: Variant.Type;

constructors: Array<ConstructorInfo>;
operators: Array<OperatorInfo>;
Expand Down
17 changes: 8 additions & 9 deletions scripts/out/jsb.core.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion scripts/out/jsb.core.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions scripts/out/jsb.editor.codegen.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion scripts/out/jsb.editor.codegen.js.map

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions scripts/out/jsb.editor.main.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion scripts/out/jsb.editor.main.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions scripts/src/jsb.editor.codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,11 @@ export default class TSDCodeGen {
for (let constructor_info of cls.constructors) {
class_cg.constructor_(constructor_info);
}
if (typeof cls.element_type !== "undefined") {
const element_type_name = PrimitiveTypeNames[cls.element_type];
class_cg.line(`set_indexed(index: number, value: ${element_type_name})`)
class_cg.line(`get_indexed(index: number): ${element_type_name}`)
}
for (let method_info of cls.methods) {
class_cg.ordinary_method_(method_info);
}
Expand Down

0 comments on commit 44b929c

Please sign in to comment.