console.log('Godot message:', message)}
122 | />
123 | );
124 | };
125 | ```
126 |
127 | ### Godot implementation (GDScript) 🧙♂️
128 |
129 | ```gdscript
130 | # This class is a demonstration of GDScript with React Native.
131 |
132 | extends Node
133 |
134 | func _ready() -> void:
135 | if Engine.has_singleton("ReactNative"): # Always check if the ReactNative singleton exists
136 | Engine.get_singleton("ReactNative").on_message(_on_message)
137 |
138 | func _on_message(message: Dictionary) -> void:
139 | print("React Native message:", message)
140 |
141 | func _input(event: InputEvent) -> void:
142 | if "position" not in event:
143 | return
144 |
145 | var adjusted_position = adjust_for_window(event.position)
146 |
147 | if Engine.has_singleton("ReactNative"):
148 | # Emit a message to React Native
149 | Engine.get_singleton("ReactNative").emit_message({
150 | "message": "Input event position",
151 | "pos": adjusted_position,
152 | })
153 |
154 | func hello_world() -> void:
155 | print("Hello World!")
156 |
157 | func method_that_returns_something() -> int:
158 | return 42
159 |
160 | ## This function is used to adjust the screen position for the window.
161 | func adjust_for_window(pos: Vector2) -> Vector2:
162 | var window = get_viewport().get_window()
163 | var window_id = window.get_window_id()
164 |
165 | if window_id == DisplayServer.MAIN_WINDOW_ID or window_id == DisplayServer.INVALID_WINDOW_ID:
166 | return pos
167 |
168 | var window_position = Vector2()
169 |
170 | if Engine.has_singleton("ReactNative"):
171 | window_position = Engine.get_singleton("ReactNative").get_subwindow_position(window_id)
172 |
173 | return Vector2(
174 | pos.x + window_position.x,
175 | pos.y + window_position.y
176 | )
177 | ```
178 |
179 | ## Godot Variants 🍭
180 |
181 | Godot variants are available in React Native, here is the list:
182 | `AABB | Basis | Color | Plane | Projection | Quaternion | Rect2 | Rect2i | Transform2D | Transform3D | Vector2 | Vector2i | Vector3 | Vector3i | Vector4 | Vector4i`.
183 |
184 | For primitives like `int`, `float`, `bool`, `dictionary`, `array`, etc, you can use normal JS types and it will be automatically converted to Godot variants and vice versa.
185 |
186 | All methods and properties are available too, for instance, you can use `Vector3(1, 2, 3).length()`.
187 | Complete documentation is available at [https://docs.godotengine.org/en/stable/classes/index.html#variant-types](https://docs.godotengine.org/en/stable/classes/index.html#variant-types).
188 |
189 | ## Access any Godot Nodes from React Native 🎯
190 |
191 | You can retrieve a node from your scene in React Native and call methods on it.
192 |
193 | Current supported methods for a Node are:
194 |
195 | * getNode(name: string): Node | null
196 | * getParent(): Node | null
197 | * getChildren(): Node[]
198 | * getChildCount(): number
199 |
200 | (+ Any method you've defined in your gdscript 😌)
201 |
202 | ## Import your Godot Project (How to) 📥
203 |
204 | * To import your **Godot project** into React Native, you need to **generate a pck file** that basically packs up all your game assets, scripts etc.
205 | It's a convenient way to pack your game into a single file.
206 |
207 | * First, you need to add a `export_presets.cfg` in the directory of your Godot project.
208 | We provide a working example of this file at the root of this repository.
209 |
210 | * After that, you're now able to generate a pck file, just run `./gen-pck PROJECT_FOLDER_PATH`.
211 | Be sure you have `/Applications/Godot.app` set on your machine, if you're using another path or another OS than macOS, just modify this very simple shell at your convenience.
212 |
213 | * Then, you just need to move the pck file in your assets folder.
214 |
215 | * One last important thing, don't forget to add a `project.godot` in your XCode project, see in the example folder for more details.
216 |
217 | ## Metro Config 🚇
218 |
219 | * You need to add the following to your `metro.config.js` in order to treat `.pck` files as assets and exclude them from being treated as source files.
220 |
221 | ```js
222 | // Treat `.pck` files as assets
223 | assetExts: [...assetExts, 'pck'],
224 | // Exclude `.pck` from being treated as source files
225 | sourceExts: sourceExts.filter(ext => ext !== 'pck'),
226 | ```
227 |
228 | And...
229 |
230 | ```js
231 | server: {
232 | enhanceMiddleware: (middleware) => {
233 | return (req, res, next) => {
234 | if (/\.pck$/.test(req.url)) {
235 | res.setHeader('Content-Type', 'application/octet-stream');
236 | }
237 | return middleware(req, res, next);
238 | };
239 | },
240 | },
241 | ```
242 |
243 | ## Limitations & Known Issues 🚧
244 |
245 | * When importing a texture or 3D model, be sure you don't import them as `VRAM Compressed`, for some reason when exporting the pck file, it doesn't import the assets. Might be a mistake from our side.... (TBD) 😅
246 |
247 | [
](screenshots/screenshot3.png)
248 |
249 | * **PCK Asset Swapping**: For now, you can't swap the pck asset at runtime properly, you need to reopen the app to load a new pck asset. It seems to be a limitation of the Godot engine itself, but we're investigating this as it would be super useful to debug on device in almost real-time.
250 |
251 | ## TODO 📝
252 |
253 | * [x] iOS support
254 | * [ ] Android support
255 | * [x] Improve library size
256 | * [x] Add support for all Godot variants
257 | * [ ] Investigate PCK asset swapping
258 | * [x] Add support for more Godot features
259 |
260 | ## Contributing 🤝
261 |
262 | We're open to any contributions. Feel free to open an issue if you want to help us improve this library.
263 |
264 | All the interesting stuff is located in a private repository so if you want to contribute, just send us an email at `team@calico.games`.
265 | You should have previous experiences of building the Godot Engine yourself, C++, and building blazing fast React Native libraries is a plus.
266 | [Bazel](https://github.com/bazelbuild/bazel) is also used internally to build the library fyk.
267 |
268 | ## Copyright / License 👨⚖️
269 |
270 | Copyright **Calico Games** 2024. All rights reserved.
271 |
272 | This library is released under a **Custom License** with the following conditions:
273 |
274 | * **Free for non-commercial use**: You may freely use this library for personal, educational, or open-source projects.
275 | * **Commercial use by revenue-generating entities**: Any company or individual with an annual revenue exceeding $50,000 must obtain a commercial license to use this library.
276 | * **No Redistribution Allowed**: This library cannot be redistributed, repackaged, or resold.
277 |
278 | PS: We are pretty flexible atm and we would like to also support the Godot Foundation by giving them a share of the revenue generated by this library.
279 |
280 | For commercial licensing inquiries, please contact us at `team@calico.games`.
281 |
282 | ## Credits 🙏
283 |
284 | * Special thanks to all the contributors of the [Godot Engine](https://github.com/godotengine/godot).
285 | * A big shoutout to [Migeran](https://github.com/migeran) that helped us a lot to build this library.
286 |
--------------------------------------------------------------------------------
/example/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | extends: ['eslint:recommended', '@react-native', 'plugin:prettier/recommended'],
4 | plugins: ['prettier'],
5 | rules: {
6 | 'react/react-in-jsx-scope': 'off',
7 | 'react-native/no-inline-styles': 'off',
8 | 'react-hooks/exhaustive-deps': 'off',
9 | 'no-shadow': 'off',
10 | 'no-alert': 'off',
11 | 'prettier/prettier': 'error',
12 | '@typescript-eslint/no-unused-vars': 'warn',
13 | 'react-native/no-unused-styles': 1,
14 | },
15 | requireConfigFile: false,
16 | };
17 |
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | ios/.xcode.env.local
24 |
25 | # Android/IntelliJ
26 | #
27 | build/
28 | .idea
29 | .gradle
30 | local.properties
31 | *.iml
32 | *.hprof
33 | .cxx/
34 | *.keystore
35 | !debug.keystore
36 |
37 | # node.js
38 | #
39 | node_modules/
40 | npm-debug.log
41 | yarn-error.log
42 |
43 | # fastlane
44 | #
45 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
46 | # screenshots whenever they are needed.
47 | # For more information about the recommended setup visit:
48 | # https://docs.fastlane.tools/best-practices/source-control/
49 |
50 | **/fastlane/report.xml
51 | **/fastlane/Preview.html
52 | **/fastlane/screenshots
53 | **/fastlane/test_output
54 |
55 | # Bundle artifact
56 | *.jsbundle
57 |
58 | # Ruby / CocoaPods
59 | /ios/Pods/
60 | /ios/vendor/bundle/
61 |
62 | # Temporary files created by Metro to check the health of the file watcher
63 | .metro-health-check*
64 |
65 | # testing
66 | /coverage
67 |
68 | # Godot 4+ specific ignores
69 | .godot/
--------------------------------------------------------------------------------
/example/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | arrowParens: 'avoid',
3 | bracketSameLine: true,
4 | bracketSpacing: false,
5 | singleQuote: true,
6 | trailingComma: 'all',
7 | tabWidth: 2,
8 | printWidth: 100,
9 | };
10 |
--------------------------------------------------------------------------------
/example/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # Example using React Native Godot
2 |
3 | ## Usage
4 |
5 | Use `yarn` for this example as we use a certain feature `link:...` to use the `react-native-godot` package locally.
6 |
7 | ```sh
8 | # To launch metro debugger
9 | $ yarn start
10 | # To launch the app for iOS
11 | $ yarn ios
12 | # To launch the app for Android
13 | $ yarn android
14 | # To pack your assets in the iOS/Android app (needed when updating assets)
15 | $ yarn asset
16 | ```
17 |
--------------------------------------------------------------------------------
/example/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.application"
2 | apply plugin: "com.facebook.react"
3 |
4 | /**
5 | * This is the configuration block to customize your React Native Android app.
6 | * By default you don't need to apply any configuration, just uncomment the lines you need.
7 | */
8 | react {
9 | /* Folders */
10 | // The root of your project, i.e. where "package.json" lives. Default is '..'
11 | // root = file("../")
12 | // The folder where the react-native NPM package is. Default is ../node_modules/react-native
13 | // reactNativeDir = file("../node_modules/react-native")
14 | // The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen
15 | // codegenDir = file("../node_modules/@react-native/codegen")
16 | // The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js
17 | // cliFile = file("../node_modules/react-native/cli.js")
18 |
19 | /* Variants */
20 | // The list of variants to that are debuggable. For those we're going to
21 | // skip the bundling of the JS bundle and the assets. By default is just 'debug'.
22 | // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants.
23 | // debuggableVariants = ["liteDebug", "prodDebug"]
24 |
25 | /* Bundling */
26 | // A list containing the node command and its flags. Default is just 'node'.
27 | // nodeExecutableAndArgs = ["node"]
28 | //
29 | // The command to run when bundling. By default is 'bundle'
30 | // bundleCommand = "ram-bundle"
31 | //
32 | // The path to the CLI configuration file. Default is empty.
33 | // bundleConfig = file(../rn-cli.config.js)
34 | //
35 | // The name of the generated asset file containing your JS bundle
36 | // bundleAssetName = "MyApplication.android.bundle"
37 | //
38 | // The entry file for bundle generation. Default is 'index.android.js' or 'index.js'
39 | // entryFile = file("../js/MyApplication.android.js")
40 | //
41 | // A list of extra flags to pass to the 'bundle' commands.
42 | // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle
43 | // extraPackagerArgs = []
44 |
45 | /* Hermes Commands */
46 | // The hermes compiler command to run. By default it is 'hermesc'
47 | // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc"
48 | //
49 | // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
50 | // hermesFlags = ["-O", "-output-source-map"]
51 | }
52 |
53 | /**
54 | * Set this to true to Run Proguard on Release builds to minify the Java bytecode.
55 | */
56 | def enableProguardInReleaseBuilds = false
57 |
58 | /**
59 | * The preferred build flavor of JavaScriptCore (JSC)
60 | *
61 | * For example, to use the international variant, you can use:
62 | * `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
63 | *
64 | * The international variant includes ICU i18n library and necessary data
65 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
66 | * give correct results when using with locales other than en-US. Note that
67 | * this variant is about 6MiB larger per architecture than default.
68 | */
69 | def jscFlavor = 'org.webkit:android-jsc:+'
70 |
71 | android {
72 | ndkVersion rootProject.ext.ndkVersion
73 |
74 | compileSdkVersion rootProject.ext.compileSdkVersion
75 |
76 | namespace "com.example"
77 | defaultConfig {
78 | applicationId "com.example"
79 | minSdkVersion rootProject.ext.minSdkVersion
80 | targetSdkVersion rootProject.ext.targetSdkVersion
81 | versionCode 1
82 | versionName "1.0"
83 | }
84 | signingConfigs {
85 | debug {
86 | storeFile file('debug.keystore')
87 | storePassword 'android'
88 | keyAlias 'androiddebugkey'
89 | keyPassword 'android'
90 | }
91 | }
92 | buildTypes {
93 | debug {
94 | signingConfig signingConfigs.debug
95 | }
96 | release {
97 | // Caution! In production, you need to generate your own keystore file.
98 | // see https://reactnative.dev/docs/signed-apk-android.
99 | signingConfig signingConfigs.debug
100 | minifyEnabled enableProguardInReleaseBuilds
101 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
102 | }
103 | }
104 | }
105 |
106 | dependencies {
107 | // The version of react-native is set by the React Native Gradle Plugin
108 | implementation("com.facebook.react:react-android")
109 |
110 | debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}")
111 | debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
112 | exclude group:'com.squareup.okhttp3', module:'okhttp'
113 | }
114 |
115 | debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}")
116 | if (hermesEnabled.toBoolean()) {
117 | implementation("com.facebook.react:hermes-android")
118 | } else {
119 | implementation jscFlavor
120 | }
121 | }
122 |
123 | apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
--------------------------------------------------------------------------------
/example/android/app/debug.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calico-games/react-native-godot/3892f30db6e43715609562c6e50960613ecf0df9/example/android/app/debug.keystore
--------------------------------------------------------------------------------
/example/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | -keep class com.facebook.hermes.unicode.** { *; }
13 | -keep class com.facebook.jni.** { *; }
--------------------------------------------------------------------------------
/example/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/example/android/app/src/debug/java/com/example/ReactNativeFlipper.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | * This source code is licensed under the MIT license found in the LICENSE file in the root
5 | * directory of this source tree.
6 | */
7 | package com.example;
8 |
9 | import android.content.Context;
10 | import com.facebook.flipper.android.AndroidFlipperClient;
11 | import com.facebook.flipper.android.utils.FlipperUtils;
12 | import com.facebook.flipper.core.FlipperClient;
13 | import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin;
14 | import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin;
15 | import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin;
16 | import com.facebook.flipper.plugins.inspector.DescriptorMapping;
17 | import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
18 | import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
19 | import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
20 | import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
21 | import com.facebook.react.ReactInstanceEventListener;
22 | import com.facebook.react.ReactInstanceManager;
23 | import com.facebook.react.bridge.ReactContext;
24 | import com.facebook.react.modules.network.NetworkingModule;
25 | import okhttp3.OkHttpClient;
26 |
27 | /**
28 | * Class responsible of loading Flipper inside your React Native application. This is the debug
29 | * flavor of it. Here you can add your own plugins and customize the Flipper setup.
30 | */
31 | public class ReactNativeFlipper {
32 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
33 | if (FlipperUtils.shouldEnableFlipper(context)) {
34 | final FlipperClient client = AndroidFlipperClient.getInstance(context);
35 |
36 | client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
37 | client.addPlugin(new DatabasesFlipperPlugin(context));
38 | client.addPlugin(new SharedPreferencesFlipperPlugin(context));
39 | client.addPlugin(CrashReporterPlugin.getInstance());
40 |
41 | NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
42 | NetworkingModule.setCustomClientBuilder(
43 | new NetworkingModule.CustomClientBuilder() {
44 | @Override
45 | public void apply(OkHttpClient.Builder builder) {
46 | builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
47 | }
48 | });
49 | client.addPlugin(networkFlipperPlugin);
50 | client.start();
51 |
52 | // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
53 | // Hence we run if after all native modules have been initialized
54 | ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
55 | if (reactContext == null) {
56 | reactInstanceManager.addReactInstanceEventListener(
57 | new ReactInstanceEventListener() {
58 | @Override
59 | public void onReactContextInitialized(ReactContext reactContext) {
60 | reactInstanceManager.removeReactInstanceEventListener(this);
61 | reactContext.runOnNativeModulesQueueThread(
62 | new Runnable() {
63 | @Override
64 | public void run() {
65 | client.addPlugin(new FrescoFlipperPlugin());
66 | }
67 | });
68 | }
69 | });
70 | } else {
71 | client.addPlugin(new FrescoFlipperPlugin());
72 | }
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
12 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/example/android/app/src/main/assets/custom/cube.pck:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calico-games/react-native-godot/3892f30db6e43715609562c6e50960613ecf0df9/example/android/app/src/main/assets/custom/cube.pck
--------------------------------------------------------------------------------
/example/android/app/src/main/assets/custom/earth.pck:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calico-games/react-native-godot/3892f30db6e43715609562c6e50960613ecf0df9/example/android/app/src/main/assets/custom/earth.pck
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/example/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import com.facebook.react.ReactActivity;
4 | import com.facebook.react.ReactActivityDelegate;
5 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
6 | import com.facebook.react.defaults.DefaultReactActivityDelegate;
7 |
8 | public class MainActivity extends ReactActivity {
9 |
10 | /**
11 | * Returns the name of the main component registered from JavaScript. This is used to schedule
12 | * rendering of the component.
13 | */
14 | @Override
15 | protected String getMainComponentName() {
16 | return "example";
17 | }
18 |
19 | /**
20 | * Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link
21 | * DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React
22 | * (aka React 18) with two boolean flags.
23 | */
24 | @Override
25 | protected ReactActivityDelegate createReactActivityDelegate() {
26 | return new DefaultReactActivityDelegate(
27 | this,
28 | getMainComponentName(),
29 | // If you opted-in for the New Architecture, we enable the Fabric Renderer.
30 | DefaultNewArchitectureEntryPoint.getFabricEnabled());
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/example/MainApplication.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import android.app.Application;
4 | import com.facebook.react.PackageList;
5 | import com.facebook.react.ReactApplication;
6 | import com.facebook.react.ReactNativeHost;
7 | import com.facebook.react.ReactPackage;
8 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
9 | import com.facebook.react.defaults.DefaultReactNativeHost;
10 | import com.facebook.soloader.SoLoader;
11 | import java.util.List;
12 |
13 | public class MainApplication extends Application implements ReactApplication {
14 |
15 | private final ReactNativeHost mReactNativeHost =
16 | new DefaultReactNativeHost(this) {
17 | @Override
18 | public boolean getUseDeveloperSupport() {
19 | return BuildConfig.DEBUG;
20 | }
21 |
22 | @Override
23 | protected List getPackages() {
24 | @SuppressWarnings("UnnecessaryLocalVariable")
25 | List packages = new PackageList(this).getPackages();
26 | // Packages that cannot be autolinked yet can be added manually here, for example:
27 | // packages.add(new MyReactNativePackage());
28 | return packages;
29 | }
30 |
31 | @Override
32 | protected String getJSMainModuleName() {
33 | return "index";
34 | }
35 |
36 | @Override
37 | protected boolean isNewArchEnabled() {
38 | return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
39 | }
40 |
41 | @Override
42 | protected Boolean isHermesEnabled() {
43 | return BuildConfig.IS_HERMES_ENABLED;
44 | }
45 | };
46 |
47 | @Override
48 | public ReactNativeHost getReactNativeHost() {
49 | return mReactNativeHost;
50 | }
51 |
52 | @Override
53 | public void onCreate() {
54 | super.onCreate();
55 | SoLoader.init(this, /* native exopackage */ false);
56 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
57 | // If you opted-in for the New Architecture, we load the native entry point for this app.
58 | DefaultNewArchitectureEntryPoint.load();
59 | }
60 | ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable/rn_edit_text_material.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
21 |
22 |
23 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calico-games/react-native-godot/3892f30db6e43715609562c6e50960613ecf0df9/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calico-games/react-native-godot/3892f30db6e43715609562c6e50960613ecf0df9/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calico-games/react-native-godot/3892f30db6e43715609562c6e50960613ecf0df9/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calico-games/react-native-godot/3892f30db6e43715609562c6e50960613ecf0df9/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calico-games/react-native-godot/3892f30db6e43715609562c6e50960613ecf0df9/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calico-games/react-native-godot/3892f30db6e43715609562c6e50960613ecf0df9/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calico-games/react-native-godot/3892f30db6e43715609562c6e50960613ecf0df9/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calico-games/react-native-godot/3892f30db6e43715609562c6e50960613ecf0df9/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calico-games/react-native-godot/3892f30db6e43715609562c6e50960613ecf0df9/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calico-games/react-native-godot/3892f30db6e43715609562c6e50960613ecf0df9/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | example
3 |
4 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/example/android/app/src/release/java/com/example/ReactNativeFlipper.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | * This source code is licensed under the MIT license found in the LICENSE file in the root
5 | * directory of this source tree.
6 | */
7 | package com.example;
8 |
9 | import android.content.Context;
10 | import com.facebook.react.ReactInstanceManager;
11 |
12 | /**
13 | * Class responsible of loading Flipper inside your React Native application. This is the release
14 | * flavor of it so it's empty as we don't want to load Flipper.
15 | */
16 | public class ReactNativeFlipper {
17 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
18 | // Do nothing as we don't want to initialize Flipper on Release.
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/example/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext {
5 | buildToolsVersion = "33.0.0"
6 | minSdkVersion = 21
7 | compileSdkVersion = 33
8 | targetSdkVersion = 33
9 |
10 | // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.
11 | ndkVersion = "23.1.7779620"
12 | }
13 | repositories {
14 | google()
15 | mavenCentral()
16 | maven {
17 | url "https://plugins.gradle.org/m2/"
18 | }
19 | }
20 | dependencies {
21 | classpath("com.android.tools.build:gradle")
22 | classpath("com.facebook.react:react-native-gradle-plugin")
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/example/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | # AndroidX package structure to make it clearer which packages are bundled with the
21 | # Android operating system, and which are packaged with your app's APK
22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
23 | android.useAndroidX=true
24 | # Automatically convert third-party libraries to use AndroidX
25 | android.enableJetifier=true
26 |
27 | # Version of flipper SDK to use with React Native
28 | FLIPPER_VERSION=0.182.0
29 |
30 | # Use this property to specify which architecture you want to build.
31 | # You can also override it from the CLI using
32 | # ./gradlew -PreactNativeArchitectures=x86_64
33 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
34 |
35 | # Use this property to enable support to the new architecture.
36 | # This will allow you to use TurboModules and the Fabric render in
37 | # your application. You should enable this flag either if you want
38 | # to write custom TurboModules/Fabric components OR use libraries that
39 | # are providing them.
40 | newArchEnabled=true
41 |
42 | # Use this property to enable or disable the Hermes JS engine.
43 | # If set to false, you will be using JSC instead.
44 | hermesEnabled=true
45 |
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calico-games/react-native-godot/3892f30db6e43715609562c6e50960613ecf0df9/example/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip
4 | networkTimeout=10000
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/example/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 | # SPDX-License-Identifier: Apache-2.0
19 | #
20 |
21 | ##############################################################################
22 | #
23 | # Gradle start up script for POSIX generated by Gradle.
24 | #
25 | # Important for running:
26 | #
27 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
28 | # noncompliant, but you have some other compliant shell such as ksh or
29 | # bash, then to run this script, type that shell name before the whole
30 | # command line, like:
31 | #
32 | # ksh Gradle
33 | #
34 | # Busybox and similar reduced shells will NOT work, because this script
35 | # requires all of these POSIX shell features:
36 | # * functions;
37 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
38 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
39 | # * compound commands having a testable exit status, especially «case»;
40 | # * various built-in commands including «command», «set», and «ulimit».
41 | #
42 | # Important for patching:
43 | #
44 | # (2) This script targets any POSIX shell, so it avoids extensions provided
45 | # by Bash, Ksh, etc; in particular arrays are avoided.
46 | #
47 | # The "traditional" practice of packing multiple parameters into a
48 | # space-separated string is a well documented source of bugs and security
49 | # problems, so this is (mostly) avoided, by progressively accumulating
50 | # options in "$@", and eventually passing that to Java.
51 | #
52 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
53 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
54 | # see the in-line comments for details.
55 | #
56 | # There are tweaks for specific operating systems such as AIX, CygWin,
57 | # Darwin, MinGW, and NonStop.
58 | #
59 | # (3) This script is generated from the Groovy template
60 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
61 | # within the Gradle project.
62 | #
63 | # You can find Gradle at https://github.com/gradle/gradle/.
64 | #
65 | ##############################################################################
66 |
67 | # Attempt to set APP_HOME
68 |
69 | # Resolve links: $0 may be a link
70 | app_path=$0
71 |
72 | # Need this for daisy-chained symlinks.
73 | while
74 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
75 | [ -h "$app_path" ]
76 | do
77 | ls=$( ls -ld "$app_path" )
78 | link=${ls#*' -> '}
79 | case $link in #(
80 | /*) app_path=$link ;; #(
81 | *) app_path=$APP_HOME$link ;;
82 | esac
83 | done
84 |
85 | # This is normally unused
86 | # shellcheck disable=SC2034
87 | APP_BASE_NAME=${0##*/}
88 | APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
89 |
90 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
91 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
92 |
93 | # Use the maximum available, or set MAX_FD != -1 to use that value.
94 | MAX_FD=maximum
95 |
96 | warn () {
97 | echo "$*"
98 | } >&2
99 |
100 | die () {
101 | echo
102 | echo "$*"
103 | echo
104 | exit 1
105 | } >&2
106 |
107 | # OS specific support (must be 'true' or 'false').
108 | cygwin=false
109 | msys=false
110 | darwin=false
111 | nonstop=false
112 | case "$( uname )" in #(
113 | CYGWIN* ) cygwin=true ;; #(
114 | Darwin* ) darwin=true ;; #(
115 | MSYS* | MINGW* ) msys=true ;; #(
116 | NONSTOP* ) nonstop=true ;;
117 | esac
118 |
119 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
120 |
121 |
122 | # Determine the Java command to use to start the JVM.
123 | if [ -n "$JAVA_HOME" ] ; then
124 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
125 | # IBM's JDK on AIX uses strange locations for the executables
126 | JAVACMD=$JAVA_HOME/jre/sh/java
127 | else
128 | JAVACMD=$JAVA_HOME/bin/java
129 | fi
130 | if [ ! -x "$JAVACMD" ] ; then
131 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
132 |
133 | Please set the JAVA_HOME variable in your environment to match the
134 | location of your Java installation."
135 | fi
136 | else
137 | JAVACMD=java
138 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
139 |
140 | Please set the JAVA_HOME variable in your environment to match the
141 | location of your Java installation."
142 | fi
143 |
144 | # Increase the maximum file descriptors if we can.
145 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
146 | case $MAX_FD in #(
147 | max*)
148 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
149 | # shellcheck disable=SC3045
150 | MAX_FD=$( ulimit -H -n ) ||
151 | warn "Could not query maximum file descriptor limit"
152 | esac
153 | case $MAX_FD in #(
154 | '' | soft) :;; #(
155 | *)
156 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
157 | # shellcheck disable=SC3045
158 | ulimit -n "$MAX_FD" ||
159 | warn "Could not set maximum file descriptor limit to $MAX_FD"
160 | esac
161 | fi
162 |
163 | # Collect all arguments for the java command, stacking in reverse order:
164 | # * args from the command line
165 | # * the main class name
166 | # * -classpath
167 | # * -D...appname settings
168 | # * --module-path (only if needed)
169 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
170 |
171 | # For Cygwin or MSYS, switch paths to Windows format before running java
172 | if "$cygwin" || "$msys" ; then
173 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
174 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
175 |
176 | JAVACMD=$( cygpath --unix "$JAVACMD" )
177 |
178 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
179 | for arg do
180 | if
181 | case $arg in #(
182 | -*) false ;; # don't mess with options #(
183 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
184 | [ -e "$t" ] ;; #(
185 | *) false ;;
186 | esac
187 | then
188 | arg=$( cygpath --path --ignore --mixed "$arg" )
189 | fi
190 | # Roll the args list around exactly as many times as the number of
191 | # args, so each arg winds up back in the position where it started, but
192 | # possibly modified.
193 | #
194 | # NB: a `for` loop captures its iteration list before it begins, so
195 | # changing the positional parameters here affects neither the number of
196 | # iterations, nor the values presented in `arg`.
197 | shift # remove old arg
198 | set -- "$@" "$arg" # push replacement arg
199 | done
200 | fi
201 |
202 | # Collect all arguments for the java command;
203 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
204 | # shell script including quotes and variable substitutions, so put them in
205 | # double quotes to make sure that they get re-expanded; and
206 | # * put everything else in single quotes, so that it's not re-expanded.
207 |
208 | set -- \
209 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
210 | -classpath "$CLASSPATH" \
211 | org.gradle.wrapper.GradleWrapperMain \
212 | "$@"
213 |
214 | # Stop when "xargs" is not available.
215 | if ! command -v xargs >/dev/null 2>&1
216 | then
217 | die "xargs is not available"
218 | fi
219 |
220 | # Use "xargs" to parse quoted args.
221 | #
222 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
223 | #
224 | # In Bash we could simply go:
225 | #
226 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
227 | # set -- "${ARGS[@]}" "$@"
228 | #
229 | # but POSIX shell has neither arrays nor command substitution, so instead we
230 | # post-process each arg (as a line of input to sed) to backslash-escape any
231 | # character that might be a shell metacharacter, then use eval to reverse
232 | # that process (while maintaining the separation between arguments), and wrap
233 | # the whole thing up as a single "set" statement.
234 | #
235 | # This will of course break if any of these variables contains a newline or
236 | # an unmatched quote.
237 | #
238 |
239 | eval "set -- $(
240 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
241 | xargs -n1 |
242 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
243 | tr '\n' ' '
244 | )" '"$@"'
245 |
246 | exec "$JAVACMD" "$@"
247 |
--------------------------------------------------------------------------------
/example/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 | @rem SPDX-License-Identifier: Apache-2.0
17 | @rem
18 |
19 | @if "%DEBUG%"=="" @echo off
20 | @rem ##########################################################################
21 | @rem
22 | @rem Gradle startup script for Windows
23 | @rem
24 | @rem ##########################################################################
25 |
26 | @rem Set local scope for the variables with windows NT shell
27 | if "%OS%"=="Windows_NT" setlocal
28 |
29 | set DIRNAME=%~dp0
30 | if "%DIRNAME%"=="" set DIRNAME=.
31 | @rem This is normally unused
32 | set APP_BASE_NAME=%~n0
33 | set APP_HOME=%DIRNAME%
34 |
35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
37 |
38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
40 |
41 | @rem Find java.exe
42 | if defined JAVA_HOME goto findJavaFromJavaHome
43 |
44 | set JAVA_EXE=java.exe
45 | %JAVA_EXE% -version >NUL 2>&1
46 | if %ERRORLEVEL% equ 0 goto execute
47 |
48 | echo.
49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
50 | echo.
51 | echo Please set the JAVA_HOME variable in your environment to match the
52 | echo location of your Java installation.
53 |
54 | goto fail
55 |
56 | :findJavaFromJavaHome
57 | set JAVA_HOME=%JAVA_HOME:"=%
58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
59 |
60 | if exist "%JAVA_EXE%" goto execute
61 |
62 | echo.
63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
64 | echo.
65 | echo Please set the JAVA_HOME variable in your environment to match the
66 | echo location of your Java installation.
67 |
68 | goto fail
69 |
70 | :execute
71 | @rem Setup the command line
72 |
73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
74 |
75 |
76 | @rem Execute Gradle
77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
78 |
79 | :end
80 | @rem End local scope for the variables with windows NT shell
81 | if %ERRORLEVEL% equ 0 goto mainEnd
82 |
83 | :fail
84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
85 | rem the _cmd.exe /c_ return code!
86 | set EXIT_CODE=%ERRORLEVEL%
87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
89 | exit /b %EXIT_CODE%
90 |
91 | :mainEnd
92 | if "%OS%"=="Windows_NT" endlocal
93 |
94 | :omega
95 |
--------------------------------------------------------------------------------
/example/android/link-assets-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "migIndex": 1,
3 | "data": [
4 | {
5 | "path": "src/assets/cube.pck",
6 | "sha1": "e55b073942e0cb05956c49b976eee6716c833d41"
7 | },
8 | {
9 | "path": "src/assets/earth.pck",
10 | "sha1": "49cc7c2f10c2413a8c1d45199bc4904f4fdc783e"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/example/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'example'
2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
3 | include ':app'
4 | includeBuild('../node_modules/@react-native/gradle-plugin')
5 |
--------------------------------------------------------------------------------
/example/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example",
3 | "displayName": "Godot Example"
4 | }
5 |
--------------------------------------------------------------------------------
/example/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = function (api) {
2 | const babelEnv = api.env();
3 |
4 | api.cache(true);
5 |
6 | const plugins = [
7 | [
8 | 'module-resolver',
9 | {
10 | root: ['./'],
11 | alias: {
12 | '@': './src',
13 | },
14 | extensions: ['.tsx', '.ts', '.js'],
15 | },
16 | ],
17 | ];
18 |
19 | if (babelEnv === 'production') {
20 | plugins.push(['babel-plugin-transform-remove-console', {exclude: ['error', 'warn']}]);
21 | }
22 |
23 | plugins.push(["@babel/plugin-proposal-decorators", { "legacy": true }]);
24 |
25 | plugins.push(["react-native-reanimated/plugin"]);
26 |
27 | return {
28 | presets: ['module:@react-native/babel-preset'],
29 | plugins,
30 | };
31 | };
--------------------------------------------------------------------------------
/example/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @format
3 | */
4 |
5 | import {AppRegistry} from 'react-native';
6 | import App from './src/App';
7 | import {name as appName} from './app.json';
8 |
9 | AppRegistry.registerComponent(appName, () => App);
10 |
--------------------------------------------------------------------------------
/example/ios/.bundle/config:
--------------------------------------------------------------------------------
1 | BUNDLE_PATH: "vendor/bundle"
2 | BUNDLE_FORCE_RUBY_PLATFORM: 1
3 |
--------------------------------------------------------------------------------
/example/ios/.xcode.env:
--------------------------------------------------------------------------------
1 | # This `.xcode.env` file is versioned and is used to source the environment
2 | # used when running script phases inside Xcode.
3 | # To customize your local environment, you can create an `.xcode.env.local`
4 | # file that is not versioned.
5 |
6 | # NODE_BINARY variable contains the PATH to the node executable.
7 | #
8 | # Customize the NODE_BINARY variable here.
9 | # For example, to use nvm with brew, add the following line
10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use
11 | export NODE_BINARY=$(command -v node)
12 |
--------------------------------------------------------------------------------
/example/ios/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | # Exclude problematic versions of cocoapods and activesupport that causes build failures.
4 | gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1'
5 | gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0'
6 | gem 'xcodeproj', '< 1.26.0'
7 | gem 'concurrent-ruby', '< 1.3.4'
--------------------------------------------------------------------------------
/example/ios/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | CFPropertyList (3.0.7)
5 | base64
6 | nkf
7 | rexml
8 | activesupport (7.1.3.4)
9 | base64
10 | bigdecimal
11 | concurrent-ruby (~> 1.0, >= 1.0.2)
12 | connection_pool (>= 2.2.5)
13 | drb
14 | i18n (>= 1.6, < 2)
15 | minitest (>= 5.1)
16 | mutex_m
17 | tzinfo (~> 2.0)
18 | addressable (2.8.6)
19 | public_suffix (>= 2.0.2, < 6.0)
20 | algoliasearch (1.27.5)
21 | httpclient (~> 2.8, >= 2.8.3)
22 | json (>= 1.5.1)
23 | atomos (0.1.3)
24 | base64 (0.2.0)
25 | bigdecimal (3.1.8)
26 | claide (1.1.0)
27 | cocoapods (1.15.2)
28 | addressable (~> 2.8)
29 | claide (>= 1.0.2, < 2.0)
30 | cocoapods-core (= 1.15.2)
31 | cocoapods-deintegrate (>= 1.0.3, < 2.0)
32 | cocoapods-downloader (>= 2.1, < 3.0)
33 | cocoapods-plugins (>= 1.0.0, < 2.0)
34 | cocoapods-search (>= 1.0.0, < 2.0)
35 | cocoapods-trunk (>= 1.6.0, < 2.0)
36 | cocoapods-try (>= 1.1.0, < 2.0)
37 | colored2 (~> 3.1)
38 | escape (~> 0.0.4)
39 | fourflusher (>= 2.3.0, < 3.0)
40 | gh_inspector (~> 1.0)
41 | molinillo (~> 0.8.0)
42 | nap (~> 1.0)
43 | ruby-macho (>= 2.3.0, < 3.0)
44 | xcodeproj (>= 1.23.0, < 2.0)
45 | cocoapods-core (1.15.2)
46 | activesupport (>= 5.0, < 8)
47 | addressable (~> 2.8)
48 | algoliasearch (~> 1.0)
49 | concurrent-ruby (~> 1.1)
50 | fuzzy_match (~> 2.0.4)
51 | nap (~> 1.0)
52 | netrc (~> 0.11)
53 | public_suffix (~> 4.0)
54 | typhoeus (~> 1.0)
55 | cocoapods-deintegrate (1.0.5)
56 | cocoapods-downloader (2.1)
57 | cocoapods-plugins (1.0.0)
58 | nap
59 | cocoapods-search (1.0.1)
60 | cocoapods-trunk (1.6.0)
61 | nap (>= 0.8, < 2.0)
62 | netrc (~> 0.11)
63 | cocoapods-try (1.2.0)
64 | colored2 (3.1.2)
65 | concurrent-ruby (1.3.2)
66 | connection_pool (2.4.1)
67 | drb (2.2.1)
68 | escape (0.0.4)
69 | ethon (0.16.0)
70 | ffi (>= 1.15.0)
71 | ffi (1.17.0)
72 | ffi (1.17.0-aarch64-linux-gnu)
73 | ffi (1.17.0-aarch64-linux-musl)
74 | ffi (1.17.0-arm-linux-gnu)
75 | ffi (1.17.0-arm-linux-musl)
76 | ffi (1.17.0-arm64-darwin)
77 | ffi (1.17.0-x86-linux-gnu)
78 | ffi (1.17.0-x86-linux-musl)
79 | ffi (1.17.0-x86_64-darwin)
80 | ffi (1.17.0-x86_64-linux-gnu)
81 | ffi (1.17.0-x86_64-linux-musl)
82 | fourflusher (2.3.1)
83 | fuzzy_match (2.0.4)
84 | gh_inspector (1.1.3)
85 | httpclient (2.8.3)
86 | i18n (1.14.5)
87 | concurrent-ruby (~> 1.0)
88 | json (2.7.2)
89 | minitest (5.23.1)
90 | molinillo (0.8.0)
91 | mutex_m (0.2.0)
92 | nanaimo (0.3.0)
93 | nap (1.1.0)
94 | netrc (0.11.0)
95 | nkf (0.2.0)
96 | public_suffix (4.0.7)
97 | rexml (3.2.8)
98 | strscan (>= 3.0.9)
99 | ruby-macho (2.5.1)
100 | strscan (3.1.0)
101 | typhoeus (1.4.1)
102 | ethon (>= 0.9.0)
103 | tzinfo (2.0.6)
104 | concurrent-ruby (~> 1.0)
105 | xcodeproj (1.24.0)
106 | CFPropertyList (>= 2.3.3, < 4.0)
107 | atomos (~> 0.1.3)
108 | claide (>= 1.0.2, < 2.0)
109 | colored2 (~> 3.1)
110 | nanaimo (~> 0.3.0)
111 | rexml (~> 3.2.4)
112 |
113 | PLATFORMS
114 | aarch64-linux-gnu
115 | aarch64-linux-musl
116 | arm-linux-gnu
117 | arm-linux-musl
118 | arm64-darwin
119 | ruby
120 | x86-linux-gnu
121 | x86-linux-musl
122 | x86_64-darwin
123 | x86_64-linux-gnu
124 | x86_64-linux-musl
125 |
126 | DEPENDENCIES
127 | activesupport (>= 6.1.7.5, != 7.1.0)
128 | cocoapods (>= 1.13, != 1.15.1, != 1.15.0)
129 | concurrent-ruby (< 1.3.4)
130 | xcodeproj (< 1.26.0)
131 |
132 | BUNDLED WITH
133 | 2.5.11
134 |
--------------------------------------------------------------------------------
/example/ios/Podfile:
--------------------------------------------------------------------------------
1 | source 'https://cdn.cocoapods.org/'
2 |
3 | using_bundler = defined? Bundler
4 | unless using_bundler
5 | puts "\nPlease re-run using:".red
6 | puts " bundle exec pod install\n\n"
7 | exit(1)
8 | end
9 |
10 | ENV['RCT_NEW_ARCH_ENABLED'] = '1'
11 |
12 | # Resolve react_native_pods.rb with node to allow for hoisting
13 | require Pod::Executable.execute_command('node', ['-p',
14 | 'require.resolve(
15 | "react-native/scripts/react_native_pods.rb",
16 | {paths: [process.argv[1]]},
17 | )', __dir__]).strip
18 |
19 | platform :ios, min_ios_version_supported
20 | prepare_react_native_project!
21 |
22 | target 'example' do
23 | config = use_native_modules!
24 |
25 | # Flags change depending on the env values.
26 | flags = get_default_flags()
27 |
28 | use_react_native!(
29 | :path => config[:reactNativePath],
30 | # An absolute path to your application root.
31 | :app_path => "#{Pod::Config.instance.installation_root}/.."
32 | )
33 |
34 | post_install do |installer|
35 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202
36 | react_native_post_install(
37 | installer,
38 | config[:reactNativePath],
39 | :mac_catalyst_enabled => false,
40 | :ccache_enabled => true
41 | )
42 |
43 | # Fix issue with No template named 'unary_function' in namespace in XCode 15
44 | installer.pods_project.targets.each do |target|
45 | target.build_configurations.each do |config|
46 | config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)', '_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION']
47 | end
48 | end
49 | end
50 | end
--------------------------------------------------------------------------------
/example/ios/example-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Use this file to import your target's public headers that you would like to expose to Swift.
3 | //
4 |
5 |
--------------------------------------------------------------------------------
/example/ios/example.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 54;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
11 | 2D86C531EB428C1D7385AAF2 /* libPods-example.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C992B1E8C02CE5C555DB33CB /* libPods-example.a */; };
12 | 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
13 | 96300DA62D99B50F0017B15C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96300DA52D99B50F0017B15C /* AppDelegate.swift */; };
14 | 969790742D07FB5F0063149D /* project.godot in Resources */ = {isa = PBXBuildFile; fileRef = 969790732D07FB5F0063149D /* project.godot */; };
15 | 96D697622CD34109008FC432 /* ReactNativeGodot.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96E79FFD2CD320C100270EE4 /* ReactNativeGodot.xcframework */; };
16 | F2051D322750828A58F73D7C /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 6D6D63580D84DB476010F438 /* PrivacyInfo.xcprivacy */; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXFileReference section */
20 | 13B07F961A680F5B00A75B9A /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example.app; sourceTree = BUILT_PRODUCTS_DIR; };
21 | 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = example/Images.xcassets; sourceTree = ""; };
22 | 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = example/Info.plist; sourceTree = ""; };
23 | 3B4392A12AC88292D35C810B /* Pods-example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example.debug.xcconfig"; path = "Target Support Files/Pods-example/Pods-example.debug.xcconfig"; sourceTree = ""; };
24 | 5709B34CF0A7D63546082F79 /* Pods-example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example.release.xcconfig"; path = "Target Support Files/Pods-example/Pods-example.release.xcconfig"; sourceTree = ""; };
25 | 6D6D63580D84DB476010F438 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = example/PrivacyInfo.xcprivacy; sourceTree = ""; };
26 | 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = example/LaunchScreen.storyboard; sourceTree = ""; };
27 | 96300DA52D99B50F0017B15C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = example/AppDelegate.swift; sourceTree = ""; };
28 | 96300DA72D99B5110017B15C /* example-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "example-Bridging-Header.h"; sourceTree = ""; };
29 | 96300DA82D9F91FE0017B15C /* MetalFX.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalFX.framework; path = System/Library/Frameworks/MetalFX.framework; sourceTree = SDKROOT; };
30 | 969790732D07FB5F0063149D /* project.godot */ = {isa = PBXFileReference; lastKnownFileType = text; path = project.godot; sourceTree = ""; };
31 | 96E772B42BF79BD600B09EE0 /* hermes.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = hermes.xcframework; path = "Pods/hermes-engine/destroot/Library/Frameworks/universal/hermes.xcframework"; sourceTree = ""; };
32 | 96E79FFD2CD320C100270EE4 /* ReactNativeGodot.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = ReactNativeGodot.xcframework; path = "/Users/seb/Projects/react-native-godot/example/node_modules/react-native-godot/../../../package/libs/ios/ReactNativeGodot.xcframework"; sourceTree = ""; };
33 | C992B1E8C02CE5C555DB33CB /* libPods-example.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-example.a"; sourceTree = BUILT_PRODUCTS_DIR; };
34 | ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
35 | /* End PBXFileReference section */
36 |
37 | /* Begin PBXFrameworksBuildPhase section */
38 | 13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
39 | isa = PBXFrameworksBuildPhase;
40 | buildActionMask = 2147483647;
41 | files = (
42 | 96D697622CD34109008FC432 /* ReactNativeGodot.xcframework in Frameworks */,
43 | 2D86C531EB428C1D7385AAF2 /* libPods-example.a in Frameworks */,
44 | );
45 | runOnlyForDeploymentPostprocessing = 0;
46 | };
47 | /* End PBXFrameworksBuildPhase section */
48 |
49 | /* Begin PBXGroup section */
50 | 1325C79119A445E4BA5750C5 /* Resources */ = {
51 | isa = PBXGroup;
52 | children = (
53 | 969790732D07FB5F0063149D /* project.godot */,
54 | );
55 | name = Resources;
56 | sourceTree = "";
57 | };
58 | 13B07FAE1A68108700A75B9A /* example */ = {
59 | isa = PBXGroup;
60 | children = (
61 | 13B07FB51A68108700A75B9A /* Images.xcassets */,
62 | 13B07FB61A68108700A75B9A /* Info.plist */,
63 | 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */,
64 | 96300DA52D99B50F0017B15C /* AppDelegate.swift */,
65 | 6D6D63580D84DB476010F438 /* PrivacyInfo.xcprivacy */,
66 | 96300DA72D99B5110017B15C /* example-Bridging-Header.h */,
67 | );
68 | name = example;
69 | sourceTree = "";
70 | };
71 | 2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
72 | isa = PBXGroup;
73 | children = (
74 | 96300DA82D9F91FE0017B15C /* MetalFX.framework */,
75 | 96E79FFD2CD320C100270EE4 /* ReactNativeGodot.xcframework */,
76 | 96E772B42BF79BD600B09EE0 /* hermes.xcframework */,
77 | ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
78 | C992B1E8C02CE5C555DB33CB /* libPods-example.a */,
79 | );
80 | name = Frameworks;
81 | sourceTree = "";
82 | };
83 | 832341AE1AAA6A7D00B99B32 /* Libraries */ = {
84 | isa = PBXGroup;
85 | children = (
86 | );
87 | name = Libraries;
88 | sourceTree = "";
89 | };
90 | 83CBB9F61A601CBA00E9B192 = {
91 | isa = PBXGroup;
92 | children = (
93 | 13B07FAE1A68108700A75B9A /* example */,
94 | 832341AE1AAA6A7D00B99B32 /* Libraries */,
95 | 83CBBA001A601CBA00E9B192 /* Products */,
96 | 2D16E6871FA4F8E400B85C8A /* Frameworks */,
97 | BBD78D7AC51CEA395F1C20DB /* Pods */,
98 | 1325C79119A445E4BA5750C5 /* Resources */,
99 | );
100 | indentWidth = 2;
101 | sourceTree = "";
102 | tabWidth = 2;
103 | usesTabs = 0;
104 | };
105 | 83CBBA001A601CBA00E9B192 /* Products */ = {
106 | isa = PBXGroup;
107 | children = (
108 | 13B07F961A680F5B00A75B9A /* example.app */,
109 | );
110 | name = Products;
111 | sourceTree = "";
112 | };
113 | BBD78D7AC51CEA395F1C20DB /* Pods */ = {
114 | isa = PBXGroup;
115 | children = (
116 | 3B4392A12AC88292D35C810B /* Pods-example.debug.xcconfig */,
117 | 5709B34CF0A7D63546082F79 /* Pods-example.release.xcconfig */,
118 | );
119 | path = Pods;
120 | sourceTree = "";
121 | };
122 | /* End PBXGroup section */
123 |
124 | /* Begin PBXNativeTarget section */
125 | 13B07F861A680F5B00A75B9A /* example */ = {
126 | isa = PBXNativeTarget;
127 | buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "example" */;
128 | buildPhases = (
129 | C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */,
130 | FD10A7F022414F080027D42C /* Start Packager */,
131 | 13B07F871A680F5B00A75B9A /* Sources */,
132 | 13B07F8C1A680F5B00A75B9A /* Frameworks */,
133 | 13B07F8E1A680F5B00A75B9A /* Resources */,
134 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
135 | 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */,
136 | E235C05ADACE081382539298 /* [CP] Copy Pods Resources */,
137 | );
138 | buildRules = (
139 | );
140 | dependencies = (
141 | );
142 | name = example;
143 | productName = example;
144 | productReference = 13B07F961A680F5B00A75B9A /* example.app */;
145 | productType = "com.apple.product-type.application";
146 | };
147 | /* End PBXNativeTarget section */
148 |
149 | /* Begin PBXProject section */
150 | 83CBB9F71A601CBA00E9B192 /* Project object */ = {
151 | isa = PBXProject;
152 | attributes = {
153 | LastUpgradeCheck = 1210;
154 | TargetAttributes = {
155 | 13B07F861A680F5B00A75B9A = {
156 | LastSwiftMigration = 1600;
157 | };
158 | };
159 | };
160 | buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "example" */;
161 | compatibilityVersion = "Xcode 12.0";
162 | developmentRegion = en;
163 | hasScannedForEncodings = 0;
164 | knownRegions = (
165 | en,
166 | Base,
167 | );
168 | mainGroup = 83CBB9F61A601CBA00E9B192;
169 | productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
170 | projectDirPath = "";
171 | projectRoot = "";
172 | targets = (
173 | 13B07F861A680F5B00A75B9A /* example */,
174 | );
175 | };
176 | /* End PBXProject section */
177 |
178 | /* Begin PBXResourcesBuildPhase section */
179 | 13B07F8E1A680F5B00A75B9A /* Resources */ = {
180 | isa = PBXResourcesBuildPhase;
181 | buildActionMask = 2147483647;
182 | files = (
183 | 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */,
184 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
185 | F2051D322750828A58F73D7C /* PrivacyInfo.xcprivacy in Resources */,
186 | 969790742D07FB5F0063149D /* project.godot in Resources */,
187 | );
188 | runOnlyForDeploymentPostprocessing = 0;
189 | };
190 | /* End PBXResourcesBuildPhase section */
191 |
192 | /* Begin PBXShellScriptBuildPhase section */
193 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = {
194 | isa = PBXShellScriptBuildPhase;
195 | buildActionMask = 2147483647;
196 | files = (
197 | );
198 | inputPaths = (
199 | "$(SRCROOT)/.xcode.env.local",
200 | "$(SRCROOT)/.xcode.env",
201 | );
202 | name = "Bundle React Native code and images";
203 | outputPaths = (
204 | );
205 | runOnlyForDeploymentPostprocessing = 0;
206 | shellPath = /bin/sh;
207 | shellScript = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n";
208 | };
209 | 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = {
210 | isa = PBXShellScriptBuildPhase;
211 | buildActionMask = 2147483647;
212 | files = (
213 | );
214 | inputFileListPaths = (
215 | "${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-frameworks-${CONFIGURATION}-input-files.xcfilelist",
216 | );
217 | name = "[CP] Embed Pods Frameworks";
218 | outputFileListPaths = (
219 | "${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-frameworks-${CONFIGURATION}-output-files.xcfilelist",
220 | );
221 | runOnlyForDeploymentPostprocessing = 0;
222 | shellPath = /bin/sh;
223 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-frameworks.sh\"\n";
224 | showEnvVarsInLog = 0;
225 | };
226 | C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */ = {
227 | isa = PBXShellScriptBuildPhase;
228 | buildActionMask = 2147483647;
229 | files = (
230 | );
231 | inputFileListPaths = (
232 | );
233 | inputPaths = (
234 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
235 | "${PODS_ROOT}/Manifest.lock",
236 | );
237 | name = "[CP] Check Pods Manifest.lock";
238 | outputFileListPaths = (
239 | );
240 | outputPaths = (
241 | "$(DERIVED_FILE_DIR)/Pods-example-checkManifestLockResult.txt",
242 | );
243 | runOnlyForDeploymentPostprocessing = 0;
244 | shellPath = /bin/sh;
245 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
246 | showEnvVarsInLog = 0;
247 | };
248 | E235C05ADACE081382539298 /* [CP] Copy Pods Resources */ = {
249 | isa = PBXShellScriptBuildPhase;
250 | buildActionMask = 2147483647;
251 | files = (
252 | );
253 | inputFileListPaths = (
254 | "${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-resources-${CONFIGURATION}-input-files.xcfilelist",
255 | );
256 | name = "[CP] Copy Pods Resources";
257 | outputFileListPaths = (
258 | "${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-resources-${CONFIGURATION}-output-files.xcfilelist",
259 | );
260 | runOnlyForDeploymentPostprocessing = 0;
261 | shellPath = /bin/sh;
262 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-resources.sh\"\n";
263 | showEnvVarsInLog = 0;
264 | };
265 | FD10A7F022414F080027D42C /* Start Packager */ = {
266 | isa = PBXShellScriptBuildPhase;
267 | buildActionMask = 2147483647;
268 | files = (
269 | );
270 | inputFileListPaths = (
271 | );
272 | inputPaths = (
273 | );
274 | name = "Start Packager";
275 | outputFileListPaths = (
276 | );
277 | outputPaths = (
278 | );
279 | runOnlyForDeploymentPostprocessing = 0;
280 | shellPath = /bin/sh;
281 | shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n";
282 | showEnvVarsInLog = 0;
283 | };
284 | /* End PBXShellScriptBuildPhase section */
285 |
286 | /* Begin PBXSourcesBuildPhase section */
287 | 13B07F871A680F5B00A75B9A /* Sources */ = {
288 | isa = PBXSourcesBuildPhase;
289 | buildActionMask = 2147483647;
290 | files = (
291 | 96300DA62D99B50F0017B15C /* AppDelegate.swift in Sources */,
292 | );
293 | runOnlyForDeploymentPostprocessing = 0;
294 | };
295 | /* End PBXSourcesBuildPhase section */
296 |
297 | /* Begin XCBuildConfiguration section */
298 | 13B07F941A680F5B00A75B9A /* Debug */ = {
299 | isa = XCBuildConfiguration;
300 | baseConfigurationReference = 3B4392A12AC88292D35C810B /* Pods-example.debug.xcconfig */;
301 | buildSettings = {
302 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
303 | CLANG_ENABLE_MODULES = YES;
304 | COMPRESS_PNG_FILES = NO;
305 | CURRENT_PROJECT_VERSION = 11;
306 | DEVELOPMENT_TEAM = 2TE7AHNP9P;
307 | ENABLE_BITCODE = NO;
308 | INFOPLIST_FILE = example/Info.plist;
309 | INFOPLIST_KEY_CFBundleDisplayName = "Godot Example";
310 | LD_RUNPATH_SEARCH_PATHS = (
311 | "$(inherited)",
312 | "@executable_path/Frameworks",
313 | );
314 | MARKETING_VERSION = 1.0;
315 | OTHER_LDFLAGS = (
316 | "$(inherited)",
317 | "-ObjC",
318 | "-lc++",
319 | );
320 | PRODUCT_BUNDLE_IDENTIFIER = games.calico.godotExample;
321 | PRODUCT_NAME = example;
322 | STRIP_PNG_TEXT = NO;
323 | SWIFT_OBJC_BRIDGING_HEADER = "example-Bridging-Header.h";
324 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
325 | SWIFT_VERSION = 5.0;
326 | VERSIONING_SYSTEM = "apple-generic";
327 | };
328 | name = Debug;
329 | };
330 | 13B07F951A680F5B00A75B9A /* Release */ = {
331 | isa = XCBuildConfiguration;
332 | baseConfigurationReference = 5709B34CF0A7D63546082F79 /* Pods-example.release.xcconfig */;
333 | buildSettings = {
334 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
335 | CLANG_ENABLE_MODULES = YES;
336 | COMPRESS_PNG_FILES = NO;
337 | CURRENT_PROJECT_VERSION = 11;
338 | DEVELOPMENT_TEAM = 2TE7AHNP9P;
339 | INFOPLIST_FILE = example/Info.plist;
340 | INFOPLIST_KEY_CFBundleDisplayName = "Godot Example";
341 | LD_RUNPATH_SEARCH_PATHS = (
342 | "$(inherited)",
343 | "@executable_path/Frameworks",
344 | );
345 | MARKETING_VERSION = 1.0;
346 | OTHER_LDFLAGS = (
347 | "$(inherited)",
348 | "-ObjC",
349 | "-lc++",
350 | );
351 | PRODUCT_BUNDLE_IDENTIFIER = games.calico.godotExample;
352 | PRODUCT_NAME = example;
353 | STRIP_PNG_TEXT = NO;
354 | SWIFT_OBJC_BRIDGING_HEADER = "example-Bridging-Header.h";
355 | SWIFT_VERSION = 5.0;
356 | VERSIONING_SYSTEM = "apple-generic";
357 | };
358 | name = Release;
359 | };
360 | 83CBBA201A601CBA00E9B192 /* Debug */ = {
361 | isa = XCBuildConfiguration;
362 | buildSettings = {
363 | ALWAYS_SEARCH_USER_PATHS = NO;
364 | CC = "$(REACT_NATIVE_PATH)/scripts/xcode/ccache-clang.sh";
365 | CCACHE_BINARY = /opt/homebrew/bin/ccache;
366 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
367 | CLANG_CXX_LANGUAGE_STANDARD = "c++20";
368 | CLANG_CXX_LIBRARY = "libc++";
369 | CLANG_ENABLE_MODULES = YES;
370 | CLANG_ENABLE_OBJC_ARC = YES;
371 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
372 | CLANG_WARN_BOOL_CONVERSION = YES;
373 | CLANG_WARN_COMMA = YES;
374 | CLANG_WARN_CONSTANT_CONVERSION = YES;
375 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
376 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
377 | CLANG_WARN_EMPTY_BODY = YES;
378 | CLANG_WARN_ENUM_CONVERSION = YES;
379 | CLANG_WARN_INFINITE_RECURSION = YES;
380 | CLANG_WARN_INT_CONVERSION = YES;
381 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
382 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
383 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
384 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
385 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
386 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
387 | CLANG_WARN_STRICT_PROTOTYPES = YES;
388 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
389 | CLANG_WARN_UNREACHABLE_CODE = YES;
390 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
391 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
392 | COPY_PHASE_STRIP = NO;
393 | CXX = "$(REACT_NATIVE_PATH)/scripts/xcode/ccache-clang++.sh";
394 | ENABLE_STRICT_OBJC_MSGSEND = YES;
395 | ENABLE_TESTABILITY = YES;
396 | "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
397 | GCC_C_LANGUAGE_STANDARD = gnu99;
398 | GCC_DYNAMIC_NO_PIC = NO;
399 | GCC_NO_COMMON_BLOCKS = YES;
400 | GCC_OPTIMIZATION_LEVEL = 0;
401 | GCC_PREPROCESSOR_DEFINITIONS = (
402 | "DEBUG=1",
403 | "$(inherited)",
404 | _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION,
405 | );
406 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
407 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
408 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
409 | GCC_WARN_UNDECLARED_SELECTOR = YES;
410 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
411 | GCC_WARN_UNUSED_FUNCTION = YES;
412 | GCC_WARN_UNUSED_VARIABLE = YES;
413 | IPHONEOS_DEPLOYMENT_TARGET = 12.4;
414 | LD = "$(REACT_NATIVE_PATH)/scripts/xcode/ccache-clang.sh";
415 | LDPLUSPLUS = "$(REACT_NATIVE_PATH)/scripts/xcode/ccache-clang++.sh";
416 | LD_RUNPATH_SEARCH_PATHS = (
417 | /usr/lib/swift,
418 | "$(inherited)",
419 | );
420 | LIBRARY_SEARCH_PATHS = (
421 | "\"$(SDKROOT)/usr/lib/swift\"",
422 | "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
423 | "\"$(inherited)\"",
424 | );
425 | MTL_ENABLE_DEBUG_INFO = YES;
426 | ONLY_ACTIVE_ARCH = YES;
427 | OTHER_CFLAGS = "$(inherited)";
428 | OTHER_CPLUSPLUSFLAGS = (
429 | "$(OTHER_CFLAGS)",
430 | "-DFOLLY_NO_CONFIG",
431 | "-DFOLLY_MOBILE=1",
432 | "-DFOLLY_USE_LIBCPP=1",
433 | );
434 | OTHER_LDFLAGS = "$(inherited)";
435 | REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
436 | SDKROOT = iphoneos;
437 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
438 | USE_HERMES = true;
439 | };
440 | name = Debug;
441 | };
442 | 83CBBA211A601CBA00E9B192 /* Release */ = {
443 | isa = XCBuildConfiguration;
444 | buildSettings = {
445 | ALWAYS_SEARCH_USER_PATHS = NO;
446 | CC = "$(REACT_NATIVE_PATH)/scripts/xcode/ccache-clang.sh";
447 | CCACHE_BINARY = /opt/homebrew/bin/ccache;
448 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
449 | CLANG_CXX_LANGUAGE_STANDARD = "c++20";
450 | CLANG_CXX_LIBRARY = "libc++";
451 | CLANG_ENABLE_MODULES = YES;
452 | CLANG_ENABLE_OBJC_ARC = YES;
453 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
454 | CLANG_WARN_BOOL_CONVERSION = YES;
455 | CLANG_WARN_COMMA = YES;
456 | CLANG_WARN_CONSTANT_CONVERSION = YES;
457 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
458 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
459 | CLANG_WARN_EMPTY_BODY = YES;
460 | CLANG_WARN_ENUM_CONVERSION = YES;
461 | CLANG_WARN_INFINITE_RECURSION = YES;
462 | CLANG_WARN_INT_CONVERSION = YES;
463 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
464 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
465 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
466 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
467 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
468 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
469 | CLANG_WARN_STRICT_PROTOTYPES = YES;
470 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
471 | CLANG_WARN_UNREACHABLE_CODE = YES;
472 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
473 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
474 | COPY_PHASE_STRIP = YES;
475 | CXX = "$(REACT_NATIVE_PATH)/scripts/xcode/ccache-clang++.sh";
476 | ENABLE_NS_ASSERTIONS = NO;
477 | ENABLE_STRICT_OBJC_MSGSEND = YES;
478 | "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
479 | GCC_C_LANGUAGE_STANDARD = gnu99;
480 | GCC_NO_COMMON_BLOCKS = YES;
481 | GCC_PREPROCESSOR_DEFINITIONS = (
482 | "$(inherited)",
483 | _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION,
484 | );
485 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
486 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
487 | GCC_WARN_UNDECLARED_SELECTOR = YES;
488 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
489 | GCC_WARN_UNUSED_FUNCTION = YES;
490 | GCC_WARN_UNUSED_VARIABLE = YES;
491 | IPHONEOS_DEPLOYMENT_TARGET = 12.4;
492 | LD = "$(REACT_NATIVE_PATH)/scripts/xcode/ccache-clang.sh";
493 | LDPLUSPLUS = "$(REACT_NATIVE_PATH)/scripts/xcode/ccache-clang++.sh";
494 | LD_RUNPATH_SEARCH_PATHS = (
495 | /usr/lib/swift,
496 | "$(inherited)",
497 | );
498 | LIBRARY_SEARCH_PATHS = (
499 | "\"$(SDKROOT)/usr/lib/swift\"",
500 | "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
501 | "\"$(inherited)\"",
502 | );
503 | MTL_ENABLE_DEBUG_INFO = NO;
504 | OTHER_CFLAGS = "$(inherited)";
505 | OTHER_CPLUSPLUSFLAGS = (
506 | "$(OTHER_CFLAGS)",
507 | "-DFOLLY_NO_CONFIG",
508 | "-DFOLLY_MOBILE=1",
509 | "-DFOLLY_USE_LIBCPP=1",
510 | );
511 | OTHER_LDFLAGS = "$(inherited)";
512 | REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
513 | SDKROOT = iphoneos;
514 | USE_HERMES = true;
515 | VALIDATE_PRODUCT = YES;
516 | };
517 | name = Release;
518 | };
519 | /* End XCBuildConfiguration section */
520 |
521 | /* Begin XCConfigurationList section */
522 | 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "example" */ = {
523 | isa = XCConfigurationList;
524 | buildConfigurations = (
525 | 13B07F941A680F5B00A75B9A /* Debug */,
526 | 13B07F951A680F5B00A75B9A /* Release */,
527 | );
528 | defaultConfigurationIsVisible = 0;
529 | defaultConfigurationName = Release;
530 | };
531 | 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "example" */ = {
532 | isa = XCConfigurationList;
533 | buildConfigurations = (
534 | 83CBBA201A601CBA00E9B192 /* Debug */,
535 | 83CBBA211A601CBA00E9B192 /* Release */,
536 | );
537 | defaultConfigurationIsVisible = 0;
538 | defaultConfigurationName = Release;
539 | };
540 | /* End XCConfigurationList section */
541 | };
542 | rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
543 | }
544 |
--------------------------------------------------------------------------------
/example/ios/example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/example.xcodeproj/xcshareddata/xcschemes/example.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
54 |
56 |
62 |
63 |
64 |
65 |
71 |
73 |
79 |
80 |
81 |
82 |
84 |
85 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/example/ios/example.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/example/ios/example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/example/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import React
3 | import React_RCTAppDelegate
4 | import ReactAppDependencyProvider
5 |
6 | @main
7 | class AppDelegate: RCTAppDelegate {
8 | override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
9 | self.moduleName = "example"
10 | self.dependencyProvider = RCTAppDependencyProvider()
11 |
12 | // You can add your custom initial props in the dictionary below.
13 | // They will be passed down to the ViewController used by React Native.
14 | self.initialProps = [:]
15 |
16 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
17 | }
18 |
19 | override func sourceURL(for bridge: RCTBridge) -> URL? {
20 | self.bundleURL()
21 | }
22 |
23 | override func bundleURL() -> URL? {
24 | #if DEBUG
25 | RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
26 | #else
27 | Bundle.main.url(forResource: "main", withExtension: "jsbundle")
28 | #endif
29 | }
30 | }
--------------------------------------------------------------------------------
/example/ios/example/Images.xcassets/AppIcon.appiconset/CALICO.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calico-games/react-native-godot/3892f30db6e43715609562c6e50960613ecf0df9/example/ios/example/Images.xcassets/AppIcon.appiconset/CALICO.png
--------------------------------------------------------------------------------
/example/ios/example/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "CALICO.png",
5 | "idiom" : "universal",
6 | "platform" : "ios",
7 | "size" : "1024x1024"
8 | }
9 | ],
10 | "info" : {
11 | "author" : "xcode",
12 | "version" : 1
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/example/ios/example/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/example/ios/example/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CADisableMinimumFrameDurationOnPhone
6 |
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleDisplayName
10 | Godot Example
11 | CFBundleExecutable
12 | $(EXECUTABLE_NAME)
13 | CFBundleIdentifier
14 | $(PRODUCT_BUNDLE_IDENTIFIER)
15 | CFBundleInfoDictionaryVersion
16 | 6.0
17 | CFBundleName
18 | $(PRODUCT_NAME)
19 | CFBundlePackageType
20 | APPL
21 | CFBundleShortVersionString
22 | $(MARKETING_VERSION)
23 | CFBundleSignature
24 | ????
25 | CFBundleVersion
26 | $(CURRENT_PROJECT_VERSION)
27 | LSRequiresIPhoneOS
28 |
29 | NSAppTransportSecurity
30 |
31 | NSAllowsArbitraryLoads
32 |
33 |
34 | UIAppFonts
35 |
36 | UILaunchStoryboardName
37 | LaunchScreen
38 | UIRequiredDeviceCapabilities
39 |
40 | armv7
41 |
42 | UISupportedInterfaceOrientations
43 |
44 | UIInterfaceOrientationPortrait
45 | UIInterfaceOrientationLandscapeLeft
46 | UIInterfaceOrientationLandscapeRight
47 |
48 | UIViewControllerBasedStatusBarAppearance
49 |
50 | ITSAppUsesNonExemptEncryption
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/example/ios/example/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
24 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/example/ios/example/PrivacyInfo.xcprivacy:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSPrivacyAccessedAPITypes
6 |
7 |
8 | NSPrivacyAccessedAPIType
9 | NSPrivacyAccessedAPICategorySystemBootTime
10 | NSPrivacyAccessedAPITypeReasons
11 |
12 | 35F9.1
13 |
14 |
15 |
16 | NSPrivacyAccessedAPIType
17 | NSPrivacyAccessedAPICategoryUserDefaults
18 | NSPrivacyAccessedAPITypeReasons
19 |
20 | CA92.1
21 |
22 |
23 |
24 | NSPrivacyAccessedAPIType
25 | NSPrivacyAccessedAPICategoryFileTimestamp
26 | NSPrivacyAccessedAPITypeReasons
27 |
28 | C617.1
29 |
30 |
31 |
32 | NSPrivacyAccessedAPIType
33 | NSPrivacyAccessedAPICategoryDiskSpace
34 | NSPrivacyAccessedAPITypeReasons
35 |
36 | 85F4.1
37 |
38 |
39 |
40 | NSPrivacyCollectedDataTypes
41 |
42 | NSPrivacyTracking
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/example/ios/link-assets-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "migIndex": 1,
3 | "data": [
4 | {
5 | "path": "src/assets/cube.pck",
6 | "sha1": "e55b073942e0cb05956c49b976eee6716c833d41"
7 | },
8 | {
9 | "path": "src/assets/earth.pck",
10 | "sha1": "49cc7c2f10c2413a8c1d45199bc4904f4fdc783e"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/example/ios/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=5
10 |
11 | [application]
12 |
13 | boot_splash/bg_color=Color(0, 0, 0, 1)
14 | boot_splash/show_image=false
15 | config/icon="res://icon.png"
16 |
17 | [rendering]
18 |
19 | environment/defaults/default_clear_color=Color(0, 0, 0, 1)
--------------------------------------------------------------------------------
/example/metro.config.js:
--------------------------------------------------------------------------------
1 | // metro.config.js
2 | //
3 | // with multiple workarounds for this issue with symlinks:
4 | // https://github.com/facebook/metro/issues/1
5 | //
6 | // with thanks to @johnryan ()
7 | // for the pointers to multiple workaround solutions here:
8 | // https://github.com/facebook/metro/issues/1#issuecomment-541642857
9 | //
10 | // see also this discussion:
11 | // https://github.com/brodybits/create-react-native-module/issues/232
12 |
13 | const {getDefaultConfig} = require('@react-native/metro-config');
14 | const path = require('path');
15 | const {mergeConfig} = require('metro-config');
16 | const exclusionList = require('metro-config/src/defaults/exclusionList');
17 | const glob = require('glob-to-regexp');
18 |
19 | function getBlacklist() {
20 | const nodeModuleDirs = [
21 | glob(`${path.resolve(__dirname, '../package')}/node_modules/*`),
22 | ];
23 | return exclusionList(nodeModuleDirs);
24 | }
25 |
26 | const defaultConfig = getDefaultConfig(__dirname);
27 |
28 | const {
29 | resolver: {sourceExts, assetExts},
30 | } = defaultConfig;
31 |
32 | const config = {
33 | // workaround for an issue with symlinks encountered starting with
34 | // metro@0.55 / React Native 0.61
35 | // (not needed with React Native 0.60 / metro@0.54)
36 | resolver: {
37 | extraNodeModules: new Proxy(
38 | {},
39 | { get: (_, name) => path.resolve('.', 'node_modules', name) }
40 | ),
41 | // /dist\/.*/
42 | blacklistRE: getBlacklist(),
43 | // Treat `.pck` files as assets
44 | assetExts: [...assetExts, 'pck'],
45 | // Exclude `.pck` from being treated as source files
46 | sourceExts: sourceExts.filter(ext => ext !== 'pck'),
47 | },
48 |
49 | // quick workaround for another issue with symlinks
50 | watchFolders: [path.resolve('.'), path.resolve('../package')],
51 |
52 | transformer: {
53 | getTransformOptions: async () => ({
54 | transform: {
55 | experimentalImportSupport: false,
56 | inlineRequires: true,
57 | },
58 | }),
59 | },
60 |
61 | server: {
62 | enhanceMiddleware: (middleware) => {
63 | return (req, res, next) => {
64 | if (/\.pck/.test(req.url)) {
65 | res.setHeader('Content-Type', 'application/octet-stream');
66 | }
67 | return middleware(req, res, next);
68 | };
69 | },
70 | },
71 | };
72 |
73 | module.exports = mergeConfig(defaultConfig, config);
--------------------------------------------------------------------------------
/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "android": "react-native run-android",
7 | "ios": "react-native run-ios",
8 | "lint": "eslint .",
9 | "start": "react-native start",
10 | "asset": "npx react-native-asset",
11 | "pod-install": "cd ios && bundle exec pod install"
12 | },
13 | "dependencies": {
14 | "@react-navigation/native": "^7.1.5",
15 | "@react-navigation/native-stack": "^7.3.9",
16 | "@react-navigation/stack": "^7.2.9",
17 | "axios": "^1.8.4",
18 | "babel-plugin-module-resolver": "^5.0.2",
19 | "date-fns": "^4.1.0",
20 | "react": "19.0.0",
21 | "react-native": "0.78.1",
22 | "react-native-device-info": "^14.0.4",
23 | "react-native-gesture-handler": "^2.25.0",
24 | "react-native-godot": "link:../package/",
25 | "react-native-haptic-feedback": "^2.3.3",
26 | "react-native-reanimated": "^3.17.3",
27 | "react-native-safe-area-context": "^5.3.0",
28 | "react-native-screens": "^4.10.0",
29 | "react-native-sound": "^0.11.2"
30 | },
31 | "devDependencies": {
32 | "@babel/core": "^7.25.2",
33 | "@babel/plugin-proposal-decorators": "^7.25.9",
34 | "@babel/preset-env": "^7.25.3",
35 | "@babel/runtime": "^7.25.0",
36 | "@react-native-community/cli": "15.0.1",
37 | "@react-native-community/cli-platform-android": "15.0.1",
38 | "@react-native-community/cli-platform-ios": "15.0.1",
39 | "@react-native/babel-preset": "0.78.1",
40 | "@react-native/eslint-config": "0.78.1",
41 | "@react-native/metro-config": "0.78.1",
42 | "@react-native/typescript-config": "0.78.1",
43 | "@types/react": "^19.0.0",
44 | "babel-plugin-transform-remove-console": "^6.9.4",
45 | "eslint": "^9.23.0",
46 | "glob-to-regexp": "^0.4.1",
47 | "prettier": "3.5.3",
48 | "typescript": "5.0.4"
49 | },
50 | "engines": {
51 | "node": ">=18"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/example/react-native.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | project: {
3 | ios: {},
4 | android: {},
5 | },
6 | assets: ['./src/assets'],
7 | };
--------------------------------------------------------------------------------
/example/src/App.tsx:
--------------------------------------------------------------------------------
1 | import {JSX} from 'react';
2 | import {enableScreens} from 'react-native-screens';
3 | enableScreens(true);
4 |
5 | import Sound from 'react-native-sound';
6 | Sound.setCategory('Ambient', true);
7 |
8 | import Root from '@/Root';
9 |
10 | function App(): JSX.Element {
11 | return ;
12 | }
13 |
14 | export default App;
15 |
--------------------------------------------------------------------------------
/example/src/Root.tsx:
--------------------------------------------------------------------------------
1 | import {useEffect, useRef} from 'react';
2 | import {Platform, StatusBar, View, StyleSheet} from 'react-native';
3 | import {createStaticNavigation, NavigationContainerRef, ParamListBase} from '@react-navigation/native';
4 | import {createNativeStackNavigator} from '@react-navigation/native-stack';
5 | import {SafeAreaProvider} from 'react-native-safe-area-context';
6 | import {GestureHandlerRootView} from 'react-native-gesture-handler';
7 | import withPreventGoBack from '@/Utils/withPreventGoBack';
8 | import {Godot, GodotProvider, GodotView} from 'react-native-godot';
9 |
10 | import Home from '@/Screens/Home.tsx';
11 | import CubesExample from '@/Screens/CubesExample';
12 | import EarthExample from '@/Screens/EarthExample.tsx';
13 |
14 | const RootStack = createNativeStackNavigator({
15 | initialRouteName: 'Home',
16 | screenOptions: {
17 | presentation: 'card',
18 | headerStyle: {backgroundColor: 'transparent'},
19 | gestureEnabled: true,
20 | headerShown: false,
21 | },
22 | screens: {
23 | Home: {
24 | screen: withPreventGoBack(Home),
25 | options: {
26 | animation: 'slide_from_bottom',
27 | headerLargeTitle: true,
28 | },
29 | },
30 | CubesExample: {
31 | screen: CubesExample,
32 | options: {
33 | animation: 'slide_from_right',
34 | },
35 | },
36 | EarthExample: {
37 | screen: EarthExample,
38 | options: {
39 | animation: 'slide_from_right',
40 | },
41 | },
42 | },
43 | });
44 |
45 | const Navigation = createStaticNavigation(RootStack as any);
46 |
47 | const Root = () => {
48 | const navigationRef = useRef | undefined>(undefined);
49 | const routeNameRef = useRef(null);
50 | const testingNavigation = useRef(true);
51 |
52 | useEffect(() => {
53 | if (!GodotView) {
54 | return;
55 | }
56 | GodotView.startDrawing();
57 |
58 | return () => {
59 | GodotView.stopDrawing();
60 | }
61 | }, []);
62 |
63 | return (
64 |
65 |
66 |
67 |
68 | {Platform.OS === 'android' ? (
69 |
70 | ) : (
71 |
72 | )}
73 | {testingNavigation.current && (
74 | {
77 | const root = navigationRef.current?.getCurrentRoute();
78 |
79 | if (root) {
80 | routeNameRef.current = root.name;
81 | }
82 | }}
83 | onStateChange={async _state => {
84 | const previousRouteName = routeNameRef.current;
85 | const currentRouteName =
86 | navigationRef.current?.getCurrentRoute()?.name;
87 |
88 | if (previousRouteName !== currentRouteName) {
89 | console.log(
90 | `Route changed: ${previousRouteName} => ${currentRouteName}`,
91 | );
92 | }
93 | routeNameRef.current = currentRouteName || null;
94 | }}
95 | />
96 | )}
97 | {!testingNavigation.current && (
98 |
99 |
103 |
104 | )}
105 |
106 |
107 |
108 |
109 | );
110 | };
111 |
112 | const styles = StyleSheet.create({
113 | container: {
114 | flex: 1,
115 | },
116 | });
117 |
118 | export default Root;
119 |
--------------------------------------------------------------------------------
/example/src/Routes.tsx:
--------------------------------------------------------------------------------
1 | export type Routes = {
2 | Home: undefined;
3 | CubesExample: undefined;
4 | EarthExample: undefined;
5 | };
6 |
--------------------------------------------------------------------------------
/example/src/Screens/CubesExample.tsx:
--------------------------------------------------------------------------------
1 | import React, {useEffect} from 'react';
2 | import {StyleSheet, View} from 'react-native';
3 | import {Godot, GodotView} from 'react-native-godot';
4 | import {useNavigation} from '@react-navigation/native';
5 |
6 | const CubesExample: React.FC = _props => {
7 | const navigation = useNavigation();
8 |
9 | useEffect(() => {
10 | const unsubscribe = navigation.addListener('transitionStart', (e: any) => {
11 | if (e.data.closing) {
12 | GodotView.stopDrawing();
13 | }
14 | });
15 |
16 | return unsubscribe;
17 | }, [navigation]);
18 |
19 | useEffect(() => {
20 | const unsubscribe = navigation.addListener('transitionEnd', (e: any) => {
21 | if (!e.data.closing) {
22 | GodotView.startDrawing();
23 | }
24 | });
25 |
26 | return () => {
27 | unsubscribe();
28 | }
29 | }, [navigation]);
30 |
31 | useEffect(() => {
32 | const unsubscribe = navigation.addListener('gestureCancel', () => {
33 | GodotView.startDrawing();
34 | });
35 |
36 | return unsubscribe;
37 | }, [navigation]);
38 |
39 | return (
40 |
41 |
45 |
49 |
53 |
54 | );
55 | };
56 |
57 | const styles = StyleSheet.create({
58 | cube: {
59 | flex: 1,
60 | },
61 | });
62 |
63 | export default CubesExample;
64 |
--------------------------------------------------------------------------------
/example/src/Screens/EarthExample.tsx:
--------------------------------------------------------------------------------
1 | import React, {useCallback, useEffect, useRef, useState} from 'react';
2 | import {StyleSheet, View, Text, ActivityIndicator} from 'react-native';
3 | import {useNavigation} from '@react-navigation/native';
4 | import {Godot, GodotView, useGodot} from 'react-native-godot';
5 | import axios from 'axios';
6 | import RNReactNativeHapticFeedback from 'react-native-haptic-feedback';
7 | import SolarCalculator from '@/Utils/SolarCalculator';
8 | import {addHours, addMinutes} from 'date-fns';
9 | import { SafeAreaView } from 'react-native-safe-area-context';
10 |
11 | type Coordinates = {
12 | lat: number | null;
13 | lon: number | null;
14 | };
15 |
16 | const EarthExample: React.FC = _props => {
17 | const navigation = useNavigation();
18 |
19 | const earthRef = useRef(null);
20 |
21 | const coordinates = useRef({ lat: null, lon: null });
22 | const [country, setCountry] = useState('');
23 | const [sunrise, setSunrise] = useState(null);
24 | const [sunset, setSunset] = useState(null);
25 | const defaultTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
26 | const [timezone, setTimezone] = useState(defaultTimezone);
27 | const [currentDate, setCurrentDate] = useState(null);
28 | const offset = useRef(0);
29 |
30 | const {Vector3, Vector2, Quaternion, Transform3D} = useGodot();
31 |
32 | // Some examples
33 | useEffect(() => {
34 | const pos = Vector3(3, 0, 0);
35 | console.log('Position:', pos);
36 | pos.y = 5;
37 | console.log('New Position:', pos);
38 | console.log('Vector2:', Vector2(1, 1).normalized().isNormalized());
39 | console.log('Length:', Vector2(3, 1).length());
40 | console.log('Quaternion:', Quaternion(0, 0, 0, 1));
41 | console.log('Transform3D origin:', Transform3D().origin);
42 | console.log('Vector3 y:', Vector3(1, 2, 3).y);
43 | }, []);
44 |
45 | const isReady = earthRef.current?.isReady || false;
46 |
47 | useEffect(() => {
48 | if (!earthRef.current || !isReady) {
49 | return;
50 | }
51 |
52 | console.log('Earth is Ready!');
53 |
54 | const sun = earthRef.current?.getRoot()?.getNode('Sun');
55 | if (!sun) {
56 | return;
57 | }
58 |
59 | console.log('Sun node:', sun);
60 | // Call get_info method from the Godot script attached to the Sun node!!!
61 | // console.log(sun?.get_info());
62 | }, [isReady]);
63 |
64 | useEffect(() => {
65 | const unsubscribe = navigation.addListener('transitionStart', (e: any) => {
66 | if (e.data.closing) {
67 | GodotView.stopDrawing();
68 | }
69 | });
70 |
71 | return unsubscribe;
72 | }, [navigation]);
73 |
74 | useEffect(() => {
75 | const unsubscribe = navigation.addListener('transitionEnd', (e: any) => {
76 | if (!e.data.closing) {
77 | GodotView.startDrawing();
78 | }
79 | });
80 |
81 | return () => {
82 | unsubscribe();
83 | }
84 | }, [navigation]);
85 |
86 | useEffect(() => {
87 | const unsubscribe = navigation.addListener('gestureCancel', () => {
88 | GodotView.startDrawing();
89 | });
90 |
91 | return unsubscribe;
92 | }, [navigation]);
93 |
94 | const onMessage = useCallback((message: any) => {
95 | if (message.lat === undefined || message.lon === undefined) {
96 | return;
97 | }
98 |
99 | const newLat = Math.round(message.lat * 10000) / 10000;
100 | const newLon = Math.round(message.lon * 10000) / 10000;
101 |
102 | const oldLat = Math.round((coordinates.current.lat ?? 0) * 10000) / 10000;
103 | const oldLon = Math.round((coordinates.current.lon ?? 0) * 10000) / 10000;
104 |
105 | if (newLat === oldLat && newLon === oldLon) {
106 | return;
107 | }
108 |
109 | console.log('Message received:', message);
110 |
111 | RNReactNativeHapticFeedback.trigger('impactHeavy');
112 |
113 | setCurrentDate(null);
114 | setTimezone(null);
115 |
116 | coordinates.current = {
117 | lat: message.lat,
118 | lon: message.lon,
119 | };
120 | }, []);
121 |
122 | const letterToLetterEmoji = (letter: string) => {
123 | return String.fromCodePoint(letter.toLowerCase().charCodeAt(0) + 127365);
124 | };
125 |
126 | const countryCodeToFlagEmoji = (countryCode: string) => {
127 | return Array.from(countryCode).map(letterToLetterEmoji).join('');
128 | };
129 |
130 | const convertTZ = (date: Date, tzString: string) => {
131 | if (tzString === 'Asia/Kolkata') {
132 | tzString = 'Asia/Calcutta';
133 | }
134 |
135 | try {
136 | const result = date.toLocaleString('en-US', {timeZone: tzString, hour12: false}).replace(/,/g, "");
137 | const [month, day, year, hours, minutes, seconds] = (result.match(/\d+/g) || []) as number[];
138 | return new Date(Date.UTC(year, month - 1, day, hours, minutes, seconds));
139 | } catch (error) {
140 | console.log('Error converting timezone:', error);
141 | return date;
142 | }
143 | }
144 |
145 | const convertDate = (date: Date, tz: string) => {
146 | const timezoneDate = convertTZ(date, tz);
147 | return addHours(timezoneDate, date.getTimezoneOffset() / 60);
148 | };
149 |
150 | const computeSolarData = useCallback((tz: string) => {
151 | let utc = new Date();
152 | utc.setMilliseconds(0);
153 | utc = addMinutes(utc, offset.current);
154 | offset.current += 0;
155 |
156 | setCurrentDate(convertDate(utc, tz));
157 |
158 | const coords = coordinates.current;
159 | if (!coords.lat || !coords.lon) {
160 | return;
161 | }
162 | const solarData = SolarCalculator(utc, coords.lat, coords.lon);
163 | setSunrise(convertDate(solarData.sunrise, tz));
164 | setSunset(convertDate(solarData.sunset, tz));
165 |
166 | const message = {
167 | latitude: solarData.subsolarLatitude + 1,
168 | longitude: solarData.subsolarLongitude - 15, // Why -15?
169 | };
170 |
171 | earthRef.current?.emitMessage(message);
172 | }, [earthRef.current, timezone]);
173 |
174 | useEffect(() => {
175 | const coords = coordinates.current;
176 | if (!coords.lat || !coords.lon) {
177 | return;
178 | }
179 |
180 | // Don't use this token in your app, it's for testing purposes only 😅
181 | const accessToken =
182 | 'pk.eyJ1IjoibXVnZWViIiwiYSI6ImNsZndnMWptdzBncHozYnM2Zzh3OXhnaDAifQ.LXTzWjHgMWiiyYppgQSwWQ';
183 | const lat = coords.lat.toFixed(4);
184 | const lon = coords.lon.toFixed(4);
185 |
186 | async function getCountryInfo() {
187 | try {
188 | const url = `https://api.mapbox.com/search/geocode/v6/reverse?longitude=${lon}&latitude=${lat}&types=country&access_token=${accessToken}`;
189 |
190 | const resp = await axios.get(url);
191 | const data = resp.data;
192 |
193 | const feature = data?.features?.[0];
194 | const countryContext = feature?.properties?.context?.country;
195 |
196 | const countryCode = countryContext?.country_code;
197 |
198 | if (!countryCode) {
199 | setCountry('');
200 | return;
201 | }
202 |
203 | const countryName = countryContext?.name || 'Unknown';
204 | const emoji = countryCodeToFlagEmoji(countryCode);
205 | setCountry(`${countryName} ${emoji}`);
206 | } catch (error) {}
207 | }
208 |
209 | async function getTimezone() {
210 | try {
211 | const url = `https://api.mapbox.com/v4/examples.4ze9z6tv/tilequery/${lon},${lat}.json?access_token=${accessToken}`;
212 |
213 | const resp = await axios.get(url);
214 | const data = resp.data;
215 |
216 | const feature = data?.features?.[0];
217 | const timezone = feature?.properties?.TZID;
218 |
219 | if (!timezone) {
220 | setTimezone(null);
221 | return;
222 | }
223 |
224 | setTimezone(timezone);
225 | computeSolarData(timezone);
226 | } catch (error) {
227 | console.error('Error getting timezone:', error);
228 | }
229 | }
230 |
231 | getCountryInfo();
232 | getTimezone();
233 | }, [coordinates.current]);
234 |
235 | useEffect(() => {
236 | const interval = setInterval(() => {
237 | if (timezone) {
238 | computeSolarData(timezone);
239 | }
240 | }, 1000);
241 |
242 | return () => clearInterval(interval);
243 | }, [timezone, computeSolarData]);
244 |
245 | const formatTime = (date: Date, displaySeconds: boolean = false) => {
246 | if (displaySeconds) {
247 | return date
248 | .toLocaleTimeString([], {hour: '2-digit', minute: '2-digit', second: '2-digit'})
249 | .toLowerCase();
250 | }
251 |
252 | return date
253 | .toLocaleTimeString([], {hour: '2-digit', minute: '2-digit'})
254 | .toLowerCase();
255 | }
256 |
257 | return (
258 |
259 |
266 |
267 | {country ? country : ''}
268 | {country && (<>
269 | {currentDate ? formatTime(currentDate, true) : 'Loading...'}
270 | 🌅 {sunrise && timezone ? formatTime(sunrise) : '00:00'}
271 | 🌃 {sunset && timezone ? formatTime(sunset) : '00:00'}
272 | >)}
273 |
274 | {!isReady && (
275 |
276 |
277 |
278 | )}
279 |
280 | );
281 | };
282 |
283 | const styles = StyleSheet.create({
284 | container: {
285 | flex: 1,
286 | backgroundColor: 'black',
287 | },
288 | earth: {
289 | flex: 1,
290 | },
291 | countryInfo: {
292 | position: 'absolute',
293 | top: 0,
294 | left: 0,
295 | padding: 20,
296 | paddingRight: 20,
297 | },
298 | countryName: {
299 | color: 'white',
300 | fontSize: 40,
301 | marginBottom: 10,
302 | paddingRight: 20,
303 | },
304 | time: {
305 | color: 'white',
306 | fontSize: 26,
307 | marginTop: 2,
308 | },
309 | loading: {
310 | position: 'absolute',
311 | top: 0,
312 | left: 0,
313 | right: 0,
314 | bottom: 0,
315 | justifyContent: 'center',
316 | alignItems: 'center',
317 | backgroundColor: 'rgb(20, 20, 20)',
318 | },
319 | });
320 |
321 | export default EarthExample;
322 |
--------------------------------------------------------------------------------
/example/src/Screens/Home.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import {ScrollView, StyleSheet, Text, View} from 'react-native';
3 | import {useNavigation} from '@react-navigation/native';
4 | import {RectButton} from 'react-native-gesture-handler';
5 | import type {NativeStackNavigationProp} from '@react-navigation/native-stack';
6 |
7 | import type {Routes} from '@/Routes';
8 | import { GodotView } from 'react-native-godot';
9 |
10 | export const examples = [
11 | {
12 | screen: 'CubesExample',
13 | title: '🔢 Cubes',
14 | },
15 | {
16 | screen: 'EarthExample',
17 | title: '🌎 Earth',
18 | },
19 | ] as const;
20 |
21 | const Home: React.FC = _props => {
22 | const {navigate} = useNavigation>();
23 |
24 | const onPress = React.useCallback((screen: any) => {
25 | // Do not wait for the transition to finish to start drawing
26 | GodotView.startDrawing();
27 | navigate(screen);
28 | }, [navigate]);
29 |
30 | return (
31 |
35 | {examples.map(thumbnail => (
36 | onPress(thumbnail.screen)}>
39 |
40 | {thumbnail.title}
41 | ➡️
42 |
43 |
44 | ))}
45 |
46 | );
47 | };
48 |
49 | const styles = StyleSheet.create({
50 | container: {
51 | backgroundColor: '#ebf5f7',
52 | },
53 | content: {
54 | paddingBottom: 100,
55 | backgroundColor: 'clear',
56 | },
57 | thumbnail: {
58 | backgroundColor: 'white',
59 | padding: 20,
60 | borderBottomWidth: 2,
61 | borderColor: '#afc8e0',
62 | flexDirection: 'row',
63 | justifyContent: 'space-between',
64 | alignItems: 'center',
65 | },
66 | title: {
67 | fontSize: 24,
68 | fontWeight: 'bold',
69 | },
70 | arrow: {
71 | fontSize: 32,
72 | },
73 | });
74 |
75 | export default Home;
76 |
--------------------------------------------------------------------------------
/example/src/Utils/SolarCalculator.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Sources:
3 | * https://gml.noaa.gov/grad/solcalc/
4 | * https://github.com/NASAWorldWind/WebWorldWind/blob/develop/src/util/SunPosition.js
5 | * https://github.com/arcticio/weather-simulation/blob/master/scripts/libs/orb2/solarsystem_v2r1.js
6 | * https://worldwind.earth/explorer/
7 | * https://www.timeanddate.com/scripts/sunmap.php
8 | *
9 | * @param {Date} utcDate
10 | * @param {Number} lat
11 | * @param {Number} lng
12 | * @returns {undefined}
13 | */
14 |
15 | const SolarCalculator = (utcDate: Date, lat: number, lng: number) => {
16 |
17 | /**
18 | * Returns the angle in the range 0 to 360
19 | * @param {Number} angle
20 | * @returns {Number}
21 | */
22 | const roundAngle = (angle: number) => {
23 | if (angle > 360){
24 | angle = angle % 360;
25 | } else if (angle < 0) {
26 | angle = angle % 360 + 360;
27 | } else {
28 | angle = angle;
29 | }
30 |
31 | return angle;
32 | }
33 |
34 | const normalizedDegreesLongitude = (degrees: number) => {
35 | const lon = degrees % 360;
36 |
37 | return lon > 180 ? lon - 360 : lon < -180 ? 360 + lon : lon;
38 | }
39 |
40 | /**
41 | *
42 | * @param {Number} jd
43 | * @returns {Number}
44 | */
45 | const calcTimeJulianCent = (jd: number) => {
46 | const t = (jd - 2451545.0) / 36525.0;
47 |
48 | return t;
49 | };
50 |
51 | /**
52 | *
53 | * @param {Number} t
54 | * @returns {Number}
55 | */
56 | const calcJDFromJulianCent = (t: number) => {
57 | const jd = t * 36525 + 2451545;
58 |
59 | return jd;
60 | };
61 |
62 | /**
63 | *
64 | * @param {Number} yr
65 | * @returns {Boolean}
66 | */
67 | const isLeapYear = (yr: number) => {
68 | return ((yr % 4 == 0 && yr % 100 != 0) || yr % 400 == 0);
69 | };
70 |
71 | /**
72 | *
73 | * @param {Number} jd
74 | * @returns {Number}
75 | */
76 | const calcDoyFromJD = (jd: number) => {
77 | const z = Math.floor(jd + 0.5);
78 | const f = (jd + 0.5) - z;
79 |
80 | let A;
81 | if (z < 2299161) {
82 | A = z;
83 | } else {
84 | const alpha = Math.floor((z - 1867216.25) / 36524.25);
85 | A = z + 1 + alpha - Math.floor(alpha / 4);
86 | }
87 |
88 | const B = A + 1524;
89 | const C = Math.floor((B - 122.1) / 365.25);
90 | const D = Math.floor(365.25 * C);
91 | const E = Math.floor((B - D) / 30.6001);
92 | const day = B - D - Math.floor(30.6001 * E) + f;
93 | const month = (E < 14) ? E - 1 : E - 13;
94 | const year = (month > 2) ? C - 4716 : C - 4715;
95 |
96 | const k = (isLeapYear(year) ? 1 : 2);
97 | const doy = Math.floor((275 * month) / 9) - k * Math.floor((month + 9) / 12) + day - 30;
98 |
99 | return doy;
100 | };
101 |
102 | /**
103 | * Converts an angle in radians to degrees
104 | * @param {Number} angleRad
105 | * @returns {Number}
106 | */
107 | const radToDeg = (angleRad: number) => {
108 | return (180.0 * angleRad / Math.PI);
109 | };
110 |
111 | /**
112 | * Converts an angle in degrees to radians
113 | * @param {Number} angleDeg
114 | * @returns {Number}
115 | */
116 | const degToRad = (angleDeg: number) => {
117 | return (Math.PI * angleDeg / 180.0);
118 | };
119 |
120 | /**
121 | * Returns the geometric mean longitude of the Sun in degrees
122 | * @param {Number} t
123 | * @returns {Number}
124 | */
125 | const calcGeometricMeanLongitudeSun = (t: number) => {
126 | let longitude = 280.46646 + 36000.76983 * t + 0.0003032 * t * t;
127 | return roundAngle(longitude);
128 | };
129 |
130 | /**
131 | * Returns the mean anomaly of the Sun
132 | * @param {Number} t
133 | * @returns {Number}
134 | */
135 | const calcGeomMeanAnomalySun = (t: number) => {
136 | var M = 357.52911 + t * (35999.05029 - 0.0001537 * t);
137 | return M; // in degrees
138 | };
139 |
140 | /**
141 | * Returns the eccentricity of the Earth's orbit
142 | * @param {Number} t
143 | * @returns {Number}
144 | */
145 | const calcEccentricityEarthOrbit = (t: number) => {
146 | const eccentricity = 0.016708634 - t * (0.000042037 + 0.0000001267 * t);
147 | return eccentricity; // unitless
148 | };
149 |
150 | /**
151 | * Returns the Sun's equation of center in degrees
152 | * @param {Number} Julian date century
153 | * @returns {Number} degrees
154 | */
155 | const calcSunEquationOfCenter = (t: number) => {
156 | const meanAnomaly = calcGeomMeanAnomalySun(t);
157 | const meanRad = degToRad(meanAnomaly);
158 | const sinm = Math.sin(meanRad);
159 | const sin2m = Math.sin(meanRad + meanRad);
160 | const sin3m = Math.sin(meanRad + meanRad + meanRad);
161 |
162 | // Sun's equation of the center
163 | const equation = sinm * (1.914602 - t * (0.004817 + 0.000014 * t)) + sin2m * (0.019993 - 0.000101 * t) + sin3m * 0.000289;
164 | return equation; // in degrees
165 | };
166 |
167 | /**
168 | * Returns the true longitude of the Sun in degrees
169 | * @param {Number} t
170 | * @returns {Number}
171 | */
172 | const calcSunTrueLongitude = (t: number) => {
173 | const meanLongitude = calcGeometricMeanLongitudeSun(t);
174 | const equation = calcSunEquationOfCenter(t);
175 | const trueLongitude = meanLongitude + equation;
176 |
177 | return trueLongitude;
178 | };
179 |
180 | /**
181 | * Returns the apparent longitude of the Sun in degrees
182 | * @param {Number} t
183 | * @returns {Number}
184 | */
185 | const calcSunApparentLongitude = (t: number) => {
186 | const trueLongitude = calcSunTrueLongitude(t);
187 | // TODO: seenms the omega is not completly precise (https://github.com/arcticio/weather-simulation/blob/master/scripts/libs/orb2/solarsystem_v2r1.js#L21)
188 | const omega = 125.04452 - 1934.136261 * t;
189 | const lambda = trueLongitude - 0.00569 - 0.00478 * Math.sin(degToRad(omega));
190 |
191 | return lambda;
192 | };
193 |
194 | /**
195 | * Returns the mean obliquity of the ecliptic in degrees
196 | * @param {Number} t
197 | * @returns {Number}
198 | */
199 | const calcMeanObliquityOfEcliptic = (t: number) => {
200 | const seconds = 21.448 - t * (46.8150 + t * (0.00059 - t * (0.001813)));
201 | const e0 = 23.0 + (26.0 + (seconds / 60.0)) / 60.0;
202 |
203 | return e0;
204 | };
205 |
206 | /**
207 | *
208 | * @param {Number} t
209 | * @returns {Number} degrees
210 | */
211 | const calcObliquityCorrection = (t: number) => {
212 | const meanObliquity = calcMeanObliquityOfEcliptic(t);
213 | const omega = 125.04 - 1934.136 * t;
214 | var e = meanObliquity + 0.00256 * Math.cos(degToRad(omega));
215 | return e; // in degrees
216 | };
217 |
218 | /**
219 | * Returns the Sun's right ascension in degrees
220 | * @param {Number} t
221 | * @returns {Number} degrees
222 | */
223 | const calcSunRightAscension = (t: number) => {
224 | const obliquity = calcObliquityCorrection(t);
225 | const longitude = calcSunApparentLongitude(t);
226 | const tananum = Math.cos(degToRad(obliquity)) * Math.sin(degToRad(longitude));
227 | const tanadenom = Math.cos(degToRad(longitude));
228 | const ascension = radToDeg(Math.atan2(tananum, tanadenom));
229 |
230 | return roundAngle(ascension);
231 | };
232 |
233 | /**
234 | * Returns the Sun's declination in degrees
235 | * @param {Number} t Julian date century
236 | * @returns {Number} degrees
237 | */
238 | const calcSunDeclination = (t: number) => {
239 | const obliquity = calcObliquityCorrection(t);
240 | const apparentLongitude = calcSunApparentLongitude(t);
241 |
242 | const sint = Math.sin(degToRad(obliquity)) * Math.sin(degToRad(apparentLongitude));
243 | const theta = radToDeg(Math.asin(sint));
244 | return theta;
245 | };
246 |
247 | /**
248 | * Computes the equation of time.
249 | * @param {Number} t
250 | * @returns {Number} minutes
251 | */
252 | const calcEquationOfTime = (t: number) => {
253 | var epsilon = calcObliquityCorrection(t);
254 | var meanLongitude = calcGeometricMeanLongitudeSun(t);
255 | const eccentricity = calcEccentricityEarthOrbit(t);
256 | const meanAnomaly = calcGeomMeanAnomalySun(t);
257 |
258 | var y = Math.tan(degToRad(epsilon) / 2.0);
259 | y *= y;
260 |
261 | var sin2l0 = Math.sin(2.0 * degToRad(meanLongitude));
262 | var sinm = Math.sin(degToRad(meanAnomaly));
263 | var cos2l0 = Math.cos(2.0 * degToRad(meanLongitude));
264 | var sin4l0 = Math.sin(4.0 * degToRad(meanLongitude));
265 | var sin2m = Math.sin(2.0 * degToRad(meanAnomaly));
266 |
267 | var Etime = y * sin2l0 - 2.0 * eccentricity * sinm + 4.0 * eccentricity * y * sinm * cos2l0 - 0.5 * y * y * sin4l0 - 1.25 * eccentricity * eccentricity * sin2m;
268 | return radToDeg(Etime) * 4.0; // in minutes of time
269 | };
270 |
271 | /**
272 | * Returns the hour angle [radians] at sunrise; negate teh value for sunset.
273 | * @param {Number} lat Observer latitude
274 | * @param {Number} solarDec Declination
275 | * @returns {Number} radians
276 | */
277 | const calcHourAngleSunrise = (lat: number, solarDec: number) => {
278 | var latRad = degToRad(lat);
279 | var sdRad = degToRad(solarDec);
280 | var HAarg = (Math.cos(degToRad(90.833)) / (Math.cos(latRad) * Math.cos(sdRad)) - Math.tan(latRad) * Math.tan(sdRad));
281 | var HA = Math.acos(HAarg);
282 | return HA; // in radians (for sunset, use -HA)
283 | };
284 |
285 | /**
286 | *
287 | * @param {Object} inputVal
288 | * @returns {Boolean}
289 | */
290 | const isNumber = (inputVal: any) => {
291 | var oneDecimal = false;
292 | var inputStr = "" + inputVal;
293 | for (var i = 0; i < inputStr.length; i++) {
294 | var oneChar = inputStr.charAt(i);
295 | if (i == 0 && (oneChar == "-" || oneChar == "+")) {
296 | continue;
297 | }
298 | if (oneChar == "." && !oneDecimal) {
299 | oneDecimal = true;
300 | continue;
301 | }
302 | if (oneChar < "0" || oneChar > "9") {
303 | return false;
304 | }
305 | }
306 | return true;
307 | }
308 |
309 | /**
310 | * Computes the Julian day for the given Jajascript date
311 | * @param {Date} date
312 | * @returns {Number} The julian day
313 | */
314 | const computeJulianDay = (date: Date) => {
315 | let year = date.getUTCFullYear();
316 | // Convert from zero-based month
317 | let month = date.getUTCMonth() + 1;
318 | const day = date.getUTCDate();
319 |
320 | if (month <= 2) {
321 | year -= 1;
322 | month += 12;
323 | }
324 |
325 | const A = Math.floor(year / 100);
326 | const B = 2 - A + Math.floor(A / 4);
327 | const JD0h = Math.floor(365.25 * (year + 4716)) + Math.floor(30.6001 * (month + 1)) + day + B - 1524.5;
328 |
329 | return JD0h;
330 | };
331 |
332 | /**
333 | * Computes the fractional minutes for the given date
334 | * @param {Date} date
335 | * @returns {Number} The fractional minutes
336 | */
337 | const getFractionalMinutes = (date: Date) => {
338 | const hour = date.getUTCHours();
339 | const minute = date.getUTCMinutes();
340 | const second = date.getUTCSeconds();
341 |
342 | const mins = hour * 60 + minute + second / 60.0;
343 | return mins;
344 | };
345 |
346 | /**
347 | * Calculates the azimuth and elevation of the sun for the given
348 | * observer location and time.
349 | * @param {Number} t
350 | * @param {Number} timeLocal
351 | * @param {Number} latitude
352 | * @param {Number} longitude
353 | * @param {Number} zone
354 | * @returns {Number}
355 | */
356 | const calcSunLatLon = (t: number) => {
357 | const latitude = calcSunDeclination(t);
358 | const rightAscension = calcSunRightAscension(t);
359 | const jday = calcJDFromJulianCent(t);
360 | // Number of days (positive or negative) since Greenwich noon, Terrestrial Time, on 1 January 2000 (J2000.0)
361 | const elapsedJulianDays = jday - 2451545;
362 | const greenwichMeanSiderealTime = roundAngle(280.46061837 + 360.98564736629 * elapsedJulianDays);
363 | let longitude = normalizedDegreesLongitude(greenwichMeanSiderealTime - rightAscension); // TODO: Why -90?
364 |
365 | return {
366 | latitude: latitude,
367 | longitude: longitude,
368 | };
369 | };
370 |
371 | /**
372 | *
373 | * @param {Boolean} rise
374 | * @param {Number} jday
375 | * @param {Number} latitude
376 | * @param {Number} longitude
377 | * @returns {Number} The time of sunrise or sunset in minutes
378 | */
379 | const calcSunriseSetUTC = (rise: boolean, jday: number, latitude: number, longitude: number) => {
380 | const t = calcTimeJulianCent(jday);
381 | const eqTime = calcEquationOfTime(t);
382 | const solarDec = calcSunDeclination(t);
383 | let hourAngle = calcHourAngleSunrise(latitude, solarDec);
384 | if (!rise)
385 | hourAngle = -hourAngle;
386 | const delta = longitude + radToDeg(hourAngle);
387 | const timeUTC = 720 - (4.0 * delta) - eqTime; // in minutes
388 |
389 | return timeUTC;
390 | };
391 |
392 | /**
393 | * Calculate the time of sunrise or sunset for the given observer location and date.
394 | * @param {Boolean} rise true for sunrise, false for sunset
395 | * @param {Number} jday
396 | * @param {Number} latitude
397 | * @param {Number} longitude
398 | * @param {Number} timezone
399 | * @returns {Number} The time of sunrise or sunset in minutes
400 | */
401 | const calcSunriseSet = (rise: boolean, jday: number, latitude: number, longitude: number, timezone: number) => {
402 | var timeUTC = calcSunriseSetUTC(rise, jday, latitude, longitude);
403 | var newTimeUTC = calcSunriseSetUTC(rise, jday + timeUTC/1440.0, latitude, longitude);
404 | let timeLocal = 0.0;
405 |
406 | if (isNumber(newTimeUTC)) {
407 | timeLocal = newTimeUTC + (timezone * 60.0);
408 |
409 | if (timeLocal < 0.0 || timeLocal >= 1440.0) {
410 | var increment = ((timeLocal < 0) ? 1 : -1)
411 | while ((timeLocal < 0.0)||(timeLocal >= 1440.0)) {
412 | timeLocal += increment * 1440.0;
413 | jday -= increment;
414 | }
415 | }
416 | } else { // No sunrise/set found
417 | var doy = calcDoyFromJD(jday)
418 | if (((latitude > 66.4) && (doy > 79) && (doy < 267)) ||
419 | ((latitude < -66.4) && ((doy < 83) || (doy > 263)))) {
420 | // previous sunrise/next sunset
421 | jday = calcJDofNextPrevRiseSet(!rise, rise, jday, latitude, longitude, timezone)
422 | } else { //previous sunset/next sunrise
423 | jday = calcJDofNextPrevRiseSet(rise, rise, jday, latitude, longitude, timezone)
424 | }
425 | }
426 |
427 | return timeLocal
428 | };
429 |
430 | /**
431 | * Calculate the Julian date of the next or previous sunrise or sunset.
432 | * @param {Boolean} next
433 | * @param {Number} rise
434 | * @param {Number} jday
435 | * @param {Number} latitude
436 | * @param {Number} longitude
437 | * @param {Number} tz
438 | * @returns {Number}
439 | */
440 | const calcJDofNextPrevRiseSet = (next: boolean, rise: boolean, jday: number, latitude: number, longitude: number, tz: number) => {
441 | const increment = next ? 1.0 : -1.0;
442 | let time = calcSunriseSetUTC(rise, jday, latitude, longitude);
443 |
444 | while(!isNumber(time)) {
445 | jday += increment;
446 | time = calcSunriseSetUTC(rise, jday, latitude, longitude);
447 | }
448 | var timeLocal = time + tz * 60.0
449 | while ((timeLocal < 0.0) || (timeLocal >= 1440.0)) {
450 | var incr = ((timeLocal < 0) ? 1 : -1)
451 | timeLocal += (incr * 1440.0)
452 | jday -= incr
453 | }
454 |
455 | return jday;
456 | };
457 |
458 | /*********************/
459 |
460 | const tz = -utcDate.getTimezoneOffset() / 60;
461 | const jday = computeJulianDay(utcDate);
462 | const fractionalMinutes = getFractionalMinutes(utcDate);
463 | const julianDate = jday + fractionalMinutes / 1440.0 - tz / 24.0;
464 | const t = calcTimeJulianCent(julianDate);
465 | const sunLatLon = calcSunLatLon(t);
466 | const sunriseTimeOffset = calcSunriseSet(true, jday, lat, lng, tz);
467 | const sunsetTimeOffset = calcSunriseSet(false, jday, lat, lng, tz);
468 | const midnight = new Date(utcDate.getUTCFullYear(), utcDate.getUTCMonth(), utcDate.getUTCDate());
469 | const sunriseTime = new Date(midnight.getTime() + sunriseTimeOffset * 60000);
470 | const sunsetTime = new Date(midnight.getTime() + sunsetTimeOffset * 60000);
471 |
472 | return {
473 | lat: lat,
474 | lng: lng,
475 | sunrise: sunriseTime,
476 | sunset: sunsetTime,
477 | subsolarLatitude: sunLatLon.latitude,
478 | subsolarLongitude: sunLatLon.longitude,
479 | };
480 | };
481 |
482 | export default SolarCalculator;
--------------------------------------------------------------------------------
/example/src/Utils/withPreventGoBack.tsx:
--------------------------------------------------------------------------------
1 | import {useEffect} from 'react';
2 | import {BackHandler, NativeEventSubscription} from 'react-native';
3 | import {useIsFocused} from '@react-navigation/native';
4 |
5 | // Prevent the user from going back to the previous screen
6 | const withPreventGoBack = (WrappedComponent: any) => {
7 | const PreventGoBackComponent = (props: any) => {
8 | const isFocused = useIsFocused();
9 |
10 | useEffect(() => {
11 | let backHandler: NativeEventSubscription;
12 |
13 | backHandler = BackHandler.addEventListener('hardwareBackPress', () => {
14 | if (!isFocused) {
15 | return false;
16 | }
17 |
18 | BackHandler.exitApp();
19 | console.log('Prevented going back');
20 | return true;
21 | });
22 |
23 | return () => {
24 | backHandler ? backHandler.remove() : null;
25 | };
26 | }, [isFocused]);
27 |
28 | return ;
29 | };
30 |
31 | return PreventGoBackComponent;
32 | };
33 |
34 | export default withPreventGoBack;
35 |
--------------------------------------------------------------------------------
/example/src/assets/cube.pck:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calico-games/react-native-godot/3892f30db6e43715609562c6e50960613ecf0df9/example/src/assets/cube.pck
--------------------------------------------------------------------------------
/example/src/assets/earth.pck:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calico-games/react-native-godot/3892f30db6e43715609562c6e50960613ecf0df9/example/src/assets/earth.pck
--------------------------------------------------------------------------------
/example/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "esModuleInterop": true,
8 | "allowSyntheticDefaultImports": true,
9 | "strict": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "noFallthroughCasesInSwitch": true,
12 | "module": "esnext",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "noImplicitAny": true,
16 | "noEmit": true,
17 | "jsx": "react-jsx",
18 | "baseUrl": ".",
19 | "paths": {
20 | "@/*": ["./src/*"],
21 | "react": ["react-native/node_modules/@types/react"]
22 | }
23 | },
24 | "include": ["src"],
25 | "extends": "@react-native/typescript-config/tsconfig.json"
26 | }
--------------------------------------------------------------------------------
/export_presets.cfg:
--------------------------------------------------------------------------------
1 | [preset.0]
2 |
3 | name="main"
4 | platform="iOS"
5 | runnable=true
6 | advanced_options=false
7 | dedicated_server=false
8 | custom_features=""
9 | export_filter=""
10 | include_filter="project.godot"
11 | exclude_filter=""
12 | export_path=""
13 | encryption_include_filters=""
14 | encryption_exclude_filters=""
15 | encrypt_pck=false
16 | encrypt_directory=false
17 | script_export_mode=2
18 |
19 | [preset.0.options]
20 |
21 | export/distribution_type=1
22 | binary_format/architecture="universal"
23 | binary_format/embed_pck=false
24 | custom_template/debug=""
25 | custom_template/release=""
26 | debug/export_console_wrapper=0
27 | display/high_res=true
28 |
--------------------------------------------------------------------------------
/gen-pck.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set -eux
4 |
5 | PROJECT_DIR=$@
6 | CURRENT_DIR=$(pwd)
7 |
8 | cp -r $PROJECT_DIR $PROJECT_DIR-export
9 | cd $PROJECT_DIR-export
10 |
11 | /Applications/Godot.app/Contents/MacOS/Godot --headless --export-pack "main" main.pck
12 |
13 | PROJECT_NAME=$(basename $PROJECT_DIR)
14 |
15 | mv main.pck $CURRENT_DIR/$PROJECT_NAME.pck
16 |
17 | cd $CURRENT_DIR
18 | rm -rf $PROJECT_DIR-export
--------------------------------------------------------------------------------
/package/.gitignore:
--------------------------------------------------------------------------------
1 | # Prebuilt static binaries from filament
2 | *.a
3 | *.so
4 |
5 | # OSX
6 | #
7 | .DS_Store
8 |
9 | # XDE
10 | .expo/
11 |
12 | # VSCode
13 | .vscode/
14 | jsconfig.json
15 |
16 | # Xcode
17 | #
18 | build/
19 | *.pbxuser
20 | !default.pbxuser
21 | *.mode1v3
22 | !default.mode1v3
23 | *.mode2v3
24 | !default.mode2v3
25 | *.perspectivev3
26 | !default.perspectivev3
27 | xcuserdata
28 | *.xccheckout
29 | *.moved-aside
30 | DerivedData
31 | *.hmap
32 | *.ipa
33 | *.xcuserstate
34 | RNFFabric.xcworkspace
35 | .xcode.env.local
36 |
37 | # Android/IJ
38 | #
39 | .classpath
40 | .cxx
41 | .gradle
42 | .idea
43 | .project
44 | .settings
45 | local.properties
46 | android.iml
47 |
48 | # Cocoapods
49 | #
50 | example/ios/Pods
51 |
52 | # Ruby
53 | example/vendor/
54 |
55 | # node.js
56 | #
57 | node_modules/
58 | npm-debug.log
59 | yarn-debug.log
60 | yarn-error.log
61 |
62 | # BUCK
63 | buck-out/
64 | \.buckd/
65 | android/app/libs
66 | android/keystores/debug.keystore
67 |
68 | # Yarn
69 | .yarn/*
70 | !.yarn/patches
71 | !.yarn/plugins
72 | !.yarn/releases
73 | !.yarn/sdks
74 | !.yarn/versions
75 |
76 | # Expo
77 | .expo/
78 |
79 | # Turborepo
80 | .turbo/
81 |
82 | # generated by bob
83 | lib/
84 |
85 | # Ignore bullet3 library code
86 | android/libs/bullet3
87 | ios/libs/bullet3
88 |
89 | # Yarn
90 | .yarn/*
91 | !.yarn/patches
92 | !.yarn/plugins
93 | !.yarn/releases
94 | !.yarn/sdks
95 | !.yarn/versions
--------------------------------------------------------------------------------
/package/android/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | ios/.xcode.env.local
24 |
25 | # Android/IntelliJ
26 | #
27 | build/
28 | .idea
29 | .gradle
30 | local.properties
31 | *.iml
32 | *.hprof
33 | .cxx/
34 | *.keystore
35 | !debug.keystore
36 |
37 | # node.js
38 | #
39 | node_modules/
40 | npm-debug.log
41 | yarn-error.log
42 |
43 | # fastlane
44 | #
45 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
46 | # screenshots whenever they are needed.
47 | # For more information about the recommended setup visit:
48 | # https://docs.fastlane.tools/best-practices/source-control/
49 |
50 | **/fastlane/report.xml
51 | **/fastlane/Preview.html
52 | **/fastlane/screenshots
53 | **/fastlane/test_output
54 |
55 | # Bundle artifact
56 | *.jsbundle
57 |
58 | # Ruby / CocoaPods
59 | /ios/Pods/
60 | /vendor/bundle/
61 |
62 | # Temporary files created by Metro to check the health of the file watcher
63 | .metro-health-check*
64 |
65 | # testing
66 | /coverage
67 |
--------------------------------------------------------------------------------
/package/android/.settings/org.eclipse.buildship.core.prefs:
--------------------------------------------------------------------------------
1 | arguments=--init-script /var/folders/xp/q9zpqk1j1yj5qc3bgwybkz1h0000gn/T/db3b08fc4a9ef609cb16b96b200fa13e563f396e9bb1ed0905fdab7bc3bc513b.gradle --init-script /var/folders/xp/q9zpqk1j1yj5qc3bgwybkz1h0000gn/T/52cde0cfcf3e28b8b7510e992210d9614505e0911af0c190bd590d7158574963.gradle
2 | auto.sync=false
3 | build.scans.enabled=false
4 | connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(8.9))
5 | connection.project.dir=
6 | eclipse.preferences.version=1
7 | gradle.user.home=
8 | java.home=/Library/Java/JavaVirtualMachines/jdk-19.jdk/Contents/Home
9 | jvm.arguments=
10 | offline.mode=false
11 | override.workspace.settings=true
12 | show.console.view=true
13 | show.executions.view=true
14 |
--------------------------------------------------------------------------------
/package/android/build.gradle:
--------------------------------------------------------------------------------
1 | import java.nio.file.Paths
2 | import org.apache.tools.ant.taskdefs.condition.Os
3 |
4 | buildscript {
5 | // The Android Gradle plugin is only required when opening the android folder stand-alone.
6 | // This avoids unnecessary downloads and potential conflicts when the library is included as a
7 | // module dependency in an application project.
8 | // ref: https://docs.gradle.org/current/userguide/tutorial_using_tasks.html#sec:build_script_external_dependencies
9 | if (project == rootProject) {
10 | repositories {
11 | google()
12 | }
13 | dependencies {
14 | // This should reflect the Gradle plugin version used by
15 | // the minimum React Native version supported.
16 | classpath 'com.android.tools.build:gradle:3.4.1'
17 | }
18 | }
19 | }
20 |
21 | def reactNativeArchitectures() {
22 | def value = project.getProperties().get("reactNativeArchitectures")
23 | return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
24 | }
25 |
26 | static def findNodeModules(baseDir) {
27 | def basePath = baseDir.toPath().normalize()
28 | // Node's module resolution algorithm searches up to the root directory,
29 | // after which the base path will be null
30 | while (basePath) {
31 | def nodeModulesPath = Paths.get(basePath.toString(), "node_modules")
32 | def reactNativePath = Paths.get(nodeModulesPath.toString(), "react-native")
33 | if (nodeModulesPath.toFile().exists() && reactNativePath.toFile().exists()) {
34 | return nodeModulesPath.toString()
35 | }
36 | basePath = basePath.getParent()
37 | }
38 | throw new GradleException("react-native-engine: Failed to find node_modules/ path!")
39 | }
40 |
41 | def nodeModules = findNodeModules(projectDir)
42 | logger.warn("react-native-engine: node_modules/ found at: ${nodeModules}")
43 |
44 | def sourceBuild = false
45 | def defaultDir
46 |
47 | if (rootProject.ext.has('reactNativeAndroidRoot')) {
48 | defaultDir = rootProject.ext.get('reactNativeAndroidRoot')
49 | } else if (findProject(':ReactAndroid') != null) {
50 | sourceBuild = true
51 | defaultDir = project(':ReactAndroid').projectDir
52 | } else {
53 | defaultDir = file("$nodeModules/react-native")
54 | }
55 |
56 | if (!defaultDir.exists()) {
57 | throw new GradleException(
58 | "${project.name}: React Native android directory (node_modules/react-native/android) does not exist! Resolved node_modules to: ${nodeModules}"
59 | )
60 | }
61 |
62 | def buildType = "debug"
63 | if (gradle.startParameter.taskRequests.args[0].toString().contains("Release")) {
64 | buildType = "release"
65 | } else if (gradle.startParameter.taskRequests.args[0].toString().contains("Debug")) {
66 | buildType = "debug"
67 | }
68 |
69 | def reactProperties = new Properties()
70 | file("$nodeModules/react-native/ReactAndroid/gradle.properties").withInputStream { reactProperties.load(it) }
71 | def FULL_RN_VERSION = (System.getenv("REACT_NATIVE_OVERRIDE_VERSION") ?: reactProperties.getProperty("VERSION_NAME"))
72 | def REACT_NATIVE_VERSION = FULL_RN_VERSION.split("\\.")[1].toInteger()
73 | def ENABLE_PREFAB = REACT_NATIVE_VERSION > 68
74 |
75 | def JS_RUNTIME = {
76 | // Override JS runtime with environment variable
77 | if (System.getenv("JS_RUNTIME")) {
78 | return System.getenv("JS_RUNTIME")
79 | }
80 |
81 | // Check if Hermes is enabled in app setup
82 | def appProject = rootProject.allprojects.find { it.plugins.hasPlugin('com.android.application') }
83 | if (appProject?.hermesEnabled?.toBoolean() || appProject?.ext?.react?.enableHermes?.toBoolean()) {
84 | return "hermes"
85 | }
86 |
87 | // Use JavaScriptCore (JSC) by default
88 | return "jsc"
89 | }.call()
90 |
91 | def jsRuntimeDir = {
92 | if (JS_RUNTIME == "hermes") {
93 | return Paths.get("$nodeModules/react-native", "sdks", "hermes")
94 | } else {
95 | return Paths.get("$nodeModules/react-native", "ReactCommon", "jsi")
96 | }
97 | }.call()
98 |
99 | def reactNativeRootDir = file("$nodeModules/react-native")
100 |
101 | logger.warn("[react-native-engine] RN Version: ${REACT_NATIVE_VERSION} / ${FULL_RN_VERSION}")
102 | logger.warn("[react-native-engine] isSourceBuild: ${sourceBuild}")
103 | logger.warn("[react-native-engine] buildType: ${buildType}")
104 | logger.warn("[react-native-engine] buildDir: ${buildDir}")
105 | logger.warn("[react-native-engine] node_modules: ${nodeModules}")
106 | logger.warn("[react-native-engine] Enable Prefab: ${ENABLE_PREFAB}")
107 | logger.warn("[react-native-engine] JS Runtime: ${JS_RUNTIME}")
108 |
109 | apply plugin: "com.android.library"
110 |
111 | if (isNewArchitectureEnabled()) {
112 | apply plugin: "com.facebook.react"
113 | }
114 |
115 | def getExtOrDefault(name) {
116 | return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["Engine_" + name]
117 | }
118 |
119 | def getExtOrIntegerDefault(name) {
120 | return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["Engine_" + name]).toInteger()
121 | }
122 |
123 | def supportsNamespace() {
124 | def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')
125 | def major = parsed[0].toInteger()
126 | def minor = parsed[1].toInteger()
127 |
128 | // Namespace support was added in 7.3.0
129 | return (major == 7 && minor >= 3) || major >= 8
130 | }
131 |
132 | def isNewArchitectureEnabled() {
133 | // To opt-in for the New Architecture, you can either:
134 | // - Set `newArchEnabled` to true inside the `gradle.properties` file
135 | // - Invoke gradle with `-newArchEnabled=true`
136 | // - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
137 | return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
138 | }
139 |
140 | def toPlatformFileString(String path) {
141 | if (Os.isFamily(Os.FAMILY_WINDOWS)) {
142 | path = path.replace(File.separatorChar, '/' as char)
143 | }
144 | return path
145 | }
146 |
147 | logger.warn("[react-native-engine] Thanks for using react-native-engine 💜")
148 |
149 | android {
150 | if (supportsNamespace()) {
151 | namespace "games.calico"
152 |
153 | sourceSets {
154 | main {
155 | manifest.srcFile "src/main/AndroidManifestNew.xml"
156 | }
157 | }
158 | }
159 |
160 | ndkVersion getExtOrDefault("ndkVersion")
161 | compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
162 |
163 | defaultConfig {
164 | minSdkVersion getExtOrIntegerDefault("minSdkVersion")
165 | targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
166 | versionCode 1
167 | versionName "1.0"
168 | buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
169 |
170 | externalNativeBuild {
171 | cmake {
172 | cppFlags "-fexceptions", "-frtti", "-std=c++1y", "-DONANDROID"
173 | abiFilters (*reactNativeArchitectures())
174 | arguments '-DANDROID_STL=c++_shared',
175 | "-DREACT_NATIVE_VERSION=${REACT_NATIVE_VERSION}",
176 | "-DNODE_MODULES_DIR=${nodeModules}",
177 | "-DREACT_NATIVE_DIR=${toPlatformFileString(reactNativeRootDir.path)}",
178 | "-DJS_RUNTIME=${JS_RUNTIME}",
179 | "-DJS_RUNTIME_DIR=${jsRuntimeDir}"
180 |
181 | }
182 | }
183 | }
184 |
185 | buildFeatures {
186 | prefab true
187 | prefabPublishing true
188 | buildConfig true
189 | }
190 |
191 | buildTypes {
192 | debug {
193 | // if you need to debug your native module in Android Studio, this
194 | // will prevent Gradle from stripping out the native symbols that
195 | // are needed
196 | packagingOptions {
197 | doNotStrip '../libs/android/*/libengine.so'
198 | jniLibs.useLegacyPackaging = true
199 | excludes = [
200 | "META-INF",
201 | "META-INF/**",
202 | "**/libc++_shared.so",
203 | "**/libfbjni.so",
204 | "**/libjsi.so",
205 | "**/libfolly_json.so",
206 | "**/libfolly_runtime.so",
207 | "**/libglog.so",
208 | "**/libhermes.so",
209 | "**/libhermes-executor-debug.so",
210 | "**/libhermes_executor.so",
211 | "**/libreactnativejni.so",
212 | "**/libturbomodulejsijni.so",
213 | "**/libreact_nativemodule_core.so",
214 | "**/libjscexecutor.so",
215 | "**/libv8executor.so",
216 | ]
217 | }
218 |
219 | ndk {
220 | debugSymbolLevel 'full'
221 | }
222 |
223 | externalNativeBuild {
224 | cmake {
225 | if (JS_RUNTIME == "hermes") {
226 | arguments "-DHERMES_ENABLE_DEBUGGER=1"
227 | } else {
228 | arguments "-DHERMES_ENABLE_DEBUGGER=0"
229 | }
230 | }
231 | }
232 | }
233 |
234 | release {
235 | minifyEnabled false
236 |
237 | externalNativeBuild {
238 | cmake {
239 | arguments "-DHERMES_ENABLE_DEBUGGER=0"
240 | }
241 | }
242 | }
243 | }
244 |
245 | lintOptions {
246 | disable "GradleCompatible"
247 | }
248 |
249 | compileOptions {
250 | sourceCompatibility JavaVersion.VERSION_1_8
251 | targetCompatibility JavaVersion.VERSION_1_8
252 | }
253 |
254 | sourceSets.main {
255 | jniLibs {
256 | srcDirs += ['../libs/android']
257 | }
258 | }
259 |
260 | externalNativeBuild {
261 | cmake {
262 | path("src/main/cpp/CMakeLists.txt")
263 | }
264 | }
265 | }
266 |
267 | repositories {
268 | mavenCentral()
269 | google()
270 | }
271 |
272 | dependencies {
273 | // From node_modules
274 | implementation "com.facebook.react:react-native:+"
275 |
276 | implementation "com.facebook.react:react-android"
277 | if (JS_RUNTIME == "hermes") {
278 | implementation "com.facebook.react:hermes-android" // version substituted by RNGP
279 | }
280 | }
--------------------------------------------------------------------------------
/package/android/gradle.properties:
--------------------------------------------------------------------------------
1 | Engine_kotlinVersion=1.7.0
2 | Engine_minSdkVersion=21
3 | Engine_targetSdkVersion=31
4 | Engine_compileSdkVersion=31
5 | Engine_ndkversion=21.4.7075529
--------------------------------------------------------------------------------
/package/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
--------------------------------------------------------------------------------
/package/android/src/main/AndroidManifestNew.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/package/android/src/main/cpp/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | project(rnengine)
2 | cmake_minimum_required(VERSION 3.8)
3 |
4 | set (CMAKE_VERBOSE_MAKEFILE ON)
5 | set (CMAKE_CXX_STANDARD 17)
6 |
7 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSK_GL -DSK_GANESH -DSK_BUILD_FOR_ANDROID -DFOLLY_NO_CONFIG=1 -DFOLLY_HAVE_CLOCK_GETTIME=1 -DFOLLY_HAVE_MEMRCHR=1 -DFOLLY_USE_LIBCPP=1 -DFOLLY_MOBILE=1 -DON_ANDROID -DONANDROID")
8 | string(APPEND CMAKE_CXX_FLAGS " -DHERMES_ENABLE_DEBUGGER=${HERMES_ENABLE_DEBUGGER}")
9 |
10 | message("-- REACT_NATIVE_DIR : " ${REACT_NATIVE_DIR})
11 |
12 | include("${REACT_NATIVE_DIR}/ReactAndroid/cmake-utils/folly-flags.cmake")
13 | add_compile_options(${folly_FLAGS})
14 |
15 | message("-- REACT NATIVE VERSION : " ${REACT_NATIVE_VERSION})
16 |
17 | set (PACKAGE_NAME "rnengine")
18 |
19 | # Consume shared libraries and headers from prefabs
20 | find_package(fbjni REQUIRED CONFIG)
21 | find_package(ReactAndroid REQUIRED CONFIG)
22 | if(${JS_RUNTIME} STREQUAL "hermes")
23 | find_package(hermes-engine REQUIRED CONFIG)
24 | endif()
25 |
26 | add_library( # Sets the name of the library.
27 | rnengine
28 |
29 | # Sets the library as a shared library.
30 | SHARED
31 |
32 | # Provides a relative path to your source file(s).
33 | native-lib.cpp)
34 |
35 | # includes
36 |
37 | target_include_directories(
38 | ${PACKAGE_NAME}
39 | PRIVATE
40 | "${REACT_NATIVE_DIR}/ReactAndroid/src/main/jni/react/turbomodule"
41 | "${REACT_NATIVE_DIR}/ReactCommon"
42 | "${REACT_NATIVE_DIR}/ReactCommon/callinvoker"
43 | "${REACT_NATIVE_DIR}/ReactCommon/react/renderer/graphics/platform/cxx"
44 | "${REACT_NATIVE_DIR}/ReactCommon/runtimeexecutor"
45 | "${REACT_NATIVE_DIR}/ReactCommon/yoga"
46 | )
47 |
48 | # build shared lib
49 |
50 | set_target_properties(${PACKAGE_NAME} PROPERTIES LINKER_LANGUAGE CXX)
51 |
52 | find_library( # Sets the name of the path variable.
53 | LOG_LIB
54 |
55 | # Specifies the name of the NDK library that
56 | # you want CMake to locate.
57 | log
58 | )
59 | message("-- LOG : " ${LOG_LIB})
60 |
61 | target_link_libraries( # Specifies the target library.
62 | ${PACKAGE_NAME}
63 | ${LOG_LIB}
64 | ReactAndroid::folly_runtime
65 | ReactAndroid::glog
66 | ReactAndroid::jsi
67 | ReactAndroid::reactnativejni
68 | fbjni::fbjni
69 | )
70 |
71 | if(${JS_RUNTIME} STREQUAL "hermes")
72 | string(APPEND CMAKE_CXX_FLAGS " -DJS_RUNTIME_HERMES=1")
73 | # From prefab from module `com.facebook.react:hermes-android`
74 | set(HERMES_LIB hermes-engine::libhermes)
75 | target_link_libraries(
76 | ${PACKAGE_NAME}
77 | ${HERMES_LIB}
78 | )
79 | if (${HERMES_ENABLE_DEBUGGER})
80 | set(HERMES_EXECUTOR_LIB ReactAndroid::hermes_executor)
81 | target_link_libraries(
82 | ${PACKAGE_NAME}
83 | ${HERMES_EXECUTOR_LIB}
84 | )
85 | endif()
86 | elseif(${JS_RUNTIME} STREQUAL "jsc")
87 | string(APPEND CMAKE_CXX_FLAGS " -DJS_RUNTIME_JSC=1")
88 | set(JSEXECUTOR_LIB ReactAndroid::jscexecutor)
89 | target_link_libraries(${PACKAGE_NAME} ${JSEXECUTOR_LIB})
90 | else()
91 | message(FATAL_ERROR "Unknown JS runtime ${JS_RUNTIME}.")
92 | endif()
--------------------------------------------------------------------------------
/package/android/src/main/cpp/native-lib.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
--------------------------------------------------------------------------------
/package/android/src/main/java/games/calico/EngineJsiModule.java:
--------------------------------------------------------------------------------
1 | package games.calico;
2 |
3 | import android.util.Log;
4 |
5 | import androidx.annotation.NonNull;
6 |
7 | import com.facebook.react.bridge.ReactApplicationContext;
8 | import com.facebook.react.turbomodule.core.CallInvokerHolderImpl;
9 | import com.facebook.react.bridge.ReactContextBaseJavaModule;
10 | import com.facebook.react.bridge.ReactMethod;
11 | import com.facebook.react.module.annotations.ReactModule;
12 | import java.lang.ref.WeakReference;
13 |
14 | @ReactModule(name = "EngineJsiModule")
15 | public class EngineJsiModule extends ReactContextBaseJavaModule {
16 | public static final String NAME = "EngineJsiModule";
17 | public static native void engine_init(long runtimePtr, CallInvokerHolderImpl callInvoker);
18 |
19 | private final WeakReference weakReactContext;
20 |
21 | public EngineJsiModule(ReactApplicationContext reactContext) {
22 | super(reactContext);
23 | this.weakReactContext = new WeakReference<>(reactContext);
24 | }
25 |
26 | @NonNull
27 | @Override
28 | public String getName() {
29 | return NAME;
30 | }
31 |
32 | @ReactMethod(isBlockingSynchronousMethod = true)
33 | public boolean install() {
34 | try {
35 | // Load our dynamic library
36 | System.loadLibrary("engine");
37 | } catch (Exception ex) {
38 | System.err.println("Could not load Engine library");
39 | return false;
40 | }
41 |
42 | Log.i(NAME, "Engine Loaded!");
43 |
44 | try {
45 | ReactApplicationContext context = weakReactContext.get();
46 | if (context == null) {
47 | Log.e(NAME, "React Application Context was null!");
48 | return false;
49 | }
50 | var jsContext = context.getJavaScriptContextHolder();
51 | var runtimePtr = jsContext.get();
52 | var callInvoker = (CallInvokerHolderImpl)context.getCatalystInstance().getJSCallInvokerHolder();
53 |
54 | Log.i(NAME, "Initializing Engine...");
55 |
56 | if (jsContext.get() != 0) {
57 | EngineJsiModule.engine_init(runtimePtr, callInvoker);
58 | Log.i(NAME, "Engine initialized yeahhh");
59 |
60 | return true;
61 | } else {
62 | Log.e(NAME,"Failed to initialize engine: no runtime");
63 | return false;
64 | }
65 | } catch (Exception exception) {
66 | Log.e(NAME, "Failed to initialize engine", exception);
67 | return false;
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/package/android/src/main/java/games/calico/EngineJsiPackage.java:
--------------------------------------------------------------------------------
1 | package games.calico;
2 |
3 | import androidx.annotation.NonNull;
4 | import java.util.Collections;
5 | import java.util.List;
6 | import com.facebook.react.ReactPackage;
7 | import com.facebook.react.bridge.NativeModule;
8 | import com.facebook.react.bridge.ReactApplicationContext;
9 | import com.facebook.react.uimanager.ViewManager;
10 |
11 | public class EngineJsiPackage implements ReactPackage {
12 | @NonNull
13 | @Override
14 | public List createNativeModules(@NonNull ReactApplicationContext reactContext) {
15 | return List.of(new EngineJsiModule(reactContext));
16 | }
17 |
18 | @NonNull
19 | @Override
20 | public List createViewManagers(@NonNull ReactApplicationContext reactContext) {
21 | return Collections.emptyList();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/package/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./src";
--------------------------------------------------------------------------------
/package/ios/GodotModule.mm:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | #import
4 | #import
5 | #import
6 | #import
7 |
8 | #import
9 | #import
10 |
11 | using namespace facebook;
12 |
13 | @implementation GodotModule {
14 | GodotManager *godotManager;
15 | std::shared_ptr jsCallInvoker;
16 | }
17 |
18 | RCT_EXPORT_MODULE()
19 | @synthesize bridge = _bridge;
20 |
21 | #pragma Accessors
22 |
23 | - (GodotManager *)manager {
24 | return godotManager;
25 | }
26 |
27 | #pragma Setup and invalidation
28 |
29 | + (BOOL)requiresMainQueueSetup {
30 | return NO;
31 | }
32 |
33 | - (void)invalidate {
34 | if (godotManager != nil) {
35 | [godotManager invalidate];
36 | }
37 | godotManager = nil;
38 | }
39 |
40 | RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install)
41 | {
42 | if (godotManager != nil) {
43 | // Already initialized, ignore call.
44 | return @true;
45 | }
46 |
47 | RCTCxxBridge *cxxBridge = (RCTCxxBridge *)self.bridge;
48 | if (!jsCallInvoker) {
49 | jsCallInvoker = cxxBridge.jsCallInvoker;
50 | }
51 |
52 | godotManager = [[GodotManager alloc] initWithBridge:_bridge jsInvoker:jsCallInvoker];
53 |
54 | return @true;
55 | }
56 |
57 | #ifdef RCT_NEW_ARCH_ENABLED
58 | - (std::shared_ptr)getTurboModule:
59 | (const facebook::react::ObjCTurboModule::InitParams &)params {
60 | jsCallInvoker = params.jsInvoker;
61 | return std::make_shared(params);
62 | }
63 | #endif
64 |
65 | @end
66 |
--------------------------------------------------------------------------------
/package/libs/android/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calico-games/react-native-godot/3892f30db6e43715609562c6e50960613ecf0df9/package/libs/android/.gitkeep
--------------------------------------------------------------------------------
/package/libs/ios/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calico-games/react-native-godot/3892f30db6e43715609562c6e50960613ecf0df9/package/libs/ios/.gitkeep
--------------------------------------------------------------------------------
/package/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-godot",
3 | "version": "0.0.9",
4 | "description": "Bring Godot to React Native.",
5 | "main": "lib/commonjs/index",
6 | "module": "lib/module/index",
7 | "types": "lib/typescript/src/index.d.ts",
8 | "react-native": "src/index.ts",
9 | "source": "src/index.ts",
10 | "files": [
11 | "android",
12 | "ios",
13 | "lib/commonjs",
14 | "lib/module",
15 | "lib/typescript",
16 | "libs/ios/.gitkeep",
17 | "libs/android/.gitkeep",
18 | "src",
19 | "index.ts",
20 | "react-native-godot-utils.rb",
21 | "react-native-godot.podspec",
22 | "tsconfig.json"
23 | ],
24 | "scripts": {
25 | "typescript": "tsc --noEmit",
26 | "prepack": "bob build"
27 | },
28 | "keywords": [
29 | "react-native",
30 | "ios",
31 | "android",
32 | "godot",
33 | "game",
34 | "engine",
35 | "3d",
36 | "rendering",
37 | "gltf",
38 | "model",
39 | "threejs",
40 | "physics",
41 | "opengl",
42 | "metal",
43 | "vulkan"
44 | ],
45 | "repository": {
46 | "type": "git",
47 | "url": "git+https://github.com/calico-games/react-native-godot.git"
48 | },
49 | "author": "Calico Games (https://github.com/calico-games)",
50 | "license": "UNLICENSED",
51 | "homepage": "https://github.com/calico-games/react-native-godot",
52 | "publishConfig": {
53 | "registry": "https://registry.npmjs.org/",
54 | "access": "public"
55 | },
56 | "devDependencies": {
57 | "@types/react": "^19.0.0",
58 | "react": "^19.0.0",
59 | "react-native": "^0.78.1",
60 | "react-native-builder-bob": "^0.39.0",
61 | "typescript": "5.0.4"
62 | },
63 | "resolutions": {
64 | "@types/react": "^18.2.44",
65 | "@react-native-community/cli": "^14.0.0-alpha.4"
66 | },
67 | "peerDependencies": {
68 | "react": "*",
69 | "react-native": "*"
70 | },
71 | "eslintIgnore": [
72 | "node_modules/",
73 | "lib/"
74 | ],
75 | "prettier": {
76 | "quoteProps": "consistent",
77 | "singleQuote": true,
78 | "tabWidth": 2,
79 | "trailingComma": "es5",
80 | "useTabs": false
81 | },
82 | "codegenConfig": {
83 | "name": "RNGodot",
84 | "type": "all",
85 | "jsSrcsDir": "src/specs",
86 | "android": {
87 | "javaPackageName": "games.calico.godot"
88 | }
89 | },
90 | "react-native-builder-bob": {
91 | "source": "src",
92 | "output": "lib",
93 | "targets": [
94 | "commonjs",
95 | "module",
96 | [
97 | "typescript",
98 | {
99 | "project": "tsconfig.json"
100 | }
101 | ]
102 | ]
103 | },
104 | "directories": {
105 | "lib": "lib"
106 | },
107 | "bugs": {
108 | "url": "https://github.com/calico/react-native-godot/issues"
109 | },
110 | "dependencies": {}
111 | }
112 |
--------------------------------------------------------------------------------
/package/react-native-godot-utils.rb:
--------------------------------------------------------------------------------
1 | require 'net/http'
2 |
3 | def download_prebuilt(react_native_path, version)
4 | url = prebuilt_url(version)
5 | download_stable(react_native_path, version)
6 | return {:http => url}
7 | end
8 |
9 | # HELPERS
10 |
11 | def prebuilt_url(version)
12 | return "https://storage.googleapis.com/react-native-godot/react-native-godot-ios-#{version}.zip"
13 | end
14 |
15 |
16 | def library_dir()
17 | return File.join(Pod::Config.instance.project_pods_root, "package/libs")
18 | end
19 |
20 | def download_stable(react_native_path, version)
21 | url = prebuilt_url(version)
22 | download_xcframework(react_native_path, url, version)
23 | end
24 |
25 | def download_xcframework(react_native_path, url, version)
26 | destination_dir = "#{react_native_path}/libs/ios"
27 | zip_file = "#{destination_dir}/react-native-godot-ios-#{version}.zip"
28 | xcframework_dir = "#{destination_dir}/ReactNativeGodot.xcframework"
29 |
30 | if File.exist?(zip_file)
31 | react_native_godot_log("Using cached prebuilt at #{zip_file}")
32 |
33 | if File.exist?(xcframework_dir)
34 | react_native_godot_log("Prebuilt already extracted at #{xcframework_dir}")
35 | return zip_file
36 | end
37 | else
38 | react_native_godot_log("Downloading prebuilt from URL: #{url}")
39 |
40 | # Download to a temporary file first so we don't cache incomplete downloads.
41 | tmp_file = "#{library_dir()}/react-native-godot-ios.download"
42 |
43 | `mkdir -p "#{library_dir()}" &&
44 | curl "#{url}" -Lo "#{tmp_file}" &&
45 | mv "#{tmp_file}" "#{zip_file}" &&
46 | rm -rf "#{tmp_file}"`
47 | end
48 |
49 | `rm -rf "#{xcframework_dir}" &&
50 | unzip "#{zip_file}" -d "#{destination_dir}"`
51 |
52 | return zip_file
53 | end
54 |
55 | def react_native_godot_log(message, level = :warning)
56 | if !Object.const_defined?("Pod::UI")
57 | return
58 | end
59 | custom_message = '[react-native-godot] ' + message
60 | case level
61 | when :info
62 | Pod::UI.puts custom_message.green
63 | when :error
64 | Pod::UI.puts custom_message.red
65 | else
66 | Pod::UI.puts custom_message.yellow
67 | end
68 | end
--------------------------------------------------------------------------------
/package/react-native-godot.podspec:
--------------------------------------------------------------------------------
1 | require "json"
2 | require_relative "./react-native-godot-utils.rb"
3 |
4 | # package.json
5 | package = JSON.parse(File.read(File.join(__dir__, "package.json")))
6 | version = package['version'].gsub(/dev-.*/, '')
7 |
8 | source = download_prebuilt(__dir__, version)
9 |
10 | Pod::Spec.new do |s|
11 | s.name = "react-native-godot"
12 | s.version = package["version"]
13 | s.summary = package["description"]
14 | s.description = "Bring Godot to React Native."
15 | s.homepage = "https://github.com/calico-games/react-native-godot"
16 | s.license = "Copyright © 2024 Calico Games. All rights reserved."
17 | s.authors = { "Calico Games" => "team@calico.games" }
18 | s.platforms = { :ios => min_ios_version_supported }
19 | s.source = source
20 |
21 | s.requires_arc = true
22 | s.pod_target_xcconfig = {
23 | "CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
24 | "CLANG_CXX_LIBRARY" => "libc++",
25 | 'DEFINES_MODULE' => 'YES'
26 | }
27 | if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
28 | s.compiler_flags = "-DRCT_NEW_ARCH_ENABLED=1"
29 | end
30 |
31 | s.dependency 'React-Core'
32 | s.dependency 'React-CoreModules'
33 |
34 | s.frameworks = ['MetalKit', 'MetalFX']
35 |
36 | s.ios.vendored_frameworks = [
37 | 'libs/ios/ReactNativeGodot.xcframework',
38 | ]
39 |
40 | # All iOS files
41 | s.source_files = [
42 | 'ios/GodotModule.mm',
43 | ]
44 | end
--------------------------------------------------------------------------------
/package/src/GodotProvider.tsx:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED. DO NOT EDIT.
2 | import React, {createContext, useContext, useEffect, useState} from 'react';
3 | import NativeGodotModule from './specs/NativeGodotModule';
4 |
5 | interface GodotContextType {
6 |
7 | AABB: typeof global.AABB | null;
8 | Basis: typeof global.Basis | null;
9 | Color: typeof global.Color | null;
10 | Plane: typeof global.Plane | null;
11 | Projection: typeof global.Projection | null;
12 | Quaternion: typeof global.Quaternion | null;
13 | Rect2: typeof global.Rect2 | null;
14 | Rect2i: typeof global.Rect2i | null;
15 | Transform2D: typeof global.Transform2D | null;
16 | Transform3D: typeof global.Transform3D | null;
17 | Vector2: typeof global.Vector2 | null;
18 | Vector2i: typeof global.Vector2i | null;
19 | Vector3: typeof global.Vector3 | null;
20 | Vector3i: typeof global.Vector3i | null;
21 | Vector4: typeof global.Vector4 | null;
22 | Vector4i: typeof global.Vector4i | null;
23 | isInitialized: boolean;
24 | }
25 |
26 | export const GodotContext = createContext(undefined);
27 |
28 | export const GodotProvider: React.FC<{children: React.ReactNode}> = ({children}) => {
29 |
30 | const [AABB, setAABB] = useState(null);
31 | const [Basis, setBasis] = useState(null);
32 | const [Color, setColor] = useState(null);
33 | const [Plane, setPlane] = useState(null);
34 | const [Projection, setProjection] = useState(null);
35 | const [Quaternion, setQuaternion] = useState(null);
36 | const [Rect2, setRect2] = useState(null);
37 | const [Rect2i, setRect2i] = useState(null);
38 | const [Transform2D, setTransform2D] = useState(null);
39 | const [Transform3D, setTransform3D] = useState(null);
40 | const [Vector2, setVector2] = useState(null);
41 | const [Vector2i, setVector2i] = useState(null);
42 | const [Vector3, setVector3] = useState(null);
43 | const [Vector3i, setVector3i] = useState(null);
44 | const [Vector4, setVector4] = useState(null);
45 | const [Vector4i, setVector4i] = useState(null);
46 | const [isInitialized, setIsInitialized] = useState(false);
47 |
48 | useEffect(() => {
49 | const initialize = () => {
50 | if (!NativeGodotModule) {
51 | console.error('[react-native-godot] NativeGodotModule is not available');
52 | return;
53 | }
54 | NativeGodotModule.install();
55 |
56 | if (typeof global.AABB === 'function') {
57 | setAABB(() => global.AABB);
58 | }
59 | if (typeof global.Basis === 'function') {
60 | setBasis(() => global.Basis);
61 | }
62 | if (typeof global.Color === 'function') {
63 | setColor(() => global.Color);
64 | }
65 | if (typeof global.Plane === 'function') {
66 | setPlane(() => global.Plane);
67 | }
68 | if (typeof global.Projection === 'function') {
69 | setProjection(() => global.Projection);
70 | }
71 | if (typeof global.Quaternion === 'function') {
72 | setQuaternion(() => global.Quaternion);
73 | }
74 | if (typeof global.Rect2 === 'function') {
75 | setRect2(() => global.Rect2);
76 | }
77 | if (typeof global.Rect2i === 'function') {
78 | setRect2i(() => global.Rect2i);
79 | }
80 | if (typeof global.Transform2D === 'function') {
81 | setTransform2D(() => global.Transform2D);
82 | }
83 | if (typeof global.Transform3D === 'function') {
84 | setTransform3D(() => global.Transform3D);
85 | }
86 | if (typeof global.Vector2 === 'function') {
87 | setVector2(() => global.Vector2);
88 | }
89 | if (typeof global.Vector2i === 'function') {
90 | setVector2i(() => global.Vector2i);
91 | }
92 | if (typeof global.Vector3 === 'function') {
93 | setVector3(() => global.Vector3);
94 | }
95 | if (typeof global.Vector3i === 'function') {
96 | setVector3i(() => global.Vector3i);
97 | }
98 | if (typeof global.Vector4 === 'function') {
99 | setVector4(() => global.Vector4);
100 | }
101 | if (typeof global.Vector4i === 'function') {
102 | setVector4i(() => global.Vector4i);
103 | }
104 |
105 | if (typeof global.AABB === 'function' && typeof global.Basis === 'function' && typeof global.Color === 'function' && typeof global.Plane === 'function' && typeof global.Projection === 'function' && typeof global.Quaternion === 'function' && typeof global.Rect2 === 'function' && typeof global.Rect2i === 'function' && typeof global.Transform2D === 'function' && typeof global.Transform3D === 'function' && typeof global.Vector2 === 'function' && typeof global.Vector2i === 'function' && typeof global.Vector3 === 'function' && typeof global.Vector3i === 'function' && typeof global.Vector4 === 'function' && typeof global.Vector4i === 'function') {
106 | console.info('[react-native-godot] Godot initialized');
107 | setIsInitialized(true);
108 | }
109 | };
110 |
111 | initialize();
112 | }, []);
113 |
114 | return (
115 |
116 | {children}
117 |
118 | );
119 | };
120 |
121 | export const useGodot = () => {
122 | const context = useContext(GodotContext);
123 | if (context === undefined) {
124 | throw new Error('useGodot must be used within a GodotProvider');
125 | }
126 | return context;
127 | };
128 |
--------------------------------------------------------------------------------
/package/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './views';
2 | export * from './GodotProvider';
3 | export * from './types';
--------------------------------------------------------------------------------
/package/src/specs/GodotViewNativeComponent.ts:
--------------------------------------------------------------------------------
1 | import codegenNativeComponent from "react-native/Libraries/Utilities/codegenNativeComponent";
2 | import type {ViewProps} from "react-native";
3 |
4 | export interface NativeProps extends ViewProps {}
5 |
6 | export default codegenNativeComponent("GodotView");
--------------------------------------------------------------------------------
/package/src/specs/NativeGodotModule.ts:
--------------------------------------------------------------------------------
1 | import {TurboModule, TurboModuleRegistry} from 'react-native';
2 |
3 | export interface Spec extends TurboModule {
4 | install: () => boolean;
5 | }
6 |
7 | export default TurboModuleRegistry.getEnforcing("GodotModule") as Spec | null;
--------------------------------------------------------------------------------
/package/src/types/Node.tsx:
--------------------------------------------------------------------------------
1 | export declare namespace GD {
2 | export interface Node {
3 | getNode(name: string): Node | null;
4 | getParent(): Node | null;
5 | getChildren(): Node[];
6 | getChildCount(): number;
7 | }
8 | }
9 |
10 | declare global {
11 | var GodotNode: GD.Node;
12 | }
13 |
14 | export {};
--------------------------------------------------------------------------------
/package/src/types/index.ts:
--------------------------------------------------------------------------------
1 | export * from './Node';
--------------------------------------------------------------------------------
/package/src/variants/AABB.ts:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED. DO NOT EDIT.
2 |
3 | import {Plane} from './Plane';
4 | import {Vector3} from './Vector3';
5 |
6 | type AABBConstructor = {
7 | (): AABB;
8 | (from_: AABB): AABB;
9 | (position_: Vector3, size_: Vector3): AABB;
10 |
11 | };
12 |
13 | declare global {
14 | var AABB: AABBConstructor;
15 | }
16 |
17 | export interface AABB {
18 | position: Vector3;
19 | size: Vector3;
20 |
21 | abs(): AABB;
22 | getCenter(): Vector3;
23 | getVolume(): number;
24 | hasVolume(): boolean;
25 | hasSurface(): boolean;
26 | hasPoint(point_: Vector3): boolean;
27 | isEqualApprox(aabb_: AABB): boolean;
28 | isFinite(): boolean;
29 | intersects(with_: AABB): boolean;
30 | encloses(with_: AABB): boolean;
31 | intersectsPlane(plane_: Plane): boolean;
32 | intersection(with_: AABB): AABB;
33 | merge(with_: AABB): AABB;
34 | expand(toPoint_: Vector3): AABB;
35 | grow(by_: number): AABB;
36 | getSupport(direction_: Vector3): Vector3;
37 | getLongestAxis(): Vector3;
38 | getLongestAxisIndex(): number;
39 | getLongestAxisSize(): number;
40 | getShortestAxis(): Vector3;
41 | getShortestAxisIndex(): number;
42 | getShortestAxisSize(): number;
43 | getEndpoint(idx_: number): Vector3;
44 | intersectsSegment(from_: Vector3, to_: Vector3): any;
45 | intersectsRay(from_: Vector3, dir_: Vector3): any;
46 |
47 | }
48 |
49 | export {}; // Ensure this file is treated as a module
50 |
--------------------------------------------------------------------------------
/package/src/variants/Basis.ts:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED. DO NOT EDIT.
2 |
3 | import {Quaternion} from './Quaternion';
4 | import {Vector3} from './Vector3';
5 |
6 | type BasisConstructor = {
7 | (): Basis;
8 | (from_: Basis): Basis;
9 | (from_: Quaternion): Basis;
10 | (axis_: Vector3, angle_: number): Basis;
11 | (xAxis_: Vector3, yAxis_: Vector3, zAxis_: Vector3): Basis;
12 |
13 | };
14 |
15 | declare global {
16 | var Basis: BasisConstructor;
17 | }
18 |
19 | export interface Basis {
20 | x: Vector3;
21 | y: Vector3;
22 | z: Vector3;
23 |
24 | inverse(): Basis;
25 | transposed(): Basis;
26 | orthonormalized(): Basis;
27 | determinant(): number;
28 | rotated(axis_: Vector3, angle_: number): Basis;
29 | scaled(scale_: Vector3): Basis;
30 | getScale(): Vector3;
31 | tdotx(with_: Vector3): number;
32 | tdoty(with_: Vector3): number;
33 | tdotz(with_: Vector3): number;
34 | slerp(to_: Basis, weight_: number): Basis;
35 | isEqualApprox(b_: Basis): boolean;
36 | isFinite(): boolean;
37 | getRotationQuaternion(): Quaternion;
38 | fromScale(scale_: Vector3): Basis;
39 |
40 | }
41 |
42 | export {}; // Ensure this file is treated as a module
43 |
--------------------------------------------------------------------------------
/package/src/variants/Color.ts:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED. DO NOT EDIT.
2 |
3 | type ColorConstructor = {
4 | (): Color;
5 | (from_: Color): Color;
6 | (from_: Color, alpha_: number): Color;
7 | (r_: number, g_: number, b_: number): Color;
8 | (r_: number, g_: number, b_: number, a_: number): Color;
9 | (code_: string): Color;
10 | (code_: string, alpha_: number): Color;
11 |
12 | };
13 |
14 | declare global {
15 | var Color: ColorConstructor;
16 | }
17 |
18 | export interface Color {
19 | r: number;
20 | g: number;
21 | b: number;
22 | a: number;
23 |
24 | toArgb32(): number;
25 | toAbgr32(): number;
26 | toRgba32(): number;
27 | toArgb64(): number;
28 | toAbgr64(): number;
29 | toRgba64(): number;
30 | toHtml(withAlpha_: boolean): string;
31 | clamp(min_: Color, max_: Color): Color;
32 | inverted(): Color;
33 | lerp(to_: Color, weight_: number): Color;
34 | lightened(amount_: number): Color;
35 | darkened(amount_: number): Color;
36 | blend(over_: Color): Color;
37 | getLuminance(): number;
38 | srgbToLinear(): Color;
39 | linearToSrgb(): Color;
40 | isEqualApprox(to_: Color): boolean;
41 | hex(hex_: number): Color;
42 | hex64(hex_: number): Color;
43 | html(rgba_: string): Color;
44 | fromString(str_: string, default_: Color): Color;
45 | fromHsv(h_: number, s_: number, v_: number, alpha_: number): Color;
46 | fromRgbe9995(rgbe_: number): Color;
47 |
48 | }
49 |
50 | export {}; // Ensure this file is treated as a module
51 |
--------------------------------------------------------------------------------
/package/src/variants/Plane.ts:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED. DO NOT EDIT.
2 |
3 | import {Vector3} from './Vector3';
4 |
5 | type PlaneConstructor = {
6 | (): Plane;
7 | (from_: Plane): Plane;
8 | (normal_: Vector3): Plane;
9 | (normal_: Vector3, d_: number): Plane;
10 | (normal_: Vector3, point_: Vector3): Plane;
11 | (point1_: Vector3, point2_: Vector3, point3_: Vector3): Plane;
12 | (a_: number, b_: number, c_: number, d_: number): Plane;
13 |
14 | };
15 |
16 | declare global {
17 | var Plane: PlaneConstructor;
18 | }
19 |
20 | export interface Plane {
21 | normal: Vector3;
22 | d: number;
23 |
24 | normalized(): Plane;
25 | isEqualApprox(toPlane_: Plane): boolean;
26 | isFinite(): boolean;
27 | isPointOver(point_: Vector3): boolean;
28 | distanceTo(point_: Vector3): number;
29 | hasPoint(point_: Vector3, tolerance_: number): boolean;
30 | project(point_: Vector3): Vector3;
31 | intersect3(b_: Plane, c_: Plane): any;
32 |
33 | }
34 |
35 | export {}; // Ensure this file is treated as a module
36 |
--------------------------------------------------------------------------------
/package/src/variants/Projection.ts:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED. DO NOT EDIT.
2 |
3 | import {AABB} from './AABB';
4 | import {Plane} from './Plane';
5 | import {Rect2} from './Rect2';
6 | import {Transform3D} from './Transform3D';
7 | import {Vector2} from './Vector2';
8 | import {Vector4} from './Vector4';
9 |
10 | type ProjectionConstructor = {
11 | (): Projection;
12 | (from_: Projection): Projection;
13 | (from_: Transform3D): Projection;
14 | (xAxis_: Vector4, yAxis_: Vector4, zAxis_: Vector4, wAxis_: Vector4): Projection;
15 |
16 | };
17 |
18 | declare global {
19 | var Projection: ProjectionConstructor;
20 | }
21 |
22 | export interface Projection {
23 | x: Vector4;
24 | y: Vector4;
25 | z: Vector4;
26 | w: Vector4;
27 |
28 | createDepthCorrection(flipY_: boolean): Projection;
29 | createLightAtlasRect(rect_: Rect2): Projection;
30 | createPerspective(fovy_: number, aspect_: number, zNear_: number, zFar_: number, flipFov_: boolean): Projection;
31 | createPerspectiveHmd(fovy_: number, aspect_: number, zNear_: number, zFar_: number, flipFov_: boolean, eye_: number, intraocularDist_: number, convergenceDist_: number): Projection;
32 | createForHmd(eye_: number, aspect_: number, intraocularDist_: number, displayWidth_: number, displayToLens_: number, oversample_: number, zNear_: number, zFar_: number): Projection;
33 | createOrthogonal(left_: number, right_: number, bottom_: number, top_: number, zNear_: number, zFar_: number): Projection;
34 | createOrthogonalAspect(size_: number, aspect_: number, zNear_: number, zFar_: number, flipFov_: boolean): Projection;
35 | createFrustum(left_: number, right_: number, bottom_: number, top_: number, zNear_: number, zFar_: number): Projection;
36 | createFrustumAspect(size_: number, aspect_: number, offset_: Vector2, zNear_: number, zFar_: number, flipFov_: boolean): Projection;
37 | createFitAabb(aabb_: AABB): Projection;
38 | determinant(): number;
39 | perspectiveZnearAdjusted(newZnear_: number): Projection;
40 | flippedY(): Projection;
41 | jitterOffseted(offset_: Vector2): Projection;
42 | getFovy(fovx_: number, aspect_: number): number;
43 | getZFar(): number;
44 | getZNear(): number;
45 | getAspect(): number;
46 | getFov(): number;
47 | isOrthogonal(): boolean;
48 | getViewportHalfExtents(): Vector2;
49 | getFarPlaneHalfExtents(): Vector2;
50 | inverse(): Projection;
51 | getPixelsPerMeter(forPixelWidth_: number): number;
52 | getLodMultiplier(): number;
53 |
54 | }
55 |
56 | export {}; // Ensure this file is treated as a module
57 |
--------------------------------------------------------------------------------
/package/src/variants/Quaternion.ts:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED. DO NOT EDIT.
2 |
3 | import {Basis} from './Basis';
4 | import {Vector3} from './Vector3';
5 |
6 | type QuaternionConstructor = {
7 | (): Quaternion;
8 | (from_: Quaternion): Quaternion;
9 | (from_: Basis): Quaternion;
10 | (axis_: Vector3, angle_: number): Quaternion;
11 | (arcFrom_: Vector3, arcTo_: Vector3): Quaternion;
12 | (x_: number, y_: number, z_: number, w_: number): Quaternion;
13 |
14 | };
15 |
16 | declare global {
17 | var Quaternion: QuaternionConstructor;
18 | }
19 |
20 | export interface Quaternion {
21 | x: number;
22 | y: number;
23 | z: number;
24 | w: number;
25 |
26 | length(): number;
27 | lengthSquared(): number;
28 | normalized(): Quaternion;
29 | isNormalized(): boolean;
30 | isEqualApprox(to_: Quaternion): boolean;
31 | isFinite(): boolean;
32 | inverse(): Quaternion;
33 | log(): Quaternion;
34 | exp(): Quaternion;
35 | angleTo(to_: Quaternion): number;
36 | dot(with_: Quaternion): number;
37 | slerp(to_: Quaternion, weight_: number): Quaternion;
38 | slerpni(to_: Quaternion, weight_: number): Quaternion;
39 | sphericalCubicInterpolate(b_: Quaternion, preA_: Quaternion, postB_: Quaternion, weight_: number): Quaternion;
40 | sphericalCubicInterpolateInTime(b_: Quaternion, preA_: Quaternion, postB_: Quaternion, weight_: number, bT_: number, preAT_: number, postBT_: number): Quaternion;
41 | getAxis(): Vector3;
42 | getAngle(): number;
43 |
44 | }
45 |
46 | export {}; // Ensure this file is treated as a module
47 |
--------------------------------------------------------------------------------
/package/src/variants/Rect2.ts:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED. DO NOT EDIT.
2 |
3 | import {Rect2i} from './Rect2i';
4 | import {Vector2} from './Vector2';
5 |
6 | type Rect2Constructor = {
7 | (): Rect2;
8 | (from_: Rect2): Rect2;
9 | (from_: Rect2i): Rect2;
10 | (position_: Vector2, size_: Vector2): Rect2;
11 | (x_: number, y_: number, width_: number, height_: number): Rect2;
12 |
13 | };
14 |
15 | declare global {
16 | var Rect2: Rect2Constructor;
17 | }
18 |
19 | export interface Rect2 {
20 | position: Vector2;
21 | size: Vector2;
22 |
23 | getCenter(): Vector2;
24 | getArea(): number;
25 | hasArea(): boolean;
26 | hasPoint(point_: Vector2): boolean;
27 | isEqualApprox(rect_: Rect2): boolean;
28 | isFinite(): boolean;
29 | intersects(b_: Rect2, includeBorders_: boolean): boolean;
30 | encloses(b_: Rect2): boolean;
31 | intersection(b_: Rect2): Rect2;
32 | merge(b_: Rect2): Rect2;
33 | expand(to_: Vector2): Rect2;
34 | getSupport(direction_: Vector2): Vector2;
35 | grow(amount_: number): Rect2;
36 | growIndividual(left_: number, top_: number, right_: number, bottom_: number): Rect2;
37 | abs(): Rect2;
38 |
39 | }
40 |
41 | export {}; // Ensure this file is treated as a module
42 |
--------------------------------------------------------------------------------
/package/src/variants/Rect2i.ts:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED. DO NOT EDIT.
2 |
3 | import {Rect2} from './Rect2';
4 | import {Vector2i} from './Vector2i';
5 |
6 | type Rect2iConstructor = {
7 | (): Rect2i;
8 | (from_: Rect2i): Rect2i;
9 | (from_: Rect2): Rect2i;
10 | (position_: Vector2i, size_: Vector2i): Rect2i;
11 | (x_: number, y_: number, width_: number, height_: number): Rect2i;
12 |
13 | };
14 |
15 | declare global {
16 | var Rect2i: Rect2iConstructor;
17 | }
18 |
19 | export interface Rect2i {
20 | position: Vector2i;
21 | size: Vector2i;
22 |
23 | getCenter(): Vector2i;
24 | getArea(): number;
25 | hasArea(): boolean;
26 | hasPoint(point_: Vector2i): boolean;
27 | intersects(b_: Rect2i): boolean;
28 | encloses(b_: Rect2i): boolean;
29 | intersection(b_: Rect2i): Rect2i;
30 | merge(b_: Rect2i): Rect2i;
31 | expand(to_: Vector2i): Rect2i;
32 | grow(amount_: number): Rect2i;
33 | growIndividual(left_: number, top_: number, right_: number, bottom_: number): Rect2i;
34 | abs(): Rect2i;
35 |
36 | }
37 |
38 | export {}; // Ensure this file is treated as a module
39 |
--------------------------------------------------------------------------------
/package/src/variants/Transform2D.ts:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED. DO NOT EDIT.
2 |
3 | import {Vector2} from './Vector2';
4 |
5 | type Transform2DConstructor = {
6 | (): Transform2D;
7 | (from_: Transform2D): Transform2D;
8 | (rotation_: number, position_: Vector2): Transform2D;
9 | (rotation_: number, scale_: Vector2, skew_: number, position_: Vector2): Transform2D;
10 | (xAxis_: Vector2, yAxis_: Vector2, origin_: Vector2): Transform2D;
11 |
12 | };
13 |
14 | declare global {
15 | var Transform2D: Transform2DConstructor;
16 | }
17 |
18 | export interface Transform2D {
19 | x: Vector2;
20 | y: Vector2;
21 | origin: Vector2;
22 |
23 | inverse(): Transform2D;
24 | affineInverse(): Transform2D;
25 | getRotation(): number;
26 | getOrigin(): Vector2;
27 | getScale(): Vector2;
28 | getSkew(): number;
29 | orthonormalized(): Transform2D;
30 | rotated(angle_: number): Transform2D;
31 | rotatedLocal(angle_: number): Transform2D;
32 | scaled(scale_: Vector2): Transform2D;
33 | scaledLocal(scale_: Vector2): Transform2D;
34 | translated(offset_: Vector2): Transform2D;
35 | translatedLocal(offset_: Vector2): Transform2D;
36 | basisXform(v_: Vector2): Vector2;
37 | basisXformInv(v_: Vector2): Vector2;
38 | interpolateWith(xform_: Transform2D, weight_: number): Transform2D;
39 | isEqualApprox(xform_: Transform2D): boolean;
40 | isFinite(): boolean;
41 |
42 | }
43 |
44 | export {}; // Ensure this file is treated as a module
45 |
--------------------------------------------------------------------------------
/package/src/variants/Transform3D.ts:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED. DO NOT EDIT.
2 |
3 | import {Basis} from './Basis';
4 | import {Projection} from './Projection';
5 | import {Vector3} from './Vector3';
6 |
7 | type Transform3DConstructor = {
8 | (): Transform3D;
9 | (from_: Transform3D): Transform3D;
10 | (basis_: Basis, origin_: Vector3): Transform3D;
11 | (xAxis_: Vector3, yAxis_: Vector3, zAxis_: Vector3, origin_: Vector3): Transform3D;
12 | (from_: Projection): Transform3D;
13 |
14 | };
15 |
16 | declare global {
17 | var Transform3D: Transform3DConstructor;
18 | }
19 |
20 | export interface Transform3D {
21 | basis: Basis;
22 | origin: Vector3;
23 |
24 | inverse(): Transform3D;
25 | affineInverse(): Transform3D;
26 | orthonormalized(): Transform3D;
27 | rotated(axis_: Vector3, angle_: number): Transform3D;
28 | rotatedLocal(axis_: Vector3, angle_: number): Transform3D;
29 | scaled(scale_: Vector3): Transform3D;
30 | scaledLocal(scale_: Vector3): Transform3D;
31 | translated(offset_: Vector3): Transform3D;
32 | translatedLocal(offset_: Vector3): Transform3D;
33 | interpolateWith(xform_: Transform3D, weight_: number): Transform3D;
34 | isEqualApprox(xform_: Transform3D): boolean;
35 | isFinite(): boolean;
36 |
37 | }
38 |
39 | export {}; // Ensure this file is treated as a module
40 |
--------------------------------------------------------------------------------
/package/src/variants/Vector2.ts:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED. DO NOT EDIT.
2 |
3 | import {Vector2i} from './Vector2i';
4 |
5 | type Vector2Constructor = {
6 | (): Vector2;
7 | (from_: Vector2): Vector2;
8 | (from_: Vector2i): Vector2;
9 | (x_: number, y_: number): Vector2;
10 |
11 | };
12 |
13 | declare global {
14 | var Vector2: Vector2Constructor;
15 | }
16 |
17 | export interface Vector2 {
18 | x: number;
19 | y: number;
20 |
21 | angle(): number;
22 | angleTo(to_: Vector2): number;
23 | angleToPoint(to_: Vector2): number;
24 | directionTo(to_: Vector2): Vector2;
25 | distanceTo(to_: Vector2): number;
26 | distanceSquaredTo(to_: Vector2): number;
27 | length(): number;
28 | lengthSquared(): number;
29 | limitLength(length_: number): Vector2;
30 | normalized(): Vector2;
31 | isNormalized(): boolean;
32 | isEqualApprox(to_: Vector2): boolean;
33 | isZeroApprox(): boolean;
34 | isFinite(): boolean;
35 | posmod(mod_: number): Vector2;
36 | posmodv(modv_: Vector2): Vector2;
37 | project(b_: Vector2): Vector2;
38 | lerp(to_: Vector2, weight_: number): Vector2;
39 | slerp(to_: Vector2, weight_: number): Vector2;
40 | cubicInterpolate(b_: Vector2, preA_: Vector2, postB_: Vector2, weight_: number): Vector2;
41 | cubicInterpolateInTime(b_: Vector2, preA_: Vector2, postB_: Vector2, weight_: number, bT_: number, preAT_: number, postBT_: number): Vector2;
42 | bezierInterpolate(control1_: Vector2, control2_: Vector2, end_: Vector2, t_: number): Vector2;
43 | maxAxisIndex(): number;
44 | minAxisIndex(): number;
45 | moveToward(to_: Vector2, delta_: number): Vector2;
46 | rotated(angle_: number): Vector2;
47 | orthogonal(): Vector2;
48 | floor(): Vector2;
49 | ceil(): Vector2;
50 | round(): Vector2;
51 | aspect(): number;
52 | dot(with_: Vector2): number;
53 | slide(n_: Vector2): Vector2;
54 | bounce(n_: Vector2): Vector2;
55 | reflect(line_: Vector2): Vector2;
56 | cross(with_: Vector2): number;
57 | abs(): Vector2;
58 | sign(): Vector2;
59 | clamp(min_: Vector2, max_: Vector2): Vector2;
60 | clampf(min_: number, max_: number): Vector2;
61 | snapped(step_: Vector2): Vector2;
62 | snappedf(step_: number): Vector2;
63 | min(with_: Vector2): Vector2;
64 | minf(with_: number): Vector2;
65 | max(with_: Vector2): Vector2;
66 | maxf(with_: number): Vector2;
67 | fromAngle(angle_: number): Vector2;
68 |
69 | }
70 |
71 | export {}; // Ensure this file is treated as a module
72 |
--------------------------------------------------------------------------------
/package/src/variants/Vector2i.ts:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED. DO NOT EDIT.
2 |
3 | import {Vector2} from './Vector2';
4 |
5 | type Vector2iConstructor = {
6 | (): Vector2i;
7 | (from_: Vector2i): Vector2i;
8 | (from_: Vector2): Vector2i;
9 | (x_: number, y_: number): Vector2i;
10 |
11 | };
12 |
13 | declare global {
14 | var Vector2i: Vector2iConstructor;
15 | }
16 |
17 | export interface Vector2i {
18 | x: number;
19 | y: number;
20 |
21 | aspect(): number;
22 | maxAxisIndex(): number;
23 | minAxisIndex(): number;
24 | distanceTo(to_: Vector2i): number;
25 | distanceSquaredTo(to_: Vector2i): number;
26 | length(): number;
27 | lengthSquared(): number;
28 | sign(): Vector2i;
29 | abs(): Vector2i;
30 | clamp(min_: Vector2i, max_: Vector2i): Vector2i;
31 | clampi(min_: number, max_: number): Vector2i;
32 | snapped(step_: Vector2i): Vector2i;
33 | snappedi(step_: number): Vector2i;
34 | min(with_: Vector2i): Vector2i;
35 | mini(with_: number): Vector2i;
36 | max(with_: Vector2i): Vector2i;
37 | maxi(with_: number): Vector2i;
38 |
39 | }
40 |
41 | export {}; // Ensure this file is treated as a module
42 |
--------------------------------------------------------------------------------
/package/src/variants/Vector3.ts:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED. DO NOT EDIT.
2 |
3 | import {Basis} from './Basis';
4 | import {Vector2} from './Vector2';
5 | import {Vector3i} from './Vector3i';
6 |
7 | type Vector3Constructor = {
8 | (): Vector3;
9 | (from_: Vector3): Vector3;
10 | (from_: Vector3i): Vector3;
11 | (x_: number, y_: number, z_: number): Vector3;
12 |
13 | };
14 |
15 | declare global {
16 | var Vector3: Vector3Constructor;
17 | }
18 |
19 | export interface Vector3 {
20 | x: number;
21 | y: number;
22 | z: number;
23 |
24 | minAxisIndex(): number;
25 | maxAxisIndex(): number;
26 | angleTo(to_: Vector3): number;
27 | signedAngleTo(to_: Vector3, axis_: Vector3): number;
28 | directionTo(to_: Vector3): Vector3;
29 | distanceTo(to_: Vector3): number;
30 | distanceSquaredTo(to_: Vector3): number;
31 | length(): number;
32 | lengthSquared(): number;
33 | limitLength(length_: number): Vector3;
34 | normalized(): Vector3;
35 | isNormalized(): boolean;
36 | isEqualApprox(to_: Vector3): boolean;
37 | isZeroApprox(): boolean;
38 | isFinite(): boolean;
39 | inverse(): Vector3;
40 | clamp(min_: Vector3, max_: Vector3): Vector3;
41 | clampf(min_: number, max_: number): Vector3;
42 | snapped(step_: Vector3): Vector3;
43 | snappedf(step_: number): Vector3;
44 | rotated(axis_: Vector3, angle_: number): Vector3;
45 | lerp(to_: Vector3, weight_: number): Vector3;
46 | slerp(to_: Vector3, weight_: number): Vector3;
47 | cubicInterpolate(b_: Vector3, preA_: Vector3, postB_: Vector3, weight_: number): Vector3;
48 | cubicInterpolateInTime(b_: Vector3, preA_: Vector3, postB_: Vector3, weight_: number, bT_: number, preAT_: number, postBT_: number): Vector3;
49 | bezierInterpolate(control1_: Vector3, control2_: Vector3, end_: Vector3, t_: number): Vector3;
50 | moveToward(to_: Vector3, delta_: number): Vector3;
51 | dot(with_: Vector3): number;
52 | cross(with_: Vector3): Vector3;
53 | outer(with_: Vector3): Basis;
54 | abs(): Vector3;
55 | floor(): Vector3;
56 | ceil(): Vector3;
57 | round(): Vector3;
58 | posmod(mod_: number): Vector3;
59 | posmodv(modv_: Vector3): Vector3;
60 | project(b_: Vector3): Vector3;
61 | slide(n_: Vector3): Vector3;
62 | bounce(n_: Vector3): Vector3;
63 | reflect(n_: Vector3): Vector3;
64 | sign(): Vector3;
65 | octahedronEncode(): Vector2;
66 | min(with_: Vector3): Vector3;
67 | minf(with_: number): Vector3;
68 | max(with_: Vector3): Vector3;
69 | maxf(with_: number): Vector3;
70 | octahedronDecode(uv_: Vector2): Vector3;
71 |
72 | }
73 |
74 | export {}; // Ensure this file is treated as a module
75 |
--------------------------------------------------------------------------------
/package/src/variants/Vector3i.ts:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED. DO NOT EDIT.
2 |
3 | import {Vector3} from './Vector3';
4 |
5 | type Vector3iConstructor = {
6 | (): Vector3i;
7 | (from_: Vector3i): Vector3i;
8 | (from_: Vector3): Vector3i;
9 | (x_: number, y_: number, z_: number): Vector3i;
10 |
11 | };
12 |
13 | declare global {
14 | var Vector3i: Vector3iConstructor;
15 | }
16 |
17 | export interface Vector3i {
18 | x: number;
19 | y: number;
20 | z: number;
21 |
22 | minAxisIndex(): number;
23 | maxAxisIndex(): number;
24 | distanceTo(to_: Vector3i): number;
25 | distanceSquaredTo(to_: Vector3i): number;
26 | length(): number;
27 | lengthSquared(): number;
28 | sign(): Vector3i;
29 | abs(): Vector3i;
30 | clamp(min_: Vector3i, max_: Vector3i): Vector3i;
31 | clampi(min_: number, max_: number): Vector3i;
32 | snapped(step_: Vector3i): Vector3i;
33 | snappedi(step_: number): Vector3i;
34 | min(with_: Vector3i): Vector3i;
35 | mini(with_: number): Vector3i;
36 | max(with_: Vector3i): Vector3i;
37 | maxi(with_: number): Vector3i;
38 |
39 | }
40 |
41 | export {}; // Ensure this file is treated as a module
42 |
--------------------------------------------------------------------------------
/package/src/variants/Vector4.ts:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED. DO NOT EDIT.
2 |
3 | import {Vector4i} from './Vector4i';
4 |
5 | type Vector4Constructor = {
6 | (): Vector4;
7 | (from_: Vector4): Vector4;
8 | (from_: Vector4i): Vector4;
9 | (x_: number, y_: number, z_: number, w_: number): Vector4;
10 |
11 | };
12 |
13 | declare global {
14 | var Vector4: Vector4Constructor;
15 | }
16 |
17 | export interface Vector4 {
18 | x: number;
19 | y: number;
20 | z: number;
21 | w: number;
22 |
23 | minAxisIndex(): number;
24 | maxAxisIndex(): number;
25 | length(): number;
26 | lengthSquared(): number;
27 | abs(): Vector4;
28 | sign(): Vector4;
29 | floor(): Vector4;
30 | ceil(): Vector4;
31 | round(): Vector4;
32 | lerp(to_: Vector4, weight_: number): Vector4;
33 | cubicInterpolate(b_: Vector4, preA_: Vector4, postB_: Vector4, weight_: number): Vector4;
34 | cubicInterpolateInTime(b_: Vector4, preA_: Vector4, postB_: Vector4, weight_: number, bT_: number, preAT_: number, postBT_: number): Vector4;
35 | posmod(mod_: number): Vector4;
36 | posmodv(modv_: Vector4): Vector4;
37 | snapped(step_: Vector4): Vector4;
38 | snappedf(step_: number): Vector4;
39 | clamp(min_: Vector4, max_: Vector4): Vector4;
40 | clampf(min_: number, max_: number): Vector4;
41 | normalized(): Vector4;
42 | isNormalized(): boolean;
43 | directionTo(to_: Vector4): Vector4;
44 | distanceTo(to_: Vector4): number;
45 | distanceSquaredTo(to_: Vector4): number;
46 | dot(with_: Vector4): number;
47 | inverse(): Vector4;
48 | isEqualApprox(to_: Vector4): boolean;
49 | isZeroApprox(): boolean;
50 | isFinite(): boolean;
51 | min(with_: Vector4): Vector4;
52 | minf(with_: number): Vector4;
53 | max(with_: Vector4): Vector4;
54 | maxf(with_: number): Vector4;
55 |
56 | }
57 |
58 | export {}; // Ensure this file is treated as a module
59 |
--------------------------------------------------------------------------------
/package/src/variants/Vector4i.ts:
--------------------------------------------------------------------------------
1 | // THIS FILE IS GENERATED. DO NOT EDIT.
2 |
3 | import {Vector4} from './Vector4';
4 |
5 | type Vector4iConstructor = {
6 | (): Vector4i;
7 | (from_: Vector4i): Vector4i;
8 | (from_: Vector4): Vector4i;
9 | (x_: number, y_: number, z_: number, w_: number): Vector4i;
10 |
11 | };
12 |
13 | declare global {
14 | var Vector4i: Vector4iConstructor;
15 | }
16 |
17 | export interface Vector4i {
18 | x: number;
19 | y: number;
20 | z: number;
21 | w: number;
22 |
23 | minAxisIndex(): number;
24 | maxAxisIndex(): number;
25 | length(): number;
26 | lengthSquared(): number;
27 | sign(): Vector4i;
28 | abs(): Vector4i;
29 | clamp(min_: Vector4i, max_: Vector4i): Vector4i;
30 | clampi(min_: number, max_: number): Vector4i;
31 | snapped(step_: Vector4i): Vector4i;
32 | snappedi(step_: number): Vector4i;
33 | min(with_: Vector4i): Vector4i;
34 | mini(with_: number): Vector4i;
35 | max(with_: Vector4i): Vector4i;
36 | maxi(with_: number): Vector4i;
37 | distanceTo(to_: Vector4i): number;
38 | distanceSquaredTo(to_: Vector4i): number;
39 |
40 | }
41 |
42 | export {}; // Ensure this file is treated as a module
43 |
--------------------------------------------------------------------------------
/package/src/views/Godot.tsx:
--------------------------------------------------------------------------------
1 | import React, {useEffect, forwardRef, useRef} from 'react';
2 | import type {Ref, MutableRefObject, ForwardedRef, FunctionComponent} from 'react';
3 |
4 | import {GodotView} from './GodotView';
5 | import type {GodotViewProps} from './types';
6 |
7 | export const useGodotRef = () => useRef(null);
8 |
9 | export interface GodotProps extends GodotViewProps {
10 | ref?: Ref | undefined;
11 | }
12 |
13 | export const Godot = forwardRef(
14 | (
15 | {
16 | style,
17 | onLayout: _onLayout,
18 | source,
19 | scene,
20 | debug,
21 | onMessage,
22 | ...props
23 | },
24 | forwardedRef
25 | ) => {
26 | const innerRef = useGodotRef();
27 | const ref = useCombinedRefs(forwardedRef, innerRef);
28 |
29 | return (
30 |
40 | );
41 | }
42 | ) as FunctionComponent>;
43 |
44 | /**
45 | * Combines a list of refs into a single ref. This can be used to provide
46 | * both a forwarded ref and an internal ref keeping the same functionality
47 | * on both of the refs.
48 | * @param refs Array of refs to combine
49 | * @returns A single ref that can be used in a ref prop.
50 | */
51 | const useCombinedRefs = (
52 | ...refs: Array | ForwardedRef>
53 | ) => {
54 | const targetRef = React.useRef(null);
55 |
56 | useEffect(() => {
57 | refs.forEach((ref) => {
58 | if (ref) {
59 | if (typeof ref === 'function') {
60 | ref(targetRef.current);
61 | } else {
62 | ref.current = targetRef.current;
63 | }
64 | }
65 | });
66 | }, [refs]);
67 |
68 | return targetRef;
69 | };
--------------------------------------------------------------------------------
/package/src/views/GodotView.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {Image} from 'react-native';
3 | import type {HostComponent} from 'react-native';
4 |
5 | import GodotViewNativeComponent from '../specs/GodotViewNativeComponent';
6 |
7 | import {GodotViewApi} from './api';
8 | import type {GodotViewProps} from './types';
9 | import {GodotViewNativeId} from './GodotViewNativeId';
10 |
11 | const NativeGodotView: HostComponent = GodotViewNativeComponent;
12 |
13 | export class GodotView extends React.Component {
14 | constructor(props: GodotViewProps) {
15 | super(props);
16 | this._nativeID = GodotViewNativeId.current++;
17 | const {source, scene, onMessage} = props;
18 |
19 | if (source) {
20 | assertGodotViewApi();
21 | GodotViewApi.setJsiProperty(this._nativeID, "source", Image.resolveAssetSource(source as any).uri);
22 | }
23 |
24 | if (scene) {
25 | assertGodotViewApi();
26 | GodotViewApi.setJsiProperty(this._nativeID, "scene", scene);
27 | }
28 |
29 | if (onMessage) {
30 | assertGodotViewApi();
31 | GodotViewApi.setJsiProperty(this._nativeID, "onMessage", onMessage);
32 | }
33 | }
34 |
35 | private _nativeID: number;
36 |
37 | public get nativeId() {
38 | return this._nativeID;
39 | }
40 |
41 | componentDidUpdate(prevProps: GodotViewProps) {
42 | const {source, scene, onMessage} = this.props;
43 |
44 | if (source !== prevProps.source) {
45 | assertGodotViewApi();
46 | GodotViewApi.setJsiProperty(this._nativeID, "source", Image.resolveAssetSource(source as any).uri);
47 | }
48 |
49 | if (scene !== prevProps.scene) {
50 | assertGodotViewApi();
51 | GodotViewApi.setJsiProperty(this._nativeID, "scene", scene);
52 | }
53 |
54 | if (prevProps.onMessage === undefined && onMessage !== undefined) {
55 | assertGodotViewApi();
56 | GodotViewApi.setJsiProperty(this._nativeID, "onMessage", onMessage);
57 | }
58 | }
59 |
60 | /**
61 | * Pause the Godot view.
62 | */
63 | public pause() {
64 | assertGodotViewApi();
65 | GodotViewApi.pause(this._nativeID);
66 | }
67 |
68 | /**
69 | * Resume the Godot view.
70 | */
71 | public resume() {
72 | assertGodotViewApi();
73 | GodotViewApi.resume(this._nativeID);
74 | }
75 |
76 | /**
77 | * Resume the Godot view.
78 | */
79 | public getRoot() {
80 | assertGodotViewApi();
81 | return GodotViewApi.getRoot(this._nativeID);
82 | }
83 |
84 | /**
85 | * Start drawing the Godot view.
86 | */
87 | public static startDrawing() {
88 | assertGodotViewApi();
89 | GodotViewApi.startDrawing();
90 | }
91 |
92 | /**
93 | * Stop drawing the Godot view
94 | */
95 | public static stopDrawing() {
96 | assertGodotViewApi();
97 | GodotViewApi.stopDrawing();
98 | }
99 |
100 | /**
101 | * Emit a message to the Godot view.
102 | */
103 | public emitMessage(message: any) {
104 | assertGodotViewApi();
105 | GodotViewApi.emitMessage(this._nativeID, message);
106 | }
107 |
108 | /**
109 | * Check if the Godot view is ready.
110 | */
111 | public get isReady(): boolean {
112 | assertGodotViewApi();
113 | return GodotViewApi.isReady(this._nativeID);
114 | }
115 |
116 | render() {
117 | const {debug = false, ...viewProps} = this.props;
118 | return (
119 |
124 | );
125 | }
126 | }
127 |
128 | const assertGodotViewApi = () => {
129 | if (
130 | GodotViewApi === null ||
131 | GodotViewApi.setJsiProperty === null ||
132 | GodotViewApi.pause === null ||
133 | GodotViewApi.resume === null ||
134 | GodotViewApi.getRoot === null ||
135 | GodotViewApi.isReady === null
136 | ) {
137 | throw Error('Godot View API was not found.');
138 | }
139 | };
--------------------------------------------------------------------------------
/package/src/views/GodotViewNativeId.ts:
--------------------------------------------------------------------------------
1 | export const GodotViewNativeId = {current: 1000};
--------------------------------------------------------------------------------
/package/src/views/api.ts:
--------------------------------------------------------------------------------
1 | import type {IGodotViewApi} from './types';
2 |
3 | declare global {
4 | var GodotViewApi: IGodotViewApi;
5 | }
6 |
7 | export const {GodotViewApi} = global;
--------------------------------------------------------------------------------
/package/src/views/index.ts:
--------------------------------------------------------------------------------
1 | export * from './Godot';
2 | export * from './GodotView';
3 | export * from './types';
--------------------------------------------------------------------------------
/package/src/views/types.ts:
--------------------------------------------------------------------------------
1 | import type {ViewProps, ImageSourcePropType} from 'react-native';
2 | import {GD} from '../types';
3 |
4 | export interface IGodotViewApi {
5 | setJsiProperty: (nativeId: number, name: string, value: T) => void;
6 | pause: (nativeId: number) => void;
7 | resume: (nativeId: number) => void;
8 | getRoot: (nativeId: number) => GD.Node | null;
9 | isReady: (nativeId: number) => boolean;
10 | startDrawing: () => void;
11 | stopDrawing: () => void;
12 | emitMessage: (nativeId: number, message: any) => void;
13 | }
14 |
15 | export type GodotMessageEventHandler = (message: any) => void;
16 |
17 | type Source = ImageSourcePropType;
18 |
19 | export interface GodotViewProps extends ViewProps {
20 | source?: Source;
21 | scene?: string;
22 | debug?: boolean;
23 | onMessage?: GodotMessageEventHandler;
24 | }
--------------------------------------------------------------------------------
/package/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "esnext",
4 | "lib": [
5 | "dom",
6 | "es2019"
7 | ],
8 | "allowJs": true,
9 | "skipLibCheck": true,
10 | "allowSyntheticDefaultImports": true,
11 | "resolveJsonModule": true,
12 | "esModuleInterop": true,
13 | "moduleResolution": "node",
14 | "jsx": "react-native",
15 | "strict": true,
16 | "forceConsistentCasingInFileNames": true,
17 | "noUnusedLocals": false /* Report errors on unused locals. */,
18 | "noUnusedParameters": true /* Report errors on unused parameters. */,
19 | "noImplicitReturns": true /* Report error when not all code paths in function return a value. */,
20 | "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */,
21 | "noUncheckedIndexedAccess": false, /* Include 'undefined' in index signature results */
22 | "allowUnreachableCode": false,
23 | "allowUnusedLabels": false,
24 | "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
25 | "strictNullChecks": true, /* Enable strict null checks. */
26 | "strictFunctionTypes": true, /* Enable strict checking of function types. */
27 | "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
28 | "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
29 | "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
30 | "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
31 | },
32 | "exclude": [
33 | "node_modules",
34 | "babel.config.js",
35 | "metro.config.js",
36 | "lib",
37 | ]
38 | }
39 |
--------------------------------------------------------------------------------
/screenshots/screenshot1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calico-games/react-native-godot/3892f30db6e43715609562c6e50960613ecf0df9/screenshots/screenshot1.jpeg
--------------------------------------------------------------------------------
/screenshots/screenshot2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calico-games/react-native-godot/3892f30db6e43715609562c6e50960613ecf0df9/screenshots/screenshot2.jpeg
--------------------------------------------------------------------------------
/screenshots/screenshot3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calico-games/react-native-godot/3892f30db6e43715609562c6e50960613ecf0df9/screenshots/screenshot3.png
--------------------------------------------------------------------------------
/static/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/calico-games/react-native-godot/3892f30db6e43715609562c6e50960613ecf0df9/static/banner.png
--------------------------------------------------------------------------------