| 612 | } |
| 613 | |
| 614 | jsi::Value createNativeGodotModule(jsi::Runtime &rt, const std::shared_ptr<facebook::react::CallInvoker> &callInvoker) { |
| 615 | // Perform initialization |
| 616 | |
| 617 | std::shared_ptr<facebook::react::CallInvoker> jsCallInvoker = callInvoker; |
| 618 | |
| 619 | auto runOnJS = [jsCallInvoker](std::function<void()> &&f) { |
| 620 | // Run on React JS Runtime |
| 621 | jsCallInvoker->invokeAsync(std::move(f)); |
| 622 | }; |
| 623 | |
| 624 | auto runOnWorklet = [](std::function<void()> &&f) { |
| 625 | GodotModule::get_singleton()->runOnGodotThread(std::move(f)); |
| 626 | }; |
| 627 | |
| 628 | std::shared_ptr<RNWorklet::JsiWorkletContext> workletContext = std::make_shared<RNWorklet::JsiWorkletContext>( |
| 629 | "ReactNativeGodot", |
| 630 | &rt, |
| 631 | runOnJS, |
| 632 | runOnWorklet); |
| 633 | |
| 634 | LOGI("NativeGodotModule::createNativeModule"); |
| 635 | |
| 636 | auto runOnGodotThreadFunc = [workletContext](jsi::Runtime &runtime, const jsi::Value &thisValue, const jsi::Value *arguments, size_t count) -> jsi::Value { |
| 637 | if (!arguments[0].isObject()) { |
| 638 | throw jsi::JSError(runtime, "runOnGodotThread: First argument has to be a function!"); |
| 639 | } |
| 640 | |
| 641 | auto worklet = std::make_shared<RNWorklet::JsiWorklet>(runtime, arguments[0]); |
| 642 | auto workletInvoker = std::make_shared<RNWorklet::WorkletInvoker>(worklet); |
| 643 | |
| 644 | auto runOnGodotCallback = jsi::Function::createFromHostFunction(runtime, |
| 645 | jsi::PropNameID::forAscii(runtime, "runOnGodotCallback"), |
| 646 | 2, |
| 647 | [workletInvoker, workletContext](jsi::Runtime &runtime, const jsi::Value &thisValue, const jsi::Value *arguments, size_t count) -> jsi::Value { |
| 648 | auto resolverValue = std::make_shared<jsi::Value>((arguments[0].asObject(runtime))); |
| 649 | auto rejecterValue = std::make_shared<jsi::Value>((arguments[1].asObject(runtime))); |
| 650 | |
| 651 | auto resolver = [resolverValue, workletContext](std::shared_ptr<RNWorklet::JsiWrapper> wrappedValue) { |
| 652 | workletContext->invokeOnJsThread([resolverValue, wrappedValue](jsi::Runtime &runtime) { |
| 653 | auto resolverFunc = resolverValue->asObject(runtime).asFunction(runtime); |
| 654 | auto resultValue = wrappedValue->unwrap(runtime); |
| 655 | resolverFunc.call(runtime, resultValue); |
| 656 | }); |
| 657 | }; |
| 658 | auto rejecter = [rejecterValue, workletContext](const std::string &message) { |
| 659 | workletContext->invokeOnJsThread([rejecterValue, message](jsi::Runtime &runtime) { |
| 660 | auto rejecterFunc = rejecterValue->asObject(runtime).asFunction(runtime); |
| 661 | auto messageValue = jsi::String::createFromUtf8(runtime, message); |
| 662 | rejecterFunc.call(runtime, messageValue); |
| 663 | }); |
| 664 | }; |
| 665 | |
| 666 | workletContext->invokeOnWorkletThread([resolver, rejecter, workletInvoker](RNWorklet::JsiWorkletContext *ctx, jsi::Runtime &workletRT) { |
| 667 | try { |
| 668 | auto resultValue = workletInvoker->call(workletRT, jsi::Value::undefined(), nullptr, 0); |
| 669 | auto result = RNWorklet::JsiWrapper::wrap(workletRT, resultValue); |
| 670 | resolver(result); |
| 671 | } catch (std::exception &exc) { |
no test coverage detected