Skip to content

Commit 9ef89f6

Browse files
authored
feat: Support adopting Prototypes and NativeState (Nitro support 🔥) (#223)
* feat: Add NativeState creator * Create dummy native * Update App.tsx * Get NativeState * Update App.tsx * fix: Copy over prototype * fix: Only look for native state & prototype * Revert unnecessary changes
1 parent e8a63b4 commit 9ef89f6

File tree

1 file changed

+32
-22
lines changed

1 file changed

+32
-22
lines changed

‎cpp/wrappers/WKTJsiObjectWrapper.h

+32-22
Original file line numberDiff line numberDiff line change
@@ -60,22 +60,8 @@ class JsiObjectWrapper : public JsiHostObject,
6060
} else {
6161
setObjectValue(runtime, object);
6262
}
63-
// NativeState functionality is also available in JSC with react-native 74+, but let's just keep this simple for now
64-
#if JS_RUNTIME_HERMES
65-
updateNativeState(runtime, object);
66-
#endif
6763
}
6864

69-
#if JS_RUNTIME_HERMES
70-
void updateNativeState(jsi::Runtime &runtime, jsi::Object &obj) {
71-
if (obj.hasNativeState(runtime)) {
72-
_nativeState = obj.getNativeState(runtime);
73-
} else {
74-
_nativeState = nullptr;
75-
}
76-
}
77-
#endif
78-
7965
/**
8066
* Overridden get value where we convert from the internal representation to
8167
* a jsi value
@@ -91,13 +77,21 @@ class JsiObjectWrapper : public JsiHostObject,
9177
}
9278
}
9379

94-
jsi::Object obj = getObject(runtime);
95-
#if JS_RUNTIME_HERMES
96-
if (_nativeState != nullptr) {
97-
obj.setNativeState(runtime, _nativeState);
80+
if (_prototype != nullptr && _nativeState != nullptr) {
81+
// We have a Prototype and NativeState!
82+
// It's likely a Nitro HybridObject that does not have properties by itself.
83+
jsi::Object Object = runtime.global().getPropertyAsObject(runtime, "Object");
84+
jsi::Function create = Object.getPropertyAsFunction(runtime, "create");
85+
jsi::Value result = create.call(runtime, _prototype->getValue(runtime));
86+
result.getObject(runtime).setNativeState(runtime, _nativeState);
87+
return result;
88+
} else {
89+
jsi::Object obj = getObject(runtime);
90+
if (_nativeState != nullptr) {
91+
obj.setNativeState(runtime, _nativeState);
92+
}
93+
return obj;
9894
}
99-
#endif
100-
return obj;
10195
}
10296

10397
jsi::Object getObject(jsi::Runtime &runtime) {
@@ -208,6 +202,23 @@ class JsiObjectWrapper : public JsiHostObject,
208202
nameString,
209203
JsiWrapper::wrap(runtime, value, this, getUseProxiesForUnwrapping()));
210204
}
205+
206+
if (obj.hasNativeState(runtime)) {
207+
// 1. Get NativeState and keep it in memory.
208+
_nativeState = obj.getNativeState(runtime);
209+
// 2. If we have a NativeState, we likely also have a prototype chain. Recursively copy those over.
210+
jsi::Object Object = runtime.global().getPropertyAsObject(runtime, "Object");
211+
jsi::Function getPrototypeOf = Object.getPropertyAsFunction(runtime, "getPrototypeOf");
212+
jsi::Value prototype = getPrototypeOf.call(runtime, obj);
213+
if (prototype.isObject()) {
214+
jsi::Object prototypeObject = prototype.getObject(runtime);
215+
_prototype = std::make_shared<JsiObjectWrapper>(nullptr, false);
216+
_prototype->setObjectValue(runtime, prototypeObject);
217+
}
218+
} else {
219+
_nativeState = nullptr;
220+
_prototype = nullptr;
221+
}
211222
}
212223

213224
void setHostObjectValue(jsi::Runtime &runtime, jsi::Object &obj) {
@@ -252,11 +263,10 @@ class JsiObjectWrapper : public JsiHostObject,
252263
}
253264

254265
private:
266+
std::shared_ptr<JsiObjectWrapper> _prototype;
255267
std::map<std::string, std::shared_ptr<JsiWrapper>> _properties;
256268
std::shared_ptr<jsi::HostFunctionType> _hostFunction;
257269
std::shared_ptr<jsi::HostObject> _hostObject;
258-
#if JS_RUNTIME_HERMES
259270
std::shared_ptr<jsi::NativeState> _nativeState;
260-
#endif
261271
};
262272
} // namespace RNWorklet

0 commit comments

Comments
 (0)