| 436 | }; |
| 437 | |
| 438 | class GodotAPIObject : public jsi::HostObject { |
| 439 | std::shared_ptr<RNWorklet::JsiWorkletContext> _workletContext; |
| 440 | std::map<std::string, jsi::Value> builtin_types; |
| 441 | |
| 442 | public: |
| 443 | static jsi::Value createBuiltinTypeConstructor(std::shared_ptr<RNWorklet::JsiWorkletContext> workletContext, jsi::Runtime &rt, std::string name, std::function<godot::Variant()> constructor) { |
| 444 | jsi::Function ctorFunc = jsi::Function::createFromHostFunction(rt, |
| 445 | jsi::PropNameID::forUtf8(rt, name), |
| 446 | 0, |
| 447 | [constructor, workletContext](jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args, size_t count) { |
| 448 | return GodotHostObject::godotVariantToJsiValue(workletContext, rt, constructor()); |
| 449 | }); |
| 450 | return jsi::Value(rt, ctorFunc); |
| 451 | } |
| 452 | |
| 453 | static jsi::Value createStaticFunction(std::shared_ptr<RNWorklet::JsiWorkletContext> workletContext, jsi::Runtime &rt, std::string name, GDExtensionMethodBindPtr mb) { |
| 454 | jsi::Function f = jsi::Function::createFromHostFunction(rt, jsi::PropNameID::forUtf8(rt, name), 0, [name, mb, workletContext](jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args, size_t count) { |
| 455 | std::vector<godot::Variant> godotArgs; |
| 456 | godotArgs.reserve(count); |
| 457 | for (int i = 0; i < count; ++i) { |
| 458 | godotArgs.push_back(GodotHostObject::jsiValueToGodotVariant(workletContext, rt, args[i])); |
| 459 | } |
| 460 | std::vector<const godot::Variant *> variantArgs = createVariantArgArray(godotArgs); |
| 461 | godot::Variant r_ret; |
| 462 | GDExtensionCallError r_error; |
| 463 | |
| 464 | godot::internal::gdextension_interface_object_method_bind_call(mb, nullptr, (GDExtensionConstVariantPtr *)variantArgs.data(), count, &r_ret, &r_error); |
| 465 | if (r_error.error != GDEXTENSION_CALL_OK) { |
| 466 | throw jsi::JSINativeException(create_method_call_error_string(name, r_error)); |
| 467 | } |
| 468 | return GodotHostObject::godotVariantToJsiValue(workletContext, rt, r_ret); |
| 469 | }); |
| 470 | return jsi::Value(rt, f); |
| 471 | } |
| 472 | |
| 473 | static jsi::Value createClassConstructor(std::shared_ptr<RNWorklet::JsiWorkletContext> workletContext, jsi::Runtime &rt, std::string name) { |
| 474 | godot::StringName godotClassName(name.c_str()); |
| 475 | jsi::Function ctorFunc = jsi::Function::createFromHostFunction(rt, |
| 476 | jsi::PropNameID::forUtf8(rt, name), |
| 477 | 0, |
| 478 | [name, godotClassName, workletContext](jsi::Runtime &rt, const jsi::Value &thisVal, const jsi::Value *args, size_t count) { |
| 479 | if (!godot::ClassDB::can_instantiate(godotClassName)) { |
| 480 | throw jsi::JSINativeException("Unable to instantiate class: " + name); |
| 481 | } |
| 482 | godot::Variant v = godot::ClassDB::instantiate(godotClassName); |
| 483 | return GodotHostObject::godotVariantToJsiValue(workletContext, rt, v); |
| 484 | }); |
| 485 | godot::TypedArray<godot::Dictionary> methodList = godot::ClassDB::class_get_method_list(godotClassName); |
| 486 | for (int i = 0; i < methodList.size(); ++i) { |
| 487 | godot::Dictionary d = methodList[i]; |
| 488 | godot::StringName methodName = (godot::StringName)d["name"]; |
| 489 | // LOGI("Method name: %s", methodName.to_utf8_buffer().ptr()); |
| 490 | bool isStatic = (bool)d["is_static"]; |
| 491 | if (isStatic) { |
| 492 | int64_t methodHash = (int64_t)d["hash"]; |
| 493 | GDExtensionMethodBindPtr mb = godot::internal::gdextension_interface_classdb_get_method_bind(godotClassName._native_ptr(), methodName._native_ptr(), methodHash); |
| 494 | std::string methodNameStd = (const char *)methodName.to_utf8_buffer().ptr(); |
| 495 | ctorFunc.setProperty(rt, methodNameStd.c_str(), createStaticFunction(workletContext, rt, methodNameStd, mb)); |
nothing calls this directly
no outgoing calls
no test coverage detected