@@ -52,6 +52,11 @@ JavaTurboModule::~JavaTurboModule() {
52
52
});
53
53
}
54
54
55
+ bool JavaTurboModule::useTurboModulesRAIICallbackManager_ = false ;
56
+ void JavaTurboModule::enableUseTurboModulesRAIICallbackManager (bool enable) {
57
+ JavaTurboModule::useTurboModulesRAIICallbackManager_ = enable;
58
+ }
59
+
55
60
namespace {
56
61
jni::local_ref<JCxxCallbackImpl::JavaPart> createJavaCallbackFromJSIFunction (
57
62
jsi::Function &&function,
@@ -60,9 +65,20 @@ jni::local_ref<JCxxCallbackImpl::JavaPart> createJavaCallbackFromJSIFunction(
60
65
auto weakWrapper =
61
66
react::CallbackWrapper::createWeak (std::move (function), rt, jsInvoker);
62
67
68
+ // This needs to be a shared_ptr because:
69
+ // 1. It cannot be unique_ptr. std::function is copyable but unique_ptr is
70
+ // not.
71
+ // 2. It cannot be weak_ptr since we need this object to live on.
72
+ // 3. It cannot be a value, because that would be deleted as soon as this
73
+ // function returns.
74
+ auto callbackWrapperOwner =
75
+ (JavaTurboModule::useTurboModulesRAIICallbackManager_
76
+ ? std::make_shared<RAIICallbackWrapperDestroyer>(weakWrapper)
77
+ : nullptr );
78
+
63
79
std::function<void (folly::dynamic)> fn =
64
- [weakWrapper,
65
- wrapperWasCalled = false ]( folly::dynamic responses) mutable {
80
+ [weakWrapper, callbackWrapperOwner, wrapperWasCalled = false ](
81
+ folly::dynamic responses) mutable {
66
82
if (wrapperWasCalled) {
67
83
throw std::runtime_error (
68
84
" callback 2 arg cannot be called more than once" );
@@ -73,35 +89,41 @@ jni::local_ref<JCxxCallbackImpl::JavaPart> createJavaCallbackFromJSIFunction(
73
89
return ;
74
90
}
75
91
76
- strongWrapper->jsInvoker ().invokeAsync ([weakWrapper, responses]() {
77
- auto strongWrapper2 = weakWrapper.lock ();
78
- if (!strongWrapper2) {
79
- return ;
80
- }
81
-
82
- // TODO (T43155926) valueFromDynamic already returns a Value array.
83
- // Don't iterate again
84
- jsi::Value args =
85
- jsi::valueFromDynamic (strongWrapper2->runtime (), responses);
86
- auto argsArray = args.getObject (strongWrapper2->runtime ())
87
- .asArray (strongWrapper2->runtime ());
88
- std::vector<jsi::Value> result;
89
- for (size_t i = 0 ; i < argsArray.size (strongWrapper2->runtime ());
90
- i++) {
91
- result.emplace_back (
92
- strongWrapper2->runtime (),
93
- argsArray.getValueAtIndex (strongWrapper2->runtime (), i));
94
- }
95
- strongWrapper2->callback ().call (
96
- strongWrapper2->runtime (),
97
- (const jsi::Value *)result.data (),
98
- result.size ());
99
-
100
- strongWrapper2->destroy ();
101
- });
92
+ strongWrapper->jsInvoker ().invokeAsync (
93
+ [weakWrapper, callbackWrapperOwner, responses]() mutable {
94
+ auto strongWrapper2 = weakWrapper.lock ();
95
+ if (!strongWrapper2) {
96
+ return ;
97
+ }
98
+
99
+ // TODO (T43155926) valueFromDynamic already returns a Value
100
+ // array. Don't iterate again
101
+ jsi::Value args =
102
+ jsi::valueFromDynamic (strongWrapper2->runtime (), responses);
103
+ auto argsArray = args.getObject (strongWrapper2->runtime ())
104
+ .asArray (strongWrapper2->runtime ());
105
+ std::vector<jsi::Value> result;
106
+ for (size_t i = 0 ; i < argsArray.size (strongWrapper2->runtime ());
107
+ i++) {
108
+ result.emplace_back (
109
+ strongWrapper2->runtime (),
110
+ argsArray.getValueAtIndex (strongWrapper2->runtime (), i));
111
+ }
112
+ strongWrapper2->callback ().call (
113
+ strongWrapper2->runtime (),
114
+ (const jsi::Value *)result.data (),
115
+ result.size ());
116
+
117
+ if (JavaTurboModule::useTurboModulesRAIICallbackManager_) {
118
+ callbackWrapperOwner.reset ();
119
+ } else {
120
+ strongWrapper2->destroy ();
121
+ }
122
+ });
102
123
103
124
wrapperWasCalled = true ;
104
125
};
126
+
105
127
return JCxxCallbackImpl::newObjectCxxArgs (fn);
106
128
}
107
129
0 commit comments