chore: update
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
||||
../@expo/fingerprint/bin/cli.js
|
||||
../expo/bin/fingerprint
|
||||
+37
-126
@@ -1245,7 +1245,6 @@
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz",
|
||||
"integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
},
|
||||
@@ -1778,9 +1777,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@expo/prebuild-config/node_modules/semver": {
|
||||
"version": "7.7.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
|
||||
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
||||
"version": "7.7.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
|
||||
"integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
@@ -3859,12 +3858,12 @@
|
||||
"integrity": "sha512-87OpwcEiMia/DeiKFzaQNBNFeN3XkkpYIh9FyOqq5mS2oKv3CBE67PXoEKcr6nodWdXNogTiQ0jE2NGuoffXPw=="
|
||||
},
|
||||
"node_modules/expo": {
|
||||
"version": "54.0.32",
|
||||
"resolved": "https://registry.npmjs.org/expo/-/expo-54.0.32.tgz",
|
||||
"integrity": "sha512-yL9eTxiQ/QKKggVDAWO5CLjUl6IS0lPYgEvC3QM4q4fxd6rs7ks3DnbXSGVU3KNFoY/7cRNYihvd0LKYP+MCXA==",
|
||||
"version": "54.0.33",
|
||||
"resolved": "https://registry.npmjs.org/expo/-/expo-54.0.33.tgz",
|
||||
"integrity": "sha512-3yOEfAKqo+gqHcV8vKcnq0uA5zxlohnhA3fu4G43likN8ct5ZZ3LjAh9wDdKteEkoad3tFPvwxmXW711S5OHUw==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.0",
|
||||
"@expo/cli": "54.0.22",
|
||||
"@expo/cli": "54.0.23",
|
||||
"@expo/config": "~12.0.13",
|
||||
"@expo/config-plugins": "~54.0.4",
|
||||
"@expo/devtools": "0.1.8",
|
||||
@@ -4042,9 +4041,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/expo/node_modules/@expo/cli": {
|
||||
"version": "54.0.22",
|
||||
"resolved": "https://registry.npmjs.org/@expo/cli/-/cli-54.0.22.tgz",
|
||||
"integrity": "sha512-BTH2FCczhJLfj1cpfcKrzhKnvRLTOztgW4bVloKDqH+G3ZSohWLRFNAIz56XtdjPxBbi2/qWhGBAkl7kBon/Jw==",
|
||||
"version": "54.0.23",
|
||||
"resolved": "https://registry.npmjs.org/@expo/cli/-/cli-54.0.23.tgz",
|
||||
"integrity": "sha512-km0h72SFfQCmVycH/JtPFTVy69w6Lx1cHNDmfLfQqgKFYeeHTjx7LVDP4POHCtNxFP2UeRazrygJhlh4zz498g==",
|
||||
"dependencies": {
|
||||
"@0no-co/graphql.web": "^1.0.8",
|
||||
"@expo/code-signing-certificates": "^0.0.6",
|
||||
@@ -4153,9 +4152,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/expo/node_modules/semver": {
|
||||
"version": "7.7.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
|
||||
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
||||
"version": "7.7.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
|
||||
"integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
@@ -5901,9 +5900,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/npm-package-arg/node_modules/semver": {
|
||||
"version": "7.7.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
|
||||
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
||||
"version": "7.7.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
|
||||
"integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
@@ -6693,120 +6692,32 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-worklets": {
|
||||
"version": "0.7.2",
|
||||
"resolved": "https://registry.npmjs.org/react-native-worklets/-/react-native-worklets-0.7.2.tgz",
|
||||
"integrity": "sha512-DuLu1kMV/Uyl9pQHp3hehAlThoLw7Yk2FwRTpzASOmI+cd4845FWn3m2bk9MnjUw8FBRIyhwLqYm2AJaXDXsog==",
|
||||
"peer": true,
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-worklets/-/react-native-worklets-0.5.1.tgz",
|
||||
"integrity": "sha512-lJG6Uk9YuojjEX/tQrCbcbmpdLCSFxDK1rJlkDhgqkVi1KZzG7cdcBFQRqyNOOzR9Y0CXNuldmtWTGOyM0k0+w==",
|
||||
"dependencies": {
|
||||
"@babel/plugin-transform-arrow-functions": "7.27.1",
|
||||
"@babel/plugin-transform-class-properties": "7.27.1",
|
||||
"@babel/plugin-transform-classes": "7.28.4",
|
||||
"@babel/plugin-transform-nullish-coalescing-operator": "7.27.1",
|
||||
"@babel/plugin-transform-optional-chaining": "7.27.1",
|
||||
"@babel/plugin-transform-shorthand-properties": "7.27.1",
|
||||
"@babel/plugin-transform-template-literals": "7.27.1",
|
||||
"@babel/plugin-transform-unicode-regex": "7.27.1",
|
||||
"@babel/preset-typescript": "7.27.1",
|
||||
"convert-source-map": "2.0.0",
|
||||
"semver": "7.7.3"
|
||||
"@babel/plugin-transform-arrow-functions": "^7.0.0-0",
|
||||
"@babel/plugin-transform-class-properties": "^7.0.0-0",
|
||||
"@babel/plugin-transform-classes": "^7.0.0-0",
|
||||
"@babel/plugin-transform-nullish-coalescing-operator": "^7.0.0-0",
|
||||
"@babel/plugin-transform-optional-chaining": "^7.0.0-0",
|
||||
"@babel/plugin-transform-shorthand-properties": "^7.0.0-0",
|
||||
"@babel/plugin-transform-template-literals": "^7.0.0-0",
|
||||
"@babel/plugin-transform-unicode-regex": "^7.0.0-0",
|
||||
"@babel/preset-typescript": "^7.16.7",
|
||||
"convert-source-map": "^2.0.0",
|
||||
"semver": "7.7.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "*",
|
||||
"@babel/core": "^7.0.0-0",
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-worklets/node_modules/@babel/plugin-transform-class-properties": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz",
|
||||
"integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-create-class-features-plugin": "^7.27.1",
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-worklets/node_modules/@babel/plugin-transform-classes": {
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz",
|
||||
"integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-annotate-as-pure": "^7.27.3",
|
||||
"@babel/helper-compilation-targets": "^7.27.2",
|
||||
"@babel/helper-globals": "^7.28.0",
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/helper-replace-supers": "^7.27.1",
|
||||
"@babel/traverse": "^7.28.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-worklets/node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz",
|
||||
"integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-worklets/node_modules/@babel/plugin-transform-optional-chaining": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz",
|
||||
"integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-worklets/node_modules/@babel/preset-typescript": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.27.1.tgz",
|
||||
"integrity": "sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/helper-validator-option": "^7.27.1",
|
||||
"@babel/plugin-syntax-jsx": "^7.27.1",
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.27.1",
|
||||
"@babel/plugin-transform-typescript": "^7.27.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-worklets/node_modules/semver": {
|
||||
"version": "7.7.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
|
||||
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
||||
"peer": true,
|
||||
"version": "7.7.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
||||
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
@@ -7573,9 +7484,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tar": {
|
||||
"version": "7.5.7",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.7.tgz",
|
||||
"integrity": "sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==",
|
||||
"version": "7.5.9",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.9.tgz",
|
||||
"integrity": "sha512-BTLcK0xsDh2+PUe9F6c2TlRp4zOOBMTkoQHQIWSIzI0R7KG46uEwq4OPk2W7bZcprBMsuaeFsqwYr7pjh6CuHg==",
|
||||
"dependencies": {
|
||||
"@isaacs/fs-minipass": "^4.0.0",
|
||||
"chownr": "^3.0.0",
|
||||
|
||||
+3
-2
@@ -110,8 +110,9 @@ Options:
|
||||
-l --loose
|
||||
Interpret versions and ranges loosely
|
||||
|
||||
-n <0|1>
|
||||
This is the base to be used for the prerelease identifier.
|
||||
-n <0|1|false>
|
||||
Base number for prerelease identifier (default: 0).
|
||||
Use false to omit the number altogether.
|
||||
|
||||
-p --include-prerelease
|
||||
Always include prerelease versions in range matching
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -105,7 +105,7 @@ const main = () => {
|
||||
versions = versions.map((v) => {
|
||||
return coerce ? (semver.coerce(v, options) || { version: v }).version : v
|
||||
}).filter((v) => {
|
||||
return semver.valid(v)
|
||||
return semver.valid(v, options)
|
||||
})
|
||||
if (!versions.length) {
|
||||
return fail()
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -53,7 +53,7 @@ const diff = (version1, version2) => {
|
||||
return prefix + 'patch'
|
||||
}
|
||||
|
||||
// high and low are preleases
|
||||
// high and low are prereleases
|
||||
return 'prerelease'
|
||||
}
|
||||
|
||||
|
||||
Generated
Vendored
+2
-2
@@ -78,8 +78,8 @@ createToken('MAINVERSIONLOOSE', `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
|
||||
|
||||
// ## Pre-release Version Identifier
|
||||
// A numeric identifier, or a non-numeric identifier.
|
||||
// Non-numberic identifiers include numberic identifiers but can be longer.
|
||||
// Therefore non-numberic identifiers must go first.
|
||||
// Non-numeric identifiers include numeric identifiers but can be longer.
|
||||
// Therefore non-numeric identifiers must go first.
|
||||
|
||||
createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NONNUMERICIDENTIFIER]
|
||||
}|${src[t.NUMERICIDENTIFIER]})`)
|
||||
|
||||
Generated
Vendored
+4
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "semver",
|
||||
"version": "7.7.3",
|
||||
"version": "7.7.4",
|
||||
"description": "The semantic version parser used by npm.",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
@@ -14,8 +14,8 @@
|
||||
"eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\""
|
||||
},
|
||||
"devDependencies": {
|
||||
"@npmcli/eslint-config": "^5.0.0",
|
||||
"@npmcli/template-oss": "4.25.1",
|
||||
"@npmcli/eslint-config": "^6.0.0",
|
||||
"@npmcli/template-oss": "4.29.0",
|
||||
"benchmark": "^2.1.4",
|
||||
"tap": "^16.0.0"
|
||||
},
|
||||
@@ -52,7 +52,7 @@
|
||||
"author": "GitHub Inc.",
|
||||
"templateOSS": {
|
||||
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
|
||||
"version": "4.25.1",
|
||||
"version": "4.29.0",
|
||||
"engines": ">=10",
|
||||
"distPaths": [
|
||||
"classes/",
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -38,7 +38,7 @@ const compare = require('../functions/compare.js')
|
||||
// - If LT
|
||||
// - If LT.semver is greater than any < or <= comp in C, return false
|
||||
// - If LT is <=, and LT.semver does not satisfy every C, return false
|
||||
// - If GT.semver has a prerelease, and not in prerelease mode
|
||||
// - If LT.semver has a prerelease, and not in prerelease mode
|
||||
// - If no C has a prerelease and the LT.semver tuple, return false
|
||||
// - Else return true
|
||||
|
||||
|
||||
+2
-2
@@ -32,7 +32,7 @@ buildscript {
|
||||
def reactNativeVersion = project.extensions.getByType(ExpoModuleExtension).reactNativeVersion
|
||||
|
||||
group = 'host.exp.exponent'
|
||||
version = '54.0.32'
|
||||
version = '54.0.33'
|
||||
|
||||
expoModule {
|
||||
// We can't prebuild the module because it depends on the generated files.
|
||||
@@ -43,7 +43,7 @@ android {
|
||||
namespace "expo.core"
|
||||
defaultConfig {
|
||||
versionCode 1
|
||||
versionName "54.0.32"
|
||||
versionName "54.0.33"
|
||||
consumerProguardFiles("proguard-rules.pro")
|
||||
}
|
||||
testOptions {
|
||||
|
||||
+3
-3
@@ -42,7 +42,7 @@
|
||||
"expo-document-picker": "~14.0.8",
|
||||
"expo-file-system": "~19.0.21",
|
||||
"expo-font": "~14.0.11",
|
||||
"expo-gl": "~16.0.9",
|
||||
"expo-gl": "~16.0.10",
|
||||
"expo-glass-effect": "~0.1.8",
|
||||
"expo-google-app-auth": "~8.3.0",
|
||||
"expo-haptics": "~15.0.8",
|
||||
@@ -71,7 +71,7 @@
|
||||
"expo-notifications": "~0.32.16",
|
||||
"expo-print": "~15.0.8",
|
||||
"expo-live-photo": "~1.0.8",
|
||||
"expo-router": "~6.0.22",
|
||||
"expo-router": "~6.0.23",
|
||||
"expo-screen-capture": "~8.0.9",
|
||||
"expo-screen-orientation": "~9.0.8",
|
||||
"expo-secure-store": "~15.0.8",
|
||||
@@ -92,7 +92,7 @@
|
||||
"expo-video-thumbnails": "~10.0.8",
|
||||
"expo-video": "~3.0.15",
|
||||
"expo-web-browser": "~15.0.10",
|
||||
"jest-expo": "~54.0.16",
|
||||
"jest-expo": "~54.0.17",
|
||||
"lottie-react-native": "~7.3.1",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
|
||||
+1
-1
@@ -123,7 +123,7 @@ const args = (0, _arg().default)({
|
||||
});
|
||||
if (args['--version']) {
|
||||
// Version is added in the build script.
|
||||
console.log("54.0.22");
|
||||
console.log("54.0.23");
|
||||
process.exit(0);
|
||||
}
|
||||
if (args['--non-interactive']) {
|
||||
|
||||
Generated
Vendored
+1
-9
@@ -15,19 +15,11 @@ function _ws() {
|
||||
};
|
||||
return data;
|
||||
}
|
||||
const _net = require("../../../utils/net");
|
||||
function createDevToolsPluginWebsocketEndpoint({ serverBaseUrl }) {
|
||||
function createDevToolsPluginWebsocketEndpoint() {
|
||||
const wss = new (_ws()).WebSocketServer({
|
||||
noServer: true
|
||||
});
|
||||
wss.on('connection', (ws, request)=>{
|
||||
// Explicitly limit devtools websocket to loopback requests
|
||||
if (!(0, _net.isLocalSocket)(request.socket) || !(0, _net.isMatchingOrigin)(request, serverBaseUrl)) {
|
||||
// NOTE: `socket.close` nicely closes the websocket, which will still allow incoming messages
|
||||
// `socket.terminate` instead forcefully closes down the socket
|
||||
ws.terminate();
|
||||
return;
|
||||
}
|
||||
ws.on('message', (message, isBinary)=>{
|
||||
// Broadcast the received message to all other connected clients
|
||||
wss.clients.forEach((client)=>{
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"sources":["../../../../../src/start/server/metro/DevToolsPluginWebsocketEndpoint.ts"],"sourcesContent":["import { WebSocket, WebSocketServer } from 'ws';\n\nimport { isLocalSocket, isMatchingOrigin } from '../../../utils/net';\n\ninterface DevToolsPluginWebsocketEndpointParams {\n serverBaseUrl: string;\n}\n\nexport function createDevToolsPluginWebsocketEndpoint({\n serverBaseUrl,\n}: DevToolsPluginWebsocketEndpointParams): Record<string, WebSocketServer> {\n const wss = new WebSocketServer({ noServer: true });\n\n wss.on('connection', (ws, request) => {\n // Explicitly limit devtools websocket to loopback requests\n if (!isLocalSocket(request.socket) || !isMatchingOrigin(request, serverBaseUrl)) {\n // NOTE: `socket.close` nicely closes the websocket, which will still allow incoming messages\n // `socket.terminate` instead forcefully closes down the socket\n ws.terminate();\n return;\n }\n\n ws.on('message', (message, isBinary) => {\n // Broadcast the received message to all other connected clients\n wss.clients.forEach((client) => {\n if (client !== ws && client.readyState === WebSocket.OPEN) {\n client.send(message, { binary: isBinary });\n }\n });\n });\n });\n\n return { '/expo-dev-plugins/broadcast': wss };\n}\n"],"names":["createDevToolsPluginWebsocketEndpoint","serverBaseUrl","wss","WebSocketServer","noServer","on","ws","request","isLocalSocket","socket","isMatchingOrigin","terminate","message","isBinary","clients","forEach","client","readyState","WebSocket","OPEN","send","binary"],"mappings":";;;;+BAQgBA;;;eAAAA;;;;yBAR2B;;;;;;qBAEK;AAMzC,SAASA,sCAAsC,EACpDC,aAAa,EACyB;IACtC,MAAMC,MAAM,IAAIC,CAAAA,KAAc,iBAAC,CAAC;QAAEC,UAAU;IAAK;IAEjDF,IAAIG,EAAE,CAAC,cAAc,CAACC,IAAIC;QACxB,2DAA2D;QAC3D,IAAI,CAACC,IAAAA,kBAAa,EAACD,QAAQE,MAAM,KAAK,CAACC,IAAAA,qBAAgB,EAACH,SAASN,gBAAgB;YAC/E,6FAA6F;YAC7F,+DAA+D;YAC/DK,GAAGK,SAAS;YACZ;QACF;QAEAL,GAAGD,EAAE,CAAC,WAAW,CAACO,SAASC;YACzB,gEAAgE;YAChEX,IAAIY,OAAO,CAACC,OAAO,CAAC,CAACC;gBACnB,IAAIA,WAAWV,MAAMU,OAAOC,UAAU,KAAKC,eAAS,CAACC,IAAI,EAAE;oBACzDH,OAAOI,IAAI,CAACR,SAAS;wBAAES,QAAQR;oBAAS;gBAC1C;YACF;QACF;IACF;IAEA,OAAO;QAAE,+BAA+BX;IAAI;AAC9C"}
|
||||
{"version":3,"sources":["../../../../../src/start/server/metro/DevToolsPluginWebsocketEndpoint.ts"],"sourcesContent":["import { WebSocket, WebSocketServer } from 'ws';\n\nexport function createDevToolsPluginWebsocketEndpoint(): Record<string, WebSocketServer> {\n const wss = new WebSocketServer({ noServer: true });\n\n wss.on('connection', (ws, request) => {\n ws.on('message', (message, isBinary) => {\n // Broadcast the received message to all other connected clients\n wss.clients.forEach((client) => {\n if (client !== ws && client.readyState === WebSocket.OPEN) {\n client.send(message, { binary: isBinary });\n }\n });\n });\n });\n\n return { '/expo-dev-plugins/broadcast': wss };\n}\n"],"names":["createDevToolsPluginWebsocketEndpoint","wss","WebSocketServer","noServer","on","ws","request","message","isBinary","clients","forEach","client","readyState","WebSocket","OPEN","send","binary"],"mappings":";;;;+BAEgBA;;;eAAAA;;;;yBAF2B;;;;;;AAEpC,SAASA;IACd,MAAMC,MAAM,IAAIC,CAAAA,KAAc,iBAAC,CAAC;QAAEC,UAAU;IAAK;IAEjDF,IAAIG,EAAE,CAAC,cAAc,CAACC,IAAIC;QACxBD,GAAGD,EAAE,CAAC,WAAW,CAACG,SAASC;YACzB,gEAAgE;YAChEP,IAAIQ,OAAO,CAACC,OAAO,CAAC,CAACC;gBACnB,IAAIA,WAAWN,MAAMM,OAAOC,UAAU,KAAKC,eAAS,CAACC,IAAI,EAAE;oBACzDH,OAAOI,IAAI,CAACR,SAAS;wBAAES,QAAQR;oBAAS;gBAC1C;YACF;QACF;IACF;IAEA,OAAO;QAAE,+BAA+BP;IAAI;AAC9C"}
|
||||
Generated
Vendored
+1
-3
@@ -262,9 +262,7 @@ async function instantiateMetroAsync(metroBundler, options, { isExporting, exp =
|
||||
}
|
||||
return middleware.use(metroMiddleware);
|
||||
};
|
||||
const devtoolsWebsocketEndpoints = (0, _DevToolsPluginWebsocketEndpoint.createDevToolsPluginWebsocketEndpoint)({
|
||||
serverBaseUrl
|
||||
});
|
||||
const devtoolsWebsocketEndpoints = (0, _DevToolsPluginWebsocketEndpoint.createDevToolsPluginWebsocketEndpoint)();
|
||||
Object.assign(websocketEndpoints, devtoolsWebsocketEndpoints);
|
||||
}
|
||||
// Attach Expo Atlas if enabled
|
||||
|
||||
Generated
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Generated
Vendored
+1
-1
@@ -33,7 +33,7 @@ class FetchClient {
|
||||
this.headers = {
|
||||
accept: 'application/json',
|
||||
'content-type': 'application/json',
|
||||
'user-agent': `expo-cli/${"54.0.22"}`,
|
||||
'user-agent': `expo-cli/${"54.0.23"}`,
|
||||
authorization: 'Basic ' + _nodebuffer().Buffer.from(`${target}:`).toString('base64')
|
||||
};
|
||||
}
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -83,7 +83,7 @@ function createContext() {
|
||||
cpu: summarizeCpuInfo(),
|
||||
app: {
|
||||
name: 'expo/cli',
|
||||
version: "54.0.22"
|
||||
version: "54.0.23"
|
||||
},
|
||||
ci: _ciinfo().isCI ? {
|
||||
name: _ciinfo().name,
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@expo/cli",
|
||||
"version": "54.0.22",
|
||||
"version": "54.0.23",
|
||||
"description": "The Expo CLI",
|
||||
"main": "build/bin/cli",
|
||||
"bin": {
|
||||
@@ -169,5 +169,5 @@
|
||||
"tree-kill": "^1.2.2",
|
||||
"tsd": "^0.28.1"
|
||||
},
|
||||
"gitHead": "5205083d153ffa0c5e48db969aeaa1f9810453fc"
|
||||
"gitHead": "cfd65241fb73317b63e6736e7890a784a69940fc"
|
||||
}
|
||||
|
||||
+3
-2
@@ -110,8 +110,9 @@ Options:
|
||||
-l --loose
|
||||
Interpret versions and ranges loosely
|
||||
|
||||
-n <0|1>
|
||||
This is the base to be used for the prerelease identifier.
|
||||
-n <0|1|false>
|
||||
Base number for prerelease identifier (default: 0).
|
||||
Use false to omit the number altogether.
|
||||
|
||||
-p --include-prerelease
|
||||
Always include prerelease versions in range matching
|
||||
|
||||
+1
-1
@@ -105,7 +105,7 @@ const main = () => {
|
||||
versions = versions.map((v) => {
|
||||
return coerce ? (semver.coerce(v, options) || { version: v }).version : v
|
||||
}).filter((v) => {
|
||||
return semver.valid(v)
|
||||
return semver.valid(v, options)
|
||||
})
|
||||
if (!versions.length) {
|
||||
return fail()
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ const diff = (version1, version2) => {
|
||||
return prefix + 'patch'
|
||||
}
|
||||
|
||||
// high and low are preleases
|
||||
// high and low are prereleases
|
||||
return 'prerelease'
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -78,8 +78,8 @@ createToken('MAINVERSIONLOOSE', `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
|
||||
|
||||
// ## Pre-release Version Identifier
|
||||
// A numeric identifier, or a non-numeric identifier.
|
||||
// Non-numberic identifiers include numberic identifiers but can be longer.
|
||||
// Therefore non-numberic identifiers must go first.
|
||||
// Non-numeric identifiers include numeric identifiers but can be longer.
|
||||
// Therefore non-numeric identifiers must go first.
|
||||
|
||||
createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NONNUMERICIDENTIFIER]
|
||||
}|${src[t.NUMERICIDENTIFIER]})`)
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "semver",
|
||||
"version": "7.7.3",
|
||||
"version": "7.7.4",
|
||||
"description": "The semantic version parser used by npm.",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
@@ -14,8 +14,8 @@
|
||||
"eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\""
|
||||
},
|
||||
"devDependencies": {
|
||||
"@npmcli/eslint-config": "^5.0.0",
|
||||
"@npmcli/template-oss": "4.25.1",
|
||||
"@npmcli/eslint-config": "^6.0.0",
|
||||
"@npmcli/template-oss": "4.29.0",
|
||||
"benchmark": "^2.1.4",
|
||||
"tap": "^16.0.0"
|
||||
},
|
||||
@@ -52,7 +52,7 @@
|
||||
"author": "GitHub Inc.",
|
||||
"templateOSS": {
|
||||
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
|
||||
"version": "4.25.1",
|
||||
"version": "4.29.0",
|
||||
"engines": ">=10",
|
||||
"distPaths": [
|
||||
"classes/",
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ const compare = require('../functions/compare.js')
|
||||
// - If LT
|
||||
// - If LT.semver is greater than any < or <= comp in C, return false
|
||||
// - If LT is <=, and LT.semver does not satisfy every C, return false
|
||||
// - If GT.semver has a prerelease, and not in prerelease mode
|
||||
// - If LT.semver has a prerelease, and not in prerelease mode
|
||||
// - If no C has a prerelease and the LT.semver tuple, return false
|
||||
// - Else return true
|
||||
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "expo",
|
||||
"version": "54.0.32",
|
||||
"version": "54.0.33",
|
||||
"description": "The Expo SDK",
|
||||
"main": "src/Expo.ts",
|
||||
"module": "src/Expo.ts",
|
||||
@@ -75,7 +75,7 @@
|
||||
"homepage": "https://github.com/expo/expo/tree/main/packages/expo",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.0",
|
||||
"@expo/cli": "54.0.22",
|
||||
"@expo/cli": "54.0.23",
|
||||
"@expo/config": "~12.0.13",
|
||||
"@expo/config-plugins": "~54.0.4",
|
||||
"@expo/devtools": "0.1.8",
|
||||
@@ -124,5 +124,5 @@
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"gitHead": "5205083d153ffa0c5e48db969aeaa1f9810453fc"
|
||||
"gitHead": "cfd65241fb73317b63e6736e7890a784a69940fc"
|
||||
}
|
||||
|
||||
BIN
Binary file not shown.
+3
-2
@@ -110,8 +110,9 @@ Options:
|
||||
-l --loose
|
||||
Interpret versions and ranges loosely
|
||||
|
||||
-n <0|1>
|
||||
This is the base to be used for the prerelease identifier.
|
||||
-n <0|1|false>
|
||||
Base number for prerelease identifier (default: 0).
|
||||
Use false to omit the number altogether.
|
||||
|
||||
-p --include-prerelease
|
||||
Always include prerelease versions in range matching
|
||||
|
||||
+1
-1
@@ -105,7 +105,7 @@ const main = () => {
|
||||
versions = versions.map((v) => {
|
||||
return coerce ? (semver.coerce(v, options) || { version: v }).version : v
|
||||
}).filter((v) => {
|
||||
return semver.valid(v)
|
||||
return semver.valid(v, options)
|
||||
})
|
||||
if (!versions.length) {
|
||||
return fail()
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -53,7 +53,7 @@ const diff = (version1, version2) => {
|
||||
return prefix + 'patch'
|
||||
}
|
||||
|
||||
// high and low are preleases
|
||||
// high and low are prereleases
|
||||
return 'prerelease'
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -78,8 +78,8 @@ createToken('MAINVERSIONLOOSE', `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
|
||||
|
||||
// ## Pre-release Version Identifier
|
||||
// A numeric identifier, or a non-numeric identifier.
|
||||
// Non-numberic identifiers include numberic identifiers but can be longer.
|
||||
// Therefore non-numberic identifiers must go first.
|
||||
// Non-numeric identifiers include numeric identifiers but can be longer.
|
||||
// Therefore non-numeric identifiers must go first.
|
||||
|
||||
createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NONNUMERICIDENTIFIER]
|
||||
}|${src[t.NUMERICIDENTIFIER]})`)
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "semver",
|
||||
"version": "7.7.3",
|
||||
"version": "7.7.4",
|
||||
"description": "The semantic version parser used by npm.",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
@@ -14,8 +14,8 @@
|
||||
"eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\""
|
||||
},
|
||||
"devDependencies": {
|
||||
"@npmcli/eslint-config": "^5.0.0",
|
||||
"@npmcli/template-oss": "4.25.1",
|
||||
"@npmcli/eslint-config": "^6.0.0",
|
||||
"@npmcli/template-oss": "4.29.0",
|
||||
"benchmark": "^2.1.4",
|
||||
"tap": "^16.0.0"
|
||||
},
|
||||
@@ -52,7 +52,7 @@
|
||||
"author": "GitHub Inc.",
|
||||
"templateOSS": {
|
||||
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
|
||||
"version": "4.25.1",
|
||||
"version": "4.29.0",
|
||||
"engines": ">=10",
|
||||
"distPaths": [
|
||||
"classes/",
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ const compare = require('../functions/compare.js')
|
||||
// - If LT
|
||||
// - If LT.semver is greater than any < or <= comp in C, return false
|
||||
// - If LT is <=, and LT.semver does not satisfy every C, return false
|
||||
// - If GT.semver has a prerelease, and not in prerelease mode
|
||||
// - If LT.semver has a prerelease, and not in prerelease mode
|
||||
// - If no C has a prerelease and the LT.semver tuple, return false
|
||||
// - Else return true
|
||||
|
||||
|
||||
Generated
Vendored
+18
-12
@@ -1,7 +1,6 @@
|
||||
#include <jsi/jsi.h>
|
||||
#include <worklets/AnimationFrameQueue/AnimationFrameBatchinator.h>
|
||||
#include <worklets/SharedItems/Serializable.h>
|
||||
#include <worklets/WorkletRuntime/RuntimeBindings.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
@@ -12,22 +11,26 @@
|
||||
|
||||
namespace worklets {
|
||||
|
||||
void AnimationFrameBatchinator::addToBatch(jsi::Function &&callback) {
|
||||
void AnimationFrameBatchinator::addToBatch(
|
||||
const facebook::jsi::Value &callback) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(callbacksMutex_);
|
||||
callbacks_.push_back(std::make_shared<const jsi::Function>(std::move(callback)));
|
||||
callbacks_.push_back(
|
||||
std::make_shared<const facebook::jsi::Value>(*uiRuntime_, callback));
|
||||
}
|
||||
flush();
|
||||
}
|
||||
|
||||
AnimationFrameBatchinator::JsiRequestAnimationFrame AnimationFrameBatchinator::getJsiRequestAnimationFrame() {
|
||||
return [weakThis = weak_from_this()](facebook::jsi::Runtime &rt, const facebook::jsi::Value &callback) {
|
||||
AnimationFrameBatchinator::JsiRequestAnimationFrame
|
||||
AnimationFrameBatchinator::getJsiRequestAnimationFrame() {
|
||||
return [weakThis = weak_from_this()](
|
||||
facebook::jsi::Runtime &rt, const facebook::jsi::Value &callback) {
|
||||
const auto strongThis = weakThis.lock();
|
||||
if (!strongThis) {
|
||||
return;
|
||||
}
|
||||
|
||||
strongThis->addToBatch(callback.asObject(rt).asFunction(rt));
|
||||
strongThis->addToBatch(callback);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -45,21 +48,24 @@ void AnimationFrameBatchinator::flush() {
|
||||
auto callbacks = strongThis->pullCallbacks();
|
||||
strongThis->flushRequested_ = false;
|
||||
|
||||
auto &uiWorkletRuntime = strongThis->uiWorkletRuntime_;
|
||||
auto &uiRuntime = *(strongThis->uiRuntime_);
|
||||
for (const auto &callback : callbacks) {
|
||||
uiWorkletRuntime->runSync(*callback, timestampMs);
|
||||
runOnRuntimeGuarded(uiRuntime, *callback, timestampMs);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<const jsi::Function>> AnimationFrameBatchinator::pullCallbacks() {
|
||||
std::vector<std::shared_ptr<const facebook::jsi::Value>>
|
||||
AnimationFrameBatchinator::pullCallbacks() {
|
||||
std::lock_guard<std::mutex> lock(callbacksMutex_);
|
||||
return std::move(callbacks_);
|
||||
}
|
||||
|
||||
AnimationFrameBatchinator::AnimationFrameBatchinator(
|
||||
const std::shared_ptr<WorkletRuntime> &uiWorkletRuntime,
|
||||
RuntimeBindings::RequestAnimationFrame requestAnimationFrame)
|
||||
: uiWorkletRuntime_(uiWorkletRuntime), requestAnimationFrame_(std::move(requestAnimationFrame)) {}
|
||||
facebook::jsi::Runtime &uiRuntime,
|
||||
std::function<void(std::function<void(const double)>)>
|
||||
&&forwardedRequestAnimationFrame)
|
||||
: uiRuntime_(&uiRuntime),
|
||||
requestAnimationFrame_(std::move(forwardedRequestAnimationFrame)) {}
|
||||
|
||||
} // namespace worklets
|
||||
|
||||
Generated
Vendored
+11
-11
@@ -2,9 +2,6 @@
|
||||
|
||||
#include <jsi/jsi.h>
|
||||
#include <worklets/SharedItems/Serializable.h>
|
||||
#include <worklets/WorkletRuntime/RuntimeBindings.h>
|
||||
#include <worklets/WorkletRuntime/WorkletRuntime.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
@@ -13,25 +10,28 @@
|
||||
|
||||
namespace worklets {
|
||||
|
||||
class AnimationFrameBatchinator : public std::enable_shared_from_this<AnimationFrameBatchinator> {
|
||||
class AnimationFrameBatchinator
|
||||
: public std::enable_shared_from_this<AnimationFrameBatchinator> {
|
||||
public:
|
||||
using JsiRequestAnimationFrame = std::function<void(jsi::Runtime &, const jsi::Value &)>;
|
||||
using JsiRequestAnimationFrame = std::function<
|
||||
void(facebook::jsi::Runtime &, const facebook::jsi::Value &)>;
|
||||
|
||||
void addToBatch(jsi::Function &&callback);
|
||||
void addToBatch(const facebook::jsi::Value &callback);
|
||||
JsiRequestAnimationFrame getJsiRequestAnimationFrame();
|
||||
|
||||
AnimationFrameBatchinator(
|
||||
const std::shared_ptr<WorkletRuntime> &uiWorkletRuntime,
|
||||
RuntimeBindings::RequestAnimationFrame requestAnimationFrame);
|
||||
facebook::jsi::Runtime &uiRuntime,
|
||||
std::function<void(std::function<void(const double)>)>
|
||||
&&forwardedRequestAnimationFrame);
|
||||
|
||||
private:
|
||||
void flush();
|
||||
std::vector<std::shared_ptr<const jsi::Function>> pullCallbacks();
|
||||
std::vector<std::shared_ptr<const facebook::jsi::Value>> pullCallbacks();
|
||||
|
||||
std::vector<std::shared_ptr<const jsi::Function>> callbacks_{};
|
||||
std::vector<std::shared_ptr<const facebook::jsi::Value>> callbacks_{};
|
||||
std::mutex callbacksMutex_{};
|
||||
std::atomic_bool flushRequested_{};
|
||||
std::shared_ptr<WorkletRuntime> uiWorkletRuntime_;
|
||||
facebook::jsi::Runtime *uiRuntime_;
|
||||
std::function<void(std::function<void(const double)>)> requestAnimationFrame_;
|
||||
};
|
||||
|
||||
|
||||
Generated
Vendored
+308
-142
@@ -14,10 +14,7 @@
|
||||
#include <fbjni/fbjni.h>
|
||||
#endif // __ANDROID__
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace facebook;
|
||||
|
||||
@@ -50,7 +47,7 @@ inline void scheduleOnUI(
|
||||
const auto scope = jsi::Scope(uiWorkletRuntime->getJSIRuntime());
|
||||
#endif // JS_RUNTIME_HERMES
|
||||
|
||||
uiWorkletRuntime->runSync(serializableWorklet);
|
||||
uiWorkletRuntime->runGuarded(serializableWorklet);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -59,10 +56,7 @@ inline jsi::Value executeOnUIRuntimeSync(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &worklet) {
|
||||
if (auto uiWorkletRuntime = weakUIWorkletRuntime.lock()) {
|
||||
auto serializableWorklet = extractSerializableOrThrow<SerializableWorklet>(
|
||||
rt, worklet, "[Worklets] Only worklets can be executed on UI runtime.");
|
||||
auto serializedResult = uiWorkletRuntime->runSyncSerialized(serializableWorklet);
|
||||
return serializedResult->toJSValue(rt);
|
||||
return uiWorkletRuntime->executeSync(rt, worklet);
|
||||
}
|
||||
return jsi::Value::undefined();
|
||||
}
|
||||
@@ -76,8 +70,8 @@ inline jsi::Value createWorkletRuntime(
|
||||
std::shared_ptr<SerializableWorklet> &initializer,
|
||||
const std::shared_ptr<AsyncQueue> &queue,
|
||||
bool enableEventLoop) {
|
||||
const auto workletRuntime =
|
||||
runtimeManager->createWorkletRuntime(std::move(jsiWorkletsModuleProxy), name, initializer, queue);
|
||||
const auto workletRuntime = runtimeManager->createWorkletRuntime(
|
||||
jsiWorkletsModuleProxy, name, initializer, queue);
|
||||
return jsi::Object::createFromHostObject(originRuntime, workletRuntime);
|
||||
}
|
||||
|
||||
@@ -89,9 +83,10 @@ inline jsi::Value propagateModuleUpdate(
|
||||
const auto runtimes = runtimeManager->getAllRuntimes();
|
||||
|
||||
for (auto runtime : runtimes) {
|
||||
runtime->runSync([code, sourceUrl](jsi::Runtime &rt) -> void {
|
||||
runtime->executeSync([code, sourceUrl](jsi::Runtime &rt) {
|
||||
const auto buffer = std::make_shared<jsi::StringBuffer>(code);
|
||||
rt.evaluateJavaScript(buffer, sourceUrl);
|
||||
return jsi::Value::undefined();
|
||||
});
|
||||
}
|
||||
return jsi::Value::undefined();
|
||||
@@ -105,11 +100,18 @@ inline jsi::Value reportFatalErrorOnJS(
|
||||
const std::string &name,
|
||||
const std::string &jsEngine) {
|
||||
JSLogger::reportFatalErrorOnJS(
|
||||
jsScheduler, JSErrorData{.message = message, .stack = stack, .name = name, .jsEngine = jsEngine});
|
||||
jsScheduler,
|
||||
JSErrorData{
|
||||
.message = message,
|
||||
.stack = stack,
|
||||
.name = name,
|
||||
.jsEngine = jsEngine});
|
||||
return jsi::Value::undefined();
|
||||
}
|
||||
|
||||
inline std::shared_ptr<AsyncQueue> extractAsyncQueue(jsi::Runtime &rt, const jsi::Value &value) {
|
||||
inline std::shared_ptr<AsyncQueue> extractAsyncQueue(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &value) {
|
||||
if (!value.isObject()) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -125,33 +127,13 @@ inline std::shared_ptr<AsyncQueue> extractAsyncQueue(jsi::Runtime &rt, const jsi
|
||||
return asyncQueue;
|
||||
}
|
||||
|
||||
inline void registerCustomSerializable(
|
||||
const std::shared_ptr<RuntimeManager> &runtimeManager,
|
||||
const std::shared_ptr<MemoryManager> &memoryManager,
|
||||
const std::shared_ptr<SerializableWorklet> &determine,
|
||||
const std::shared_ptr<SerializableWorklet> &pack,
|
||||
const std::shared_ptr<SerializableWorklet> &unpack,
|
||||
const int typeId) {
|
||||
const SerializationData data{.determine = determine, .pack = pack, .unpack = unpack, .typeId = typeId};
|
||||
// Prevent registering new worklet runtimes while we are updating existing ones to prevent inconsistencies.
|
||||
runtimeManager->pause();
|
||||
|
||||
memoryManager->registerCustomSerializable(data);
|
||||
for (const auto &runtime : runtimeManager->getAllRuntimes()) {
|
||||
memoryManager->loadCustomSerializable(runtime, data);
|
||||
}
|
||||
|
||||
runtimeManager->resume();
|
||||
}
|
||||
|
||||
JSIWorkletsModuleProxy::JSIWorkletsModuleProxy(
|
||||
const bool isDevBundle,
|
||||
const std::shared_ptr<const JSBigStringBuffer> &script,
|
||||
const std::shared_ptr<const BigStringBuffer> &script,
|
||||
const std::string &sourceUrl,
|
||||
const std::shared_ptr<MessageQueueThread> &jsQueue,
|
||||
const std::shared_ptr<JSScheduler> &jsScheduler,
|
||||
const std::shared_ptr<UIScheduler> &uiScheduler,
|
||||
const std::shared_ptr<MemoryManager> &memoryManager,
|
||||
const std::shared_ptr<RuntimeManager> &runtimeManager,
|
||||
const std::weak_ptr<WorkletRuntime> &uiWorkletRuntime)
|
||||
: jsi::HostObject(),
|
||||
@@ -161,11 +143,11 @@ JSIWorkletsModuleProxy::JSIWorkletsModuleProxy(
|
||||
jsQueue_(jsQueue),
|
||||
jsScheduler_(jsScheduler),
|
||||
uiScheduler_(uiScheduler),
|
||||
memoryManager_(memoryManager),
|
||||
runtimeManager_(runtimeManager),
|
||||
uiWorkletRuntime_(uiWorkletRuntime) {}
|
||||
|
||||
JSIWorkletsModuleProxy::JSIWorkletsModuleProxy(const JSIWorkletsModuleProxy &other)
|
||||
JSIWorkletsModuleProxy::JSIWorkletsModuleProxy(
|
||||
const JSIWorkletsModuleProxy &other)
|
||||
: jsi::HostObject(),
|
||||
isDevBundle_(other.isDevBundle_),
|
||||
script_(other.script_),
|
||||
@@ -173,203 +155,315 @@ JSIWorkletsModuleProxy::JSIWorkletsModuleProxy(const JSIWorkletsModuleProxy &oth
|
||||
jsQueue_(other.jsQueue_),
|
||||
jsScheduler_(other.jsScheduler_),
|
||||
uiScheduler_(other.uiScheduler_),
|
||||
memoryManager_(other.memoryManager_),
|
||||
runtimeManager_(other.runtimeManager_),
|
||||
uiWorkletRuntime_(other.uiWorkletRuntime_) {}
|
||||
|
||||
JSIWorkletsModuleProxy::~JSIWorkletsModuleProxy() = default;
|
||||
|
||||
std::vector<jsi::PropNameID> JSIWorkletsModuleProxy::getPropertyNames(jsi::Runtime &rt) {
|
||||
std::vector<jsi::PropNameID> JSIWorkletsModuleProxy::getPropertyNames(
|
||||
jsi::Runtime &rt) {
|
||||
std::vector<jsi::PropNameID> propertyNames;
|
||||
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "createSerializable"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "createSerializableBigInt"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "createSerializableBoolean"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "createSerializableImport"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "createSerializableNull"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "createSerializableNumber"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "createSerializableString"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "createSerializableUndefined"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "createSerializableHostObject"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "createSerializableInitializer"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "createSerializableArray"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "createSerializableFunction"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "createSerializableTurboModuleLike"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "createSerializableObject"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "createSerializableMap"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "createSerializableSet"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "createSerializableWorklet"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "createCustomSerializable"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "registerCustomSerializable"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "createSerializable"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "createSerializableBigInt"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "createSerializableBoolean"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "createSerializableImport"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "createSerializableNull"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "createSerializableNumber"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "createSerializableString"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "createSerializableUndefined"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "createSerializableHostObject"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "createSerializableInitializer"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "createSerializableArray"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "createSerializableFunction"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "createSerializableTurboModuleLike"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "createSerializableObject"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "createSerializableMap"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "createSerializableSet"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "createSerializableWorklet"));
|
||||
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "scheduleOnUI"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "executeOnUIRuntimeSync"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "createWorkletRuntime"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "scheduleOnRuntime"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "reportFatalErrorOnJS"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "executeOnUIRuntimeSync"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "createWorkletRuntime"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "scheduleOnRuntime"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "reportFatalErrorOnJS"));
|
||||
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "getStaticFeatureFlag"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "setDynamicFeatureFlag"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "getStaticFeatureFlag"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "setDynamicFeatureFlag"));
|
||||
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "createSynchronizable"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "synchronizableGetDirty"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "synchronizableGetBlocking"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "synchronizableSetBlocking"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "synchronizableLock"));
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "synchronizableUnlock"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "createSynchronizable"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "synchronizableGetDirty"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "synchronizableGetBlocking"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "synchronizableSetBlocking"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "synchronizableLock"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "synchronizableUnlock"));
|
||||
|
||||
#ifdef WORKLETS_BUNDLE_MODE
|
||||
propertyNames.emplace_back(jsi::PropNameID::forAscii(rt, "propagateModuleUpdate"));
|
||||
propertyNames.emplace_back(
|
||||
jsi::PropNameID::forAscii(rt, "propagateModuleUpdate"));
|
||||
#endif // WORKLETS_BUNDLE_MODE
|
||||
|
||||
return propertyNames;
|
||||
}
|
||||
|
||||
jsi::Value JSIWorkletsModuleProxy::get(jsi::Runtime &rt, const jsi::PropNameID &propName) {
|
||||
jsi::Value JSIWorkletsModuleProxy::get(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::PropNameID &propName) {
|
||||
const auto name = propName.utf8(rt);
|
||||
|
||||
if (name == "createSerializable") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 3, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
rt,
|
||||
propName,
|
||||
3,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
return makeSerializableClone(rt, args[0], args[1], args[2]);
|
||||
});
|
||||
}
|
||||
|
||||
if (name == "createSerializableBigInt") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 1, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
rt,
|
||||
propName,
|
||||
1,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
return makeSerializableBigInt(rt, args[0].asBigInt(rt));
|
||||
});
|
||||
}
|
||||
|
||||
if (name == "createSerializableBoolean") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 1, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
rt,
|
||||
propName,
|
||||
1,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
return makeSerializableBoolean(rt, args[0].asBool());
|
||||
});
|
||||
}
|
||||
|
||||
if (name == "createSerializableImport") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 2, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
return makeSerializableImport(rt, args[0].asNumber(), args[1].asString(rt));
|
||||
rt,
|
||||
propName,
|
||||
2,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
return makeSerializableImport(
|
||||
rt, args[0].asNumber(), args[1].asString(rt));
|
||||
});
|
||||
}
|
||||
|
||||
if (name == "createSerializableNumber") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 1, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
rt,
|
||||
propName,
|
||||
1,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
return makeSerializableNumber(rt, args[0].asNumber());
|
||||
});
|
||||
}
|
||||
|
||||
if (name == "createSerializableNull") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 0, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
return makeSerializableNull(rt);
|
||||
});
|
||||
rt,
|
||||
propName,
|
||||
0,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) { return makeSerializableNull(rt); });
|
||||
}
|
||||
|
||||
if (name == "createSerializableString") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 1, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
rt,
|
||||
propName,
|
||||
1,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
return makeSerializableString(rt, args[0].asString(rt));
|
||||
});
|
||||
}
|
||||
|
||||
if (name == "createSerializableUndefined") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 0, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
return makeSerializableUndefined(rt);
|
||||
});
|
||||
rt,
|
||||
propName,
|
||||
0,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) { return makeSerializableUndefined(rt); });
|
||||
}
|
||||
|
||||
if (name == "createSerializableInitializer") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 1, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
rt,
|
||||
propName,
|
||||
1,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
return makeSerializableInitializer(rt, args[0].asObject(rt));
|
||||
});
|
||||
}
|
||||
|
||||
if (name == "createSerializableArray") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 2, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
return makeSerializableArray(rt, args[0].asObject(rt).asArray(rt), args[1]);
|
||||
rt,
|
||||
propName,
|
||||
2,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
return makeSerializableArray(
|
||||
rt, args[0].asObject(rt).asArray(rt), args[1]);
|
||||
});
|
||||
}
|
||||
|
||||
if (name == "createSerializableMap") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 2, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
return makeSerializableMap(rt, args[0].asObject(rt).asArray(rt), args[1].asObject(rt).asArray(rt));
|
||||
rt,
|
||||
propName,
|
||||
2,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
return makeSerializableMap(
|
||||
rt,
|
||||
args[0].asObject(rt).asArray(rt),
|
||||
args[1].asObject(rt).asArray(rt));
|
||||
});
|
||||
}
|
||||
|
||||
if (name == "createSerializableSet") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 1, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
rt,
|
||||
propName,
|
||||
1,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
return makeSerializableSet(rt, args[0].asObject(rt).asArray(rt));
|
||||
});
|
||||
}
|
||||
|
||||
if (name == "createSerializableHostObject") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 1, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
return makeSerializableHostObject(rt, args[0].asObject(rt).asHostObject(rt));
|
||||
rt,
|
||||
propName,
|
||||
1,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
return makeSerializableHostObject(
|
||||
rt, args[0].asObject(rt).asHostObject(rt));
|
||||
});
|
||||
}
|
||||
|
||||
if (name == "createSerializableFunction") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 1, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
return makeSerializableFunction(rt, args[0].asObject(rt).asFunction(rt));
|
||||
rt,
|
||||
propName,
|
||||
1,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
return makeSerializableFunction(
|
||||
rt, args[0].asObject(rt).asFunction(rt));
|
||||
});
|
||||
}
|
||||
|
||||
if (name == "createSerializableTurboModuleLike") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 2, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
return makeSerializableTurboModuleLike(rt, args[0].asObject(rt), args[1].asObject(rt).asHostObject(rt));
|
||||
rt,
|
||||
propName,
|
||||
2,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
return makeSerializableTurboModuleLike(
|
||||
rt, args[0].asObject(rt), args[1].asObject(rt).asHostObject(rt));
|
||||
});
|
||||
}
|
||||
|
||||
if (name == "createSerializableObject") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 1, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
return makeSerializableObject(rt, args[0].getObject(rt), args[1].getBool(), args[2]);
|
||||
rt,
|
||||
propName,
|
||||
1,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
return makeSerializableObject(
|
||||
rt, args[0].getObject(rt), args[1].getBool(), args[2]);
|
||||
});
|
||||
}
|
||||
|
||||
if (name == "createSerializableWorklet") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 2, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
return makeSerializableWorklet(rt, args[0].getObject(rt), args[1].getBool());
|
||||
});
|
||||
}
|
||||
|
||||
if (name == "createCustomSerializable") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 2, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
return makeCustomSerializable(rt, args[0], args[1].asNumber());
|
||||
});
|
||||
}
|
||||
|
||||
if (name == "registerCustomSerializable") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt,
|
||||
propName,
|
||||
4,
|
||||
[memoryManager = memoryManager_, runtimeManager = runtimeManager_](
|
||||
jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
const auto determine = extractSerializableOrThrow<SerializableWorklet>(
|
||||
rt, args[0], "[Worklets] Determine function must be a worklet.");
|
||||
const auto pack = extractSerializableOrThrow<SerializableWorklet>(
|
||||
rt, args[1], "[Worklets] Pack function must be a worklet.");
|
||||
const auto unpack = extractSerializableOrThrow<SerializableWorklet>(
|
||||
rt, args[2], "[Worklets] Unpack function must be a worklet.");
|
||||
const auto typeId = args[3].asNumber();
|
||||
registerCustomSerializable(runtimeManager, memoryManager, determine, pack, unpack, typeId);
|
||||
return jsi::Value::undefined();
|
||||
2,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
return makeSerializableWorklet(
|
||||
rt, args[0].getObject(rt), args[1].getBool());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -379,7 +473,10 @@ jsi::Value JSIWorkletsModuleProxy::get(jsi::Runtime &rt, const jsi::PropNameID &
|
||||
propName,
|
||||
1,
|
||||
[uiScheduler = uiScheduler_, uiWorkletRuntime = uiWorkletRuntime_](
|
||||
jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
scheduleOnUI(uiScheduler, uiWorkletRuntime, rt, args[0]);
|
||||
return jsi::Value::undefined();
|
||||
});
|
||||
@@ -391,7 +488,10 @@ jsi::Value JSIWorkletsModuleProxy::get(jsi::Runtime &rt, const jsi::PropNameID &
|
||||
propName,
|
||||
1,
|
||||
[uiWorkletRuntime = uiWorkletRuntime_](
|
||||
jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
return executeOnUIRuntimeSync(uiWorkletRuntime, rt, args[0]);
|
||||
});
|
||||
}
|
||||
@@ -402,10 +502,14 @@ jsi::Value JSIWorkletsModuleProxy::get(jsi::Runtime &rt, const jsi::PropNameID &
|
||||
propName,
|
||||
5,
|
||||
[clone = std::make_shared<JSIWorkletsModuleProxy>(*this)](
|
||||
jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
const auto name = args[0].asString(rt).utf8(rt);
|
||||
auto serializableInitializer =
|
||||
extractSerializableOrThrow<SerializableWorklet>(rt, args[1], "[Worklets] Initializer must be a worklet.");
|
||||
extractSerializableOrThrow<SerializableWorklet>(
|
||||
rt, args[1], "[Worklets] Initializer must be a worklet.");
|
||||
const auto useDefaultQueue = args[2].asBool();
|
||||
|
||||
std::shared_ptr<AsyncQueue> asyncQueue;
|
||||
@@ -431,7 +535,13 @@ jsi::Value JSIWorkletsModuleProxy::get(jsi::Runtime &rt, const jsi::PropNameID &
|
||||
|
||||
if (name == "scheduleOnRuntime") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 2, [](jsi::Runtime &rt, const jsi ::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
rt,
|
||||
propName,
|
||||
2,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi ::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
worklets::scheduleOnRuntime(rt, args[0], args[1]);
|
||||
return jsi::Value::undefined();
|
||||
});
|
||||
@@ -443,7 +553,10 @@ jsi::Value JSIWorkletsModuleProxy::get(jsi::Runtime &rt, const jsi::PropNameID &
|
||||
propName,
|
||||
4,
|
||||
[jsScheduler = jsScheduler_](
|
||||
jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
return reportFatalErrorOnJS(
|
||||
jsScheduler,
|
||||
/* message */ args[0].asString(rt).utf8(rt),
|
||||
@@ -455,8 +568,15 @@ jsi::Value JSIWorkletsModuleProxy::get(jsi::Runtime &rt, const jsi::PropNameID &
|
||||
|
||||
if (name == "createSynchronizable") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 1, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
auto initial = extractSerializableOrThrow(rt, args[0], "[Worklets] Value must be a Serializable.");
|
||||
rt,
|
||||
propName,
|
||||
1,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
auto initial = extractSerializableOrThrow(
|
||||
rt, args[0], "[Worklets] Value must be a Serializable.");
|
||||
auto synchronizable = std::make_shared<Synchronizable>(initial);
|
||||
return SerializableJSRef::newNativeStateObject(rt, synchronizable);
|
||||
});
|
||||
@@ -464,7 +584,13 @@ jsi::Value JSIWorkletsModuleProxy::get(jsi::Runtime &rt, const jsi::PropNameID &
|
||||
|
||||
if (name == "synchronizableGetDirty") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 1, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
rt,
|
||||
propName,
|
||||
1,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
auto synchronizable = extractSynchronizableOrThrow(rt, args[0]);
|
||||
return synchronizable->getDirty()->toJSValue(rt);
|
||||
});
|
||||
@@ -472,7 +598,13 @@ jsi::Value JSIWorkletsModuleProxy::get(jsi::Runtime &rt, const jsi::PropNameID &
|
||||
|
||||
if (name == "synchronizableGetBlocking") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 1, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
rt,
|
||||
propName,
|
||||
1,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
auto synchronizable = extractSynchronizableOrThrow(rt, args[0]);
|
||||
return synchronizable->getBlocking()->toJSValue(rt);
|
||||
});
|
||||
@@ -480,17 +612,30 @@ jsi::Value JSIWorkletsModuleProxy::get(jsi::Runtime &rt, const jsi::PropNameID &
|
||||
|
||||
if (name == "synchronizableSetBlocking") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 2, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
rt,
|
||||
propName,
|
||||
2,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
auto synchronizable = extractSynchronizableOrThrow(rt, args[0]);
|
||||
auto newValue = extractSerializableOrThrow(rt, args[1], "[Worklets] Value must be a Serializable.");
|
||||
synchronizable->setBlocking(newValue);
|
||||
auto newValue = extractSerializableOrThrow(
|
||||
rt, args[1], "[Worklets] Value must be a Serializable.");
|
||||
synchronizable->setBlocking(std::move(newValue));
|
||||
return jsi::Value::undefined();
|
||||
});
|
||||
}
|
||||
|
||||
if (name == "synchronizableLock") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 1, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
rt,
|
||||
propName,
|
||||
1,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
auto synchronizable = extractSynchronizableOrThrow(rt, args[0]);
|
||||
synchronizable->lock();
|
||||
return jsi::Value::undefined();
|
||||
@@ -499,7 +644,13 @@ jsi::Value JSIWorkletsModuleProxy::get(jsi::Runtime &rt, const jsi::PropNameID &
|
||||
|
||||
if (name == "synchronizableUnlock") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 1, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
rt,
|
||||
propName,
|
||||
1,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
auto synchronizable = extractSynchronizableOrThrow(rt, args[0]);
|
||||
synchronizable->unlock();
|
||||
return jsi::Value::undefined();
|
||||
@@ -513,7 +664,10 @@ jsi::Value JSIWorkletsModuleProxy::get(jsi::Runtime &rt, const jsi::PropNameID &
|
||||
propName,
|
||||
2,
|
||||
[runtimeManager = runtimeManager_](
|
||||
jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
return propagateModuleUpdate(
|
||||
runtimeManager,
|
||||
/* code */ args[0].asString(rt).utf8(rt),
|
||||
@@ -524,7 +678,13 @@ jsi::Value JSIWorkletsModuleProxy::get(jsi::Runtime &rt, const jsi::PropNameID &
|
||||
|
||||
if (name == "getStaticFeatureFlag") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 2, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
rt,
|
||||
propName,
|
||||
2,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
return worklets::StaticFeatureFlags::getFlag(
|
||||
/* name */ args[0].asString(rt).utf8(rt));
|
||||
});
|
||||
@@ -532,7 +692,13 @@ jsi::Value JSIWorkletsModuleProxy::get(jsi::Runtime &rt, const jsi::PropNameID &
|
||||
|
||||
if (name == "setDynamicFeatureFlag") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, propName, 2, [](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) {
|
||||
rt,
|
||||
propName,
|
||||
2,
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) {
|
||||
worklets::DynamicFeatureFlags::setFlag(
|
||||
/* name */ args[0].asString(rt).utf8(rt),
|
||||
/* value */ args[1].asBool());
|
||||
|
||||
Generated
Vendored
+3
-10
@@ -5,7 +5,6 @@
|
||||
#include <react/renderer/uimanager/UIManagerBinding.h>
|
||||
#include <react/renderer/uimanager/primitives.h>
|
||||
|
||||
#include <worklets/SharedItems/MemoryManager.h>
|
||||
#include <worklets/SharedItems/Serializable.h>
|
||||
#include <worklets/Tools/Defs.h>
|
||||
#include <worklets/WorkletRuntime/RuntimeManager.h>
|
||||
@@ -31,12 +30,11 @@ class JSIWorkletsModuleProxy : public jsi::HostObject {
|
||||
public:
|
||||
explicit JSIWorkletsModuleProxy(
|
||||
const bool isDevBundle,
|
||||
const std::shared_ptr<const JSBigStringBuffer> &script,
|
||||
const std::shared_ptr<const BigStringBuffer> &script,
|
||||
const std::string &sourceUrl,
|
||||
const std::shared_ptr<MessageQueueThread> &jsQueue,
|
||||
const std::shared_ptr<JSScheduler> &jsScheduler,
|
||||
const std::shared_ptr<UIScheduler> &uiScheduler,
|
||||
const std::shared_ptr<MemoryManager> &memoryManager,
|
||||
const std::shared_ptr<RuntimeManager> &runtimeManager,
|
||||
const std::weak_ptr<WorkletRuntime> &uiWorkletRuntime);
|
||||
|
||||
@@ -64,7 +62,7 @@ class JSIWorkletsModuleProxy : public jsi::HostObject {
|
||||
return isDevBundle_;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::shared_ptr<const JSBigStringBuffer> getScript() const {
|
||||
[[nodiscard]] std::shared_ptr<const BigStringBuffer> getScript() const {
|
||||
return script_;
|
||||
}
|
||||
|
||||
@@ -72,22 +70,17 @@ class JSIWorkletsModuleProxy : public jsi::HostObject {
|
||||
return sourceUrl_;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::shared_ptr<MemoryManager> getMemoryManager() const {
|
||||
return memoryManager_;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::shared_ptr<RuntimeManager> getRuntimeManager() const {
|
||||
return runtimeManager_;
|
||||
}
|
||||
|
||||
private:
|
||||
const bool isDevBundle_;
|
||||
const std::shared_ptr<const JSBigStringBuffer> script_;
|
||||
const std::shared_ptr<const BigStringBuffer> script_;
|
||||
const std::string sourceUrl_;
|
||||
const std::shared_ptr<MessageQueueThread> jsQueue_;
|
||||
const std::shared_ptr<JSScheduler> jsScheduler_;
|
||||
const std::shared_ptr<UIScheduler> uiScheduler_;
|
||||
const std::shared_ptr<MemoryManager> memoryManager_;
|
||||
const std::shared_ptr<RuntimeManager> runtimeManager_;
|
||||
const std::weak_ptr<WorkletRuntime> uiWorkletRuntime_;
|
||||
};
|
||||
|
||||
Generated
Vendored
+20
-15
@@ -5,7 +5,6 @@
|
||||
#include <worklets/RunLoop/AsyncQueueImpl.h>
|
||||
#include <worklets/SharedItems/Serializable.h>
|
||||
#include <worklets/Tools/Defs.h>
|
||||
#include <worklets/WorkletRuntime/RuntimeBindings.h>
|
||||
#include <worklets/WorkletRuntime/UIRuntimeDecorator.h>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
@@ -13,7 +12,6 @@
|
||||
#endif // __ANDROID__
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
using namespace facebook;
|
||||
@@ -28,36 +26,44 @@ WorkletsModuleProxy::WorkletsModuleProxy(
|
||||
const std::shared_ptr<CallInvoker> &jsCallInvoker,
|
||||
const std::shared_ptr<UIScheduler> &uiScheduler,
|
||||
std::function<bool()> &&isJavaScriptThread,
|
||||
RuntimeBindings runtimeBindings,
|
||||
const std::shared_ptr<const JSBigStringBuffer> &script,
|
||||
std::function<void(std::function<void(const double)>)>
|
||||
&&forwardedRequestAnimationFrame,
|
||||
const std::shared_ptr<const BigStringBuffer> &script,
|
||||
const std::string &sourceUrl)
|
||||
: isDevBundle_(isDevBundleFromRNRuntime(rnRuntime)),
|
||||
jsQueue_(jsQueue),
|
||||
jsScheduler_(std::make_shared<JSScheduler>(rnRuntime, jsCallInvoker, std::move(isJavaScriptThread))),
|
||||
jsScheduler_(std::make_shared<JSScheduler>(
|
||||
rnRuntime,
|
||||
jsCallInvoker,
|
||||
std::move(isJavaScriptThread))),
|
||||
uiScheduler_(uiScheduler),
|
||||
jsLogger_(std::make_shared<JSLogger>(jsScheduler_)),
|
||||
runtimeBindings_(std::move(runtimeBindings)),
|
||||
script_(script),
|
||||
sourceUrl_(sourceUrl),
|
||||
memoryManager_(std::make_shared<MemoryManager>()),
|
||||
runtimeManager_(std::make_shared<RuntimeManager>()),
|
||||
uiWorkletRuntime_(
|
||||
runtimeManager_->createUninitializedUIRuntime(jsQueue_, std::make_shared<AsyncQueueUI>(uiScheduler_))) {
|
||||
uiWorkletRuntime_(runtimeManager_->createUninitializedUIRuntime(
|
||||
jsQueue_,
|
||||
std::make_shared<AsyncQueueUI>(uiScheduler_))) {
|
||||
/**
|
||||
* We call additional `init` method here because
|
||||
* JSIWorkletsModuleProxy needs a weak_ptr to the UI Runtime.
|
||||
*/
|
||||
uiWorkletRuntime_->init(createJSIWorkletsModuleProxy());
|
||||
|
||||
animationFrameBatchinator_ =
|
||||
std::make_shared<AnimationFrameBatchinator>(uiWorkletRuntime_, runtimeBindings_.requestAnimationFrame);
|
||||
animationFrameBatchinator_ = std::make_shared<AnimationFrameBatchinator>(
|
||||
uiWorkletRuntime_->getJSIRuntime(),
|
||||
std::move(forwardedRequestAnimationFrame));
|
||||
|
||||
UIRuntimeDecorator::decorate(
|
||||
uiWorkletRuntime_->getJSIRuntime(), animationFrameBatchinator_->getJsiRequestAnimationFrame());
|
||||
uiWorkletRuntime_->getJSIRuntime(),
|
||||
animationFrameBatchinator_->getJsiRequestAnimationFrame());
|
||||
}
|
||||
|
||||
std::shared_ptr<JSIWorkletsModuleProxy> WorkletsModuleProxy::createJSIWorkletsModuleProxy() const {
|
||||
assert(uiWorkletRuntime_ && "UI Worklet Runtime must be initialized before creating JSI proxy.");
|
||||
std::shared_ptr<JSIWorkletsModuleProxy>
|
||||
WorkletsModuleProxy::createJSIWorkletsModuleProxy() const {
|
||||
assert(
|
||||
uiWorkletRuntime_ &&
|
||||
"UI Worklet Runtime must be initialized before creating JSI proxy.");
|
||||
return std::make_shared<JSIWorkletsModuleProxy>(
|
||||
isDevBundle_,
|
||||
script_,
|
||||
@@ -65,7 +71,6 @@ std::shared_ptr<JSIWorkletsModuleProxy> WorkletsModuleProxy::createJSIWorkletsMo
|
||||
jsQueue_,
|
||||
jsScheduler_,
|
||||
uiScheduler_,
|
||||
memoryManager_,
|
||||
runtimeManager_,
|
||||
uiWorkletRuntime_);
|
||||
}
|
||||
|
||||
Generated
Vendored
+10
-10
@@ -5,8 +5,6 @@
|
||||
#include <jsireact/JSIExecutor.h>
|
||||
#include <worklets/AnimationFrameQueue/AnimationFrameBatchinator.h>
|
||||
#include <worklets/NativeModules/JSIWorkletsModuleProxy.h>
|
||||
#include <worklets/SharedItems/MemoryManager.h>
|
||||
#include <worklets/Tools/Defs.h>
|
||||
#include <worklets/Tools/JSLogger.h>
|
||||
#include <worklets/Tools/JSScheduler.h>
|
||||
#include <worklets/Tools/SingleInstanceChecker.h>
|
||||
@@ -19,7 +17,8 @@
|
||||
|
||||
namespace worklets {
|
||||
|
||||
class WorkletsModuleProxy : public std::enable_shared_from_this<WorkletsModuleProxy> {
|
||||
class WorkletsModuleProxy
|
||||
: public std::enable_shared_from_this<WorkletsModuleProxy> {
|
||||
public:
|
||||
explicit WorkletsModuleProxy(
|
||||
jsi::Runtime &rnRuntime,
|
||||
@@ -27,8 +26,9 @@ class WorkletsModuleProxy : public std::enable_shared_from_this<WorkletsModulePr
|
||||
const std::shared_ptr<CallInvoker> &jsCallInvoker,
|
||||
const std::shared_ptr<UIScheduler> &uiScheduler,
|
||||
std::function<bool()> &&isJavaScriptQueue,
|
||||
RuntimeBindings runtimeBindings,
|
||||
const std::shared_ptr<const JSBigStringBuffer> &script,
|
||||
std::function<void(std::function<void(const double)>)>
|
||||
&&forwardedRequestAnimationFrame,
|
||||
const std::shared_ptr<const BigStringBuffer> &script,
|
||||
const std::string &sourceUrl);
|
||||
|
||||
~WorkletsModuleProxy();
|
||||
@@ -49,11 +49,13 @@ class WorkletsModuleProxy : public std::enable_shared_from_this<WorkletsModulePr
|
||||
return jsLogger_;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline std::shared_ptr<WorkletRuntime> getUIWorkletRuntime() const {
|
||||
[[nodiscard]] inline std::shared_ptr<WorkletRuntime> getUIWorkletRuntime()
|
||||
const {
|
||||
return uiWorkletRuntime_;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::shared_ptr<JSIWorkletsModuleProxy> createJSIWorkletsModuleProxy() const;
|
||||
[[nodiscard]] std::shared_ptr<JSIWorkletsModuleProxy>
|
||||
createJSIWorkletsModuleProxy() const;
|
||||
|
||||
[[nodiscard]] inline bool isDevBundle() const {
|
||||
return isDevBundle_;
|
||||
@@ -65,10 +67,8 @@ class WorkletsModuleProxy : public std::enable_shared_from_this<WorkletsModulePr
|
||||
const std::shared_ptr<JSScheduler> jsScheduler_;
|
||||
const std::shared_ptr<UIScheduler> uiScheduler_;
|
||||
const std::shared_ptr<JSLogger> jsLogger_;
|
||||
const RuntimeBindings runtimeBindings_;
|
||||
const std::shared_ptr<const JSBigStringBuffer> script_;
|
||||
const std::shared_ptr<const BigStringBuffer> script_;
|
||||
const std::string sourceUrl_;
|
||||
const std::shared_ptr<MemoryManager> memoryManager_;
|
||||
const std::shared_ptr<RuntimeManager> runtimeManager_;
|
||||
std::shared_ptr<WorkletRuntime> uiWorkletRuntime_;
|
||||
std::shared_ptr<AnimationFrameBatchinator> animationFrameBatchinator_;
|
||||
|
||||
Generated
Vendored
+10
-8
@@ -1,14 +1,13 @@
|
||||
#include <worklets/Registries/EventHandlerRegistry.h>
|
||||
#include <worklets/Tools/WorkletEventHandler.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace worklets {
|
||||
|
||||
void EventHandlerRegistry::registerEventHandler(const std::shared_ptr<WorkletEventHandler> &eventHandler) {
|
||||
void EventHandlerRegistry::registerEventHandler(
|
||||
const std::shared_ptr<WorkletEventHandler> &eventHandler) {
|
||||
const std::lock_guard<std::mutex> lock(instanceMutex);
|
||||
const auto &eventName = eventHandler->getEventName();
|
||||
auto handlerId = eventHandler->getHandlerId();
|
||||
@@ -62,27 +61,30 @@ void EventHandlerRegistry::processEvent(
|
||||
const std::lock_guard<std::mutex> lock(instanceMutex);
|
||||
auto handlersIt = eventMappingsWithoutTag.find(eventName);
|
||||
if (handlersIt != eventMappingsWithoutTag.end()) {
|
||||
for (const auto &handler : handlersIt->second) {
|
||||
for (auto handler : handlersIt->second) {
|
||||
handlersForEvent.push_back(handler.second);
|
||||
}
|
||||
}
|
||||
const auto eventHash = std::make_pair(emitterReactTag, eventName);
|
||||
auto handlersWithTagIt = eventMappingsWithTag.find(eventHash);
|
||||
if (handlersWithTagIt != eventMappingsWithTag.end()) {
|
||||
for (const auto &handler : handlersWithTagIt->second) {
|
||||
for (auto handler : handlersWithTagIt->second) {
|
||||
handlersForEvent.push_back(handler.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
jsi::Runtime &rt = uiWorkletRuntime->getJSIRuntime();
|
||||
eventPayload.asObject(rt).setProperty(rt, "eventName", jsi::String::createFromUtf8(rt, eventName));
|
||||
for (const auto &handler : handlersForEvent) {
|
||||
eventPayload.asObject(rt).setProperty(
|
||||
rt, "eventName", jsi::String::createFromUtf8(rt, eventName));
|
||||
for (auto handler : handlersForEvent) {
|
||||
handler->process(uiWorkletRuntime, eventTimestamp, eventPayload);
|
||||
}
|
||||
}
|
||||
|
||||
bool EventHandlerRegistry::isAnyHandlerWaitingForEvent(const std::string &eventName, const int emitterReactTag) {
|
||||
bool EventHandlerRegistry::isAnyHandlerWaitingForEvent(
|
||||
const std::string &eventName,
|
||||
const int emitterReactTag) {
|
||||
const std::lock_guard<std::mutex> lock(instanceMutex);
|
||||
const auto eventHash = std::make_pair(emitterReactTag, eventName);
|
||||
auto it = eventMappingsWithTag.find(eventHash);
|
||||
|
||||
Generated
Vendored
+12
-4
@@ -18,14 +18,20 @@ namespace worklets {
|
||||
class WorkletEventHandler;
|
||||
|
||||
class EventHandlerRegistry {
|
||||
std::map<std::pair<int, std::string>, std::unordered_map<uint64_t, std::shared_ptr<WorkletEventHandler>>>
|
||||
std::map<
|
||||
std::pair<int, std::string>,
|
||||
std::unordered_map<uint64_t, std::shared_ptr<WorkletEventHandler>>>
|
||||
eventMappingsWithTag;
|
||||
std::map<std::string, std::unordered_map<uint64_t, std::shared_ptr<WorkletEventHandler>>> eventMappingsWithoutTag;
|
||||
std::map<
|
||||
std::string,
|
||||
std::unordered_map<uint64_t, std::shared_ptr<WorkletEventHandler>>>
|
||||
eventMappingsWithoutTag;
|
||||
std::map<uint64_t, std::shared_ptr<WorkletEventHandler>> eventHandlers;
|
||||
std::mutex instanceMutex;
|
||||
|
||||
public:
|
||||
void registerEventHandler(const std::shared_ptr<WorkletEventHandler> &eventHandler);
|
||||
void registerEventHandler(
|
||||
const std::shared_ptr<WorkletEventHandler> &eventHandler);
|
||||
void unregisterEventHandler(const uint64_t id);
|
||||
|
||||
void processEvent(
|
||||
@@ -35,7 +41,9 @@ class EventHandlerRegistry {
|
||||
const int emitterReactTag,
|
||||
const jsi::Value &eventPayload);
|
||||
|
||||
bool isAnyHandlerWaitingForEvent(const std::string &eventName, const int emitterReactTag);
|
||||
bool isAnyHandlerWaitingForEvent(
|
||||
const std::string &eventName,
|
||||
const int emitterReactTag);
|
||||
};
|
||||
|
||||
} // namespace worklets
|
||||
|
||||
Generated
Vendored
-2
@@ -1,7 +1,5 @@
|
||||
#include <worklets/Registries/WorkletRuntimeRegistry.h>
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace worklets {
|
||||
|
||||
std::set<jsi::Runtime *> WorkletRuntimeRegistry::registry_{};
|
||||
|
||||
Generated
Vendored
-24
@@ -1,24 +0,0 @@
|
||||
// This file was generated with
|
||||
// `packages/react-native-worklets/scripts/export-unpackers.js`.
|
||||
// Please do not modify it directly.
|
||||
|
||||
#include <worklets/Resources/Unpackers.h>
|
||||
|
||||
namespace worklets {
|
||||
|
||||
const char CustomSerializableUnpackerCode[] =
|
||||
R"DELIMITER__((function () {
|
||||
if (!globalThis.__customSerializationRegistry) {
|
||||
globalThis.__customSerializationRegistry = [];
|
||||
}
|
||||
var registry = globalThis.__customSerializationRegistry;
|
||||
function customSerializableUnpacker(value, typeId) {
|
||||
var data = registry[typeId];
|
||||
if (!data) {
|
||||
throw new Error("[Worklets] No custom serializable registered for type ID ".concat(typeId, "."));
|
||||
}
|
||||
return data.unpack(value);
|
||||
}
|
||||
globalThis.__customSerializableUnpacker = customSerializableUnpacker;
|
||||
})();)DELIMITER__";
|
||||
} // namespace worklets
|
||||
Generated
Vendored
-1
@@ -3,5 +3,4 @@
|
||||
namespace worklets {
|
||||
extern const char ValueUnpackerCode[];
|
||||
extern const char SynchronizableUnpackerCode[];
|
||||
extern const char CustomSerializableUnpackerCode[];
|
||||
} // namespace worklets
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -40,7 +40,7 @@ const char ValueUnpackerCode[] =
|
||||
} else if (category === 'RemoteFunction') {
|
||||
var fun = function fun() {
|
||||
var label = remoteFunctionName ? "function `".concat(remoteFunctionName, "`") : 'anonymous function';
|
||||
throw new Error("[Worklets] Tried to synchronously call a non-worklet ".concat(label, " on the UI thread.\nSee https://docs.swmansion.com/react-native-worklets/docs/guides/troubleshooting#tried-to-synchronously-call-a-non-worklet-function-on-the-ui-thread for more details."));
|
||||
throw new Error("[Worklets] Tried to synchronously call a non-worklet ".concat(label, " on the UI thread.\nSee https://docs.swmansion.com/react-native-reanimated/docs/guides/troubleshooting#tried-to-synchronously-call-a-non-worklet-function-on-the-ui-thread for more details."));
|
||||
};
|
||||
fun.__remoteFunction = objectToUnpack;
|
||||
return fun;
|
||||
|
||||
Generated
Vendored
-14
@@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <jsi/jsi.h>
|
||||
|
||||
namespace worklets {
|
||||
|
||||
class AsyncQueue : public facebook::jsi::NativeState {
|
||||
public:
|
||||
~AsyncQueue() override = default;
|
||||
|
||||
virtual void push(std::function<void()> &&job) = 0;
|
||||
};
|
||||
|
||||
} // namespace worklets
|
||||
Generated
Vendored
+6
-5
@@ -1,20 +1,20 @@
|
||||
#include <worklets/RunLoop/AsyncQueueImpl.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
|
||||
namespace worklets {
|
||||
|
||||
AsyncQueueImpl::AsyncQueueImpl(const std::string &name) : state_(std::make_shared<AsyncQueueState>()) {
|
||||
AsyncQueueImpl::AsyncQueueImpl(std::string name)
|
||||
: state_(std::make_shared<AsyncQueueState>()) {
|
||||
auto thread = std::thread([name, state = state_] {
|
||||
#if __APPLE__
|
||||
pthread_setname_np(name.c_str());
|
||||
#endif
|
||||
while (state->running) {
|
||||
std::unique_lock<std::mutex> lock(state->mutex);
|
||||
state->cv.wait(lock, [state] { return !state->queue.empty() || !state->running; });
|
||||
state->cv.wait(
|
||||
lock, [state] { return !state->queue.empty() || !state->running; });
|
||||
if (!state->running) {
|
||||
return;
|
||||
}
|
||||
@@ -50,7 +50,8 @@ void AsyncQueueImpl::push(std::function<void()> &&job) {
|
||||
state_->cv.notify_one();
|
||||
}
|
||||
|
||||
AsyncQueueUI::AsyncQueueUI(const std::shared_ptr<UIScheduler> &uiScheduler) : uiScheduler_(uiScheduler) {}
|
||||
AsyncQueueUI::AsyncQueueUI(const std::shared_ptr<UIScheduler> &uiScheduler)
|
||||
: uiScheduler_(uiScheduler) {}
|
||||
|
||||
void AsyncQueueUI::push(std::function<void()> &&job) {
|
||||
uiScheduler_->scheduleOnUI(std::move(job));
|
||||
|
||||
Generated
Vendored
+2
-2
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <jsi/jsi.h>
|
||||
#include <worklets/RunLoop/AsyncQueue.h>
|
||||
#include <worklets/Public/AsyncQueue.h>
|
||||
#include <worklets/Tools/UIScheduler.h>
|
||||
|
||||
#include <atomic>
|
||||
@@ -21,7 +21,7 @@ struct AsyncQueueState {
|
||||
|
||||
class AsyncQueueImpl : public AsyncQueue {
|
||||
public:
|
||||
explicit AsyncQueueImpl(const std::string &name);
|
||||
explicit AsyncQueueImpl(std::string name);
|
||||
|
||||
~AsyncQueueImpl() override;
|
||||
|
||||
|
||||
Generated
Vendored
+51
-44
@@ -1,7 +1,5 @@
|
||||
#include <worklets/RunLoop/EventLoop.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -10,9 +8,12 @@ namespace worklets {
|
||||
|
||||
EventLoop::EventLoop(
|
||||
const std::string &name,
|
||||
const std::shared_ptr<jsi::Runtime> &runtime,
|
||||
const std::shared_ptr<jsi::Runtime> runtime,
|
||||
const std::shared_ptr<AsyncQueue> &queue)
|
||||
: runtime_(runtime), queue_(queue), timeoutsQueueState_(std::make_shared<TimeoutsQueueState>()), name_(name) {}
|
||||
: runtime_(runtime),
|
||||
queue_(queue),
|
||||
timeoutsQueueState_(std::make_shared<TimeoutsQueueState>()),
|
||||
name_(name) {}
|
||||
|
||||
EventLoop::~EventLoop() {
|
||||
{
|
||||
@@ -25,50 +26,52 @@ EventLoop::~EventLoop() {
|
||||
|
||||
void EventLoop::run() {
|
||||
const auto threadName = name_ + "(timeout)";
|
||||
auto thread = std::thread([threadName, state = timeoutsQueueState_, weakThis = weak_from_this()] {
|
||||
auto thread = std::thread(
|
||||
[threadName, state = timeoutsQueueState_, weakThis = weak_from_this()] {
|
||||
#if __APPLE__
|
||||
pthread_setname_np(threadName.c_str());
|
||||
pthread_setname_np(threadName.c_str());
|
||||
#endif
|
||||
while (state->running) {
|
||||
std::unique_lock<std::mutex> lock(state->mutex);
|
||||
while (state->running) {
|
||||
std::unique_lock<std::mutex> lock(state->mutex);
|
||||
|
||||
if (state->queue.empty()) {
|
||||
state->cv.wait(lock);
|
||||
} else {
|
||||
const auto &nextTimeout = state->queue[0];
|
||||
const auto timeToWait = nextTimeout.targetTime - getCurrentTimeInMs();
|
||||
state->cv.wait_for(lock, std::chrono::milliseconds(timeToWait));
|
||||
}
|
||||
if (state->queue.empty()) {
|
||||
state->cv.wait(lock);
|
||||
} else {
|
||||
const auto &nextTimeout = state->queue[0];
|
||||
const auto timeToWait =
|
||||
nextTimeout.targetTime - getCurrentTimeInMs();
|
||||
state->cv.wait_for(lock, std::chrono::milliseconds(timeToWait));
|
||||
}
|
||||
|
||||
// Early return if the Event Loop got destroyed already.
|
||||
if (!state->running) {
|
||||
return;
|
||||
}
|
||||
// Early return if the Event Loop got destroyed already.
|
||||
if (!state->running) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto currentTime = getCurrentTimeInMs();
|
||||
std::vector<std::function<void(jsi::Runtime & rt)>> jobs;
|
||||
auto &timeouts = state->queue;
|
||||
timeouts.erase(
|
||||
std::remove_if(
|
||||
timeouts.begin(),
|
||||
timeouts.end(),
|
||||
[currentTime, &jobs](const Timeout &timeout) {
|
||||
if (currentTime >= timeout.targetTime) {
|
||||
jobs.emplace_back(timeout.callback);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}),
|
||||
timeouts.end());
|
||||
lock.unlock();
|
||||
const auto currentTime = getCurrentTimeInMs();
|
||||
std::vector<std::function<void(jsi::Runtime & rt)>> jobs;
|
||||
auto &timeouts = state->queue;
|
||||
timeouts.erase(
|
||||
std::remove_if(
|
||||
timeouts.begin(),
|
||||
timeouts.end(),
|
||||
[currentTime, &jobs](const Timeout &timeout) {
|
||||
if (currentTime >= timeout.targetTime) {
|
||||
jobs.emplace_back(timeout.callback);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}),
|
||||
timeouts.end());
|
||||
lock.unlock();
|
||||
|
||||
if (auto strongThis = weakThis.lock()) {
|
||||
for (auto &job : jobs) {
|
||||
strongThis->pushTask(std::move(job));
|
||||
if (auto strongThis = weakThis.lock()) {
|
||||
for (auto &job : jobs) {
|
||||
strongThis->pushTask(std::move(job));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
#ifdef ANDROID
|
||||
pthread_setname_np(thread.native_handle(), threadName.c_str());
|
||||
#endif
|
||||
@@ -76,14 +79,17 @@ void EventLoop::run() {
|
||||
}
|
||||
|
||||
void EventLoop::pushTask(std::function<void(jsi::Runtime &rt)> &&job) {
|
||||
queue_->push([weakRuntime = std::weak_ptr<jsi::Runtime>{runtime_}, job = std::move(job)] {
|
||||
queue_->push([weakRuntime = std::weak_ptr<jsi::Runtime>{runtime_},
|
||||
job = std::move(job)] {
|
||||
if (auto runtime = weakRuntime.lock()) {
|
||||
job(*runtime);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void EventLoop::pushTimeout(std::function<void(jsi::Runtime &rt)> &&job, int64_t delay) {
|
||||
void EventLoop::pushTimeout(
|
||||
std::function<void(jsi::Runtime &rt)> &&job,
|
||||
int64_t delay) {
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(timeoutsQueueState_->mutex);
|
||||
const auto targetTime = getCurrentTimeInMs() + delay;
|
||||
@@ -97,7 +103,8 @@ void EventLoop::pushTimeout(std::function<void(jsi::Runtime &rt)> &&job, int64_t
|
||||
|
||||
int64_t EventLoop::getCurrentTimeInMs() {
|
||||
const auto currentTime = std::chrono::system_clock::now().time_since_epoch();
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(currentTime).count();
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(currentTime)
|
||||
.count();
|
||||
}
|
||||
|
||||
} // namespace worklets
|
||||
|
||||
Generated
Vendored
+2
-2
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <jsi/jsi.h>
|
||||
#include <worklets/RunLoop/AsyncQueue.h>
|
||||
#include <worklets/Public/AsyncQueue.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
@@ -33,7 +33,7 @@ class EventLoop : public std::enable_shared_from_this<EventLoop> {
|
||||
public:
|
||||
EventLoop(
|
||||
const std::string &name,
|
||||
const std::shared_ptr<jsi::Runtime> &runtime,
|
||||
const std::shared_ptr<jsi::Runtime> runtime,
|
||||
const std::shared_ptr<AsyncQueue> &queue);
|
||||
~EventLoop();
|
||||
void run();
|
||||
|
||||
Generated
Vendored
-60
@@ -1,60 +0,0 @@
|
||||
#include <jsi/jsi.h>
|
||||
#include <react/debug/react_native_assert.h>
|
||||
#include <worklets/SharedItems/MemoryManager.h>
|
||||
#include <worklets/SharedItems/Serializable.h>
|
||||
#include <worklets/WorkletRuntime/WorkletRuntime.h>
|
||||
|
||||
namespace worklets {
|
||||
void MemoryManager::loadAllCustomSerializables(const std::shared_ptr<WorkletRuntime> &runtime) {
|
||||
std::lock_guard lock(customSerializationDataMutex_);
|
||||
runtime->executeSync([&](jsi::Runtime &rt) -> jsi::Value {
|
||||
const auto registry = getCustomSerializationRegistry(rt);
|
||||
for (const auto &data : customSerializationData_) {
|
||||
loadCustomSerializable(rt, registry, data);
|
||||
}
|
||||
return jsi::Value::undefined();
|
||||
});
|
||||
}
|
||||
|
||||
void MemoryManager::loadCustomSerializable(
|
||||
const std::shared_ptr<WorkletRuntime> &runtime,
|
||||
const SerializationData &data) {
|
||||
std::lock_guard lock(customSerializationDataMutex_);
|
||||
runtime->executeSync([this, data](jsi::Runtime &rt) -> jsi::Value {
|
||||
const auto registry = getCustomSerializationRegistry(rt);
|
||||
loadCustomSerializable(rt, registry, data);
|
||||
return jsi::Value::undefined();
|
||||
});
|
||||
}
|
||||
|
||||
void MemoryManager::loadCustomSerializable(
|
||||
jsi::Runtime &runtime,
|
||||
const jsi::Array ®istry,
|
||||
const SerializationData &data) {
|
||||
react_native_assert(
|
||||
registry.length(runtime) == data.typeId &&
|
||||
("Custom serializable type ID must match registry length. Expected typeId: " + std::to_string(data.typeId) +
|
||||
", got registry length: " + std::to_string(registry.length(runtime)) +
|
||||
". Custom serializables must be registered in the same order across all runtimes.")
|
||||
.c_str());
|
||||
|
||||
const auto item = jsi::Object(runtime);
|
||||
item.setProperty(runtime, "determine", data.determine->toJSValue(runtime));
|
||||
item.setProperty(runtime, "pack", data.pack->toJSValue(runtime));
|
||||
item.setProperty(runtime, "unpack", data.unpack->toJSValue(runtime));
|
||||
item.setProperty(runtime, "typeId", data.typeId);
|
||||
|
||||
registry.getPropertyAsFunction(runtime, "push").callWithThis(runtime, registry, item);
|
||||
}
|
||||
|
||||
void MemoryManager::registerCustomSerializable(const SerializationData &data) {
|
||||
std::lock_guard lock(customSerializationDataMutex_);
|
||||
customSerializationData_.emplace_back(data);
|
||||
}
|
||||
|
||||
jsi::Array MemoryManager::getCustomSerializationRegistry(jsi::Runtime &rt) {
|
||||
const auto data = rt.global().getProperty(rt, "__customSerializationRegistry");
|
||||
return data.asObject(rt).asArray(rt);
|
||||
}
|
||||
|
||||
} // namespace worklets
|
||||
Generated
Vendored
-29
@@ -1,29 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <jsi/jsi.h>
|
||||
#include <react/debug/react_native_assert.h>
|
||||
#include <worklets/SharedItems/Serializable.h>
|
||||
#include <worklets/WorkletRuntime/WorkletRuntime.h>
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
namespace worklets {
|
||||
class MemoryManager {
|
||||
public:
|
||||
void loadAllCustomSerializables(const std::shared_ptr<WorkletRuntime> &workletRuntime);
|
||||
|
||||
void loadCustomSerializable(const std::shared_ptr<WorkletRuntime> &workletRuntime, const SerializationData &data);
|
||||
|
||||
void registerCustomSerializable(const SerializationData &data);
|
||||
|
||||
private:
|
||||
static jsi::Array getCustomSerializationRegistry(jsi::Runtime &rt);
|
||||
|
||||
void loadCustomSerializable(jsi::Runtime &runtime, const jsi::Array ®istry, const SerializationData &data);
|
||||
|
||||
std::mutex customSerializationDataMutex_;
|
||||
std::vector<SerializationData> customSerializationData_;
|
||||
};
|
||||
} // namespace worklets
|
||||
Generated
Vendored
+169
-95
@@ -1,10 +1,6 @@
|
||||
#include <jsi/jsi.h>
|
||||
#include <worklets/SharedItems/Serializable.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
using namespace facebook;
|
||||
|
||||
namespace worklets {
|
||||
@@ -15,6 +11,34 @@ jsi::Function getValueUnpacker(jsi::Runtime &rt) {
|
||||
return valueUnpacker.asObject(rt).asFunction(rt);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
static const auto callGuardLambda = [](facebook::jsi::Runtime &rt,
|
||||
const facebook::jsi::Value &thisVal,
|
||||
const facebook::jsi::Value *args,
|
||||
size_t count) {
|
||||
return args[0].asObject(rt).asFunction(rt).call(rt, args + 1, count - 1);
|
||||
};
|
||||
|
||||
jsi::Function getCallGuard(jsi::Runtime &rt) {
|
||||
auto callGuard = rt.global().getProperty(rt, "__callGuardDEV");
|
||||
if (callGuard.isObject()) {
|
||||
// Use JS implementation if `__callGuardDEV` has already been installed.
|
||||
// This is the desired behavior.
|
||||
return callGuard.asObject(rt).asFunction(rt);
|
||||
}
|
||||
|
||||
// Otherwise, fallback to C++ JSI implementation. This is necessary so that we
|
||||
// can install `__callGuardDEV` itself and should happen only once. Note that
|
||||
// the C++ implementation doesn't intercept errors and simply throws them as
|
||||
// C++ exceptions which crashes the app. We assume that installing the guard
|
||||
// doesn't throw any errors.
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, jsi::PropNameID::forAscii(rt, "callGuard"), 1, callGuardLambda);
|
||||
}
|
||||
|
||||
#endif // NDEBUG
|
||||
|
||||
jsi::Value makeSerializableClone(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &value,
|
||||
@@ -34,26 +58,35 @@ jsi::Value makeSerializableClone(
|
||||
return makeSerializableFunction(rt, object.asFunction(rt));
|
||||
} else if (object.isArray(rt)) {
|
||||
if (shouldRetainRemote.isBool() && shouldRetainRemote.getBool()) {
|
||||
serializable = std::make_shared<RetainingSerializable<SerializableArray>>(rt, object.asArray(rt));
|
||||
serializable =
|
||||
std::make_shared<RetainingSerializable<SerializableArray>>(
|
||||
rt, object.asArray(rt));
|
||||
} else {
|
||||
serializable = std::make_shared<SerializableArray>(rt, object.asArray(rt));
|
||||
serializable =
|
||||
std::make_shared<SerializableArray>(rt, object.asArray(rt));
|
||||
}
|
||||
} else if (object.isArrayBuffer(rt)) {
|
||||
serializable = std::make_shared<SerializableArrayBuffer>(rt, object.getArrayBuffer(rt));
|
||||
serializable = std::make_shared<SerializableArrayBuffer>(
|
||||
rt, object.getArrayBuffer(rt));
|
||||
} else if (object.isHostObject(rt)) {
|
||||
if (object.isHostObject<SerializableJSRef>(rt)) {
|
||||
return object;
|
||||
}
|
||||
serializable = std::make_shared<SerializableHostObject>(rt, object.getHostObject(rt));
|
||||
serializable = std::make_shared<SerializableHostObject>(
|
||||
rt, object.getHostObject(rt));
|
||||
} else {
|
||||
if (shouldRetainRemote.isBool() && shouldRetainRemote.getBool()) {
|
||||
serializable = std::make_shared<RetainingSerializable<SerializableObject>>(rt, object, nativeStateSource);
|
||||
serializable =
|
||||
std::make_shared<RetainingSerializable<SerializableObject>>(
|
||||
rt, object, nativeStateSource);
|
||||
} else {
|
||||
serializable = std::make_shared<SerializableObject>(rt, object, nativeStateSource);
|
||||
serializable =
|
||||
std::make_shared<SerializableObject>(rt, object, nativeStateSource);
|
||||
}
|
||||
}
|
||||
} else if (value.isString()) {
|
||||
serializable = std::make_shared<SerializableString>(value.asString(rt).utf8(rt));
|
||||
serializable =
|
||||
std::make_shared<SerializableString>(value.asString(rt).utf8(rt));
|
||||
} else if (value.isUndefined()) {
|
||||
serializable = std::make_shared<SerializableScalar>();
|
||||
} else if (value.isNull()) {
|
||||
@@ -63,21 +96,25 @@ jsi::Value makeSerializableClone(
|
||||
} else if (value.isNumber()) {
|
||||
serializable = std::make_shared<SerializableScalar>(value.getNumber());
|
||||
} else if (value.isBigInt()) {
|
||||
serializable = std::make_shared<SerializableBigInt>(rt, value.getBigInt(rt));
|
||||
serializable =
|
||||
std::make_shared<SerializableBigInt>(rt, value.getBigInt(rt));
|
||||
} else if (value.isSymbol()) {
|
||||
// TODO: this is only a placeholder implementation, here we replace symbols
|
||||
// with strings in order to make certain objects to be captured. There isn't
|
||||
// yet any use-case for using symbols on the UI runtime so it is fine to keep
|
||||
// yet any usecase for using symbols on the UI runtime so it is fine to keep
|
||||
// it like this for now.
|
||||
serializable = std::make_shared<SerializableString>(value.getSymbol(rt).toString(rt));
|
||||
serializable =
|
||||
std::make_shared<SerializableString>(value.getSymbol(rt).toString(rt));
|
||||
} else {
|
||||
throw std::runtime_error("[Worklets] Attempted to convert an unsupported value type.");
|
||||
throw std::runtime_error(
|
||||
"[Worklets] Attempted to convert an unsupported value type.");
|
||||
}
|
||||
return SerializableJSRef::newNativeStateObject(rt, serializable);
|
||||
}
|
||||
|
||||
jsi::Value makeSerializableString(jsi::Runtime &rt, const jsi::String &string) {
|
||||
const auto serializable = std::make_shared<SerializableString>(string.utf8(rt));
|
||||
const auto serializable =
|
||||
std::make_shared<SerializableString>(string.utf8(rt));
|
||||
return SerializableJSRef::newNativeStateObject(rt, serializable);
|
||||
}
|
||||
|
||||
@@ -106,42 +143,58 @@ jsi::Value makeSerializableNull(jsi::Runtime &rt) {
|
||||
return SerializableJSRef::newNativeStateObject(rt, serializable);
|
||||
}
|
||||
|
||||
jsi::Value makeSerializableWorklet(jsi::Runtime &rt, const jsi::Object &object, const bool &shouldRetainRemote) {
|
||||
jsi::Value makeSerializableWorklet(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Object &object,
|
||||
const bool &shouldRetainRemote) {
|
||||
std::shared_ptr<Serializable> serializable;
|
||||
if (shouldRetainRemote) {
|
||||
serializable = std::make_shared<RetainingSerializable<SerializableWorklet>>(rt, object);
|
||||
serializable = std::make_shared<RetainingSerializable<SerializableWorklet>>(
|
||||
rt, object);
|
||||
} else {
|
||||
serializable = std::make_shared<SerializableWorklet>(rt, object);
|
||||
}
|
||||
return SerializableJSRef::newNativeStateObject(rt, serializable);
|
||||
}
|
||||
|
||||
jsi::Value makeSerializableInitializer(jsi::Runtime &rt, const jsi::Object &initializerObject) {
|
||||
const auto serializable = std::make_shared<SerializableInitializer>(rt, initializerObject);
|
||||
jsi::Value makeSerializableInitializer(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Object &initializerObject) {
|
||||
const auto serializable =
|
||||
std::make_shared<SerializableInitializer>(rt, initializerObject);
|
||||
return SerializableJSRef::newNativeStateObject(rt, serializable);
|
||||
}
|
||||
|
||||
jsi::Value makeSerializableFunction(jsi::Runtime &rt, jsi::Function function) {
|
||||
std::shared_ptr<Serializable> serializable;
|
||||
if (function.isHostFunction(rt)) {
|
||||
serializable = std::make_shared<SerializableHostFunction>(rt, std::move(function));
|
||||
serializable =
|
||||
std::make_shared<SerializableHostFunction>(rt, std::move(function));
|
||||
} else {
|
||||
serializable = std::make_shared<SerializableRemoteFunction>(rt, std::move(function));
|
||||
serializable =
|
||||
std::make_shared<SerializableRemoteFunction>(rt, std::move(function));
|
||||
}
|
||||
return SerializableJSRef::newNativeStateObject(rt, serializable);
|
||||
}
|
||||
|
||||
jsi::Value makeSerializableArray(jsi::Runtime &rt, const jsi::Array &array, const jsi::Value &shouldRetainRemote) {
|
||||
jsi::Value makeSerializableArray(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Array &array,
|
||||
const jsi::Value &shouldRetainRemote) {
|
||||
std::shared_ptr<Serializable> serializable;
|
||||
if (shouldRetainRemote.isBool() && shouldRetainRemote.getBool()) {
|
||||
serializable = std::make_shared<RetainingSerializable<SerializableArray>>(rt, array);
|
||||
serializable =
|
||||
std::make_shared<RetainingSerializable<SerializableArray>>(rt, array);
|
||||
} else {
|
||||
serializable = std::make_shared<SerializableArray>(rt, array);
|
||||
}
|
||||
return SerializableJSRef::newNativeStateObject(rt, serializable);
|
||||
}
|
||||
|
||||
jsi::Value makeSerializableMap(jsi::Runtime &rt, const jsi::Array &keys, const jsi::Array &values) {
|
||||
jsi::Value makeSerializableMap(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Array &keys,
|
||||
const jsi::Array &values) {
|
||||
auto serializable = std::make_shared<SerializableMap>(rt, keys, values);
|
||||
return SerializableJSRef::newNativeStateObject(rt, serializable);
|
||||
}
|
||||
@@ -151,7 +204,9 @@ jsi::Value makeSerializableSet(jsi::Runtime &rt, const jsi::Array &values) {
|
||||
return SerializableJSRef::newNativeStateObject(rt, serializable);
|
||||
}
|
||||
|
||||
jsi::Value makeSerializableHostObject(jsi::Runtime &rt, const std::shared_ptr<jsi::HostObject> &value) {
|
||||
jsi::Value makeSerializableHostObject(
|
||||
jsi::Runtime &rt,
|
||||
const std::shared_ptr<jsi::HostObject> &value) {
|
||||
const auto serializable = std::make_shared<SerializableHostObject>(rt, value);
|
||||
return SerializableJSRef::newNativeStateObject(rt, serializable);
|
||||
}
|
||||
@@ -160,12 +215,17 @@ jsi::Value makeSerializableTurboModuleLike(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Object &object,
|
||||
const std::shared_ptr<jsi::HostObject> &proto) {
|
||||
const auto serializable = std::make_shared<SerializableTurboModuleLike>(rt, object, proto);
|
||||
const auto serializable =
|
||||
std::make_shared<SerializableTurboModuleLike>(rt, object, proto);
|
||||
return SerializableJSRef::newNativeStateObject(rt, serializable);
|
||||
}
|
||||
|
||||
jsi::Value makeSerializableImport(jsi::Runtime &rt, const double source, const jsi::String &imported) {
|
||||
auto serializable = std::make_shared<SerializableImport>(rt, source, imported);
|
||||
jsi::Value makeSerializableImport(
|
||||
jsi::Runtime &rt,
|
||||
const double source,
|
||||
const jsi::String &imported) {
|
||||
auto serializable =
|
||||
std::make_shared<SerializableImport>(rt, source, imported);
|
||||
return SerializableJSRef::newNativeStateObject(rt, serializable);
|
||||
}
|
||||
|
||||
@@ -176,9 +236,11 @@ jsi::Value makeSerializableObject(
|
||||
const jsi::Value &nativeStateSource) {
|
||||
std::shared_ptr<Serializable> serializable;
|
||||
if (shouldRetainRemote) {
|
||||
serializable = std::make_shared<RetainingSerializable<SerializableObject>>(rt, object, nativeStateSource);
|
||||
serializable = std::make_shared<RetainingSerializable<SerializableObject>>(
|
||||
rt, object, nativeStateSource);
|
||||
} else {
|
||||
serializable = std::make_shared<SerializableObject>(rt, object, nativeStateSource);
|
||||
serializable =
|
||||
std::make_shared<SerializableObject>(rt, object, nativeStateSource);
|
||||
}
|
||||
return SerializableJSRef::newNativeStateObject(rt, serializable);
|
||||
}
|
||||
@@ -193,14 +255,15 @@ std::shared_ptr<Serializable> extractSerializableOrThrow(
|
||||
auto nativeState = object.getNativeState(rt);
|
||||
return std::dynamic_pointer_cast<SerializableJSRef>(nativeState)->value();
|
||||
}
|
||||
throw std::runtime_error("[Worklets] Attempted to extract from a Object that wasn't converted to a Serializable.");
|
||||
throw std::runtime_error(
|
||||
"[Worklets] Attempted to extract from a Object that wasn't converted to a Serializable.");
|
||||
} else if (maybeSerializableValue.isUndefined()) {
|
||||
return Serializable::undefined();
|
||||
}
|
||||
throw std::runtime_error(errorMessage);
|
||||
}
|
||||
|
||||
Serializable::~Serializable() = default;
|
||||
Serializable::~Serializable() {}
|
||||
|
||||
std::shared_ptr<Serializable> Serializable::undefined() {
|
||||
static auto undefined = std::make_shared<SerializableScalar>();
|
||||
@@ -230,13 +293,15 @@ jsi::Value RetainingSerializable<BaseClass>::toJSValue(jsi::Runtime &rt) {
|
||||
return BaseClass::toJSValue(rt);
|
||||
}
|
||||
|
||||
SerializableJSRef::~SerializableJSRef() = default;
|
||||
SerializableJSRef::~SerializableJSRef() {}
|
||||
|
||||
SerializableArray::SerializableArray(jsi::Runtime &rt, const jsi::Array &array) : Serializable(ValueType::ArrayType) {
|
||||
SerializableArray::SerializableArray(jsi::Runtime &rt, const jsi::Array &array)
|
||||
: Serializable(ArrayType) {
|
||||
auto size = array.size(rt);
|
||||
data_.reserve(size);
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
data_.push_back(extractSerializableOrThrow(rt, array.getValueAtIndex(rt, i)));
|
||||
data_.push_back(
|
||||
extractSerializableOrThrow(rt, array.getValueAtIndex(rt, i)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,14 +316,19 @@ jsi::Value SerializableArray::toJSValue(jsi::Runtime &rt) {
|
||||
|
||||
jsi::Value SerializableArrayBuffer::toJSValue(jsi::Runtime &rt) {
|
||||
auto size = static_cast<int>(data_.size());
|
||||
auto arrayBuffer =
|
||||
rt.global().getPropertyAsFunction(rt, "ArrayBuffer").callAsConstructor(rt, size).getObject(rt).getArrayBuffer(rt);
|
||||
auto arrayBuffer = rt.global()
|
||||
.getPropertyAsFunction(rt, "ArrayBuffer")
|
||||
.callAsConstructor(rt, size)
|
||||
.getObject(rt)
|
||||
.getArrayBuffer(rt);
|
||||
memcpy(arrayBuffer.data(rt), data_.data(), size);
|
||||
return arrayBuffer;
|
||||
}
|
||||
|
||||
SerializableObject::SerializableObject(jsi::Runtime &rt, const jsi::Object &object)
|
||||
: Serializable(ValueType::ObjectType) {
|
||||
SerializableObject::SerializableObject(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Object &object)
|
||||
: Serializable(ObjectType) {
|
||||
auto propertyNames = object.getPropertyNames(rt);
|
||||
auto size = propertyNames.size(rt);
|
||||
data_.reserve(size);
|
||||
@@ -272,17 +342,24 @@ SerializableObject::SerializableObject(jsi::Runtime &rt, const jsi::Object &obje
|
||||
}
|
||||
}
|
||||
|
||||
SerializableObject::SerializableObject(jsi::Runtime &rt, const jsi::Object &object, const jsi::Value &nativeStateSource)
|
||||
SerializableObject::SerializableObject(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Object &object,
|
||||
const jsi::Value &nativeStateSource)
|
||||
: SerializableObject(rt, object) {
|
||||
if (nativeStateSource.isObject() && nativeStateSource.asObject(rt).hasNativeState(rt)) {
|
||||
if (nativeStateSource.isObject() &&
|
||||
nativeStateSource.asObject(rt).hasNativeState(rt)) {
|
||||
nativeState_ = nativeStateSource.asObject(rt).getNativeState(rt);
|
||||
}
|
||||
}
|
||||
|
||||
jsi::Value SerializableObject::toJSValue(jsi::Runtime &rt) {
|
||||
auto obj = jsi::Object(rt);
|
||||
for (const auto &i : data_) {
|
||||
obj.setProperty(rt, jsi::String::createFromUtf8(rt, i.first), i.second->toJSValue(rt));
|
||||
for (size_t i = 0, size = data_.size(); i < size; i++) {
|
||||
obj.setProperty(
|
||||
rt,
|
||||
jsi::String::createFromUtf8(rt, data_[i].first),
|
||||
data_[i].second->toJSValue(rt));
|
||||
}
|
||||
if (nativeState_ != nullptr) {
|
||||
obj.setNativeState(rt, nativeState_);
|
||||
@@ -290,10 +367,15 @@ jsi::Value SerializableObject::toJSValue(jsi::Runtime &rt) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
SerializableMap::SerializableMap(jsi::Runtime &rt, const jsi::Array &keys, const jsi::Array &values)
|
||||
: Serializable(ValueType::MapType) {
|
||||
SerializableMap::SerializableMap(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Array &keys,
|
||||
const jsi::Array &values)
|
||||
: Serializable(MapType) {
|
||||
auto size = keys.size(rt);
|
||||
react_native_assert(size == values.size(rt) && "Keys and values arrays must have the same size.");
|
||||
react_native_assert(
|
||||
size == values.size(rt) &&
|
||||
"Keys and values arrays must have the same size.");
|
||||
data_.reserve(size);
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
auto key = extractSerializableOrThrow(rt, keys.getValueAtIndex(rt, i));
|
||||
@@ -312,16 +394,19 @@ jsi::Value SerializableMap::toJSValue(jsi::Runtime &rt) {
|
||||
}
|
||||
|
||||
const auto &global = rt.global();
|
||||
auto map = global.getPropertyAsFunction(rt, "Map").callAsConstructor(rt, std::move(keyValues));
|
||||
auto map = global.getPropertyAsFunction(rt, "Map").callAsConstructor(
|
||||
rt, std::move(keyValues));
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
SerializableSet::SerializableSet(jsi::Runtime &rt, const jsi::Array &values) : Serializable(ValueType::SetType) {
|
||||
SerializableSet::SerializableSet(jsi::Runtime &rt, const jsi::Array &values)
|
||||
: Serializable(SetType) {
|
||||
auto size = values.size(rt);
|
||||
data_.reserve(size);
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
data_.push_back(extractSerializableOrThrow(rt, values.getValueAtIndex(rt, i)));
|
||||
data_.push_back(
|
||||
extractSerializableOrThrow(rt, values.getValueAtIndex(rt, i)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,7 +417,8 @@ jsi::Value SerializableSet::toJSValue(jsi::Runtime &rt) {
|
||||
}
|
||||
|
||||
const auto &global = rt.global();
|
||||
auto set = global.getPropertyAsFunction(rt, "Set").callAsConstructor(rt, std::move(values));
|
||||
auto set = global.getPropertyAsFunction(rt, "Set").callAsConstructor(
|
||||
rt, std::move(values));
|
||||
|
||||
return set;
|
||||
}
|
||||
@@ -342,15 +428,20 @@ jsi::Value SerializableHostObject::toJSValue(jsi::Runtime &rt) {
|
||||
}
|
||||
|
||||
jsi::Value SerializableHostFunction::toJSValue(jsi::Runtime &rt) {
|
||||
return jsi::Function::createFromHostFunction(rt, jsi::PropNameID::forUtf8(rt, name_), paramCount_, hostFunction_);
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt, jsi::PropNameID::forUtf8(rt, name_), paramCount_, hostFunction_);
|
||||
}
|
||||
|
||||
jsi::Value SerializableWorklet::toJSValue(jsi::Runtime &rt) {
|
||||
react_native_assert(
|
||||
std::any_of(data_.cbegin(), data_.cend(), [](const auto &item) { return item.first == "__workletHash"; }) &&
|
||||
std::any_of(
|
||||
data_.cbegin(),
|
||||
data_.cend(),
|
||||
[](const auto &item) { return item.first == "__workletHash"; }) &&
|
||||
"SerializableWorklet doesn't have `__workletHash` property");
|
||||
jsi::Value obj = SerializableObject::toJSValue(rt);
|
||||
return getValueUnpacker(rt).call(rt, obj, jsi::String::createFromAscii(rt, "Worklet"));
|
||||
return getValueUnpacker(rt).call(
|
||||
rt, obj, jsi::String::createFromAscii(rt, "Worklet"));
|
||||
}
|
||||
|
||||
jsi::Value SerializableImport::toJSValue(jsi::Runtime &rt) {
|
||||
@@ -364,7 +455,11 @@ jsi::Value SerializableImport::toJSValue(jsi::Runtime &rt) {
|
||||
}
|
||||
|
||||
const auto imported = jsi::String::createFromUtf8(rt, imported_);
|
||||
return metroRequire.asObject(rt).asFunction(rt).call(rt, source_).asObject(rt).getProperty(rt, imported);
|
||||
return metroRequire.asObject(rt)
|
||||
.asFunction(rt)
|
||||
.call(rt, source_)
|
||||
.asObject(rt)
|
||||
.getProperty(rt, imported);
|
||||
}
|
||||
|
||||
jsi::Value SerializableRemoteFunction::toJSValue(jsi::Runtime &rt) {
|
||||
@@ -386,12 +481,12 @@ jsi::Value SerializableRemoteFunction::toJSValue(jsi::Runtime &rt) {
|
||||
jsi::Value SerializableInitializer::toJSValue(jsi::Runtime &rt) {
|
||||
if (remoteValue_ == nullptr) {
|
||||
auto initObj = initializer_->toJSValue(rt);
|
||||
auto value = std::make_unique<jsi::Value>(
|
||||
getValueUnpacker(rt).call(rt, initObj, jsi::String::createFromAscii(rt, "Handle")));
|
||||
auto value = std::make_unique<jsi::Value>(getValueUnpacker(rt).call(
|
||||
rt, initObj, jsi::String::createFromAscii(rt, "Handle")));
|
||||
|
||||
// We are locking the initialization here since the thread that is
|
||||
// initializing can be preempted on runtime lock. E.g.
|
||||
// UI thread can be preempted on initialization of a shared value and then
|
||||
// initalizing can be pre-empted on runtime lock. E.g.
|
||||
// UI thread can be pre-empted on initialization of a shared value and then
|
||||
// JS thread can try to access the shared value, locking the whole runtime.
|
||||
// If we put the lock on `getValueUnpacker` part (basically any part that
|
||||
// requires runtime) we would get a deadlock since UI thread would never
|
||||
@@ -406,7 +501,8 @@ jsi::Value SerializableInitializer::toJSValue(jsi::Runtime &rt) {
|
||||
return jsi::Value(rt, *remoteValue_);
|
||||
}
|
||||
auto initObj = initializer_->toJSValue(rt);
|
||||
return getValueUnpacker(rt).call(rt, initObj, jsi::String::createFromAscii(rt, "Handle"));
|
||||
return getValueUnpacker(rt).call(
|
||||
rt, initObj, jsi::String::createFromAscii(rt, "Handle"));
|
||||
}
|
||||
|
||||
jsi::Value SerializableString::toJSValue(jsi::Runtime &rt) {
|
||||
@@ -414,58 +510,36 @@ jsi::Value SerializableString::toJSValue(jsi::Runtime &rt) {
|
||||
}
|
||||
|
||||
jsi::Value SerializableBigInt::toJSValue(jsi::Runtime &rt) {
|
||||
if (fastValue_.has_value()) {
|
||||
return jsi::BigInt::fromInt64(rt, fastValue_.value());
|
||||
} else {
|
||||
return rt.global().getPropertyAsFunction(rt, "BigInt").call(rt, jsi::String::createFromUtf8(rt, slowValue_));
|
||||
}
|
||||
return rt.global()
|
||||
.getPropertyAsFunction(rt, "BigInt")
|
||||
.call(rt, jsi::String::createFromUtf8(rt, string_));
|
||||
}
|
||||
|
||||
jsi::Value SerializableScalar::toJSValue(jsi::Runtime &) {
|
||||
switch (valueType_) {
|
||||
case Serializable::ValueType::UndefinedType:
|
||||
case Serializable::UndefinedType:
|
||||
return jsi::Value();
|
||||
case Serializable::ValueType::NullType:
|
||||
case Serializable::NullType:
|
||||
return jsi::Value(nullptr);
|
||||
case Serializable::ValueType::BooleanType:
|
||||
case Serializable::BooleanType:
|
||||
return jsi::Value(data_.boolean);
|
||||
case Serializable::ValueType::NumberType:
|
||||
case Serializable::NumberType:
|
||||
return jsi::Value(data_.number);
|
||||
default:
|
||||
throw std::runtime_error("[Worklets] Attempted to convert object that's not of a scalar type.");
|
||||
throw std::runtime_error(
|
||||
"[Worklets] Attempted to convert object that's not of a scalar type.");
|
||||
}
|
||||
}
|
||||
|
||||
jsi::Value SerializableTurboModuleLike::toJSValue(jsi::Runtime &rt) {
|
||||
auto obj = properties_->toJSValue(rt).asObject(rt);
|
||||
const auto prototype = proto_->toJSValue(rt);
|
||||
rt.global().getPropertyAsObject(rt, "Object").getPropertyAsFunction(rt, "setPrototypeOf").call(rt, obj, prototype);
|
||||
rt.global()
|
||||
.getPropertyAsObject(rt, "Object")
|
||||
.getPropertyAsFunction(rt, "setPrototypeOf")
|
||||
.call(rt, obj, prototype);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
jsi::Function getCustomSerializableUnpacker(jsi::Runtime &rt) {
|
||||
auto customSerializableUnpacker = rt.global().getProperty(rt, "__customSerializableUnpacker");
|
||||
react_native_assert(customSerializableUnpacker.isObject() && "customSerializableUnpacker not found");
|
||||
return customSerializableUnpacker.asObject(rt).asFunction(rt);
|
||||
}
|
||||
|
||||
jsi::Value CustomSerializable::toJSValue(jsi::Runtime &rt) {
|
||||
try {
|
||||
auto unpack = getCustomSerializableUnpacker(rt);
|
||||
auto data = data_->toJSValue(rt);
|
||||
|
||||
return unpack.call(rt, data, jsi::Value(typeId_));
|
||||
} catch (jsi::JSError &e) {
|
||||
throw std::runtime_error(
|
||||
std::string("[Worklets] Failed to deserialize CustomSerializable. Reason: ") + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
jsi::Value makeCustomSerializable(jsi::Runtime &rt, const jsi::Value &data, const int typeId) {
|
||||
auto rawData = extractSerializableOrThrow(rt, data, "[Worklets] Data must be a Serializable object.");
|
||||
auto customSerializable = std::make_shared<CustomSerializable>(rawData, typeId);
|
||||
return SerializableJSRef::newNativeStateObject(rt, customSerializable);
|
||||
}
|
||||
|
||||
} // namespace worklets
|
||||
|
||||
Generated
Vendored
+113
-78
@@ -15,7 +15,30 @@ namespace worklets {
|
||||
|
||||
jsi::Function getValueUnpacker(jsi::Runtime &rt);
|
||||
|
||||
inline void cleanupIfRuntimeExists(jsi::Runtime *rt, std::unique_ptr<jsi::Value> &value) {
|
||||
#ifndef NDEBUG
|
||||
jsi::Function getCallGuard(jsi::Runtime &rt);
|
||||
#endif // NDEBUG
|
||||
|
||||
// If possible, please use `WorkletRuntime::runGuarded` instead.
|
||||
template <typename... Args>
|
||||
inline jsi::Value runOnRuntimeGuarded(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &function,
|
||||
Args &&...args) {
|
||||
// We only use callGuard in debug mode, otherwise we call the provided
|
||||
// function directly. CallGuard provides a way of capturing exceptions in
|
||||
// JavaScript and propagating them to the main React Native thread such that
|
||||
// they can be presented using RN's LogBox.
|
||||
#ifndef NDEBUG
|
||||
return getCallGuard(rt).call(rt, function, args...);
|
||||
#else
|
||||
return function.asObject(rt).asFunction(rt).call(rt, args...);
|
||||
#endif // NDEBUG
|
||||
}
|
||||
|
||||
inline void cleanupIfRuntimeExists(
|
||||
jsi::Runtime *rt,
|
||||
std::unique_ptr<jsi::Value> &value) {
|
||||
if (rt != nullptr && !WorkletRuntimeRegistry::isRuntimeAlive(rt)) {
|
||||
// The below use of unique_ptr.release prevents the smart pointer from
|
||||
// calling the destructor of the kept object. This effectively results in
|
||||
@@ -35,7 +58,7 @@ inline void cleanupIfRuntimeExists(jsi::Runtime *rt, std::unique_ptr<jsi::Value>
|
||||
// before the runtime is terminated. Note that the underlying memory that
|
||||
// jsi::Value refers to is managed by the VM and gets freed along with the
|
||||
// runtime.
|
||||
value.release(); // NOLINT
|
||||
value.release();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +68,7 @@ class Serializable {
|
||||
|
||||
virtual ~Serializable();
|
||||
|
||||
enum class ValueType : std::uint8_t {
|
||||
enum ValueType {
|
||||
UndefinedType,
|
||||
NullType,
|
||||
BooleanType,
|
||||
@@ -66,7 +89,6 @@ class Serializable {
|
||||
TurboModuleLikeType,
|
||||
ImportType,
|
||||
SynchronizableType,
|
||||
CustomType,
|
||||
};
|
||||
|
||||
explicit Serializable(ValueType valueType) : valueType_(valueType) {}
|
||||
@@ -105,15 +127,18 @@ class SerializableJSRef : public jsi::NativeState {
|
||||
const std::shared_ptr<Serializable> value_;
|
||||
|
||||
public:
|
||||
explicit SerializableJSRef(const std::shared_ptr<Serializable> &value) : value_(value) {}
|
||||
explicit SerializableJSRef(const std::shared_ptr<Serializable> &value)
|
||||
: value_(value) {}
|
||||
|
||||
~SerializableJSRef() override;
|
||||
virtual ~SerializableJSRef();
|
||||
|
||||
std::shared_ptr<Serializable> value() const {
|
||||
return value_;
|
||||
}
|
||||
|
||||
static jsi::Object newNativeStateObject(jsi::Runtime &rt, const std::shared_ptr<Serializable> &value) {
|
||||
static jsi::Object newNativeStateObject(
|
||||
jsi::Runtime &rt,
|
||||
const std::shared_ptr<Serializable> &value) {
|
||||
auto object = jsi::Object(rt);
|
||||
object.setNativeState(rt, std::make_shared<SerializableJSRef>(value));
|
||||
object.setProperty(rt, "__serializableRef", true);
|
||||
@@ -150,35 +175,52 @@ jsi::Value makeSerializableObject(
|
||||
bool shouldRetainRemote,
|
||||
const jsi::Value &nativeStateSource);
|
||||
|
||||
jsi::Value makeSerializableImport(jsi::Runtime &rt, double source, const jsi::String &imported);
|
||||
jsi::Value makeSerializableImport(
|
||||
jsi::Runtime &rt,
|
||||
const double source,
|
||||
const jsi::String &imported);
|
||||
|
||||
jsi::Value makeSerializableHostObject(jsi::Runtime &rt, const std::shared_ptr<jsi::HostObject> &value);
|
||||
jsi::Value makeSerializableHostObject(
|
||||
jsi::Runtime &rt,
|
||||
const std::shared_ptr<jsi::HostObject> &value);
|
||||
|
||||
jsi::Value makeSerializableArray(jsi::Runtime &rt, const jsi::Array &array, const jsi::Value &shouldRetainRemote);
|
||||
jsi::Value makeSerializableArray(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Array &array,
|
||||
const jsi::Value &shouldRetainRemote);
|
||||
|
||||
jsi::Value makeSerializableMap(jsi::Runtime &rt, const jsi::Array &keys, const jsi::Array &values);
|
||||
jsi::Value makeSerializableMap(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Array &keys,
|
||||
const jsi::Array &values);
|
||||
|
||||
jsi::Value makeSerializableSet(jsi::Runtime &rt, const jsi::Array &values);
|
||||
|
||||
jsi::Value makeSerializableInitializer(jsi::Runtime &rt, const jsi::Object &initializerObject);
|
||||
jsi::Value makeSerializableInitializer(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Object &initializerObject);
|
||||
|
||||
jsi::Value makeSerializableFunction(jsi::Runtime &rt, jsi::Function function);
|
||||
|
||||
jsi::Value makeSerializableWorklet(jsi::Runtime &rt, const jsi::Object &object, const bool &shouldRetainRemote);
|
||||
|
||||
jsi::Value makeCustomSerializable(jsi::Runtime &rt, const jsi::Value &data, int typeId);
|
||||
jsi::Value makeSerializableWorklet(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Object &object,
|
||||
const bool &shouldRetainRemote);
|
||||
|
||||
std::shared_ptr<Serializable> extractSerializableOrThrow(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &maybeSerializableValue,
|
||||
const std::string &errorMessage = "[Worklets] Expecting the object to be of type SerializableJSRef.");
|
||||
const std::string &errorMessage =
|
||||
"[Worklets] Expecting the object to be of type SerializableJSRef.");
|
||||
|
||||
template <typename T>
|
||||
std::shared_ptr<T> extractSerializableOrThrow(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &serializableRef,
|
||||
const std::string &errorMessage = "[Worklets] Provided serializable object is of an incompatible type.") {
|
||||
auto res = std::dynamic_pointer_cast<T>(extractSerializableOrThrow(rt, serializableRef, errorMessage));
|
||||
const std::string &errorMessage =
|
||||
"[Worklets] Provided serializable object is of an incompatible type.") {
|
||||
auto res = std::dynamic_pointer_cast<T>(
|
||||
extractSerializableOrThrow(rt, serializableRef, errorMessage));
|
||||
if (!res) {
|
||||
throw std::runtime_error(errorMessage);
|
||||
}
|
||||
@@ -199,7 +241,10 @@ class SerializableObject : public Serializable {
|
||||
public:
|
||||
SerializableObject(jsi::Runtime &rt, const jsi::Object &object);
|
||||
|
||||
SerializableObject(jsi::Runtime &rt, const jsi::Object &object, const jsi::Value &nativeStateSource);
|
||||
SerializableObject(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Object &object,
|
||||
const jsi::Value &nativeStateSource);
|
||||
|
||||
jsi::Value toJSValue(jsi::Runtime &rt) override;
|
||||
|
||||
@@ -210,12 +255,17 @@ class SerializableObject : public Serializable {
|
||||
|
||||
class SerializableMap : public Serializable {
|
||||
public:
|
||||
SerializableMap(jsi::Runtime &rt, const jsi::Array &keys, const jsi::Array &values);
|
||||
SerializableMap(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Array &keys,
|
||||
const jsi::Array &values);
|
||||
|
||||
jsi::Value toJSValue(jsi::Runtime &rt) override;
|
||||
|
||||
protected:
|
||||
std::vector<std::pair<std::shared_ptr<Serializable>, std::shared_ptr<Serializable>>> data_;
|
||||
std::vector<
|
||||
std::pair<std::shared_ptr<Serializable>, std::shared_ptr<Serializable>>>
|
||||
data_;
|
||||
};
|
||||
|
||||
class SerializableSet : public Serializable {
|
||||
@@ -230,8 +280,10 @@ class SerializableSet : public Serializable {
|
||||
|
||||
class SerializableHostObject : public Serializable {
|
||||
public:
|
||||
SerializableHostObject(jsi::Runtime &, const std::shared_ptr<jsi::HostObject> &hostObject)
|
||||
: Serializable(ValueType::HostObjectType), hostObject_(hostObject) {}
|
||||
SerializableHostObject(
|
||||
jsi::Runtime &,
|
||||
const std::shared_ptr<jsi::HostObject> &hostObject)
|
||||
: Serializable(HostObjectType), hostObject_(hostObject) {}
|
||||
|
||||
jsi::Value toJSValue(jsi::Runtime &rt) override;
|
||||
|
||||
@@ -242,7 +294,7 @@ class SerializableHostObject : public Serializable {
|
||||
class SerializableHostFunction : public Serializable {
|
||||
public:
|
||||
SerializableHostFunction(jsi::Runtime &rt, jsi::Function function)
|
||||
: Serializable(ValueType::HostFunctionType),
|
||||
: Serializable(HostFunctionType),
|
||||
hostFunction_(function.getHostFunction(rt)),
|
||||
name_(function.getProperty(rt, "name").asString(rt).utf8(rt)),
|
||||
paramCount_(function.getProperty(rt, "length").asNumber()) {}
|
||||
@@ -258,8 +310,10 @@ class SerializableHostFunction : public Serializable {
|
||||
class SerializableArrayBuffer : public Serializable {
|
||||
public:
|
||||
SerializableArrayBuffer(jsi::Runtime &rt, const jsi::ArrayBuffer &arrayBuffer)
|
||||
: Serializable(ValueType::ArrayBufferType),
|
||||
data_(arrayBuffer.data(rt), arrayBuffer.data(rt) + arrayBuffer.size(rt)) {}
|
||||
: Serializable(ArrayBufferType),
|
||||
data_(
|
||||
arrayBuffer.data(rt),
|
||||
arrayBuffer.data(rt) + arrayBuffer.size(rt)) {}
|
||||
|
||||
jsi::Value toJSValue(jsi::Runtime &rt) override;
|
||||
|
||||
@@ -269,8 +323,9 @@ class SerializableArrayBuffer : public Serializable {
|
||||
|
||||
class SerializableWorklet : public SerializableObject {
|
||||
public:
|
||||
SerializableWorklet(jsi::Runtime &rt, const jsi::Object &worklet) : SerializableObject(rt, worklet) {
|
||||
valueType_ = ValueType::WorkletType;
|
||||
SerializableWorklet(jsi::Runtime &rt, const jsi::Object &worklet)
|
||||
: SerializableObject(rt, worklet) {
|
||||
valueType_ = WorkletType;
|
||||
}
|
||||
|
||||
jsi::Value toJSValue(jsi::Runtime &rt) override;
|
||||
@@ -278,8 +333,13 @@ class SerializableWorklet : public SerializableObject {
|
||||
|
||||
class SerializableImport : public Serializable {
|
||||
public:
|
||||
SerializableImport(jsi::Runtime &rt, const double source, const jsi::String &imported)
|
||||
: Serializable(ValueType::ImportType), source_(source), imported_(imported.utf8(rt)) {}
|
||||
SerializableImport(
|
||||
jsi::Runtime &rt,
|
||||
const double source,
|
||||
const jsi::String &imported)
|
||||
: Serializable(ImportType),
|
||||
source_(source),
|
||||
imported_(imported.utf8(rt)) {}
|
||||
|
||||
jsi::Value toJSValue(jsi::Runtime &rt) override;
|
||||
|
||||
@@ -288,8 +348,9 @@ class SerializableImport : public Serializable {
|
||||
const std::string imported_;
|
||||
};
|
||||
|
||||
class SerializableRemoteFunction : public Serializable,
|
||||
public std::enable_shared_from_this<SerializableRemoteFunction> {
|
||||
class SerializableRemoteFunction
|
||||
: public Serializable,
|
||||
public std::enable_shared_from_this<SerializableRemoteFunction> {
|
||||
private:
|
||||
jsi::Runtime *runtime_;
|
||||
#ifndef NDEBUG
|
||||
@@ -299,7 +360,7 @@ class SerializableRemoteFunction : public Serializable,
|
||||
|
||||
public:
|
||||
SerializableRemoteFunction(jsi::Runtime &rt, jsi::Function &&function)
|
||||
: Serializable(ValueType::RemoteFunctionType),
|
||||
: Serializable(RemoteFunctionType),
|
||||
runtime_(&rt),
|
||||
#ifndef NDEBUG
|
||||
name_(function.getProperty(rt, "name").asString(rt).utf8(rt)),
|
||||
@@ -307,7 +368,7 @@ class SerializableRemoteFunction : public Serializable,
|
||||
function_(std::make_unique<jsi::Value>(rt, std::move(function))) {
|
||||
}
|
||||
|
||||
~SerializableRemoteFunction() override {
|
||||
~SerializableRemoteFunction() {
|
||||
cleanupIfRuntimeExists(runtime_, function_);
|
||||
}
|
||||
|
||||
@@ -326,11 +387,14 @@ class SerializableInitializer : public Serializable {
|
||||
jsi::Runtime *remoteRuntime_;
|
||||
|
||||
public:
|
||||
SerializableInitializer(jsi::Runtime &rt, const jsi::Object &initializerObject)
|
||||
: Serializable(ValueType::HandleType),
|
||||
initializer_(std::make_unique<SerializableObject>(rt, initializerObject)) {}
|
||||
SerializableInitializer(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Object &initializerObject)
|
||||
: Serializable(HandleType),
|
||||
initializer_(
|
||||
std::make_unique<SerializableObject>(rt, initializerObject)) {}
|
||||
|
||||
~SerializableInitializer() override {
|
||||
~SerializableInitializer() {
|
||||
cleanupIfRuntimeExists(remoteRuntime_, remoteValue_);
|
||||
}
|
||||
|
||||
@@ -339,7 +403,8 @@ class SerializableInitializer : public Serializable {
|
||||
|
||||
class SerializableString : public Serializable {
|
||||
public:
|
||||
explicit SerializableString(const std::string &string) : Serializable(ValueType::StringType), data_(string) {}
|
||||
explicit SerializableString(const std::string &string)
|
||||
: Serializable(StringType), data_(string) {}
|
||||
|
||||
jsi::Value toJSValue(jsi::Runtime &rt) override;
|
||||
|
||||
@@ -349,36 +414,27 @@ class SerializableString : public Serializable {
|
||||
|
||||
class SerializableBigInt : public Serializable {
|
||||
public:
|
||||
explicit SerializableBigInt(jsi::Runtime &rt, const jsi::BigInt &bigInt) : Serializable(ValueType::BigIntType) {
|
||||
if (bigInt.isInt64(rt)) {
|
||||
fastValue_ = bigInt.getInt64(rt);
|
||||
} else {
|
||||
slowValue_ = bigInt.toString(rt).utf8(rt);
|
||||
}
|
||||
}
|
||||
explicit SerializableBigInt(jsi::Runtime &rt, const jsi::BigInt &bigint)
|
||||
: Serializable(BigIntType), string_(bigint.toString(rt).utf8(rt)) {}
|
||||
|
||||
jsi::Value toJSValue(jsi::Runtime &rt) override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* This member is used only when the BigInt fits into int64_t range.
|
||||
*/
|
||||
std::optional<int64_t> fastValue_{};
|
||||
std::string slowValue_{};
|
||||
const std::string string_;
|
||||
};
|
||||
|
||||
class SerializableScalar : public Serializable {
|
||||
public:
|
||||
explicit SerializableScalar(double number) : Serializable(ValueType::NumberType) {
|
||||
explicit SerializableScalar(double number) : Serializable(NumberType) {
|
||||
data_.number = number;
|
||||
}
|
||||
explicit SerializableScalar(bool boolean) : Serializable(ValueType::BooleanType) {
|
||||
explicit SerializableScalar(bool boolean) : Serializable(BooleanType) {
|
||||
data_.boolean = boolean;
|
||||
}
|
||||
SerializableScalar() : Serializable(ValueType::UndefinedType) {}
|
||||
explicit SerializableScalar(std::nullptr_t) : Serializable(ValueType::NullType) {}
|
||||
SerializableScalar() : Serializable(UndefinedType) {}
|
||||
explicit SerializableScalar(std::nullptr_t) : Serializable(NullType) {}
|
||||
|
||||
jsi::Value toJSValue(jsi::Runtime &) override;
|
||||
jsi::Value toJSValue(jsi::Runtime &);
|
||||
|
||||
protected:
|
||||
union Data {
|
||||
@@ -396,7 +452,7 @@ class SerializableTurboModuleLike : public Serializable {
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Object &object,
|
||||
const std::shared_ptr<jsi::HostObject> &proto)
|
||||
: Serializable(ValueType::TurboModuleLikeType),
|
||||
: Serializable(TurboModuleLikeType),
|
||||
proto_(std::make_unique<SerializableHostObject>(rt, proto)),
|
||||
properties_(std::make_unique<SerializableObject>(rt, object)) {}
|
||||
|
||||
@@ -407,25 +463,4 @@ class SerializableTurboModuleLike : public Serializable {
|
||||
const std::unique_ptr<SerializableObject> properties_;
|
||||
};
|
||||
|
||||
jsi::Function getCustomSerializableUnpacker(jsi::Runtime &rt);
|
||||
|
||||
class CustomSerializable : public Serializable {
|
||||
public:
|
||||
CustomSerializable(std::shared_ptr<Serializable> data, const int typeId)
|
||||
: Serializable(ValueType::CustomType), data_(std::move(data)), typeId_(typeId) {}
|
||||
|
||||
jsi::Value toJSValue(jsi::Runtime &rt) override;
|
||||
|
||||
private:
|
||||
const std::shared_ptr<Serializable> data_;
|
||||
const int typeId_;
|
||||
};
|
||||
|
||||
struct SerializationData {
|
||||
std::shared_ptr<SerializableWorklet> determine;
|
||||
std::shared_ptr<SerializableWorklet> pack;
|
||||
std::shared_ptr<SerializableWorklet> unpack;
|
||||
int typeId;
|
||||
};
|
||||
|
||||
} // namespace worklets
|
||||
|
||||
frontend-admin/node_modules/react-native-worklets/Common/cpp/worklets/SharedItems/Synchronizable.cpp
Generated
Vendored
+16
-8
@@ -1,7 +1,6 @@
|
||||
#include <react/debug/react_native_assert.h>
|
||||
#include <worklets/SharedItems/Synchronizable.h>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace worklets {
|
||||
@@ -33,7 +32,8 @@ void Synchronizable::setBlocking(const std::shared_ptr<Serializable> &value) {
|
||||
|
||||
jsi::Value Synchronizable::toJSValue(jsi::Runtime &rt) {
|
||||
auto synchronizableUnpacker = getSynchronizableUnpacker(rt);
|
||||
auto ref = SerializableJSRef::newNativeStateObject(rt, this->shared_from_this());
|
||||
auto ref =
|
||||
SerializableJSRef::newNativeStateObject(rt, this->shared_from_this());
|
||||
return synchronizableUnpacker.call(rt, std::move(ref));
|
||||
}
|
||||
|
||||
@@ -41,17 +41,25 @@ Synchronizable::Synchronizable(const std::shared_ptr<Serializable> &value)
|
||||
: Serializable(ValueType::SynchronizableType), value_(value) {}
|
||||
|
||||
jsi::Function getSynchronizableUnpacker(jsi::Runtime &rt) {
|
||||
auto synchronizableUnpacker = rt.global().getProperty(rt, "__synchronizableUnpacker");
|
||||
react_native_assert(synchronizableUnpacker.isObject() && "synchronizableUnpacker not found");
|
||||
auto synchronizableUnpacker =
|
||||
rt.global().getProperty(rt, "__synchronizableUnpacker");
|
||||
react_native_assert(
|
||||
synchronizableUnpacker.isObject() && "synchronizableUnpacker not found");
|
||||
return synchronizableUnpacker.asObject(rt).asFunction(rt);
|
||||
}
|
||||
|
||||
std::shared_ptr<Synchronizable> extractSynchronizableOrThrow(jsi::Runtime &rt, const jsi::Value &value) {
|
||||
auto serializable =
|
||||
extractSerializableOrThrow(rt, value, "[Worklets] Expecting the object to be of type SerializableJSRef.");
|
||||
std::shared_ptr<Synchronizable> extractSynchronizableOrThrow(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &value) {
|
||||
auto serializable = extractSerializableOrThrow(
|
||||
rt,
|
||||
value,
|
||||
"[Worklets] Expecting the object to be of type SerializableJSRef.");
|
||||
|
||||
auto synchronizable = std::dynamic_pointer_cast<Synchronizable>(serializable);
|
||||
react_native_assert(synchronizable != nullptr && "[Worklets] Expected the object to be a Synchronizable.");
|
||||
react_native_assert(
|
||||
synchronizable != nullptr &&
|
||||
"[Worklets] Expected the object to be a Synchronizable.");
|
||||
|
||||
return synchronizable;
|
||||
}
|
||||
|
||||
Generated
Vendored
+4
-2
@@ -44,7 +44,7 @@ class Synchronizable : public SynchronizableAccess,
|
||||
|
||||
explicit Synchronizable(const std::shared_ptr<Serializable> &value);
|
||||
|
||||
~Synchronizable() override = default;
|
||||
virtual ~Synchronizable() = default;
|
||||
|
||||
private:
|
||||
std::shared_ptr<Serializable> value_;
|
||||
@@ -52,6 +52,8 @@ class Synchronizable : public SynchronizableAccess,
|
||||
|
||||
jsi::Function getSynchronizableUnpacker(jsi::Runtime &rt);
|
||||
|
||||
std::shared_ptr<Synchronizable> extractSynchronizableOrThrow(jsi::Runtime &rt, const jsi::Value &value);
|
||||
std::shared_ptr<Synchronizable> extractSynchronizableOrThrow(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &value);
|
||||
|
||||
}; // namespace worklets
|
||||
|
||||
Generated
Vendored
+6
-3
@@ -6,7 +6,8 @@ namespace worklets {
|
||||
void SynchronizableAccess::getBlockingBefore() {
|
||||
std::unique_lock<std::mutex> lock(accessLock_);
|
||||
queue_.wait(lock, [this]() {
|
||||
return !blockingWriter_ /* && dirtyWriters_ == 0 */ && (!imperativelyLocked_ || imperativeOwner_ == pthread_self());
|
||||
return !blockingWriter_ /* && dirtyWriters_ == 0 */ &&
|
||||
(!imperativelyLocked_ || imperativeOwner_ == pthread_self());
|
||||
});
|
||||
blockingReaders_++;
|
||||
}
|
||||
@@ -43,7 +44,8 @@ void SynchronizableAccess::getBlockingAfter() {
|
||||
void SynchronizableAccess::setBlockingBefore() {
|
||||
std::unique_lock<std::mutex> lock(accessLock_);
|
||||
queue_.wait(lock, [this]() {
|
||||
return !blockingWriter_ && blockingReaders_ == 0 /* && dirtyWriters_ == 0 */ &&
|
||||
return !blockingWriter_ &&
|
||||
blockingReaders_ == 0 /* && dirtyWriters_ == 0 */ &&
|
||||
(!imperativelyLocked_ || imperativeOwner_ == pthread_self());
|
||||
});
|
||||
blockingWriter_ = true;
|
||||
@@ -58,7 +60,8 @@ void SynchronizableAccess::setBlockingAfter() {
|
||||
void SynchronizableAccess::lock() {
|
||||
std::unique_lock<std::mutex> lock(accessLock_);
|
||||
queue_.wait(lock, [this]() {
|
||||
return !blockingWriter_ && blockingReaders_ == 0 /* && dirtyWriters_ == 0 */ &&
|
||||
return !blockingWriter_ &&
|
||||
blockingReaders_ == 0 /* && dirtyWriters_ == 0 */ &&
|
||||
(!imperativelyLocked_ || imperativeOwner_ == pthread_self());
|
||||
});
|
||||
imperativelyLocked_ = true;
|
||||
|
||||
Generated
Vendored
-12
@@ -8,15 +8,3 @@ so we have to check if headers are available.
|
||||
#if __APPLE__ && __has_include(<hermes/hermes.h>)
|
||||
#define JS_RUNTIME_HERMES 1
|
||||
#endif
|
||||
|
||||
#if REACT_NATIVE_MINOR_VERSION >= 84
|
||||
#include <cxxreact/JSBigString.h>
|
||||
namespace worklets {
|
||||
using JSBigStringBuffer = facebook::react::JSBigString;
|
||||
}
|
||||
#else
|
||||
#include <jsireact/JSIExecutor.h>
|
||||
namespace worklets {
|
||||
using JSBigStringBuffer = facebook::react::BigStringBuffer;
|
||||
}
|
||||
#endif // REACT_NATIVE_MINOR_VERSION >= 84
|
||||
|
||||
Generated
Vendored
-3
@@ -1,8 +1,5 @@
|
||||
#include <worklets/Tools/FeatureFlags.h>
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace worklets {
|
||||
|
||||
std::unordered_map<std::string, bool> DynamicFeatureFlags::flags_;
|
||||
|
||||
Generated
Vendored
+52
-22
@@ -1,11 +1,8 @@
|
||||
#include <worklets/Tools/JSISerializer.h>
|
||||
|
||||
#include <cxxabi.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace worklets {
|
||||
|
||||
@@ -63,23 +60,39 @@ const std::vector<std::string> SUPPORTED_REFLECTION_TYPES = {
|
||||
"Proxy",
|
||||
};
|
||||
|
||||
static inline std::string getObjectTypeName(jsi::Runtime &rt, const jsi::Object &object) {
|
||||
return object.getPropertyAsObject(rt, "constructor").getProperty(rt, "name").toString(rt).utf8(rt);
|
||||
static inline std::string getObjectTypeName(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Object &object) {
|
||||
return object.getPropertyAsObject(rt, "constructor")
|
||||
.getProperty(rt, "name")
|
||||
.toString(rt)
|
||||
.utf8(rt);
|
||||
}
|
||||
|
||||
static inline bool isInstanceOf(jsi::Runtime &rt, const jsi::Object &object, const std::string &type) {
|
||||
static inline bool isInstanceOf(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Object &object,
|
||||
const std::string &type) {
|
||||
return getObjectTypeName(rt, object) == type;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
isInstanceOfAny(jsi::Runtime &rt, const jsi::Object &object, const std::vector<std::string> &supportedTypes) {
|
||||
static inline bool isInstanceOfAny(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Object &object,
|
||||
const std::vector<std::string> &supportedTypes) {
|
||||
auto instanceType = getObjectTypeName(rt, object);
|
||||
|
||||
return std::find(supportedTypes.begin(), supportedTypes.end(), instanceType) != supportedTypes.end();
|
||||
return std::find(
|
||||
supportedTypes.begin(), supportedTypes.end(), instanceType) !=
|
||||
supportedTypes.end();
|
||||
}
|
||||
|
||||
JSISerializer::JSISerializer(jsi::Runtime &rt)
|
||||
: rt_(rt), visitedNodes_(rt_.global().getPropertyAsFunction(rt_, "Set").callAsConstructor(rt_).asObject(rt_)) {}
|
||||
: rt_(rt),
|
||||
visitedNodes_(rt_.global()
|
||||
.getPropertyAsFunction(rt_, "Set")
|
||||
.callAsConstructor(rt_)
|
||||
.asObject(rt_)) {}
|
||||
|
||||
std::string JSISerializer::stringifyWithName(const jsi::Object &object) {
|
||||
std::stringstream ss;
|
||||
@@ -117,7 +130,8 @@ std::string JSISerializer::stringifyFunction(const jsi::Function &func) {
|
||||
|
||||
std::string JSISerializer::stringifyHostObject(jsi::HostObject &hostObject) {
|
||||
int status = -1;
|
||||
char *hostObjClassName = abi::__cxa_demangle(typeid(hostObject).name(), NULL, NULL, &status);
|
||||
char *hostObjClassName =
|
||||
abi::__cxa_demangle(typeid(hostObject).name(), NULL, NULL, &status);
|
||||
if (status != 0) {
|
||||
return "[jsi::HostObject]";
|
||||
}
|
||||
@@ -135,7 +149,8 @@ std::string JSISerializer::stringifyHostObject(jsi::HostObject &hostObject) {
|
||||
for (const auto &key : props) {
|
||||
auto formattedKey = key.utf8(rt_);
|
||||
auto value = hostObject.get(rt_, key);
|
||||
ss << '"' << formattedKey << '"' << ": " << stringifyJSIValueRecursively(value);
|
||||
ss << '"' << formattedKey << '"' << ": "
|
||||
<< stringifyJSIValueRecursively(value);
|
||||
if (formattedKey != lastKey) {
|
||||
ss << ", ";
|
||||
}
|
||||
@@ -155,7 +170,8 @@ std::string JSISerializer::stringifyObject(const jsi::Object &object) {
|
||||
|
||||
for (size_t i = 0, propsCount = props.size(rt_); i < propsCount; i++) {
|
||||
jsi::String propName = props.getValueAtIndex(rt_, i).toString(rt_);
|
||||
ss << '"' << propName.utf8(rt_) << '"' << ": " << stringifyJSIValueRecursively(object.getProperty(rt_, propName));
|
||||
ss << '"' << propName.utf8(rt_) << '"' << ": "
|
||||
<< stringifyJSIValueRecursively(object.getProperty(rt_, propName));
|
||||
if (i != propsCount - 1) {
|
||||
ss << ", ";
|
||||
}
|
||||
@@ -175,7 +191,9 @@ std::string JSISerializer::stringifyError(const jsi::Object &object) {
|
||||
|
||||
std::string JSISerializer::stringifySet(const jsi::Object &object) {
|
||||
std::stringstream ss;
|
||||
jsi::Function arrayFrom = rt_.global().getPropertyAsObject(rt_, "Array").getPropertyAsFunction(rt_, "from");
|
||||
jsi::Function arrayFrom = rt_.global()
|
||||
.getPropertyAsObject(rt_, "Array")
|
||||
.getPropertyAsFunction(rt_, "from");
|
||||
jsi::Object result = arrayFrom.call(rt_, object).asObject(rt_);
|
||||
|
||||
if (!result.isArray(rt_)) {
|
||||
@@ -199,7 +217,9 @@ std::string JSISerializer::stringifySet(const jsi::Object &object) {
|
||||
|
||||
std::string JSISerializer::stringifyMap(const jsi::Object &object) {
|
||||
std::stringstream ss;
|
||||
jsi::Function arrayFrom = rt_.global().getPropertyAsObject(rt_, "Array").getPropertyAsFunction(rt_, "from");
|
||||
jsi::Function arrayFrom = rt_.global()
|
||||
.getPropertyAsObject(rt_, "Array")
|
||||
.getPropertyAsFunction(rt_, "from");
|
||||
jsi::Object result = arrayFrom.call(rt_, object).asObject(rt_);
|
||||
|
||||
if (!result.isArray(rt_)) {
|
||||
@@ -213,7 +233,8 @@ std::string JSISerializer::stringifyMap(const jsi::Object &object) {
|
||||
auto pair = arr.getValueAtIndex(rt_, i).asObject(rt_).getArray(rt_);
|
||||
auto key = pair.getValueAtIndex(rt_, 0);
|
||||
auto value = pair.getValueAtIndex(rt_, 1);
|
||||
ss << stringifyJSIValueRecursively(key) << ": " << stringifyJSIValueRecursively(value);
|
||||
ss << stringifyJSIValueRecursively(key) << ": "
|
||||
<< stringifyJSIValueRecursively(value);
|
||||
if (i != length - 1) {
|
||||
ss << ", ";
|
||||
}
|
||||
@@ -237,15 +258,21 @@ std::string JSISerializer::stringifyRecursiveType(const jsi::Object &object) {
|
||||
}
|
||||
|
||||
std::string JSISerializer::stringifyWithToString(const jsi::Object &object) {
|
||||
return object.getPropertyAsFunction(rt_, "toString").callWithThis(rt_, object).toString(rt_).utf8(rt_);
|
||||
return object.getPropertyAsFunction(rt_, "toString")
|
||||
.callWithThis(rt_, object)
|
||||
.toString(rt_)
|
||||
.utf8(rt_);
|
||||
}
|
||||
|
||||
std::string JSISerializer::stringifyJSIValueRecursively(const jsi::Value &value, bool isTopLevel) {
|
||||
std::string JSISerializer::stringifyJSIValueRecursively(
|
||||
const jsi::Value &value,
|
||||
bool isTopLevel) {
|
||||
if (value.isBool() || value.isNumber()) {
|
||||
return value.toString(rt_).utf8(rt_);
|
||||
}
|
||||
if (value.isString()) {
|
||||
return isTopLevel ? value.getString(rt_).utf8(rt_) : '"' + value.getString(rt_).utf8(rt_) + '"';
|
||||
return isTopLevel ? value.getString(rt_).utf8(rt_)
|
||||
: '"' + value.getString(rt_).utf8(rt_) + '"';
|
||||
}
|
||||
if (value.isSymbol()) {
|
||||
return value.getSymbol(rt_).toString(rt_);
|
||||
@@ -283,12 +310,15 @@ std::string JSISerializer::stringifyJSIValueRecursively(const jsi::Value &value,
|
||||
isInstanceOfAny(rt_, object, SUPPORTED_STRUCTURED_DATA_TYPES) ||
|
||||
isInstanceOfAny(rt_, object, SUPPORTED_MANAGING_MEMORY_TYPES) ||
|
||||
isInstanceOfAny(rt_, object, SUPPORTED_ABSTRACTION_OBJECT_TYPES) ||
|
||||
isInstanceOfAny(rt_, object, SUPPORTED_REFLECTION_TYPES) || isInstanceOf(rt_, object, "Intl") ||
|
||||
isInstanceOf(rt_, object, "WeakMap") || isInstanceOf(rt_, object, "WeakSet")) {
|
||||
isInstanceOfAny(rt_, object, SUPPORTED_REFLECTION_TYPES) ||
|
||||
isInstanceOf(rt_, object, "Intl") ||
|
||||
isInstanceOf(rt_, object, "WeakMap") ||
|
||||
isInstanceOf(rt_, object, "WeakSet")) {
|
||||
// TODO: Consider extending this log info
|
||||
return stringifyWithName(object);
|
||||
}
|
||||
if (isInstanceOf(rt_, object, "Date") || isInstanceOf(rt_, object, "RegExp")) {
|
||||
if (isInstanceOf(rt_, object, "Date") ||
|
||||
isInstanceOf(rt_, object, "RegExp")) {
|
||||
return stringifyWithToString(object);
|
||||
}
|
||||
if (isInstanceOf(rt_, object, "Map")) {
|
||||
|
||||
Generated
Vendored
+8
-3
@@ -11,7 +11,9 @@ namespace worklets {
|
||||
class JSISerializer {
|
||||
public:
|
||||
explicit JSISerializer(jsi::Runtime &rt);
|
||||
std::string stringifyJSIValueRecursively(const jsi::Value &value, bool isTopLevel = false);
|
||||
std::string stringifyJSIValueRecursively(
|
||||
const jsi::Value &value,
|
||||
bool isTopLevel = false);
|
||||
|
||||
private:
|
||||
std::string stringifyArray(const jsi::Array &arr);
|
||||
@@ -26,11 +28,14 @@ class JSISerializer {
|
||||
std::string stringifyRecursiveType(const jsi::Object &object);
|
||||
|
||||
bool hasBeenVisited(const jsi::Object &object) {
|
||||
return visitedNodes_.getPropertyAsFunction(rt_, "has").callWithThis(rt_, visitedNodes_, object).getBool();
|
||||
return visitedNodes_.getPropertyAsFunction(rt_, "has")
|
||||
.callWithThis(rt_, visitedNodes_, object)
|
||||
.getBool();
|
||||
}
|
||||
|
||||
void markAsVisited(const jsi::Object &object) {
|
||||
visitedNodes_.getPropertyAsFunction(rt_, "add").callWithThis(rt_, visitedNodes_, object);
|
||||
visitedNodes_.getPropertyAsFunction(rt_, "add")
|
||||
.callWithThis(rt_, visitedNodes_, object);
|
||||
}
|
||||
|
||||
jsi::Runtime &rt_;
|
||||
|
||||
Generated
Vendored
+28
-10
@@ -1,7 +1,6 @@
|
||||
#include <worklets/Tools/JSLogger.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace worklets {
|
||||
@@ -20,7 +19,8 @@ void JSLogger::reportFatalErrorOnJS(
|
||||
const std::shared_ptr<JSScheduler> &jsScheduler,
|
||||
JSErrorData &&jsErrorData,
|
||||
bool force) {
|
||||
auto job = [jsErrorData = std::move(jsErrorData), force](jsi::Runtime &rnRuntime) {
|
||||
auto job = [jsErrorData = std::move(jsErrorData),
|
||||
force](jsi::Runtime &rnRuntime) {
|
||||
reportFatalErrorOnJS(rnRuntime, jsErrorData, force);
|
||||
};
|
||||
if (jsScheduler->canInvokeSyncOnJS()) {
|
||||
@@ -30,20 +30,38 @@ void JSLogger::reportFatalErrorOnJS(
|
||||
}
|
||||
}
|
||||
|
||||
void JSLogger::reportFatalErrorOnJS(jsi::Runtime &rnRuntime, const JSErrorData &jsErrorData, bool force) {
|
||||
void JSLogger::reportFatalErrorOnJS(
|
||||
jsi::Runtime &rnRuntime,
|
||||
const JSErrorData &jsErrorData,
|
||||
bool force) {
|
||||
const auto &global = rnRuntime.global();
|
||||
const auto errorInstance =
|
||||
rnRuntime.global().getPropertyAsFunction(rnRuntime, "Error").callAsConstructor(rnRuntime).asObject(rnRuntime);
|
||||
const auto errorInstance = rnRuntime.global()
|
||||
.getPropertyAsFunction(rnRuntime, "Error")
|
||||
.callAsConstructor(rnRuntime)
|
||||
.asObject(rnRuntime);
|
||||
|
||||
errorInstance.setProperty(rnRuntime, "message", jsi::String::createFromUtf8(rnRuntime, jsErrorData.message));
|
||||
errorInstance.setProperty(
|
||||
rnRuntime,
|
||||
"message",
|
||||
jsi::String::createFromUtf8(rnRuntime, jsErrorData.message));
|
||||
|
||||
errorInstance.setProperty(rnRuntime, "stack", jsi::String::createFromUtf8(rnRuntime, jsErrorData.stack));
|
||||
errorInstance.setProperty(
|
||||
rnRuntime,
|
||||
"stack",
|
||||
jsi::String::createFromUtf8(rnRuntime, jsErrorData.stack));
|
||||
|
||||
errorInstance.setProperty(rnRuntime, "name", jsi::String::createFromUtf8(rnRuntime, jsErrorData.name));
|
||||
errorInstance.setProperty(
|
||||
rnRuntime,
|
||||
"name",
|
||||
jsi::String::createFromUtf8(rnRuntime, jsErrorData.name));
|
||||
|
||||
errorInstance.setProperty(rnRuntime, "jsEngine", jsi::String::createFromUtf8(rnRuntime, jsErrorData.jsEngine));
|
||||
errorInstance.setProperty(
|
||||
rnRuntime,
|
||||
"jsEngine",
|
||||
jsi::String::createFromUtf8(rnRuntime, jsErrorData.jsEngine));
|
||||
|
||||
const auto &reportFatalErrorFunction = global.getPropertyAsFunction(rnRuntime, "__reportFatalRemoteError");
|
||||
const auto &reportFatalErrorFunction =
|
||||
global.getPropertyAsFunction(rnRuntime, "__reportFatalRemoteError");
|
||||
reportFatalErrorFunction.call(rnRuntime, errorInstance, force);
|
||||
}
|
||||
|
||||
|
||||
Generated
Vendored
+10
-4
@@ -16,14 +16,20 @@ struct JSErrorData {
|
||||
|
||||
class JSLogger {
|
||||
public:
|
||||
explicit JSLogger(const std::shared_ptr<JSScheduler> &jsScheduler) : jsScheduler_(jsScheduler) {}
|
||||
explicit JSLogger(const std::shared_ptr<JSScheduler> &jsScheduler)
|
||||
: jsScheduler_(jsScheduler) {}
|
||||
void warnOnJS(const std::string &warning) const;
|
||||
|
||||
static void
|
||||
reportFatalErrorOnJS(const std::shared_ptr<JSScheduler> &jsScheduler, JSErrorData &&jsErrorData, bool force = false);
|
||||
static void reportFatalErrorOnJS(
|
||||
const std::shared_ptr<JSScheduler> &jsScheduler,
|
||||
JSErrorData &&jsErrorData,
|
||||
bool force = false);
|
||||
|
||||
private:
|
||||
static void reportFatalErrorOnJS(jsi::Runtime &rnRuntime, const JSErrorData &jsErrorData, bool force = false);
|
||||
static void reportFatalErrorOnJS(
|
||||
jsi::Runtime &rnRuntime,
|
||||
const JSErrorData &jsErrorData,
|
||||
bool force = false);
|
||||
|
||||
const std::shared_ptr<JSScheduler> jsScheduler_;
|
||||
};
|
||||
|
||||
Generated
Vendored
+6
-3
@@ -6,15 +6,18 @@
|
||||
namespace worklets {
|
||||
|
||||
void JSScheduler::scheduleOnJS(Job job) {
|
||||
jsCallInvoker_->invokeAsync([job = std::move(job), &rt = rnRuntime_] { job(rt); });
|
||||
jsCallInvoker_->invokeAsync(
|
||||
[job = std::move(job), &rt = rnRuntime_] { job(rt); });
|
||||
}
|
||||
|
||||
bool JSScheduler::canInvokeSyncOnJS() {
|
||||
return isJavaScriptQueue_();
|
||||
}
|
||||
|
||||
void JSScheduler::invokeSyncOnJS(const Job &job) {
|
||||
react_native_assert(canInvokeSyncOnJS() && "JSScheduler::invokeSyncOnJS should only be called from the JS thread");
|
||||
void JSScheduler::invokeSyncOnJS(Job job) {
|
||||
react_native_assert(
|
||||
canInvokeSyncOnJS() &&
|
||||
"JSScheduler::invokeSyncOnJS should only be called from the JS thread");
|
||||
job(rnRuntime_);
|
||||
}
|
||||
|
||||
|
||||
Generated
Vendored
+4
-2
@@ -18,11 +18,13 @@ class JSScheduler {
|
||||
jsi::Runtime &rnRuntime,
|
||||
const std::shared_ptr<CallInvoker> &jsCallInvoker,
|
||||
std::function<bool()> &&isJavaScriptQueue)
|
||||
: rnRuntime_(rnRuntime), jsCallInvoker_(jsCallInvoker), isJavaScriptQueue_(isJavaScriptQueue) {}
|
||||
: rnRuntime_(rnRuntime),
|
||||
jsCallInvoker_(jsCallInvoker),
|
||||
isJavaScriptQueue_(isJavaScriptQueue) {}
|
||||
|
||||
void scheduleOnJS(std::function<void(jsi::Runtime &rt)> job);
|
||||
|
||||
void invokeSyncOnJS(const std::function<void(jsi::Runtime &rt)> &job);
|
||||
void invokeSyncOnJS(std::function<void(jsi::Runtime &rt)> job);
|
||||
|
||||
bool canInvokeSyncOnJS();
|
||||
|
||||
|
||||
Generated
Vendored
+3
-2
@@ -28,7 +28,7 @@ class SingleInstanceChecker {
|
||||
~SingleInstanceChecker();
|
||||
|
||||
private:
|
||||
void assertWithMessage(bool condition, const std::string &message) {
|
||||
void assertWithMessage(bool condition, std::string message) {
|
||||
if (!condition) {
|
||||
#ifdef ANDROID
|
||||
__android_log_print(ANDROID_LOG_WARN, "Worklets", "%s", message.c_str());
|
||||
@@ -50,7 +50,8 @@ class SingleInstanceChecker {
|
||||
template <class T>
|
||||
SingleInstanceChecker<T>::SingleInstanceChecker() {
|
||||
int status = 0;
|
||||
std::string className = __cxxabiv1::__cxa_demangle(typeid(T).name(), nullptr, nullptr, &status);
|
||||
std::string className =
|
||||
__cxxabiv1::__cxa_demangle(typeid(T).name(), nullptr, nullptr, &status);
|
||||
|
||||
// React Native can spawn up to two instances of a Native Module at the same
|
||||
// time. This happens during a reload when a new instance of React Native is
|
||||
|
||||
Generated
Vendored
+4
-4
@@ -1,9 +1,7 @@
|
||||
#include <worklets/Tools/VersionUtils.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
|
||||
using namespace facebook;
|
||||
|
||||
@@ -11,7 +9,8 @@ namespace worklets {
|
||||
|
||||
bool matchVersion(const std::string &version1, const std::string &version2) {
|
||||
std::regex pattern("^\\d+\\.\\d+\\.\\d+$");
|
||||
if (std::regex_match(version1, pattern) && std::regex_match(version2, pattern)) {
|
||||
if (std::regex_match(version1, pattern) &&
|
||||
std::regex_match(version2, pattern)) {
|
||||
auto majorPattern = std::regex("^\\d+");
|
||||
std::smatch major1;
|
||||
std::smatch major2;
|
||||
@@ -64,7 +63,8 @@ void checkJSVersion(
|
||||
libraryPrefix +
|
||||
"Mismatch between C++ code version and "
|
||||
"JavaScript code version (") +
|
||||
cppVersion + " vs. " + jsVersion + " respectively).\n" + "See " + docsBaseUrl +
|
||||
cppVersion + " vs. " + jsVersion + " respectively).\n" + "See " +
|
||||
docsBaseUrl +
|
||||
"/guides/"
|
||||
"troubleshooting#mismatch-between-c-code-version-and-javascript-code-"
|
||||
"version` for more details.");
|
||||
|
||||
Generated
Vendored
+2
-4
@@ -1,15 +1,13 @@
|
||||
#include <worklets/Tools/WorkletEventHandler.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace worklets {
|
||||
|
||||
void WorkletEventHandler::process(
|
||||
const std::shared_ptr<WorkletRuntime> &workletRuntime,
|
||||
const double eventTimestamp,
|
||||
const jsi::Value &eventValue) const {
|
||||
workletRuntime->runSync(handlerFunction_, jsi::Value(eventTimestamp), eventValue);
|
||||
workletRuntime->runGuarded(
|
||||
handlerFunction_, jsi::Value(eventTimestamp), eventValue);
|
||||
}
|
||||
|
||||
uint64_t WorkletEventHandler::getHandlerId() const {
|
||||
|
||||
Generated
Vendored
+11
-5
@@ -4,14 +4,16 @@
|
||||
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace facebook;
|
||||
|
||||
namespace worklets::jsi_utils {
|
||||
|
||||
jsi::Array convertStringToArray(jsi::Runtime &rt, const std::string &value, const unsigned int expectedSize) {
|
||||
jsi::Array convertStringToArray(
|
||||
jsi::Runtime &rt,
|
||||
const std::string &value,
|
||||
const unsigned int expectedSize) {
|
||||
std::vector<float> transformMatrixList;
|
||||
std::istringstream stringStream(value);
|
||||
std::copy(
|
||||
@@ -19,7 +21,8 @@ jsi::Array convertStringToArray(jsi::Runtime &rt, const std::string &value, cons
|
||||
std::istream_iterator<float>(),
|
||||
std::back_inserter(transformMatrixList));
|
||||
react_native_assert(
|
||||
transformMatrixList.size() == expectedSize && "Transform matrix list size is different than expected");
|
||||
transformMatrixList.size() == expectedSize &&
|
||||
"Transform matrix list size is different than expected");
|
||||
jsi::Array matrix(rt, expectedSize);
|
||||
for (unsigned int i = 0; i < expectedSize; i++) {
|
||||
matrix.setValueAtIndex(rt, i, transformMatrixList[i]);
|
||||
@@ -27,10 +30,13 @@ jsi::Array convertStringToArray(jsi::Runtime &rt, const std::string &value, cons
|
||||
return matrix;
|
||||
}
|
||||
|
||||
jsi::Object optimizedFromHostObject(jsi::Runtime &rt, std::shared_ptr<jsi::HostObject> &&hostObject) {
|
||||
jsi::Object optimizedFromHostObject(
|
||||
jsi::Runtime &rt,
|
||||
std::shared_ptr<jsi::HostObject> &&hostObject) {
|
||||
auto optimizedObject = jsi::Object(rt);
|
||||
for (const auto &propertyName : hostObject->getPropertyNames(rt)) {
|
||||
optimizedObject.setProperty(rt, propertyName, hostObject->get(rt, propertyName));
|
||||
optimizedObject.setProperty(
|
||||
rt, propertyName, hostObject->get(rt, propertyName));
|
||||
}
|
||||
return optimizedObject;
|
||||
}
|
||||
|
||||
Generated
Vendored
+55
-18
@@ -40,7 +40,9 @@ inline jsi::Object get<jsi::Object>(jsi::Runtime &rt, const jsi::Value *value) {
|
||||
}
|
||||
|
||||
template <>
|
||||
inline jsi::Value const &get<jsi::Value const &>(jsi::Runtime &, const jsi::Value *value) {
|
||||
inline jsi::Value const &get<jsi::Value const &>(
|
||||
jsi::Runtime &,
|
||||
const jsi::Value *value) {
|
||||
return *value;
|
||||
}
|
||||
|
||||
@@ -55,7 +57,9 @@ inline jsi::Value const &get<jsi::Value const &>(jsi::Runtime &, const jsi::Valu
|
||||
// BEGIN implementations for `convertArgs` specializations.
|
||||
// specialization for empty `Targs` - returns an empty tuple
|
||||
template <typename... Args>
|
||||
inline std::enable_if_t<(sizeof...(Args) == 0), std::tuple<>> convertArgs(jsi::Runtime &, const jsi::Value *) {
|
||||
inline std::enable_if_t<(sizeof...(Args) == 0), std::tuple<>> convertArgs(
|
||||
jsi::Runtime &,
|
||||
const jsi::Value *) {
|
||||
return std::make_tuple();
|
||||
}
|
||||
|
||||
@@ -63,7 +67,9 @@ inline std::enable_if_t<(sizeof...(Args) == 0), std::tuple<>> convertArgs(jsi::R
|
||||
// then calls recursively on the rest of `args`
|
||||
// and returns the concatenation of results
|
||||
template <typename T, typename... Rest>
|
||||
inline std::tuple<T, Rest...> convertArgs(jsi::Runtime &rt, const jsi::Value *args) {
|
||||
inline std::tuple<T, Rest...> convertArgs(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value *args) {
|
||||
auto arg = std::tuple<T>(get<T>(rt, args));
|
||||
auto rest = convertArgs<Rest...>(rt, std::next(args));
|
||||
return std::tuple_cat(std::move(arg), std::move(rest));
|
||||
@@ -73,9 +79,14 @@ inline std::tuple<T, Rest...> convertArgs(jsi::Runtime &rt, const jsi::Value *ar
|
||||
// returns a tuple with the result of casting `args` to appropriate
|
||||
// native C++ types needed to call `function`
|
||||
template <typename Ret, typename... Args>
|
||||
std::tuple<Args...>
|
||||
getArgsForFunction(std::function<Ret(Args...)>, jsi::Runtime &rt, const jsi::Value *args, const size_t count) {
|
||||
react_native_assert(sizeof...(Args) == count && "Argument list has different length than expected");
|
||||
std::tuple<Args...> getArgsForFunction(
|
||||
std::function<Ret(Args...)>,
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value *args,
|
||||
const size_t count) {
|
||||
react_native_assert(
|
||||
sizeof...(Args) == count &&
|
||||
"Argument list has different length than expected");
|
||||
return convertArgs<Args...>(rt, args);
|
||||
}
|
||||
|
||||
@@ -88,27 +99,36 @@ std::tuple<jsi::Runtime &, Args...> getArgsForFunction(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value *args,
|
||||
const size_t count) {
|
||||
react_native_assert(sizeof...(Args) == count && "Argument list has different length than expected");
|
||||
react_native_assert(
|
||||
sizeof...(Args) == count &&
|
||||
"Argument list has different length than expected");
|
||||
return std::tuple_cat(std::tie(rt), convertArgs<Args...>(rt, args));
|
||||
}
|
||||
|
||||
// calls `function` with `args`
|
||||
template <typename Ret, typename... Args>
|
||||
inline jsi::Value apply(std::function<Ret(Args...)> function, std::tuple<Args...> args) {
|
||||
inline jsi::Value apply(
|
||||
std::function<Ret(Args...)> function,
|
||||
std::tuple<Args...> args) {
|
||||
return std::apply(function, std::move(args));
|
||||
}
|
||||
|
||||
// calls string-returning `function` with `args`,
|
||||
// and returns the string
|
||||
template <typename... Args>
|
||||
inline jsi::Value apply(jsi::Runtime &rt, std::function<std::string(Args...)> function, std::tuple<Args...> args) {
|
||||
inline jsi::Value apply(
|
||||
jsi::Runtime &rt,
|
||||
std::function<std::string(Args...)> function,
|
||||
std::tuple<Args...> args) {
|
||||
return jsi::String::createFromUtf8(rt, std::apply(function, std::move(args)));
|
||||
}
|
||||
|
||||
// calls void-returning `function` with `args`,
|
||||
// and returns `undefined`
|
||||
template <typename... Args>
|
||||
inline jsi::Value apply(std::function<void(Args...)> function, std::tuple<Args...> args) {
|
||||
inline jsi::Value apply(
|
||||
std::function<void(Args...)> function,
|
||||
std::tuple<Args...> args) {
|
||||
std::apply(function, std::move(args));
|
||||
return jsi::Value::undefined();
|
||||
}
|
||||
@@ -117,7 +137,11 @@ inline jsi::Value apply(std::function<void(Args...)> function, std::tuple<Args..
|
||||
// from a native function `function`
|
||||
template <typename Fun>
|
||||
jsi::HostFunctionType createHostFunction(Fun function) {
|
||||
return [function](jsi::Runtime &rt, const jsi::Value &, const jsi::Value *args, const size_t count) {
|
||||
return [function](
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &,
|
||||
const jsi::Value *args,
|
||||
const size_t count) {
|
||||
auto argz = getArgsForFunction(function, rt, args, count);
|
||||
return apply(function, std::move(argz));
|
||||
};
|
||||
@@ -126,8 +150,13 @@ jsi::HostFunctionType createHostFunction(Fun function) {
|
||||
// returns a function with JSI calling convention
|
||||
// from a native function `function` returning a string
|
||||
template <typename... Args>
|
||||
jsi::HostFunctionType createHostFunction(std::function<std::string(Args...)> function) {
|
||||
return [function](jsi::Runtime &rt, const jsi::Value &, const jsi::Value *args, const size_t count) {
|
||||
jsi::HostFunctionType createHostFunction(
|
||||
std::function<std::string(Args...)> function) {
|
||||
return [function](
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &,
|
||||
const jsi::Value *args,
|
||||
const size_t count) {
|
||||
auto argz = getArgsForFunction(function, rt, args, count);
|
||||
return apply(rt, function, std::move(argz));
|
||||
};
|
||||
@@ -150,11 +179,14 @@ struct takes_runtime<jsi::Runtime &, Rest...> {
|
||||
// and installs it as a global function named `name`
|
||||
// in the `rt` JS runtime
|
||||
template <typename Ret, typename... Args>
|
||||
void installJsiFunction(jsi::Runtime &rt, std::string_view name, std::function<Ret(Args...)> function) {
|
||||
void installJsiFunction(
|
||||
jsi::Runtime &rt,
|
||||
std::string_view name,
|
||||
std::function<Ret(Args...)> function) {
|
||||
auto clb = createHostFunction(function);
|
||||
auto argsCount = sizeof...(Args) - takes_runtime<Args...>::value;
|
||||
jsi::Value jsiFunction =
|
||||
jsi::Function::createFromHostFunction(rt, jsi::PropNameID::forAscii(rt, name.data()), argsCount, clb);
|
||||
jsi::Value jsiFunction = jsi::Function::createFromHostFunction(
|
||||
rt, jsi::PropNameID::forAscii(rt, name.data()), argsCount, clb);
|
||||
rt.global().setProperty(rt, name.data(), jsiFunction);
|
||||
}
|
||||
|
||||
@@ -164,8 +196,13 @@ void installJsiFunction(jsi::Runtime &rt, std::string_view name, Fun function) {
|
||||
installJsiFunction(rt, name, std::function(std::forward<Fun>(function)));
|
||||
}
|
||||
|
||||
jsi::Array convertStringToArray(jsi::Runtime &rt, const std::string &value, const unsigned int expectedSize);
|
||||
jsi::Array convertStringToArray(
|
||||
jsi::Runtime &rt,
|
||||
const std::string &value,
|
||||
const unsigned int expectedSize);
|
||||
|
||||
jsi::Object optimizedFromHostObject(jsi::Runtime &rt, std::shared_ptr<jsi::HostObject> &&hostObject);
|
||||
jsi::Object optimizedFromHostObject(
|
||||
jsi::Runtime &rt,
|
||||
std::shared_ptr<jsi::HostObject> &&hostObject);
|
||||
|
||||
} // namespace worklets::jsi_utils
|
||||
|
||||
Generated
Vendored
+30
-10
@@ -31,7 +31,9 @@ namespace worklets {
|
||||
struct WorkletsSystraceSection {
|
||||
public:
|
||||
template <typename... ConvertsToStringPiece>
|
||||
explicit WorkletsSystraceSection(const char *name, ConvertsToStringPiece &&...args) {
|
||||
explicit WorkletsSystraceSection(
|
||||
const char *name,
|
||||
ConvertsToStringPiece &&...args) {
|
||||
ATrace_beginSection(name);
|
||||
}
|
||||
|
||||
@@ -43,7 +45,8 @@ struct WorkletsSystraceSection {
|
||||
// The apple part is copied from React Native
|
||||
// from
|
||||
// https://github.com/facebook/react-native/blob/5697d923a05119314b4cfcd556cb243986637764/packages/react-native/ReactCommon/cxxreact/SystraceSection.h
|
||||
#elif defined(__APPLE__) && OS_LOG_TARGET_HAS_10_15_FEATURES && defined(WORKLETS_PROFILING)
|
||||
#elif defined(__APPLE__) && OS_LOG_TARGET_HAS_10_15_FEATURES && \
|
||||
defined(WORKLETS_PROFILING)
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct renderer {
|
||||
@@ -55,7 +58,8 @@ struct renderer {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
static auto render(const T &t) -> decltype(renderer<T>::render(std::declval<const T &>())) {
|
||||
static auto render(const T &t)
|
||||
-> decltype(renderer<T>::render(std::declval<const T &>())) {
|
||||
return renderer<T>::render(t);
|
||||
}
|
||||
|
||||
@@ -63,7 +67,8 @@ inline os_log_t instrumentsLogHandle = nullptr;
|
||||
|
||||
static inline os_log_t getOrCreateInstrumentsLogHandle() {
|
||||
if (!instrumentsLogHandle) {
|
||||
instrumentsLogHandle = os_log_create("dev.worklets.instruments", OS_LOG_CATEGORY_POINTS_OF_INTEREST);
|
||||
instrumentsLogHandle = os_log_create(
|
||||
"dev.worklets.instruments", OS_LOG_CATEGORY_POINTS_OF_INTEREST);
|
||||
}
|
||||
return instrumentsLogHandle;
|
||||
}
|
||||
@@ -71,7 +76,9 @@ static inline os_log_t getOrCreateInstrumentsLogHandle() {
|
||||
struct WorkletsSystraceSection {
|
||||
public:
|
||||
template <typename... ConvertsToStringPiece>
|
||||
explicit WorkletsSystraceSection(const char *name, ConvertsToStringPiece &&...args) {
|
||||
explicit WorkletsSystraceSection(
|
||||
const char *name,
|
||||
ConvertsToStringPiece &&...args) {
|
||||
os_log_t instrumentsLogHandle = worklets::getOrCreateInstrumentsLogHandle();
|
||||
|
||||
// If the log isn't enabled, we don't want the performance overhead of the
|
||||
@@ -90,11 +97,22 @@ struct WorkletsSystraceSection {
|
||||
|
||||
signpostID_ = os_signpost_id_make_with_pointer(instrumentsLogHandle, this);
|
||||
|
||||
os_signpost_interval_begin(instrumentsLogHandle, signpostID_, "Worklets", "%s begin: %s", name, argsString.c_str());
|
||||
os_signpost_interval_begin(
|
||||
instrumentsLogHandle,
|
||||
signpostID_,
|
||||
"Worklets",
|
||||
"%s begin: %s",
|
||||
name,
|
||||
argsString.c_str());
|
||||
}
|
||||
|
||||
~WorkletsSystraceSection() {
|
||||
os_signpost_interval_end(worklets::instrumentsLogHandle, signpostID_, "Worklets", "%s end", name_.data());
|
||||
os_signpost_interval_end(
|
||||
worklets::instrumentsLogHandle,
|
||||
signpostID_,
|
||||
"Worklets",
|
||||
"%s end",
|
||||
name_.data());
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -107,10 +125,12 @@ struct WorkletsSystraceSection {
|
||||
struct WorkletsSystraceSection {
|
||||
public:
|
||||
template <typename... ConvertsToStringPiece>
|
||||
explicit WorkletsSystraceSection(const char *name, ConvertsToStringPiece &&...args) {}
|
||||
explicit WorkletsSystraceSection(
|
||||
const char *name,
|
||||
ConvertsToStringPiece &&...args) {}
|
||||
};
|
||||
|
||||
#endif // defined(__APPLE__) && OS_LOG_TARGET_HAS_10_15_FEATURES && \
|
||||
// defined(WORKLETS_PROFILING)
|
||||
#endif // defined(__APPLE__) && OS_LOG_TARGET_HAS_10_15_FEATURES &&
|
||||
// defined(WORKLETS_PROFILING)
|
||||
|
||||
} // namespace worklets
|
||||
|
||||
Generated
Vendored
+12
-4
@@ -21,13 +21,19 @@ std::string getWorkletsCppVersion() {
|
||||
|
||||
void injectWorkletsCppVersion(jsi::Runtime &rnRuntime) {
|
||||
auto version = getWorkletsCppVersion();
|
||||
rnRuntime.global().setProperty(rnRuntime, "_WORKLETS_VERSION_CPP", jsi::String::createFromUtf8(rnRuntime, version));
|
||||
rnRuntime.global().setProperty(
|
||||
rnRuntime,
|
||||
"_WORKLETS_VERSION_CPP",
|
||||
jsi::String::createFromUtf8(rnRuntime, version));
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void checkJSVersion(jsi::Runtime &rnRuntime, const std::shared_ptr<worklets::JSLogger> &jsLogger) {
|
||||
void checkJSVersion(
|
||||
jsi::Runtime &rnRuntime,
|
||||
const std::shared_ptr<worklets::JSLogger> &jsLogger) {
|
||||
auto cppVersion = getWorkletsCppVersion();
|
||||
auto jsVersionValue = rnRuntime.global().getProperty(rnRuntime, "_WORKLETS_VERSION_JS");
|
||||
auto jsVersionValue =
|
||||
rnRuntime.global().getProperty(rnRuntime, "_WORKLETS_VERSION_JS");
|
||||
worklets::checkJSVersion(
|
||||
rnRuntime,
|
||||
jsVersionValue,
|
||||
@@ -37,7 +43,9 @@ void checkJSVersion(jsi::Runtime &rnRuntime, const std::shared_ptr<worklets::JSL
|
||||
"https://docs.swmansion.com/react-native-worklets/docs");
|
||||
}
|
||||
#else
|
||||
void checkJSVersion(jsi::Runtime &rnRuntime, const std::shared_ptr<worklets::JSLogger> &jsLogger) {
|
||||
void checkJSVersion(
|
||||
jsi::Runtime &rnRuntime,
|
||||
const std::shared_ptr<worklets::JSLogger> &jsLogger) {
|
||||
// In release builds we don't check the version, hence
|
||||
// this function is a NOOP.
|
||||
}
|
||||
|
||||
Generated
Vendored
+3
-1
@@ -13,6 +13,8 @@ namespace worklets {
|
||||
|
||||
std::string getWorkletsCppVersion();
|
||||
void injectWorkletsCppVersion(jsi::Runtime &);
|
||||
void checkJSVersion(jsi::Runtime &, const std::shared_ptr<worklets::JSLogger> &);
|
||||
void checkJSVersion(
|
||||
jsi::Runtime &,
|
||||
const std::shared_ptr<worklets::JSLogger> &);
|
||||
|
||||
}; // namespace worklets
|
||||
|
||||
Generated
Vendored
+7
-16
@@ -1,10 +1,9 @@
|
||||
#include <worklets/Tools/WorkletsJSIUtils.h>
|
||||
#include <worklets/Tools/WorkletsVersion.h>
|
||||
#include <worklets/WorkletRuntime/RNRuntimeWorkletDecorator.h>
|
||||
#include <worklets/WorkletRuntime/RuntimeKind.h>
|
||||
#include <worklets/WorkletRuntime/WorkletRuntimeCollector.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace worklets {
|
||||
@@ -13,7 +12,10 @@ void RNRuntimeWorkletDecorator::decorate(
|
||||
jsi::Runtime &rnRuntime,
|
||||
jsi::Object &&jsiWorkletsModuleProxy,
|
||||
const std::shared_ptr<JSLogger> &jsLogger) {
|
||||
rnRuntime.global().setProperty(rnRuntime, runtimeKindBindingName, static_cast<int>(RuntimeKind::ReactNative));
|
||||
rnRuntime.global().setProperty(
|
||||
rnRuntime,
|
||||
runtimeKindBindingName,
|
||||
static_cast<int>(RuntimeKind::ReactNative));
|
||||
|
||||
rnRuntime.global().setProperty(rnRuntime, "_WORKLET", false);
|
||||
|
||||
@@ -21,7 +23,8 @@ void RNRuntimeWorkletDecorator::decorate(
|
||||
// react-native-screens 4.9.0 depends on it
|
||||
rnRuntime.global().setProperty(rnRuntime, "_IS_FABRIC", true);
|
||||
|
||||
rnRuntime.global().setProperty(rnRuntime, "__workletsModuleProxy", std::move(jsiWorkletsModuleProxy));
|
||||
rnRuntime.global().setProperty(
|
||||
rnRuntime, "__workletsModuleProxy", std::move(jsiWorkletsModuleProxy));
|
||||
|
||||
WorkletRuntimeCollector::install(rnRuntime);
|
||||
|
||||
@@ -29,19 +32,7 @@ void RNRuntimeWorkletDecorator::decorate(
|
||||
checkJSVersion(rnRuntime, jsLogger);
|
||||
#endif // NDEBUG
|
||||
|
||||
#ifdef IS_REANIMATED_EXAMPLE_APP
|
||||
installDebugBindings(rnRuntime);
|
||||
#endif // IS_REANIMATED_EXAMPLE_APP
|
||||
|
||||
injectWorkletsCppVersion(rnRuntime);
|
||||
}
|
||||
|
||||
#ifdef IS_REANIMATED_EXAMPLE_APP
|
||||
void RNRuntimeWorkletDecorator::installDebugBindings(jsi::Runtime &rnRuntime) {
|
||||
jsi_utils::installJsiFunction(rnRuntime, "__hasNativeState", [](jsi::Runtime &rt, const jsi::Value &value) {
|
||||
return jsi::Value(value.isObject() && value.asObject(rt).hasNativeState(rt));
|
||||
});
|
||||
}
|
||||
#endif // IS_REANIMATED_EXAMPLE_APP
|
||||
|
||||
} // namespace worklets
|
||||
|
||||
Generated
Vendored
+4
-7
@@ -12,13 +12,10 @@ namespace worklets {
|
||||
class RNRuntimeWorkletDecorator {
|
||||
// TODO: Rename to `RNRuntimeWorkletsDecorator` or something more suitable.
|
||||
public:
|
||||
static void
|
||||
decorate(jsi::Runtime &rnRuntime, jsi::Object &&jsiWorkletsModuleProxy, const std::shared_ptr<JSLogger> &jsLogger);
|
||||
|
||||
#ifdef IS_REANIMATED_EXAMPLE_APP
|
||||
private:
|
||||
static void installDebugBindings(jsi::Runtime &rnRuntime);
|
||||
#endif // IS_REANIMATED_EXAMPLE_APP
|
||||
static void decorate(
|
||||
jsi::Runtime &rnRuntime,
|
||||
jsi::Object &&jsiWorkletsModuleProxy,
|
||||
const std::shared_ptr<JSLogger> &jsLogger);
|
||||
};
|
||||
|
||||
} // namespace worklets
|
||||
|
||||
Generated
Vendored
-17
@@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <jsi/jsi.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
using namespace facebook;
|
||||
|
||||
namespace worklets {
|
||||
|
||||
struct RuntimeBindings {
|
||||
using RequestAnimationFrame = std::function<void(std::function<void(const double)>)>;
|
||||
|
||||
const RequestAnimationFrame requestAnimationFrame;
|
||||
};
|
||||
|
||||
} // namespace worklets
|
||||
frontend-admin/node_modules/react-native-worklets/Common/cpp/worklets/WorkletRuntime/RuntimeData.cpp
Generated
Vendored
-8
@@ -1,11 +1,3 @@
|
||||
#include <worklets/WorkletRuntime/RuntimeData.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace worklets {
|
||||
namespace RuntimeData {
|
||||
|
||||
const std::string uiRuntimeName{"UI"};
|
||||
|
||||
} // namespace RuntimeData
|
||||
} // namespace worklets
|
||||
|
||||
Generated
Vendored
-13
@@ -1,23 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <jsi/jsi.h>
|
||||
#include <string>
|
||||
|
||||
namespace worklets {
|
||||
namespace RuntimeData {
|
||||
|
||||
/**
|
||||
* Unused, but kept for possible future use.
|
||||
*/
|
||||
constexpr uint64_t rnRuntimeId{0};
|
||||
constexpr uint64_t uiRuntimeId{1};
|
||||
extern const std::string uiRuntimeName;
|
||||
|
||||
#if REACT_NATIVE_MINOR_VERSION >= 81
|
||||
|
||||
constexpr facebook::jsi::UUID weakRuntimeUUID{0x770c6f2e, 0x1e4d, 0x436a, 0xa2b1, 0x9f322c8d5f5e};
|
||||
|
||||
#endif // REACT_NATIVE_MINOR_VERSION >= 81
|
||||
|
||||
}; // namespace RuntimeData
|
||||
} // namespace worklets
|
||||
|
||||
frontend-admin/node_modules/react-native-worklets/Common/cpp/worklets/WorkletRuntime/RuntimeHolder.h
Generated
Vendored
-22
@@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
#if REACT_NATIVE_MINOR_VERSION >= 81
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace worklets {
|
||||
|
||||
class WorkletRuntime;
|
||||
|
||||
/**
|
||||
* Holds a weak reference to a WorkletRuntime instance.
|
||||
*
|
||||
* Used to link jsi::Runtime instances back to their WorkletRuntime holders
|
||||
* without inducing reference cycles.
|
||||
*/
|
||||
struct WeakRuntimeHolder {
|
||||
std::weak_ptr<WorkletRuntime> weakRuntime;
|
||||
};
|
||||
|
||||
} // namespace worklets
|
||||
|
||||
#endif // REACT_NATIVE_MINOR_VERSION >= 81
|
||||
Generated
Vendored
+1
-3
@@ -1,13 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace worklets {
|
||||
/**
|
||||
* Represents the different types of runtime environments available for
|
||||
* worklets.
|
||||
*/
|
||||
enum class RuntimeKind : std::uint8_t {
|
||||
enum class RuntimeKind {
|
||||
ReactNative = 1,
|
||||
UI = 2,
|
||||
Worker = 3,
|
||||
|
||||
Generated
Vendored
+36
-24
@@ -1,10 +1,7 @@
|
||||
#include <worklets/NativeModules/JSIWorkletsModuleProxy.h>
|
||||
#include <worklets/WorkletRuntime/RuntimeManager.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace worklets {
|
||||
|
||||
@@ -16,6 +13,26 @@ std::shared_ptr<WorkletRuntime> RuntimeManager::getRuntime(uint64_t runtimeId) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<WorkletRuntime> RuntimeManager::getRuntime(
|
||||
const std::string &name) {
|
||||
std::shared_lock lock(weakRuntimesMutex_);
|
||||
if (nameToRuntimeId_.contains(name)) {
|
||||
return getRuntime(nameToRuntimeId_.at(name));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef WORKLETS_BUNDLE_MODE
|
||||
std::shared_ptr<WorkletRuntime> RuntimeManager::getRuntime(
|
||||
jsi::Runtime *runtime) {
|
||||
std::shared_lock lock(weakRuntimesMutex_);
|
||||
if (runtimeAddressToRuntimeId_.contains(runtime)) {
|
||||
return getRuntime(runtimeAddressToRuntimeId_.at(runtime));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
#endif // WORKLETS_BUNDLE_MODE
|
||||
|
||||
std::vector<std::shared_ptr<WorkletRuntime>> RuntimeManager::getAllRuntimes() {
|
||||
std::shared_lock lock(weakRuntimesMutex_);
|
||||
|
||||
@@ -32,27 +49,28 @@ std::vector<std::shared_ptr<WorkletRuntime>> RuntimeManager::getAllRuntimes() {
|
||||
}
|
||||
|
||||
std::shared_ptr<WorkletRuntime> RuntimeManager::getUIRuntime() {
|
||||
return getRuntime(RuntimeData::uiRuntimeId);
|
||||
return getRuntime(uiRuntimeId);
|
||||
}
|
||||
|
||||
std::shared_ptr<WorkletRuntime> RuntimeManager::createWorkletRuntime(
|
||||
std::shared_ptr<JSIWorkletsModuleProxy> jsiWorkletsModuleProxy,
|
||||
const std::string &name,
|
||||
const std::shared_ptr<SerializableWorklet> &initializer,
|
||||
std::shared_ptr<SerializableWorklet> initializer,
|
||||
const std::shared_ptr<AsyncQueue> &queue,
|
||||
bool enableEventLoop) {
|
||||
const auto runtimeId = getNextRuntimeId();
|
||||
const auto jsQueue = jsiWorkletsModuleProxy->getJSQueue();
|
||||
|
||||
auto workletRuntime = std::make_shared<WorkletRuntime>(runtimeId, jsQueue, name, queue, enableEventLoop);
|
||||
auto workletRuntime = std::make_shared<WorkletRuntime>(
|
||||
runtimeId, jsQueue, name, queue, enableEventLoop);
|
||||
|
||||
workletRuntime->init(std::move(jsiWorkletsModuleProxy));
|
||||
|
||||
if (initializer) {
|
||||
workletRuntime->runSync(initializer);
|
||||
workletRuntime->runGuarded(initializer);
|
||||
}
|
||||
|
||||
registerRuntime(runtimeId, workletRuntime);
|
||||
registerRuntime(runtimeId, name, workletRuntime);
|
||||
|
||||
return workletRuntime;
|
||||
}
|
||||
@@ -61,13 +79,9 @@ std::shared_ptr<WorkletRuntime> RuntimeManager::createUninitializedUIRuntime(
|
||||
const std::shared_ptr<MessageQueueThread> &jsQueue,
|
||||
const std::shared_ptr<AsyncQueue> &uiAsyncQueue) {
|
||||
const auto uiRuntime = std::make_shared<WorkletRuntime>(
|
||||
RuntimeData::uiRuntimeId,
|
||||
jsQueue,
|
||||
RuntimeData::uiRuntimeName,
|
||||
uiAsyncQueue,
|
||||
/*enableEventLoop*/ false);
|
||||
uiRuntimeId, jsQueue, uiRuntimeName, uiAsyncQueue);
|
||||
|
||||
registerRuntime(RuntimeData::uiRuntimeId, uiRuntime);
|
||||
registerRuntime(uiRuntimeId, uiRuntimeName, uiRuntime);
|
||||
|
||||
return uiRuntime;
|
||||
}
|
||||
@@ -76,18 +90,16 @@ uint64_t RuntimeManager::getNextRuntimeId() {
|
||||
return nextRuntimeId_.fetch_add(1, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
void RuntimeManager::registerRuntime(const uint64_t runtimeId, const std::shared_ptr<WorkletRuntime> &workletRuntime) {
|
||||
std::unique_lock registrationLock(registrationMutex_);
|
||||
void RuntimeManager::registerRuntime(
|
||||
const uint64_t runtimeId,
|
||||
const std::string &name,
|
||||
const std::shared_ptr<WorkletRuntime> &workletRuntime) {
|
||||
std::unique_lock lock(weakRuntimesMutex_);
|
||||
weakRuntimes_[runtimeId] = workletRuntime;
|
||||
}
|
||||
|
||||
void RuntimeManager::pause() {
|
||||
registrationMutex_.lock();
|
||||
}
|
||||
|
||||
void RuntimeManager::resume() {
|
||||
registrationMutex_.unlock();
|
||||
nameToRuntimeId_[name] = runtimeId;
|
||||
#ifdef WORKLETS_BUNDLE_MODE
|
||||
runtimeAddressToRuntimeId_[&workletRuntime->getJSIRuntime()] = runtimeId;
|
||||
#endif // WORKLETS_BUNDLE_MODE
|
||||
}
|
||||
|
||||
} // namespace worklets
|
||||
|
||||
Generated
Vendored
+14
-10
@@ -23,6 +23,10 @@ class JSIWorkletsModuleProxy;
|
||||
class RuntimeManager {
|
||||
public:
|
||||
std::shared_ptr<WorkletRuntime> getRuntime(uint64_t runtimeId);
|
||||
std::shared_ptr<WorkletRuntime> getRuntime(const std::string &name);
|
||||
#ifdef WORKLETS_BUNDLE_MODE
|
||||
std::shared_ptr<WorkletRuntime> getRuntime(jsi::Runtime *runtime);
|
||||
#endif // WORKLETS_BUNDLE_MODE
|
||||
|
||||
std::vector<std::shared_ptr<WorkletRuntime>> getAllRuntimes();
|
||||
|
||||
@@ -31,7 +35,7 @@ class RuntimeManager {
|
||||
std::shared_ptr<WorkletRuntime> createWorkletRuntime(
|
||||
std::shared_ptr<JSIWorkletsModuleProxy> jsiWorkletsModuleProxy,
|
||||
const std::string &name,
|
||||
const std::shared_ptr<SerializableWorklet> &initializer = nullptr,
|
||||
std::shared_ptr<SerializableWorklet> initializer = nullptr,
|
||||
const std::shared_ptr<AsyncQueue> &queue = nullptr,
|
||||
bool enableEventLoop = true);
|
||||
|
||||
@@ -39,21 +43,21 @@ class RuntimeManager {
|
||||
const std::shared_ptr<MessageQueueThread> &jsQueue,
|
||||
const std::shared_ptr<AsyncQueue> &uiAsyncQueue);
|
||||
|
||||
/** Pauses registration of new Worklet Runtimes. */
|
||||
void pause();
|
||||
|
||||
/** Resumes registration of new Worklet Runtimes. */
|
||||
void resume();
|
||||
|
||||
private:
|
||||
uint64_t getNextRuntimeId();
|
||||
|
||||
void registerRuntime(const uint64_t runtimeId, const std::shared_ptr<WorkletRuntime> &workletRuntime);
|
||||
void registerRuntime(
|
||||
const uint64_t runtimeId,
|
||||
const std::string &name,
|
||||
const std::shared_ptr<WorkletRuntime> &workletRuntime);
|
||||
|
||||
std::atomic_uint64_t nextRuntimeId_{RuntimeData::uiRuntimeId + 1};
|
||||
std::atomic_uint64_t nextRuntimeId_{uiRuntimeId + 1};
|
||||
std::map<uint64_t, std::weak_ptr<WorkletRuntime>> weakRuntimes_;
|
||||
std::shared_mutex weakRuntimesMutex_;
|
||||
std::mutex registrationMutex_;
|
||||
std::map<std::string, uint64_t> nameToRuntimeId_;
|
||||
#ifdef WORKLETS_BUNDLE_MODE
|
||||
std::map<jsi::Runtime *, uint64_t> runtimeAddressToRuntimeId_;
|
||||
#endif // WORKLETS_BUNDLE_MODE
|
||||
};
|
||||
|
||||
} // namespace worklets
|
||||
|
||||
Generated
Vendored
+7
-3
@@ -8,12 +8,16 @@ namespace worklets {
|
||||
|
||||
void UIRuntimeDecorator::decorate(
|
||||
facebook::jsi::Runtime &uiRuntime,
|
||||
std::function<void(facebook::jsi::Runtime &rt, const facebook::jsi::Value &callback)> &&requestAnimationFrame) {
|
||||
uiRuntime.global().setProperty(uiRuntime, runtimeKindBindingName, static_cast<int>(RuntimeKind::UI));
|
||||
std::function<
|
||||
void(facebook::jsi::Runtime &rt, const facebook::jsi::Value &callback)>
|
||||
&&requestAnimationFrame) {
|
||||
uiRuntime.global().setProperty(
|
||||
uiRuntime, runtimeKindBindingName, static_cast<int>(RuntimeKind::UI));
|
||||
|
||||
uiRuntime.global().setProperty(uiRuntime, "_UI", true);
|
||||
|
||||
jsi_utils::installJsiFunction(uiRuntime, "requestAnimationFrame", std::move(requestAnimationFrame));
|
||||
jsi_utils::installJsiFunction(
|
||||
uiRuntime, "requestAnimationFrame", std::move(requestAnimationFrame));
|
||||
}
|
||||
|
||||
} // namespace worklets
|
||||
|
||||
Generated
Vendored
+3
-1
@@ -8,7 +8,9 @@ class UIRuntimeDecorator {
|
||||
public:
|
||||
static void decorate(
|
||||
facebook::jsi::Runtime &uiRuntime,
|
||||
std::function<void(facebook::jsi::Runtime &rt, const facebook::jsi::Value &callback)> &&requestAnimationFrame);
|
||||
std::function<void(
|
||||
facebook::jsi::Runtime &rt,
|
||||
const facebook::jsi::Value &callback)> &&requestAnimationFrame);
|
||||
};
|
||||
|
||||
} // namespace worklets
|
||||
|
||||
Generated
Vendored
+27
-21
@@ -16,29 +16,25 @@ namespace worklets {
|
||||
|
||||
using namespace facebook;
|
||||
using namespace react;
|
||||
#if HERMES_ENABLE_DEBUGGER && !defined(HERMES_V1_ENABLED)
|
||||
#if HERMES_ENABLE_DEBUGGER
|
||||
using namespace facebook::hermes::inspector_modern;
|
||||
#endif // HERMES_ENABLE_DEBUGGER && !defined(HERMES_V1_ENABLED)
|
||||
#endif // HERMES_ENABLE_DEBUGGER
|
||||
|
||||
#if HERMES_ENABLE_DEBUGGER
|
||||
|
||||
class HermesExecutorRuntimeAdapter
|
||||
#if HERMES_ENABLE_DEBUGGER && !defined(HERMES_V1_ENABLED)
|
||||
: public RuntimeAdapter
|
||||
#endif // HERMES_ENABLE_DEBUGGER && !defined(HERMES_V1_ENABLED)
|
||||
{
|
||||
class HermesExecutorRuntimeAdapter : public RuntimeAdapter {
|
||||
public:
|
||||
explicit HermesExecutorRuntimeAdapter(
|
||||
facebook::hermes::HermesRuntime &hermesRuntime,
|
||||
const std::shared_ptr<MessageQueueThread> &thread)
|
||||
: hermesRuntime_(hermesRuntime), thread_(thread) {}
|
||||
: hermesRuntime_(hermesRuntime), thread_(std::move(thread)) {}
|
||||
|
||||
virtual ~HermesExecutorRuntimeAdapter() {
|
||||
// This is required by iOS, because there is an assertion in the destructor
|
||||
// that the thread was indeed `quit` before
|
||||
thread_->quitSynchronous();
|
||||
}
|
||||
#if HERMES_ENABLE_DEBUGGER && !defined(HERMES_V1_ENABLED)
|
||||
|
||||
facebook::hermes::HermesRuntime &getRuntime() override {
|
||||
return hermesRuntime_;
|
||||
}
|
||||
@@ -48,7 +44,6 @@ class HermesExecutorRuntimeAdapter
|
||||
// required us to hold a refernce to the runtime inside this adapter which
|
||||
// caused issues while reloading the app.
|
||||
void tickleJs() override {}
|
||||
#endif // HERMES_ENABLE_DEBUGGER && !defined(HERMES_V1_ENABLED)
|
||||
|
||||
public:
|
||||
facebook::hermes::HermesRuntime &hermesRuntime_;
|
||||
@@ -61,11 +56,15 @@ WorkletHermesRuntime::WorkletHermesRuntime(
|
||||
std::unique_ptr<facebook::hermes::HermesRuntime> runtime,
|
||||
const std::shared_ptr<MessageQueueThread> &jsQueue,
|
||||
const std::string &name)
|
||||
: jsi::WithRuntimeDecorator<WorkletsReentrancyCheck>(*runtime, reentrancyCheck_), runtime_(std::move(runtime)) {
|
||||
#if HERMES_ENABLE_DEBUGGER && !defined(HERMES_V1_ENABLED)
|
||||
auto adapter = std::make_unique<HermesExecutorRuntimeAdapter>(*runtime_, jsQueue);
|
||||
: jsi::WithRuntimeDecorator<WorkletsReentrancyCheck>(
|
||||
*runtime,
|
||||
reentrancyCheck_),
|
||||
runtime_(std::move(runtime)) {
|
||||
#if HERMES_ENABLE_DEBUGGER
|
||||
auto adapter =
|
||||
std::make_unique<HermesExecutorRuntimeAdapter>(*runtime_, jsQueue);
|
||||
debugToken_ = chrome::enableDebugging(std::move(adapter), name);
|
||||
#endif // HERMES_ENABLE_DEBUGGER && !defined(HERMES_V1_ENABLED)
|
||||
#endif // HERMES_ENABLE_DEBUGGER
|
||||
|
||||
#ifndef NDEBUG
|
||||
facebook::hermes::HermesRuntime *wrappedRuntime = runtime_.get();
|
||||
@@ -74,27 +73,34 @@ WorkletHermesRuntime::WorkletHermesRuntime(
|
||||
jsi::PropNameID::forAscii(*runtime_, "evalWithSourceMap"),
|
||||
3,
|
||||
[wrappedRuntime](
|
||||
jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) -> jsi::Value {
|
||||
auto code = std::make_shared<const jsi::StringBuffer>(args[0].asString(rt).utf8(rt));
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) -> jsi::Value {
|
||||
auto code = std::make_shared<const jsi::StringBuffer>(
|
||||
args[0].asString(rt).utf8(rt));
|
||||
std::string sourceURL;
|
||||
if (count > 1 && args[1].isString()) {
|
||||
sourceURL = args[1].asString(rt).utf8(rt);
|
||||
}
|
||||
std::shared_ptr<const jsi::Buffer> sourceMap;
|
||||
if (count > 2 && args[2].isString()) {
|
||||
sourceMap = std::make_shared<const jsi::StringBuffer>(args[2].asString(rt).utf8(rt));
|
||||
sourceMap = std::make_shared<const jsi::StringBuffer>(
|
||||
args[2].asString(rt).utf8(rt));
|
||||
}
|
||||
return wrappedRuntime->evaluateJavaScriptWithSourceMap(code, sourceMap, sourceURL);
|
||||
return wrappedRuntime->evaluateJavaScriptWithSourceMap(
|
||||
code, sourceMap, sourceURL);
|
||||
});
|
||||
runtime_->global().setProperty(*runtime_, "evalWithSourceMap", evalWithSourceMap);
|
||||
runtime_->global().setProperty(
|
||||
*runtime_, "evalWithSourceMap", evalWithSourceMap);
|
||||
#endif // NDEBUG
|
||||
}
|
||||
|
||||
WorkletHermesRuntime::~WorkletHermesRuntime() {
|
||||
#if HERMES_ENABLE_DEBUGGER && !defined(HERMES_V1_ENABLED)
|
||||
#if HERMES_ENABLE_DEBUGGER
|
||||
// We have to disable debugging before the runtime is destroyed.
|
||||
chrome::disableDebugging(debugToken_);
|
||||
#endif // HERMES_ENABLE_DEBUGGER && !defined(HERMES_V1_ENABLED)
|
||||
#endif // HERMES_ENABLE_DEBUGGER
|
||||
}
|
||||
|
||||
} // namespace worklets
|
||||
|
||||
Generated
Vendored
+21
-14
@@ -17,17 +17,17 @@
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
#if HERMES_ENABLE_DEBUGGER && !defined(HERMES_V1_ENABLED)
|
||||
#if HERMES_ENABLE_DEBUGGER
|
||||
#include <hermes/inspector-modern/chrome/Registration.h>
|
||||
#endif // HERMES_ENABLE_DEBUGGER && !defined(HERMES_V1_ENABLED)
|
||||
#endif // HERMES_ENABLE_DEBUGGER
|
||||
|
||||
namespace worklets {
|
||||
|
||||
using namespace facebook;
|
||||
using namespace react;
|
||||
#if HERMES_ENABLE_DEBUGGER && !defined(HERMES_V1_ENABLED)
|
||||
#if HERMES_ENABLE_DEBUGGER
|
||||
using namespace facebook::hermes::inspector_modern;
|
||||
#endif // HERMES_ENABLE_DEBUGGER && !defined(HERMES_V1_ENABLED)
|
||||
#endif // HERMES_ENABLE_DEBUGGER
|
||||
|
||||
// ReentrancyCheck is copied from React Native
|
||||
// from ReactCommon/hermes/executor/HermesExecutorFactory.cpp
|
||||
@@ -57,17 +57,20 @@ struct WorkletsReentrancyCheck {
|
||||
// of this sort would be surprising, because the decorator would
|
||||
// need to call after() without before().
|
||||
|
||||
if (tid.compare_exchange_strong(expected, this_id, std::memory_order_relaxed)) {
|
||||
if (tid.compare_exchange_strong(
|
||||
expected, this_id, std::memory_order_relaxed)) {
|
||||
// Returns true if tid and expected were the same. If they
|
||||
// were, then the stored tid referred to no thread, and we
|
||||
// atomically saved this thread's tid. Now increment depth.
|
||||
react_native_assert(depth == 0 && "[Worklets] No thread id, but depth != 0");
|
||||
react_native_assert(
|
||||
depth == 0 && "[Worklets] No thread id, but depth != 0");
|
||||
++depth;
|
||||
} else if (expected == this_id) {
|
||||
// If the stored tid referred to a thread, expected was set to
|
||||
// that value. If that value is this thread's tid, that's ok,
|
||||
// just increment depth again.
|
||||
react_native_assert(depth != 0 && "[Worklets] Thread id was set, but depth == 0");
|
||||
react_native_assert(
|
||||
depth != 0 && "[Worklets] Thread id was set, but depth == 0");
|
||||
++depth;
|
||||
} else {
|
||||
// The stored tid was some other thread. This indicates a bad
|
||||
@@ -80,12 +83,15 @@ struct WorkletsReentrancyCheck {
|
||||
|
||||
void after() {
|
||||
react_native_assert(
|
||||
tid.load(std::memory_order_relaxed) == std::this_thread::get_id() && "[Worklets] No thread id in after()");
|
||||
tid.load(std::memory_order_relaxed) == std::this_thread::get_id() &&
|
||||
"[Worklets] No thread id in after()");
|
||||
if (--depth == 0) {
|
||||
// If we decremented depth to zero, store no-thread into tid.
|
||||
std::thread::id expected = std::this_thread::get_id();
|
||||
bool didWrite = tid.compare_exchange_strong(expected, std::thread::id(), std::memory_order_relaxed);
|
||||
react_native_assert(didWrite && "[Worklets] Decremented to zero, but no tid write");
|
||||
bool didWrite = tid.compare_exchange_strong(
|
||||
expected, std::thread::id(), std::memory_order_relaxed);
|
||||
react_native_assert(
|
||||
didWrite && "[Worklets] Decremented to zero, but no tid write");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,20 +109,21 @@ struct WorkletsReentrancyCheck {
|
||||
// WithRuntimeDecorator -> DecoratedRuntime -> jsi::Runtime You can find out
|
||||
// more about this in ReactCommon/jsi/jsi/Decorator.h or by following this link:
|
||||
// https://github.com/facebook/react-native/blob/main/packages/react-native/ReactCommon/jsi/jsi/decorator.h
|
||||
class WorkletHermesRuntime : public jsi::WithRuntimeDecorator<WorkletsReentrancyCheck> {
|
||||
class WorkletHermesRuntime
|
||||
: public jsi::WithRuntimeDecorator<WorkletsReentrancyCheck> {
|
||||
public:
|
||||
WorkletHermesRuntime(
|
||||
std::unique_ptr<facebook::hermes::HermesRuntime> runtime,
|
||||
const std::shared_ptr<MessageQueueThread> &jsQueue,
|
||||
const std::string &name);
|
||||
~WorkletHermesRuntime() override;
|
||||
~WorkletHermesRuntime();
|
||||
|
||||
private:
|
||||
std::unique_ptr<facebook::hermes::HermesRuntime> runtime_;
|
||||
WorkletsReentrancyCheck reentrancyCheck_;
|
||||
#if HERMES_ENABLE_DEBUGGER && !defined(HERMES_V1_ENABLED)
|
||||
#if HERMES_ENABLE_DEBUGGER
|
||||
chrome::DebugSessionToken debugToken_;
|
||||
#endif // HERMES_ENABLE_DEBUGGER && !defined(HERMES_V1_ENABLED)
|
||||
#endif // HERMES_ENABLE_DEBUGGER
|
||||
};
|
||||
|
||||
} // namespace worklets
|
||||
|
||||
Generated
Vendored
+72
-143
@@ -4,7 +4,6 @@
|
||||
#include <worklets/Tools/JSISerializer.h>
|
||||
#include <worklets/Tools/JSLogger.h>
|
||||
#include <worklets/Tools/WorkletsJSIUtils.h>
|
||||
#include <worklets/WorkletRuntime/RuntimeHolder.h>
|
||||
#include <worklets/WorkletRuntime/WorkletRuntime.h>
|
||||
#include <worklets/WorkletRuntime/WorkletRuntimeCollector.h>
|
||||
#include <worklets/WorkletRuntime/WorkletRuntimeDecorator.h>
|
||||
@@ -14,9 +13,7 @@
|
||||
#include <jsi/jsi.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#if JS_RUNTIME_HERMES
|
||||
#include <worklets/WorkletRuntime/WorkletHermesRuntime.h>
|
||||
@@ -30,7 +27,8 @@ class AroundLock {
|
||||
const std::shared_ptr<std::recursive_mutex> mutex_;
|
||||
|
||||
public:
|
||||
explicit AroundLock(const std::shared_ptr<std::recursive_mutex> &mutex) : mutex_(mutex) {}
|
||||
explicit AroundLock(const std::shared_ptr<std::recursive_mutex> &mutex)
|
||||
: mutex_(mutex) {}
|
||||
|
||||
void before() const {
|
||||
mutex_->lock();
|
||||
@@ -61,7 +59,8 @@ static std::shared_ptr<jsi::Runtime> makeRuntime(
|
||||
std::shared_ptr<jsi::Runtime> jsiRuntime;
|
||||
#if JS_RUNTIME_HERMES
|
||||
auto hermesRuntime = facebook::hermes::makeHermesRuntime();
|
||||
jsiRuntime = std::make_shared<WorkletHermesRuntime>(std::move(hermesRuntime), jsQueue, name);
|
||||
jsiRuntime = std::make_shared<WorkletHermesRuntime>(
|
||||
std::move(hermesRuntime), jsQueue, name);
|
||||
#else
|
||||
jsiRuntime = facebook::jsc::makeJSCRuntime();
|
||||
#endif
|
||||
@@ -82,37 +81,37 @@ WorkletRuntime::WorkletRuntime(
|
||||
queue_(queue) {
|
||||
jsi::Runtime &rt = *runtime_;
|
||||
WorkletRuntimeCollector::install(rt);
|
||||
if (enableEventLoop) {
|
||||
if (enableEventLoop && name != uiRuntimeName) {
|
||||
eventLoop_ = std::make_shared<EventLoop>(name_, runtime_, queue_);
|
||||
eventLoop_->run();
|
||||
}
|
||||
}
|
||||
|
||||
void WorkletRuntime::init(std::shared_ptr<JSIWorkletsModuleProxy> jsiWorkletsModuleProxy) {
|
||||
void WorkletRuntime::init(
|
||||
std::shared_ptr<JSIWorkletsModuleProxy> jsiWorkletsModuleProxy) {
|
||||
jsi::Runtime &rt = *runtime_;
|
||||
|
||||
#if REACT_NATIVE_MINOR_VERSION >= 81
|
||||
rt.setRuntimeData(
|
||||
RuntimeData::weakRuntimeUUID,
|
||||
std::make_shared<WeakRuntimeHolder>(WeakRuntimeHolder{.weakRuntime = weak_from_this()}));
|
||||
#endif // REACT_NATIVE_MINOR_VERSION >= 81
|
||||
|
||||
const auto jsScheduler = jsiWorkletsModuleProxy->getJSScheduler();
|
||||
const auto isDevBundle = jsiWorkletsModuleProxy->isDevBundle();
|
||||
const auto memoryManager_ = jsiWorkletsModuleProxy->getMemoryManager();
|
||||
#ifdef WORKLETS_BUNDLE_MODE
|
||||
auto script = jsiWorkletsModuleProxy->getScript();
|
||||
const auto &sourceUrl = jsiWorkletsModuleProxy->getSourceUrl();
|
||||
#endif // WORKLETS_BUNDLE_MODE
|
||||
|
||||
auto optimizedJsiWorkletsModuleProxy = jsi_utils::optimizedFromHostObject(rt, std::move(jsiWorkletsModuleProxy));
|
||||
auto optimizedJsiWorkletsModuleProxy =
|
||||
jsi_utils::optimizedFromHostObject(rt, std::move(jsiWorkletsModuleProxy));
|
||||
|
||||
WorkletRuntimeDecorator::decorate(
|
||||
rt, name_, jsScheduler, isDevBundle, std::move(optimizedJsiWorkletsModuleProxy), eventLoop_);
|
||||
rt,
|
||||
name_,
|
||||
jsScheduler,
|
||||
isDevBundle,
|
||||
std::move(optimizedJsiWorkletsModuleProxy),
|
||||
eventLoop_);
|
||||
|
||||
#ifdef WORKLETS_BUNDLE_MODE
|
||||
if (!script) {
|
||||
throw std::runtime_error("[Worklets] Expected to receive the bundle, but got nullptr instead.");
|
||||
throw std::runtime_error(
|
||||
"[Worklets] Expected to receive the bundle, but got nullptr instead.");
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -121,99 +120,87 @@ void WorkletRuntime::init(std::shared_ptr<JSIWorkletsModuleProxy> jsiWorkletsMod
|
||||
const auto &message = error.getMessage();
|
||||
const auto &stack = error.getStack();
|
||||
if (!message.starts_with("[Worklets] Worklets initialized successfully")) {
|
||||
const auto newMessage = "[Worklets] Failed to initialize runtime. Reason: " + message;
|
||||
const auto newMessage =
|
||||
"[Worklets] Failed to initialize runtime. Reason: " + message;
|
||||
JSLogger::reportFatalErrorOnJS(
|
||||
jsScheduler, {.message = newMessage, .stack = stack, .name = "WorkletsError", .jsEngine = "Worklets"});
|
||||
jsScheduler,
|
||||
{.message = newMessage,
|
||||
.stack = stack,
|
||||
.name = "WorkletsError",
|
||||
.jsEngine = "Worklets"});
|
||||
}
|
||||
}
|
||||
#else
|
||||
// Legacy behavior
|
||||
auto valueUnpackerBuffer = std::make_shared<const jsi::StringBuffer>(ValueUnpackerCode);
|
||||
auto valueUnpackerBuffer =
|
||||
std::make_shared<const jsi::StringBuffer>(ValueUnpackerCode);
|
||||
rt.evaluateJavaScript(valueUnpackerBuffer, "valueUnpacker");
|
||||
|
||||
auto synchronizableUnpackerBuffer = std::make_shared<const jsi::StringBuffer>(SynchronizableUnpackerCode);
|
||||
auto synchronizableUnpackerBuffer =
|
||||
std::make_shared<const jsi::StringBuffer>(SynchronizableUnpackerCode);
|
||||
rt.evaluateJavaScript(synchronizableUnpackerBuffer, "synchronizableUnpacker");
|
||||
|
||||
auto customSerializableUnpackerBuffer = std::make_shared<const jsi::StringBuffer>(CustomSerializableUnpackerCode);
|
||||
rt.evaluateJavaScript(customSerializableUnpackerBuffer, "customSerializableUnpacker");
|
||||
#endif // WORKLETS_BUNDLE_MODE
|
||||
try {
|
||||
memoryManager_->loadAllCustomSerializables(shared_from_this());
|
||||
} catch (jsi::JSError &e) {
|
||||
throw std::runtime_error(std::string("[Worklets] Failed to load custom serializables. Reason: ") + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/* #region schedule */
|
||||
|
||||
void WorkletRuntime::schedule(jsi::Function &&function) const {
|
||||
void WorkletRuntime::runAsyncGuarded(
|
||||
const std::shared_ptr<SerializableWorklet> &worklet) {
|
||||
react_native_assert(
|
||||
queue_ &&
|
||||
"[Worklets] Tried to invoke `schedule` on a Worklet Runtime but the "
|
||||
"async queue is not set. Recreate the runtime with a valid async queue.");
|
||||
queue_->push([function = std::make_shared<jsi::Function>(std::move(function)), weakThis = weak_from_this()]() {
|
||||
"[Worklets] Tried to invoke `runAsyncGuarded` on a Worklet Runtime but "
|
||||
"the async queue is not set. Recreate the runtime with a valid async queue.");
|
||||
|
||||
queue_->push([worklet, weakThis = weak_from_this()] {
|
||||
auto strongThis = weakThis.lock();
|
||||
if (!strongThis) {
|
||||
return;
|
||||
}
|
||||
|
||||
strongThis->runSync(*function);
|
||||
strongThis->runGuarded(worklet);
|
||||
});
|
||||
}
|
||||
|
||||
void WorkletRuntime::schedule(std::shared_ptr<SerializableWorklet> worklet) const {
|
||||
react_native_assert(
|
||||
queue_ &&
|
||||
"[Worklets] Tried to invoke `schedule` on a Worklet Runtime but the "
|
||||
"async queue is not set. Recreate the runtime with a valid async queue.");
|
||||
|
||||
queue_->push([worklet = std::move(worklet), weakThis = weak_from_this()] {
|
||||
auto strongThis = weakThis.lock();
|
||||
if (!strongThis) {
|
||||
return;
|
||||
}
|
||||
|
||||
strongThis->runSync(worklet);
|
||||
});
|
||||
jsi::Value WorkletRuntime::executeSync(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &worklet) const {
|
||||
auto serializableWorklet = extractSerializableOrThrow<SerializableWorklet>(
|
||||
rt,
|
||||
worklet,
|
||||
"[Worklets] Only worklets can be executed synchronously on UI runtime.");
|
||||
auto lock = std::unique_lock<std::recursive_mutex>(*runtimeMutex_);
|
||||
jsi::Runtime &uiRuntime = getJSIRuntime();
|
||||
auto result = runGuarded(serializableWorklet);
|
||||
auto serializableResult = extractSerializableOrThrow(uiRuntime, result);
|
||||
lock.unlock();
|
||||
return serializableResult->toJSValue(rt);
|
||||
}
|
||||
|
||||
void WorkletRuntime::schedule(std::function<void()> job) const {
|
||||
react_native_assert(
|
||||
queue_ &&
|
||||
"[Worklets] Tried to invoke `schedule` on a Worklet Runtime but the "
|
||||
"async queue is not set. Recreate the runtime with a valid async queue.");
|
||||
|
||||
queue_->push(std::move(job));
|
||||
#ifdef WORKLETS_BUNDLE_MODE
|
||||
jsi::Value WorkletRuntime::executeSync(
|
||||
std::function<jsi::Value(jsi::Runtime &)> &&job) const {
|
||||
auto lock = std::unique_lock<std::recursive_mutex>(*runtimeMutex_);
|
||||
jsi::Runtime &uiRuntime = getJSIRuntime();
|
||||
return job(uiRuntime);
|
||||
}
|
||||
|
||||
void WorkletRuntime::schedule(std::function<void(jsi::Runtime &)> job) const {
|
||||
react_native_assert(
|
||||
queue_ &&
|
||||
"[Worklets] Tried to invoke `schedule` on a Worklet Runtime but the "
|
||||
"async queue is not set. Recreate the runtime with a valid async queue.");
|
||||
|
||||
queue_->push([job = std::move(job), weakThis = weak_from_this()]() {
|
||||
auto strongThis = weakThis.lock();
|
||||
if (!strongThis) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = std::unique_lock<std::recursive_mutex>(*strongThis->runtimeMutex_);
|
||||
jsi::Runtime &runtime = strongThis->getJSIRuntime();
|
||||
job(runtime);
|
||||
});
|
||||
jsi::Value WorkletRuntime::executeSync(
|
||||
const std::function<jsi::Value(jsi::Runtime &)> &job) const {
|
||||
auto lock = std::unique_lock<std::recursive_mutex>(*runtimeMutex_);
|
||||
jsi::Runtime &uiRuntime = getJSIRuntime();
|
||||
return job(uiRuntime);
|
||||
}
|
||||
#endif // WORKLETS_BUNDLE_MODE
|
||||
|
||||
/* #endregion */
|
||||
|
||||
jsi::Value WorkletRuntime::get(jsi::Runtime &rt, const jsi::PropNameID &propName) {
|
||||
jsi::Value WorkletRuntime::get(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::PropNameID &propName) {
|
||||
auto name = propName.utf8(rt);
|
||||
if (name == "toString") {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
rt,
|
||||
propName,
|
||||
0,
|
||||
[weakThis = weak_from_this()](jsi::Runtime &rt, const jsi::Value &, const jsi::Value *, size_t) -> jsi::Value {
|
||||
[weakThis = weak_from_this()](
|
||||
jsi::Runtime &rt, const jsi::Value &, const jsi::Value *, size_t)
|
||||
-> jsi::Value {
|
||||
auto strongThis = weakThis.lock();
|
||||
if (!strongThis) {
|
||||
return jsi::String::createFromUtf8(rt, "");
|
||||
@@ -228,14 +215,17 @@ jsi::Value WorkletRuntime::get(jsi::Runtime &rt, const jsi::PropNameID &propName
|
||||
return jsi::Value::undefined();
|
||||
}
|
||||
|
||||
std::vector<jsi::PropNameID> WorkletRuntime::getPropertyNames(jsi::Runtime &rt) {
|
||||
std::vector<jsi::PropNameID> WorkletRuntime::getPropertyNames(
|
||||
jsi::Runtime &rt) {
|
||||
std::vector<jsi::PropNameID> result;
|
||||
result.push_back(jsi::PropNameID::forUtf8(rt, "toString"));
|
||||
result.push_back(jsi::PropNameID::forUtf8(rt, "name"));
|
||||
return result;
|
||||
}
|
||||
|
||||
std::shared_ptr<WorkletRuntime> extractWorkletRuntime(jsi::Runtime &rt, const jsi::Value &value) {
|
||||
std::shared_ptr<WorkletRuntime> extractWorkletRuntime(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &value) {
|
||||
return value.getObject(rt).getHostObject<WorkletRuntime>(rt);
|
||||
}
|
||||
|
||||
@@ -248,68 +238,7 @@ void scheduleOnRuntime(
|
||||
rt,
|
||||
serializableWorkletValue,
|
||||
"[Worklets] Function passed to `_scheduleOnRuntime` is not a serializable worklet.");
|
||||
workletRuntime->schedule(serializableWorklet);
|
||||
workletRuntime->runAsyncGuarded(serializableWorklet);
|
||||
}
|
||||
|
||||
#if REACT_NATIVE_MINOR_VERSION >= 81
|
||||
std::weak_ptr<WorkletRuntime> WorkletRuntime::getWeakRuntimeFromJSIRuntime(jsi::Runtime &rt) {
|
||||
auto runtimeData = rt.getRuntimeData(RuntimeData::weakRuntimeUUID);
|
||||
if (!runtimeData) [[unlikely]] {
|
||||
throw std::runtime_error(
|
||||
"[Worklets] No weak runtime data found on the provided JSI runtime."
|
||||
" Perhaps the JSI Runtime is not a WorkletRuntime?");
|
||||
}
|
||||
auto weakHolder = std::static_pointer_cast<WeakRuntimeHolder>(runtimeData);
|
||||
return weakHolder->weakRuntime;
|
||||
}
|
||||
#endif // REACT_NATIVE_MINOR_VERSION >= 81
|
||||
|
||||
/* #region deprecated */
|
||||
|
||||
void WorkletRuntime::runAsyncGuarded(const std::shared_ptr<SerializableWorklet> &worklet) {
|
||||
schedule(worklet);
|
||||
}
|
||||
|
||||
jsi::Value WorkletRuntime::executeSync(jsi::Runtime &caller, const jsi::Value &worklet) const {
|
||||
auto serializableWorklet = extractSerializableOrThrow<SerializableWorklet>(
|
||||
caller, worklet, "[Worklets] Only worklets can be executed synchronously on UI runtime.");
|
||||
auto result = runSyncSerialized(serializableWorklet);
|
||||
return result->toJSValue(caller);
|
||||
}
|
||||
|
||||
jsi::Value WorkletRuntime::executeSync(std::function<jsi::Value(jsi::Runtime &)> &&job) const {
|
||||
return runSync(job);
|
||||
}
|
||||
|
||||
jsi::Value WorkletRuntime::executeSync(const std::function<jsi::Value(jsi::Runtime &)> &job) const {
|
||||
return runSync(job);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
static const auto callGuardLambda = [](facebook::jsi::Runtime &rt,
|
||||
const facebook::jsi::Value &thisVal,
|
||||
const facebook::jsi::Value *args,
|
||||
size_t count) {
|
||||
return args[0].asObject(rt).asFunction(rt).call(rt, args + 1, count - 1);
|
||||
};
|
||||
|
||||
jsi::Function WorkletRuntime::getCallGuard(jsi::Runtime &rt) {
|
||||
auto callGuard = rt.global().getProperty(rt, "__callGuardDEV");
|
||||
if (callGuard.isObject()) {
|
||||
// Use JS implementation if `__callGuardDEV` has already been installed.
|
||||
// This is the desired behavior.
|
||||
return callGuard.asObject(rt).asFunction(rt);
|
||||
}
|
||||
|
||||
// Otherwise, fallback to C++ JSI implementation. This is necessary so that we
|
||||
// can install `__callGuardDEV` itself and should happen only once. Note that
|
||||
// the C++ implementation doesn't intercept errors and simply throws them as
|
||||
// C++ exceptions which crashes the app. We assume that installing the guard
|
||||
// doesn't throw any errors.
|
||||
return jsi::Function::createFromHostFunction(rt, jsi::PropNameID::forAscii(rt, "callGuard"), 1, callGuardLambda);
|
||||
}
|
||||
#endif // NDEBUG
|
||||
|
||||
/* #endregion */
|
||||
|
||||
} // namespace worklets
|
||||
|
||||
Generated
Vendored
+34
-149
@@ -5,7 +5,7 @@
|
||||
#include <jsireact/JSIExecutor.h>
|
||||
#include <react/debug/react_native_assert.h>
|
||||
|
||||
#include <worklets/RunLoop/AsyncQueue.h>
|
||||
#include <worklets/Public/AsyncQueue.h>
|
||||
#include <worklets/RunLoop/AsyncQueueImpl.h>
|
||||
#include <worklets/RunLoop/EventLoop.h>
|
||||
#include <worklets/SharedItems/Serializable.h>
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@@ -23,111 +22,14 @@ using namespace react;
|
||||
|
||||
namespace worklets {
|
||||
|
||||
template <typename TCallable>
|
||||
concept ImplicitlySerializableCallable = std::is_assignable_v<const jsi::Function &, TCallable> ||
|
||||
std::is_assignable_v<const std::shared_ptr<SerializableWorklet> &, TCallable>;
|
||||
|
||||
template <typename TCallable>
|
||||
concept RuntimeCallable = requires(TCallable &&callable, jsi::Runtime &rt) {
|
||||
// NOLINTNEXTLINE(readability/braces) cpplint doesn't understand concepts
|
||||
{ callable(rt) };
|
||||
} || ImplicitlySerializableCallable<TCallable>;
|
||||
|
||||
/**
|
||||
* Forward declaration to avoid circular dependencies.
|
||||
*/
|
||||
class JSIWorkletsModuleProxy;
|
||||
|
||||
class WorkletRuntime : public jsi::HostObject, public std::enable_shared_from_this<WorkletRuntime> {
|
||||
class WorkletRuntime : public jsi::HostObject,
|
||||
public std::enable_shared_from_this<WorkletRuntime> {
|
||||
public:
|
||||
void schedule(jsi::Function &&function) const;
|
||||
void schedule(std::shared_ptr<SerializableWorklet> worklet) const;
|
||||
void schedule(std::function<void()> job) const;
|
||||
void schedule(std::function<void(jsi::Runtime &)> job) const;
|
||||
|
||||
/* #region runSync */
|
||||
|
||||
template <RuntimeCallable TCallable, typename... Args>
|
||||
std::invoke_result_t<TCallable, Args...> runSync(TCallable &&callable, Args &&...args) const;
|
||||
template <typename... Args>
|
||||
jsi::Value runSync(const jsi::Function &function, Args &&...args) const {
|
||||
auto &rt = *runtime_;
|
||||
// We only use callGuard in debug mode, otherwise we call the provided
|
||||
// function directly. CallGuard provides a way of capturing exceptions in
|
||||
// JavaScript and propagating them to the main React Native thread such that
|
||||
// they can be presented using RN's LogBox.
|
||||
#ifndef NDEBUG
|
||||
return getCallGuard(rt).call(rt, function, args...);
|
||||
#else
|
||||
return function.call(rt, args...);
|
||||
#endif // NDEBUG
|
||||
}
|
||||
template <typename... Args>
|
||||
jsi::Value runSync(const std::shared_ptr<SerializableWorklet> &worklet, Args &&...args) const {
|
||||
jsi::Runtime &rt = *runtime_;
|
||||
return runSync(worklet->toJSValue(rt).asObject(rt).asFunction(rt), std::forward<Args>(args)...);
|
||||
}
|
||||
template <RuntimeCallable TCallable>
|
||||
std::invoke_result_t<TCallable, jsi::Runtime &> runSync(TCallable &&job) const {
|
||||
jsi::Runtime &rt = getJSIRuntime();
|
||||
auto lock = std::unique_lock<std::recursive_mutex>(*runtimeMutex_);
|
||||
return job(rt);
|
||||
}
|
||||
|
||||
/* #endregion */
|
||||
|
||||
/* #region runSyncSerialized */
|
||||
|
||||
template <ImplicitlySerializableCallable TCallable, typename... Args>
|
||||
std::shared_ptr<Serializable> runSyncSerialized(TCallable &&callable, Args &&...args) const;
|
||||
template <typename... Args>
|
||||
std::shared_ptr<Serializable> runSyncSerialized(const jsi::Function &function, Args &&...args) const {
|
||||
jsi::Runtime &rt = getJSIRuntime();
|
||||
auto lock = std::unique_lock<std::recursive_mutex>(*runtimeMutex_);
|
||||
auto result = runSync(function, std::forward<Args>(args)...);
|
||||
auto serializableResult = extractSerializableOrThrow(
|
||||
rt,
|
||||
result,
|
||||
"[Worklets] Function passed to `runSyncSerialized`"
|
||||
"must return a value serialized with `createSerializable`.");
|
||||
return serializableResult;
|
||||
}
|
||||
template <typename... Args>
|
||||
std::shared_ptr<Serializable> runSyncSerialized(const std::shared_ptr<SerializableWorklet> &worklet, Args &&...args)
|
||||
const {
|
||||
jsi::Runtime &rt = getJSIRuntime();
|
||||
auto lock = std::unique_lock<std::recursive_mutex>(*runtimeMutex_);
|
||||
auto result = runSync(worklet, std::forward<Args>(args)...);
|
||||
auto serializableResult = extractSerializableOrThrow(
|
||||
rt,
|
||||
result,
|
||||
"[Worklets] Worklet passed to `runSyncSerialized`"
|
||||
"must return a value serialized with `createSerializable`.");
|
||||
return serializableResult;
|
||||
}
|
||||
|
||||
/* #endregion */
|
||||
|
||||
jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override;
|
||||
|
||||
std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt) override;
|
||||
|
||||
[[nodiscard]] std::string toString() const noexcept {
|
||||
return "[WorkletRuntime \"" + name_ + "\"]";
|
||||
}
|
||||
|
||||
[[nodiscard]] jsi::Runtime &getJSIRuntime() const noexcept {
|
||||
return *runtime_;
|
||||
}
|
||||
|
||||
[[nodiscard]] uint64_t getRuntimeId() const noexcept {
|
||||
return runtimeId_;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string getRuntimeName() const noexcept {
|
||||
return name_;
|
||||
}
|
||||
|
||||
explicit WorkletRuntime(
|
||||
uint64_t runtimeId,
|
||||
const std::shared_ptr<MessageQueueThread> &jsQueue,
|
||||
@@ -137,40 +39,45 @@ class WorkletRuntime : public jsi::HostObject, public std::enable_shared_from_th
|
||||
|
||||
void init(std::shared_ptr<JSIWorkletsModuleProxy> jsiWorkletsModuleProxy);
|
||||
|
||||
/* #region deprecated */
|
||||
jsi::Runtime &getJSIRuntime() const {
|
||||
return *runtime_;
|
||||
}
|
||||
|
||||
/** @deprecated Use `runSync` instead. */
|
||||
template <typename... Args>
|
||||
jsi::Value runGuarded(const std::shared_ptr<SerializableWorklet> &worklet, Args &&...args) const {
|
||||
return runSync(worklet, std::forward<Args>(args)...);
|
||||
inline jsi::Value runGuarded(
|
||||
const std::shared_ptr<SerializableWorklet> &serializableWorklet,
|
||||
Args &&...args) const {
|
||||
jsi::Runtime &rt = *runtime_;
|
||||
return runOnRuntimeGuarded(
|
||||
rt, serializableWorklet->toJSValue(rt), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/** @deprecated Use `schedule` instead. */
|
||||
void runAsyncGuarded(const std::shared_ptr<SerializableWorklet> &worklet);
|
||||
|
||||
/** @deprecated Use `runSyncSerialized` and extract to `jsi::Value` with
|
||||
* `extractSerializableOrThrow` instead. */
|
||||
jsi::Value executeSync(jsi::Runtime &rt, const jsi::Value &worklet) const;
|
||||
/** @deprecated Use `runSync` instead. */
|
||||
|
||||
#ifdef WORKLETS_BUNDLE_MODE
|
||||
jsi::Value executeSync(std::function<jsi::Value(jsi::Runtime &)> &&job) const;
|
||||
/** @deprecated Use `runSync` instead. */
|
||||
jsi::Value executeSync(const std::function<jsi::Value(jsi::Runtime &)> &job) const;
|
||||
|
||||
/* #endregion */
|
||||
jsi::Value executeSync(
|
||||
const std::function<jsi::Value(jsi::Runtime &)> &job) const;
|
||||
#endif // WORKLETS_BUNDLE_MODE
|
||||
|
||||
#if REACT_NATIVE_MINOR_VERSION >= 81
|
||||
/**
|
||||
* Retrieves a weak reference to the WorkletRuntime associated with the
|
||||
* provided jsi::Runtime.
|
||||
*
|
||||
* Throws when invoked with a non-worklet runtime.
|
||||
*/
|
||||
static std::weak_ptr<WorkletRuntime> getWeakRuntimeFromJSIRuntime(jsi::Runtime &rt);
|
||||
#endif // REACT_NATIVE_MINOR_VERSION >= 81
|
||||
std::string toString() const {
|
||||
return "[WorkletRuntime \"" + name_ + "\"]";
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
static jsi::Function getCallGuard(jsi::Runtime &rt);
|
||||
#endif // NDEBUG
|
||||
jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override;
|
||||
|
||||
std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt) override;
|
||||
|
||||
[[nodiscard]] auto getRuntimeId() const -> uint64_t {
|
||||
return runtimeId_;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto getRuntimeName() const -> std::string {
|
||||
return name_;
|
||||
}
|
||||
|
||||
private:
|
||||
const uint64_t runtimeId_;
|
||||
@@ -183,35 +90,13 @@ class WorkletRuntime : public jsi::HostObject, public std::enable_shared_from_th
|
||||
|
||||
// This function needs to be non-inline to avoid problems with dynamic_cast on
|
||||
// Android
|
||||
std::shared_ptr<WorkletRuntime> extractWorkletRuntime(jsi::Runtime &rt, const jsi::Value &value);
|
||||
std::shared_ptr<WorkletRuntime> extractWorkletRuntime(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &value);
|
||||
|
||||
void scheduleOnRuntime(
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &workletRuntimeValue,
|
||||
const jsi::Value &serializableWorkletValue);
|
||||
|
||||
/**
|
||||
* @deprecated Use `WorkletRuntime::runSync` instead.
|
||||
*/
|
||||
template <typename... Args>
|
||||
inline jsi::Value runOnRuntimeGuarded(jsi::Runtime &rt, const jsi::Function &function, Args &&...args) {
|
||||
// We only use callGuard in debug mode, otherwise we call the provided
|
||||
// function directly. CallGuard provides a way of capturing exceptions in
|
||||
// JavaScript and propagating them to the main React Native thread such that
|
||||
// they can be presented using RN's LogBox.
|
||||
#ifndef NDEBUG
|
||||
return WorkletRuntime::getCallGuard(rt).call(rt, function, args...);
|
||||
#else
|
||||
return function.call(rt, args...);
|
||||
#endif // NDEBUG
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use `WorkletRuntime::runSync` instead.
|
||||
*/
|
||||
template <typename... Args>
|
||||
inline jsi::Value runOnRuntimeGuarded(jsi::Runtime &rt, const jsi::Value &function, Args &&...args) {
|
||||
return runOnRuntimeGuarded(rt, function.asObject(rt).asFunction(rt), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
} // namespace worklets
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -19,7 +19,7 @@ class WorkletRuntimeCollector : public jsi::HostObject {
|
||||
WorkletRuntimeRegistry::registerRuntime(runtime_);
|
||||
}
|
||||
|
||||
~WorkletRuntimeCollector() override {
|
||||
~WorkletRuntimeCollector() {
|
||||
WorkletRuntimeRegistry::unregisterRuntime(runtime_);
|
||||
}
|
||||
|
||||
|
||||
Generated
Vendored
+152
-73
@@ -6,8 +6,6 @@
|
||||
#include <worklets/WorkletRuntime/WorkletRuntime.h>
|
||||
#include <worklets/WorkletRuntime/WorkletRuntimeDecorator.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@@ -16,7 +14,9 @@ namespace worklets {
|
||||
static inline double performanceNow() {
|
||||
// copied from JSExecutor.cpp
|
||||
auto time = std::chrono::steady_clock::now();
|
||||
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(time.time_since_epoch()).count();
|
||||
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||
time.time_since_epoch())
|
||||
.count();
|
||||
|
||||
constexpr double NANOSECONDS_IN_MILLISECOND = 1000000.0;
|
||||
return duration / NANOSECONDS_IN_MILLISECOND;
|
||||
@@ -24,7 +24,7 @@ static inline double performanceNow() {
|
||||
|
||||
static inline std::vector<jsi::Value> parseArgs(
|
||||
jsi::Runtime &rt,
|
||||
const std::shared_ptr<SerializableArray> &serializableArgs) {
|
||||
std::shared_ptr<SerializableArray> serializableArgs) {
|
||||
if (serializableArgs == nullptr) {
|
||||
return {};
|
||||
}
|
||||
@@ -48,7 +48,8 @@ void WorkletRuntimeDecorator::decorate(
|
||||
// resolves "ReferenceError: Property 'global' doesn't exist at ..."
|
||||
rt.global().setProperty(rt, "global", rt.global());
|
||||
|
||||
rt.global().setProperty(rt, runtimeKindBindingName, static_cast<int>(RuntimeKind::Worker));
|
||||
rt.global().setProperty(
|
||||
rt, runtimeKindBindingName, static_cast<int>(RuntimeKind::Worker));
|
||||
|
||||
rt.global().setProperty(rt, "_WORKLET", true);
|
||||
|
||||
@@ -60,12 +61,16 @@ void WorkletRuntimeDecorator::decorate(
|
||||
|
||||
rt.global().setProperty(rt, "__DEV__", isDevBundle);
|
||||
|
||||
rt.global().setProperty(rt, "__workletsModuleProxy", std::move(jsiWorkletsModuleProxy));
|
||||
rt.global().setProperty(
|
||||
rt, "__workletsModuleProxy", std::move(jsiWorkletsModuleProxy));
|
||||
|
||||
#ifndef NDEBUG
|
||||
auto evalWithSourceUrl =
|
||||
[](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) -> jsi::Value {
|
||||
auto code = std::make_shared<const jsi::StringBuffer>(args[0].asString(rt).utf8(rt));
|
||||
auto evalWithSourceUrl = [](jsi::Runtime &rt,
|
||||
const jsi::Value &thisValue,
|
||||
const jsi::Value *args,
|
||||
size_t count) -> jsi::Value {
|
||||
auto code = std::make_shared<const jsi::StringBuffer>(
|
||||
args[0].asString(rt).utf8(rt));
|
||||
std::string url;
|
||||
if (count > 1 && args[1].isString()) {
|
||||
url = args[1].asString(rt).utf8(rt);
|
||||
@@ -76,51 +81,85 @@ void WorkletRuntimeDecorator::decorate(
|
||||
rt,
|
||||
"evalWithSourceUrl",
|
||||
jsi::Function::createFromHostFunction(
|
||||
rt, jsi::PropNameID::forAscii(rt, "evalWithSourceUrl"), 1, evalWithSourceUrl));
|
||||
rt,
|
||||
jsi::PropNameID::forAscii(rt, "evalWithSourceUrl"),
|
||||
1,
|
||||
evalWithSourceUrl));
|
||||
#endif // NDEBUG
|
||||
|
||||
jsi_utils::installJsiFunction(
|
||||
rt, "_log", [](jsi::Runtime &rt, const jsi::Value &value) { PlatformLogger::log(stringifyJSIValue(rt, value)); });
|
||||
|
||||
jsi_utils::installJsiFunction(rt, "_toString", [](jsi::Runtime &rt, const jsi::Value &value) {
|
||||
return jsi::String::createFromUtf8(rt, stringifyJSIValue(rt, value));
|
||||
});
|
||||
|
||||
jsi_utils::installJsiFunction(
|
||||
rt, "_createSerializable", [](jsi::Runtime &rt, const jsi::Value &value, const jsi::Value &nativeStateSource) {
|
||||
auto shouldRetainRemote = jsi::Value::undefined();
|
||||
return makeSerializableClone(rt, value, shouldRetainRemote, nativeStateSource);
|
||||
rt, "_log", [](jsi::Runtime &rt, const jsi::Value &value) {
|
||||
PlatformLogger::log(stringifyJSIValue(rt, value));
|
||||
});
|
||||
|
||||
jsi_utils::installJsiFunction(rt, "_createSerializableHostObject", [](jsi::Runtime &rt, const jsi::Value &value) {
|
||||
return makeSerializableHostObject(rt, value.asObject(rt).asHostObject(rt));
|
||||
});
|
||||
|
||||
jsi_utils::installJsiFunction(rt, "_createSerializableString", [](jsi::Runtime &rt, const jsi::Value &value) {
|
||||
return makeSerializableString(rt, value.asString(rt));
|
||||
});
|
||||
|
||||
jsi_utils::installJsiFunction(rt, "_createSerializableNumber", [](jsi::Runtime &rt, const jsi::Value &value) {
|
||||
return makeSerializableNumber(rt, value.asNumber());
|
||||
});
|
||||
|
||||
jsi_utils::installJsiFunction(rt, "_createSerializableBoolean", [](jsi::Runtime &rt, const jsi::Value &value) {
|
||||
return makeSerializableBoolean(rt, value.asBool());
|
||||
});
|
||||
|
||||
jsi_utils::installJsiFunction(rt, "_createSerializableBigInt", [](jsi::Runtime &rt, const jsi::Value &value) {
|
||||
return makeSerializableBigInt(rt, value.asBigInt(rt));
|
||||
});
|
||||
jsi_utils::installJsiFunction(
|
||||
rt, "_toString", [](jsi::Runtime &rt, const jsi::Value &value) {
|
||||
return jsi::String::createFromUtf8(rt, stringifyJSIValue(rt, value));
|
||||
});
|
||||
|
||||
jsi_utils::installJsiFunction(
|
||||
rt, "_createSerializableUndefined", [](jsi::Runtime &rt) { return makeSerializableUndefined(rt); });
|
||||
|
||||
jsi_utils::installJsiFunction(rt, "_createSerializableArray", [](jsi::Runtime &rt, const jsi::Value &value) {
|
||||
return makeSerializableArray(rt, value.asObject(rt).asArray(rt), false);
|
||||
});
|
||||
rt,
|
||||
"_createSerializable",
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &value,
|
||||
const jsi::Value &nativeStateSource) {
|
||||
auto shouldRetainRemote = jsi::Value::undefined();
|
||||
return makeSerializableClone(
|
||||
rt, value, shouldRetainRemote, nativeStateSource);
|
||||
});
|
||||
|
||||
jsi_utils::installJsiFunction(
|
||||
rt, "_createSerializableNull", [](jsi::Runtime &rt) { return makeSerializableNull(rt); });
|
||||
rt,
|
||||
"_createSerializableHostObject",
|
||||
[](jsi::Runtime &rt, const jsi::Value &value) {
|
||||
return makeSerializableHostObject(
|
||||
rt, value.asObject(rt).asHostObject(rt));
|
||||
});
|
||||
|
||||
jsi_utils::installJsiFunction(
|
||||
rt,
|
||||
"_createSerializableString",
|
||||
[](jsi::Runtime &rt, const jsi::Value &value) {
|
||||
return makeSerializableString(rt, value.asString(rt));
|
||||
});
|
||||
|
||||
jsi_utils::installJsiFunction(
|
||||
rt,
|
||||
"_createSerializableNumber",
|
||||
[](jsi::Runtime &rt, const jsi::Value &value) {
|
||||
return makeSerializableNumber(rt, value.asNumber());
|
||||
});
|
||||
|
||||
jsi_utils::installJsiFunction(
|
||||
rt,
|
||||
"_createSerializableBoolean",
|
||||
[](jsi::Runtime &rt, const jsi::Value &value) {
|
||||
return makeSerializableBoolean(rt, value.asBool());
|
||||
});
|
||||
|
||||
jsi_utils::installJsiFunction(
|
||||
rt,
|
||||
"_createSerializableBigInt",
|
||||
[](jsi::Runtime &rt, const jsi::Value &value) {
|
||||
return makeSerializableBigInt(rt, value.asBigInt(rt));
|
||||
});
|
||||
|
||||
jsi_utils::installJsiFunction(
|
||||
rt, "_createSerializableUndefined", [](jsi::Runtime &rt) {
|
||||
return makeSerializableUndefined(rt);
|
||||
});
|
||||
|
||||
jsi_utils::installJsiFunction(
|
||||
rt,
|
||||
"_createSerializableArray",
|
||||
[](jsi::Runtime &rt, const jsi::Value &value) {
|
||||
return makeSerializableArray(rt, value.asObject(rt).asArray(rt), false);
|
||||
});
|
||||
|
||||
jsi_utils::installJsiFunction(
|
||||
rt, "_createSerializableNull", [](jsi::Runtime &rt) {
|
||||
return makeSerializableNull(rt);
|
||||
});
|
||||
|
||||
jsi_utils::installJsiFunction(
|
||||
rt,
|
||||
@@ -129,46 +168,70 @@ void WorkletRuntimeDecorator::decorate(
|
||||
const jsi::Value &value,
|
||||
const jsi::Value &shouldRetainRemote,
|
||||
const jsi::Value &nativeStateSource) {
|
||||
return makeSerializableObject(rt, value.getObject(rt), shouldRetainRemote.getBool(), nativeStateSource);
|
||||
return makeSerializableObject(
|
||||
rt,
|
||||
value.getObject(rt),
|
||||
shouldRetainRemote.getBool(),
|
||||
nativeStateSource);
|
||||
});
|
||||
|
||||
jsi_utils::installJsiFunction(rt, "_createSerializableWorklet", [](jsi::Runtime &rt, const jsi::Value &value) {
|
||||
return makeSerializableWorklet(rt, value.asObject(rt), false);
|
||||
});
|
||||
jsi_utils::installJsiFunction(
|
||||
rt,
|
||||
"_createSerializableWorklet",
|
||||
[](jsi::Runtime &rt, const jsi::Value &value) {
|
||||
return makeSerializableWorklet(rt, value.asObject(rt), false);
|
||||
});
|
||||
|
||||
jsi_utils::installJsiFunction(rt, "_createSerializableInitializer", [](jsi::Runtime &rt, const jsi::Value &value) {
|
||||
return makeSerializableInitializer(rt, value.asObject(rt));
|
||||
});
|
||||
jsi_utils::installJsiFunction(
|
||||
rt,
|
||||
"_createSerializableInitializer",
|
||||
[](jsi::Runtime &rt, const jsi::Value &value) {
|
||||
return makeSerializableInitializer(rt, value.asObject(rt));
|
||||
});
|
||||
|
||||
jsi_utils::installJsiFunction(rt, "_createSerializableFunction", [](jsi::Runtime &rt, const jsi::Value &value) {
|
||||
return makeSerializableFunction(rt, value.asObject(rt).asFunction(rt));
|
||||
});
|
||||
jsi_utils::installJsiFunction(
|
||||
rt,
|
||||
"_createSerializableFunction",
|
||||
[](jsi::Runtime &rt, const jsi::Value &value) {
|
||||
return makeSerializableFunction(rt, value.asObject(rt).asFunction(rt));
|
||||
});
|
||||
|
||||
jsi_utils::installJsiFunction(rt, "_createSerializableSynchronizable", [](jsi::Runtime &rt, const jsi::Value &value) {
|
||||
return SerializableJSRef::newNativeStateObject(rt, extractSerializableOrThrow(rt, value));
|
||||
});
|
||||
jsi_utils::installJsiFunction(
|
||||
rt,
|
||||
"_createSerializableSynchronizable",
|
||||
[](jsi::Runtime &rt, const jsi::Value &value) {
|
||||
return SerializableJSRef::newNativeStateObject(
|
||||
rt, extractSerializableOrThrow(rt, value));
|
||||
});
|
||||
|
||||
jsi_utils::installJsiFunction(
|
||||
rt,
|
||||
"_scheduleRemoteFunctionOnJS",
|
||||
[jsScheduler](jsi::Runtime &rt, const jsi::Value &funValue, const jsi::Value &argsValue) {
|
||||
auto serializableRemoteFun = extractSerializableOrThrow<SerializableRemoteFunction>(
|
||||
[jsScheduler](
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &funValue,
|
||||
const jsi::Value &argsValue) {
|
||||
auto serializableRemoteFun = extractSerializableOrThrow<
|
||||
SerializableRemoteFunction>(
|
||||
rt,
|
||||
funValue,
|
||||
"[Worklets] Incompatible object passed to scheduleOnJS. It is only allowed to schedule worklets or functions defined on the React Native JS runtime this way.");
|
||||
|
||||
auto serializableArgs = argsValue.isUndefined()
|
||||
? nullptr
|
||||
: extractSerializableOrThrow<SerializableArray>(rt, argsValue, "[Worklets] Args must be an array.");
|
||||
: extractSerializableOrThrow<SerializableArray>(
|
||||
rt, argsValue, "[Worklets] Args must be an array.");
|
||||
|
||||
jsScheduler->scheduleOnJS([=](jsi::Runtime &rt) {
|
||||
auto fun = serializableRemoteFun->toJSValue(rt).asObject(rt).asFunction(rt);
|
||||
auto fun =
|
||||
serializableRemoteFun->toJSValue(rt).asObject(rt).asFunction(rt);
|
||||
if (serializableArgs == nullptr) {
|
||||
// fast path for remote function w/o arguments
|
||||
fun.call(rt);
|
||||
} else {
|
||||
auto args = parseArgs(rt, serializableArgs);
|
||||
fun.call(rt, const_cast<const jsi::Value *>(args.data()), args.size());
|
||||
fun.call(
|
||||
rt, const_cast<const jsi::Value *>(args.data()), args.size());
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -176,23 +239,34 @@ void WorkletRuntimeDecorator::decorate(
|
||||
jsi_utils::installJsiFunction(
|
||||
rt,
|
||||
"_scheduleHostFunctionOnJS",
|
||||
[jsScheduler](jsi::Runtime &rt, const jsi::Value &hostFunValue, const jsi::Value &argsValue) {
|
||||
auto hostFun = hostFunValue.asObject(rt).asFunction(rt).getHostFunction(rt);
|
||||
[jsScheduler](
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &hostFunValue,
|
||||
const jsi::Value &argsValue) {
|
||||
auto hostFun =
|
||||
hostFunValue.asObject(rt).asFunction(rt).getHostFunction(rt);
|
||||
|
||||
auto serializableArgs = argsValue.isUndefined()
|
||||
? nullptr
|
||||
: extractSerializableOrThrow<SerializableArray>(rt, argsValue, "[Worklets] Args must be an array.");
|
||||
: extractSerializableOrThrow<SerializableArray>(
|
||||
rt, argsValue, "[Worklets] Args must be an array.");
|
||||
|
||||
jsScheduler->scheduleOnJS([=](jsi::Runtime &rt) {
|
||||
auto args = parseArgs(rt, serializableArgs);
|
||||
hostFun(rt, jsi::Value::undefined(), const_cast<const jsi::Value *>(args.data()), args.size());
|
||||
hostFun(
|
||||
rt,
|
||||
jsi::Value::undefined(),
|
||||
const_cast<const jsi::Value *>(args.data()),
|
||||
args.size());
|
||||
});
|
||||
});
|
||||
|
||||
jsi_utils::installJsiFunction(
|
||||
rt,
|
||||
"_scheduleOnRuntime",
|
||||
[](jsi::Runtime &rt, const jsi::Value &workletRuntimeValue, const jsi::Value &serializableWorkletValue) {
|
||||
[](jsi::Runtime &rt,
|
||||
const jsi::Value &workletRuntimeValue,
|
||||
const jsi::Value &serializableWorkletValue) {
|
||||
scheduleOnRuntime(rt, workletRuntimeValue, serializableWorkletValue);
|
||||
});
|
||||
|
||||
@@ -204,20 +278,25 @@ void WorkletRuntimeDecorator::decorate(
|
||||
rt,
|
||||
jsi::PropNameID::forAscii(rt, "now"),
|
||||
0,
|
||||
[](jsi::Runtime &runtime, const jsi::Value &, const jsi::Value *args, size_t count) {
|
||||
return jsi::Value(performanceNow());
|
||||
}));
|
||||
[](jsi::Runtime &runtime,
|
||||
const jsi::Value &,
|
||||
const jsi::Value *args,
|
||||
size_t count) { return jsi::Value(performanceNow()); }));
|
||||
rt.global().setProperty(rt, "performance", performance);
|
||||
|
||||
jsi_utils::installJsiFunction(
|
||||
rt,
|
||||
"_scheduleTimeoutCallback",
|
||||
[weakEventLoop = std::weak_ptr<EventLoop>(eventLoop)](
|
||||
jsi::Runtime &rt, const jsi::Value &delayJs, const jsi::Value &handlerIdJs) -> jsi::Value {
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &delayJs,
|
||||
const jsi::Value &handlerIdJs) -> jsi::Value {
|
||||
const auto delay = delayJs.asNumber();
|
||||
const auto handlerId = handlerIdJs.asNumber();
|
||||
const auto job = [handlerId](jsi::Runtime &rt) {
|
||||
rt.global().getPropertyAsFunction(rt, "__runTimeoutCallback").call(rt, handlerId);
|
||||
rt.global()
|
||||
.getPropertyAsFunction(rt, "__runTimeoutCallback")
|
||||
.call(rt, handlerId);
|
||||
};
|
||||
if (auto strongEventLoop = weakEventLoop.lock()) {
|
||||
strongEventLoop->pushTimeout(job, delay);
|
||||
|
||||
+2
-3
@@ -11,8 +11,7 @@ worklets_assert_new_architecture_enabled($new_arch_enabled)
|
||||
ios_min_version = '13.4'
|
||||
|
||||
feature_flags = "-DWORKLETS_FEATURE_FLAGS=\"#{worklets_get_static_feature_flags()}\""
|
||||
version_flags = "-DWORKLETS_VERSION=#{package['version']} -DREACT_NATIVE_MINOR_VERSION=#{$worklets_config[:react_native_minor_version]}"
|
||||
hermes_v1_flag = ENV['RCT_HERMES_V1_ENABLED'] == '1' ? '-DHERMES_V1_ENABLED' : ''
|
||||
version_flags = "-DWORKLETS_VERSION=#{package['version']}"
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "RNWorklets"
|
||||
@@ -76,7 +75,7 @@ Pod::Spec.new do |s|
|
||||
"CLANG_CXX_LANGUAGE_STANDARD" => "c++20",
|
||||
"GCC_PREPROCESSOR_DEFINITIONS[config=*Debug*]" => "$(inherited) #{hermes_debug_hidden_flags} #{bundle_mode_flag}",
|
||||
"GCC_PREPROCESSOR_DEFINITIONS[config=*Release*]" => "$(inherited) #{bundle_mode_flag}",
|
||||
"OTHER_CFLAGS" => "$(inherited) #{feature_flags} #{version_flags} #{hermes_v1_flag}",
|
||||
"OTHER_CFLAGS" => "$(inherited) #{feature_flags} #{version_flags}",
|
||||
}
|
||||
s.xcconfig = {
|
||||
"HEADER_SEARCH_PATHS" => [
|
||||
|
||||
+29
-13
@@ -15,9 +15,8 @@ string(
|
||||
APPEND
|
||||
CMAKE_CXX_FLAGS
|
||||
" -DREACT_NATIVE_MINOR_VERSION=${REACT_NATIVE_MINOR_VERSION}\
|
||||
-DWORKLETS_VERSION=${WORKLETS_VERSION}\
|
||||
-DWORKLETS_FEATURE_FLAGS=\"${WORKLETS_FEATURE_FLAGS}\"\
|
||||
-DHERMES_V1_ENABLED=${HERMES_V1_ENABLED}")
|
||||
-DWORKLETS_VERSION=${WORKLETS_VERSION}\
|
||||
-DWORKLETS_FEATURE_FLAGS=\"${WORKLETS_FEATURE_FLAGS}\"")
|
||||
|
||||
string(APPEND CMAKE_CXX_FLAGS " -fno-omit-frame-pointer -fstack-protector-all")
|
||||
|
||||
@@ -85,24 +84,41 @@ target_include_directories(
|
||||
"${REACT_NATIVE_DIR}/ReactCommon/react/renderer/graphics/platform/cxx"
|
||||
)
|
||||
|
||||
if(ReactAndroid_VERSION_MINOR LESS 76)
|
||||
target_link_libraries(
|
||||
worklets ReactAndroid::fabricjni ReactAndroid::react_debug
|
||||
ReactAndroid::react_render_core
|
||||
ReactAndroid::react_render_componentregistry ReactAndroid::rrc_view)
|
||||
endif()
|
||||
|
||||
# build shared lib
|
||||
set_target_properties(worklets PROPERTIES LINKER_LANGUAGE CXX)
|
||||
|
||||
target_link_libraries(worklets log ReactAndroid::reactnative ReactAndroid::jsi
|
||||
fbjni::fbjni)
|
||||
target_link_libraries(worklets log ReactAndroid::jsi fbjni::fbjni)
|
||||
|
||||
if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76)
|
||||
target_link_libraries(worklets ReactAndroid::reactnative)
|
||||
else()
|
||||
target_link_libraries(
|
||||
worklets ReactAndroid::react_nativemodule_core ReactAndroid::folly_runtime
|
||||
ReactAndroid::glog ReactAndroid::reactnativejni)
|
||||
endif()
|
||||
|
||||
if(${JS_RUNTIME} STREQUAL "hermes")
|
||||
if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 82)
|
||||
target_link_libraries(worklets hermes-engine::hermesvm)
|
||||
else()
|
||||
target_link_libraries(worklets hermes-engine::libhermes)
|
||||
endif()
|
||||
target_link_libraries(worklets hermes-engine::libhermes)
|
||||
|
||||
if(${HERMES_ENABLE_DEBUGGER})
|
||||
string(APPEND CMAKE_CXX_FLAGS " -DHERMES_ENABLE_DEBUGGER=1")
|
||||
|
||||
target_link_libraries(worklets ReactAndroid::hermestooling)
|
||||
if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76)
|
||||
target_link_libraries(worklets ReactAndroid::hermestooling)
|
||||
else()
|
||||
target_link_libraries(worklets ReactAndroid::hermes_executor)
|
||||
endif()
|
||||
endif()
|
||||
elseif(${JS_RUNTIME} STREQUAL "jsc")
|
||||
target_link_libraries(worklets ReactAndroid::jsctooling)
|
||||
if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76)
|
||||
target_link_libraries(worklets ReactAndroid::jsctooling)
|
||||
else()
|
||||
target_link_libraries(worklets ReactAndroid::jscexecutor)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
+11
-6
@@ -102,7 +102,6 @@ def IS_NEW_ARCHITECTURE_ENABLED = isNewArchitectureEnabled()
|
||||
def IS_REANIMATED_EXAMPLE_APP = safeAppExtGet("isReanimatedExampleApp", false)
|
||||
def BUNDLE_MODE = safeAppExtGet("workletsBundleMode", false)
|
||||
def WORKLETS_FEATURE_FLAGS = getStaticFeatureFlags()
|
||||
def HERMES_V1_ENABLED = safeAppExtGet("hermesV1Enabled", false)
|
||||
|
||||
// Set version for prefab
|
||||
version WORKLETS_VERSION
|
||||
@@ -150,8 +149,6 @@ apply plugin: "com.android.library"
|
||||
apply plugin: "maven-publish"
|
||||
apply plugin: "de.undercouch.download"
|
||||
|
||||
apply from: "./fix-prefab.gradle"
|
||||
|
||||
|
||||
android {
|
||||
compileSdkVersion safeExtGet("compileSdkVersion", 34)
|
||||
@@ -199,8 +196,7 @@ android {
|
||||
"-DWORKLETS_BUNDLE_MODE=${BUNDLE_MODE}",
|
||||
"-DWORKLETS_VERSION=${WORKLETS_VERSION}",
|
||||
"-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON",
|
||||
"-DWORKLETS_FEATURE_FLAGS=${WORKLETS_FEATURE_FLAGS}",
|
||||
"-DHERMES_V1_ENABLED=${HERMES_V1_ENABLED}"
|
||||
"-DWORKLETS_FEATURE_FLAGS=${WORKLETS_FEATURE_FLAGS}"
|
||||
abiFilters (*reactNativeArchitectures())
|
||||
targets("worklets")
|
||||
}
|
||||
@@ -248,10 +244,19 @@ android {
|
||||
"**/libc++_shared.so",
|
||||
"**/libfbjni.so",
|
||||
"**/libjsi.so",
|
||||
"**/libfolly_json.so",
|
||||
"**/libfolly_runtime.so",
|
||||
"**/libglog.so",
|
||||
"**/libhermes.so",
|
||||
"**/libhermesvm.so",
|
||||
"**/libhermes-executor-debug.so",
|
||||
"**/libhermes_executor.so",
|
||||
"**/libhermestooling.so",
|
||||
"**/libreactnativejni.so",
|
||||
"**/libturbomodulejsijni.so",
|
||||
"**/libreactnative.so",
|
||||
"**/libreact_nativemodule_core.so",
|
||||
"**/libreact_render*.so",
|
||||
"**/librrc_root.so",
|
||||
"**/libjscexecutor.so",
|
||||
]
|
||||
}
|
||||
|
||||
-53
@@ -1,53 +0,0 @@
|
||||
tasks.configureEach { task ->
|
||||
// Make sure that we generate our prefab publication file only after having built the native library
|
||||
// so that not a header publication file, but a full configuration publication will be generated, which
|
||||
// will include the .so file
|
||||
|
||||
def prefabConfigurePattern = ~/^prefab(.+)ConfigurePackage$/
|
||||
def matcher = task.name =~ prefabConfigurePattern
|
||||
if (matcher.matches()) {
|
||||
def variantName = matcher[0][1]
|
||||
task.outputs.upToDateWhen { false }
|
||||
task.dependsOn("externalNativeBuild${variantName}")
|
||||
}
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
def abis = reactNativeArchitectures()
|
||||
rootProject.allprojects.each { proj ->
|
||||
|
||||
if (proj === rootProject) return
|
||||
|
||||
def dependsOnThisLib = proj.configurations.any { config ->
|
||||
config.dependencies.any { dep ->
|
||||
dep.group == project.group && dep.name == project.name
|
||||
}
|
||||
}
|
||||
|
||||
if (!dependsOnThisLib && proj != project) return
|
||||
|
||||
if (!proj.plugins.hasPlugin('com.android.application') && !proj.plugins.hasPlugin('com.android.library')) {
|
||||
return
|
||||
}
|
||||
|
||||
def variants = proj.android.hasProperty('applicationVariants') ? proj.android.applicationVariants : proj.android.libraryVariants
|
||||
// Touch the prefab_config.json files to ensure that in ExternalNativeJsonGenerator.kt we will re-trigger the prefab CLI to
|
||||
// generate a libnameConfig.cmake file that will contain our native library (.so).
|
||||
// See this condition: https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/ExternalNativeJsonGenerator.kt;l=207-219?q=createPrefabBuildSystemGlue
|
||||
variants.all { variant ->
|
||||
def variantName = variant.name
|
||||
abis.each { abi ->
|
||||
def searchDir = new File(proj.projectDir, ".cxx/${variantName}")
|
||||
if (!searchDir.exists()) return
|
||||
def matches = []
|
||||
searchDir.eachDir { randomDir ->
|
||||
def prefabFile = new File(randomDir, "${abi}/prefab_config.json")
|
||||
if (prefabFile.exists()) matches << prefabFile
|
||||
}
|
||||
matches.each { prefabConfig ->
|
||||
prefabConfig.setLastModified(System.currentTimeMillis())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
Vendored
+17
-8
@@ -3,12 +3,13 @@ package com.swmansion.worklets;
|
||||
import androidx.annotation.OptIn;
|
||||
import com.facebook.jni.HybridData;
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
import com.facebook.react.bridge.BundleConsumer;
|
||||
import com.facebook.react.bridge.LifecycleEventListener;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.queue.MessageQueueThread;
|
||||
import com.facebook.react.common.annotations.FrameworkAPI;
|
||||
import com.facebook.react.fabric.BundleWrapper;
|
||||
import com.facebook.react.fabric.BigStringBufferWrapper;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import com.facebook.react.turbomodule.core.CallInvokerHolderImpl;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
@@ -19,7 +20,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
@SuppressWarnings("JavaJniMissingFunction")
|
||||
@ReactModule(name = WorkletsModule.NAME)
|
||||
public class WorkletsModule extends NativeWorkletsModuleSpec implements LifecycleEventListener {
|
||||
public class WorkletsModule extends NativeWorkletsModuleSpec
|
||||
implements LifecycleEventListener, BundleConsumer {
|
||||
static {
|
||||
SoLoader.loadLibrary("worklets");
|
||||
}
|
||||
@@ -37,9 +39,19 @@ public class WorkletsModule extends NativeWorkletsModuleSpec implements Lifecycl
|
||||
private final AndroidUIScheduler mAndroidUIScheduler;
|
||||
private final AnimationFrameQueue mAnimationFrameQueue;
|
||||
private boolean mSlowAnimationsEnabled;
|
||||
private BundleWrapper mBundleWrapper = null;
|
||||
private BigStringBufferWrapper mScriptWrapper = null;
|
||||
private String mSourceURL = null;
|
||||
|
||||
@Override
|
||||
public void setScriptWrapper(BigStringBufferWrapper scriptWrapper) {
|
||||
mScriptWrapper = scriptWrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSourceURL(String sourceURL) {
|
||||
mSourceURL = sourceURL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidating concurrently could be fatal. It shouldn't happen in a normal flow, but it doesn't
|
||||
* cost us much to add synchronization for extra safety.
|
||||
@@ -52,7 +64,7 @@ public class WorkletsModule extends NativeWorkletsModuleSpec implements Lifecycl
|
||||
MessageQueueThread messageQueueThread,
|
||||
CallInvokerHolderImpl jsCallInvokerHolder,
|
||||
AndroidUIScheduler androidUIScheduler,
|
||||
BundleWrapper bundleWrapper,
|
||||
BigStringBufferWrapper scriptWrapper,
|
||||
String sourceURL);
|
||||
|
||||
public WorkletsModule(ReactApplicationContext reactContext) {
|
||||
@@ -78,16 +90,13 @@ public class WorkletsModule extends NativeWorkletsModuleSpec implements Lifecycl
|
||||
var jsContext = Objects.requireNonNull(context.getJavaScriptContextHolder()).get();
|
||||
var jsCallInvokerHolder = JSCallInvokerResolver.getJSCallInvokerHolder(context);
|
||||
|
||||
mSourceURL = context.getSourceURL();
|
||||
mBundleWrapper = context.getBundle();
|
||||
|
||||
mHybridData =
|
||||
initHybrid(
|
||||
jsContext,
|
||||
mMessageQueueThread,
|
||||
jsCallInvokerHolder,
|
||||
mAndroidUIScheduler,
|
||||
mBundleWrapper,
|
||||
mScriptWrapper,
|
||||
mSourceURL);
|
||||
return true;
|
||||
}
|
||||
|
||||
Generated
Vendored
+11
-5
@@ -10,7 +10,8 @@ class UISchedulerWrapper : public UIScheduler {
|
||||
jni::global_ref<AndroidUIScheduler::javaobject> androidUiScheduler_;
|
||||
|
||||
public:
|
||||
explicit UISchedulerWrapper(jni::global_ref<AndroidUIScheduler::javaobject> androidUiScheduler)
|
||||
explicit UISchedulerWrapper(
|
||||
jni::global_ref<AndroidUIScheduler::javaobject> androidUiScheduler)
|
||||
: androidUiScheduler_(androidUiScheduler) {}
|
||||
|
||||
void scheduleOnUI(std::function<void()> job) override {
|
||||
@@ -22,10 +23,14 @@ class UISchedulerWrapper : public UIScheduler {
|
||||
}
|
||||
};
|
||||
|
||||
AndroidUIScheduler::AndroidUIScheduler(jni::alias_ref<AndroidUIScheduler::javaobject> jThis)
|
||||
: javaPart_(jni::make_global(jThis)), uiScheduler_(std::make_shared<UISchedulerWrapper>(jni::make_global(jThis))) {}
|
||||
AndroidUIScheduler::AndroidUIScheduler(
|
||||
jni::alias_ref<AndroidUIScheduler::javaobject> jThis)
|
||||
: javaPart_(jni::make_global(jThis)),
|
||||
uiScheduler_(
|
||||
std::make_shared<UISchedulerWrapper>(jni::make_global(jThis))) {}
|
||||
|
||||
jni::local_ref<AndroidUIScheduler::jhybriddata> AndroidUIScheduler::initHybrid(jni::alias_ref<jhybridobject> jThis) {
|
||||
jni::local_ref<AndroidUIScheduler::jhybriddata> AndroidUIScheduler::initHybrid(
|
||||
jni::alias_ref<jhybridobject> jThis) {
|
||||
return makeCxxInstance(jThis);
|
||||
}
|
||||
|
||||
@@ -37,7 +42,8 @@ void AndroidUIScheduler::triggerUI() {
|
||||
}
|
||||
|
||||
void AndroidUIScheduler::scheduleTriggerOnUI() {
|
||||
static const auto method = javaPart_->getClass()->getMethod<void()>("scheduleTriggerOnUI");
|
||||
static const auto method =
|
||||
javaPart_->getClass()->getMethod<void()>("scheduleTriggerOnUI");
|
||||
method(javaPart_.get());
|
||||
}
|
||||
|
||||
|
||||
Generated
Vendored
+6
-3
@@ -14,8 +14,10 @@ using namespace worklets;
|
||||
|
||||
class AndroidUIScheduler : public jni::HybridClass<AndroidUIScheduler> {
|
||||
public:
|
||||
static auto constexpr kJavaDescriptor = "Lcom/swmansion/worklets/AndroidUIScheduler;";
|
||||
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> jThis);
|
||||
static auto constexpr kJavaDescriptor =
|
||||
"Lcom/swmansion/worklets/AndroidUIScheduler;";
|
||||
static jni::local_ref<jhybriddata> initHybrid(
|
||||
jni::alias_ref<jhybridobject> jThis);
|
||||
static void registerNatives();
|
||||
|
||||
std::shared_ptr<UIScheduler> getUIScheduler() {
|
||||
@@ -34,7 +36,8 @@ class AndroidUIScheduler : public jni::HybridClass<AndroidUIScheduler> {
|
||||
jni::global_ref<AndroidUIScheduler::javaobject> javaPart_;
|
||||
std::shared_ptr<UIScheduler> uiScheduler_;
|
||||
|
||||
explicit AndroidUIScheduler(jni::alias_ref<AndroidUIScheduler::jhybridobject> jThis);
|
||||
explicit AndroidUIScheduler(
|
||||
jni::alias_ref<AndroidUIScheduler::jhybridobject> jThis);
|
||||
};
|
||||
|
||||
} // namespace worklets
|
||||
|
||||
Generated
Vendored
+8
-4
@@ -6,9 +6,11 @@
|
||||
|
||||
namespace worklets {
|
||||
|
||||
class AnimationFrameCallback : public facebook::jni::HybridClass<AnimationFrameCallback> {
|
||||
class AnimationFrameCallback
|
||||
: public facebook::jni::HybridClass<AnimationFrameCallback> {
|
||||
public:
|
||||
static auto constexpr kJavaDescriptor = "Lcom/swmansion/worklets/runloop/AnimationFrameCallback;";
|
||||
static auto constexpr kJavaDescriptor =
|
||||
"Lcom/swmansion/worklets/runloop/AnimationFrameCallback;";
|
||||
|
||||
void onAnimationFrame(double timestampMs) {
|
||||
callback_(timestampMs);
|
||||
@@ -16,14 +18,16 @@ class AnimationFrameCallback : public facebook::jni::HybridClass<AnimationFrameC
|
||||
|
||||
static void registerNatives() {
|
||||
javaClassStatic()->registerNatives({
|
||||
makeNativeMethod("onAnimationFrame", AnimationFrameCallback::onAnimationFrame),
|
||||
makeNativeMethod(
|
||||
"onAnimationFrame", AnimationFrameCallback::onAnimationFrame),
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
friend HybridBase;
|
||||
|
||||
explicit AnimationFrameCallback(std::function<void(const double)> callback) : callback_(std::move(callback)) {}
|
||||
explicit AnimationFrameCallback(std::function<void(const double)> callback)
|
||||
: callback_(std::move(callback)) {}
|
||||
|
||||
std::function<void(double)> callback_;
|
||||
};
|
||||
|
||||
Generated
Vendored
-2
@@ -2,8 +2,6 @@
|
||||
|
||||
#include <worklets/Tools/PlatformLogger.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
constexpr const auto tag = "Worklets";
|
||||
|
||||
namespace worklets {
|
||||
|
||||
Generated
Vendored
+37
-16
@@ -5,7 +5,6 @@
|
||||
#include <worklets/android/WorkletsModule.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace worklets {
|
||||
@@ -19,7 +18,7 @@ WorkletsModule::WorkletsModule(
|
||||
jni::alias_ref<JavaMessageQueueThread::javaobject> messageQueueThread,
|
||||
const std::shared_ptr<facebook::react::CallInvoker> &jsCallInvoker,
|
||||
const std::shared_ptr<UIScheduler> &uiScheduler,
|
||||
const std::shared_ptr<const JSBigStringBuffer> &script,
|
||||
const std::shared_ptr<const BigStringBuffer> &script,
|
||||
const std::string &sourceURL)
|
||||
: javaPart_(jni::make_global(jThis)),
|
||||
rnRuntime_(rnRuntime),
|
||||
@@ -29,25 +28,32 @@ WorkletsModule::WorkletsModule(
|
||||
jsCallInvoker,
|
||||
uiScheduler,
|
||||
getIsOnJSQueueThread(),
|
||||
RuntimeBindings{.requestAnimationFrame = getRequestAnimationFrame()},
|
||||
getForwardedRequestAnimationFrame(),
|
||||
script,
|
||||
sourceURL)) {
|
||||
auto jsiWorkletsModuleProxy = workletsModuleProxy_->createJSIWorkletsModuleProxy();
|
||||
auto jsiWorkletsModuleProxy =
|
||||
workletsModuleProxy_->createJSIWorkletsModuleProxy();
|
||||
auto optimizedJsiWorkletsModuleProxy = jsi_utils::optimizedFromHostObject(
|
||||
*rnRuntime_, std::static_pointer_cast<jsi::HostObject>(std::move(jsiWorkletsModuleProxy)));
|
||||
*rnRuntime_,
|
||||
std::static_pointer_cast<jsi::HostObject>(
|
||||
std::move(jsiWorkletsModuleProxy)));
|
||||
RNRuntimeWorkletDecorator::decorate(
|
||||
*rnRuntime_, std::move(optimizedJsiWorkletsModuleProxy), workletsModuleProxy_->getJSLogger());
|
||||
*rnRuntime_,
|
||||
std::move(optimizedJsiWorkletsModuleProxy),
|
||||
workletsModuleProxy_->getJSLogger());
|
||||
}
|
||||
|
||||
jni::local_ref<WorkletsModule::jhybriddata> WorkletsModule::initHybrid(
|
||||
jni::alias_ref<jhybridobject> jThis,
|
||||
jlong jsContext,
|
||||
jni::alias_ref<JavaMessageQueueThread::javaobject> messageQueueThread,
|
||||
jni::alias_ref<facebook::react::CallInvokerHolder::javaobject> jsCallInvokerHolder,
|
||||
jni::alias_ref<facebook::react::CallInvokerHolder::javaobject>
|
||||
jsCallInvokerHolder,
|
||||
jni::alias_ref<worklets::AndroidUIScheduler::javaobject> androidUIScheduler
|
||||
#ifdef WORKLETS_BUNDLE_MODE
|
||||
,
|
||||
jni::alias_ref<facebook::react::BundleWrapper::javaobject> bundleWrapper,
|
||||
jni::alias_ref<facebook::react::BigStringBufferWrapper::javaobject>
|
||||
scriptWrapper,
|
||||
const std::string &sourceURL
|
||||
#endif // WORKLETS_BUNDLE_MODE
|
||||
) {
|
||||
@@ -55,27 +61,42 @@ jni::local_ref<WorkletsModule::jhybriddata> WorkletsModule::initHybrid(
|
||||
auto rnRuntime = reinterpret_cast<jsi::Runtime *>(jsContext);
|
||||
auto uiScheduler = androidUIScheduler->cthis()->getUIScheduler();
|
||||
|
||||
std::shared_ptr<const JSBigStringBuffer> script = nullptr;
|
||||
std::shared_ptr<const BigStringBuffer> script = nullptr;
|
||||
#ifdef WORKLETS_BUNDLE_MODE
|
||||
script = bundleWrapper->cthis()->getBundle();
|
||||
script = scriptWrapper->cthis()->getScript();
|
||||
#else
|
||||
const auto sourceURL = std::string{};
|
||||
#endif // WORKLETS_BUNDLE_MODE
|
||||
|
||||
return makeCxxInstance(jThis, rnRuntime, messageQueueThread, jsCallInvoker, uiScheduler, script, sourceURL);
|
||||
return makeCxxInstance(
|
||||
jThis,
|
||||
rnRuntime,
|
||||
messageQueueThread,
|
||||
jsCallInvoker,
|
||||
uiScheduler,
|
||||
script,
|
||||
sourceURL);
|
||||
}
|
||||
|
||||
RuntimeBindings::RequestAnimationFrame WorkletsModule::getRequestAnimationFrame() {
|
||||
return [javaPart = javaPart_](std::function<void(const double)> &&callback) -> void {
|
||||
std::function<void(std::function<void(const double)>)>
|
||||
WorkletsModule::getForwardedRequestAnimationFrame() {
|
||||
return [javaPart =
|
||||
javaPart_](std::function<void(const double)> &&callback) -> void {
|
||||
static const auto jRequestAnimationFrame =
|
||||
javaPart->getClass()->getMethod<void(AnimationFrameCallback::javaobject)>("requestAnimationFrame");
|
||||
jRequestAnimationFrame(javaPart.get(), AnimationFrameCallback::newObjectCxxArgs(std::move(callback)).get());
|
||||
javaPart->getClass()
|
||||
->getMethod<void(AnimationFrameCallback::javaobject)>(
|
||||
"requestAnimationFrame");
|
||||
jRequestAnimationFrame(
|
||||
javaPart.get(),
|
||||
AnimationFrameCallback::newObjectCxxArgs(std::move(callback)).get());
|
||||
};
|
||||
}
|
||||
|
||||
std::function<bool()> WorkletsModule::getIsOnJSQueueThread() {
|
||||
return [javaPart = javaPart_]() -> bool {
|
||||
return javaPart->getClass()->getMethod<jboolean()>("isOnJSQueueThread").operator()(javaPart);
|
||||
return javaPart->getClass()
|
||||
->getMethod<jboolean()>("isOnJSQueueThread")
|
||||
.operator()(javaPart);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Generated
Vendored
+13
-9
@@ -3,14 +3,13 @@
|
||||
#include <ReactCommon/CallInvokerHolder.h>
|
||||
#include <fbjni/fbjni.h>
|
||||
#include <jsi/jsi.h>
|
||||
#include <jsireact/JSIExecutor.h>
|
||||
#include <react/jni/JMessageQueueThread.h>
|
||||
#include <worklets/Tools/Defs.h>
|
||||
#ifdef WORKLETS_BUNDLE_MODE
|
||||
#include <react/fabric/BundleWrapper.h>
|
||||
#include <react/fabric/BigStringBufferWrapper.h>
|
||||
#endif // WORKLETS_BUNDLE_MODE
|
||||
|
||||
#include <worklets/NativeModules/WorkletsModuleProxy.h>
|
||||
#include <worklets/WorkletRuntime/RuntimeBindings.h>
|
||||
#include <worklets/android/AndroidUIScheduler.h>
|
||||
|
||||
#include <memory>
|
||||
@@ -23,17 +22,21 @@ using namespace facebook::jni;
|
||||
|
||||
class WorkletsModule : public jni::HybridClass<WorkletsModule> {
|
||||
public:
|
||||
static auto constexpr kJavaDescriptor = "Lcom/swmansion/worklets/WorkletsModule;";
|
||||
static auto constexpr kJavaDescriptor =
|
||||
"Lcom/swmansion/worklets/WorkletsModule;";
|
||||
|
||||
static jni::local_ref<jhybriddata> initHybrid(
|
||||
jni::alias_ref<jhybridobject> jThis,
|
||||
jlong jsContext,
|
||||
jni::alias_ref<JavaMessageQueueThread::javaobject> messageQueueThread,
|
||||
jni::alias_ref<facebook::react::CallInvokerHolder::javaobject> jsCallInvokerHolder,
|
||||
jni::alias_ref<worklets::AndroidUIScheduler::javaobject> androidUIScheduler
|
||||
jni::alias_ref<facebook::react::CallInvokerHolder::javaobject>
|
||||
jsCallInvokerHolder,
|
||||
jni::alias_ref<worklets::AndroidUIScheduler::javaobject>
|
||||
androidUIScheduler
|
||||
#ifdef WORKLETS_BUNDLE_MODE
|
||||
,
|
||||
jni::alias_ref<facebook::react::BundleWrapper::javaobject> bundleWrapper,
|
||||
jni::alias_ref<facebook::react::BigStringBufferWrapper::javaobject>
|
||||
scriptWrapper,
|
||||
const std::string &sourceURL
|
||||
#endif // WORKLETS_BUNDLE_MODE
|
||||
);
|
||||
@@ -51,7 +54,7 @@ class WorkletsModule : public jni::HybridClass<WorkletsModule> {
|
||||
jni::alias_ref<JavaMessageQueueThread::javaobject> messageQueueThread,
|
||||
const std::shared_ptr<facebook::react::CallInvoker> &jsCallInvoker,
|
||||
const std::shared_ptr<UIScheduler> &uiScheduler,
|
||||
const std::shared_ptr<const JSBigStringBuffer> &bundle,
|
||||
const std::shared_ptr<const BigStringBuffer> &script,
|
||||
const std::string &sourceURL);
|
||||
|
||||
void invalidateCpp();
|
||||
@@ -61,7 +64,8 @@ class WorkletsModule : public jni::HybridClass<WorkletsModule> {
|
||||
return javaPart_->getClass()->getMethod<Signature>(methodName.c_str());
|
||||
}
|
||||
|
||||
RuntimeBindings::RequestAnimationFrame getRequestAnimationFrame();
|
||||
std::function<void(std::function<void(const double)>)>
|
||||
getForwardedRequestAnimationFrame();
|
||||
|
||||
std::function<bool()> getIsOnJSQueueThread();
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user