Last active
August 8, 2024 10:43
-
-
Save tmikov/3e6310abcd77ff8066297cdd4927b44d to your computer and use it in GitHub Desktop.
Example usage of NativeState
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Pseudocode implementation of jsi::Object::setNativeState() | |
function setNativeState(obj, ns) { obj.__ns = ns; } | |
/// Pseudocode implementation of jsi::object::getNativeState() | |
function getNativeState(obj) { return obj.__ns; } | |
/// This is a HostFunction, shown as JS pseudo-code | |
/// Create and initialize NativeState instance. | |
function _installNativeState(constructor, object, ...args) { | |
switch (constructor.name) { | |
case "Camera": | |
setNativeState(object, {marker: "Camera", param: args[0]}); | |
break; | |
default: | |
throw Error("Invalid native constructor " + constructor.name); | |
} | |
} | |
/// This is a HostFunction, shown as JS pseudo-code | |
/// Create and populate native methods | |
function _installMethods(constructor, prototype) { | |
switch (constructor.name) { | |
case "Camera": | |
// Attach a native HostFunction, shown here as JS | |
// for illustration. | |
prototype.update = function update() { | |
let ns = getNativeState(this); | |
if (ns?.marker !== "Camera") | |
throw TypeError("Not a Camera object"); | |
return ns.param++; | |
} | |
break; | |
default: | |
throw Error("Invalid native constructor " + constructor.name); | |
} | |
} | |
/// This defines the camera Class, backed by native data and | |
/// native methods. | |
class Camera { | |
name; | |
constructor(name, param) { | |
// JS properties work too. | |
this.name = name; | |
// Create NativeState, possibly using constructor arguments, | |
// and attach it. | |
_installNativeState(Camera, this, param); | |
} | |
// JS methods work too. | |
bar() {} | |
} | |
// Attach the native methods. | |
_installMethods(Camera, Camera.prototype); | |
// Example usage. | |
let c = new Camera("my cam", 10); | |
c.bar(); | |
console.log(c.update()); | |
console.log(c.update()); | |
console.log(c.update()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Really helpful to see how this would work from the JS side by using classes and allowing
new
/instanceof
, thanks for sharing! 🙏I went the C++ route, created a
jsi::Object
for each prototype on that side and created my instance usingObject.create(prototype)
. Set up the prototype chain properly to represent inheritance, and all objects have associated nativestate automatically. Works like a charm, and all JS functions are HostFunctions - meaning they could be shared between Runtimes/worklet contexts! (which a JSclass
currently can't)