rngine 0.9.1 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/typescript/src/GameEngine.d.ts +1 -1
- package/lib/typescript/src/GameEngine.d.ts.map +1 -1
- package/lib/typescript/src/GameMethods.d.ts +2 -2
- package/lib/typescript/src/GameMethods.d.ts.map +1 -1
- package/lib/typescript/src/GameMethods.nitro.d.ts +1 -1
- package/lib/typescript/src/GameMethods.nitro.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +4 -4
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/nativeTypes.d.ts +3 -1
- package/lib/typescript/src/nativeTypes.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +1 -1
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/nitrogen/generated/android/c++/views/JHybridGameEngineStateUpdater.cpp +34 -17
- package/nitrogen/generated/android/c++/views/JHybridGameEngineStateUpdater.hpp +6 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngine/HybridGameEngineSpec.kt +2 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngine/views/HybridGameEngineManager.kt +26 -10
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngine/views/HybridGameEngineStateUpdater.kt +2 -2
- package/nitrogen/generated/ios/c++/views/HybridGameEngineComponent.mm +40 -19
- package/nitrogen/generated/shared/c++/Entity.hpp +5 -1
- package/nitrogen/generated/shared/c++/EntityUpdate.hpp +5 -1
- package/nitrogen/generated/shared/c++/Screen.hpp +6 -2
- package/nitrogen/generated/shared/c++/ScreenUpdate.hpp +6 -2
- package/nitrogen/generated/shared/c++/views/HybridGameEngineComponent.cpp +5 -45
- package/nitrogen/generated/shared/c++/views/HybridGameEngineComponent.hpp +20 -48
- package/package.json +21 -63
- package/shared/GameLoop.cpp +2 -2
- package/shared/GameMethods.cpp +2 -0
- package/shared/utils/AssetUtils.cpp +12 -5
- package/shared/utils/AssetUtils.hpp +3 -2
- package/src/nativeTypes.ts +3 -1
- package/android/kls_database.db +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { GameEngineMethods, GameEngineProps } from './GameEngine.nitro';
|
|
1
|
+
import type { GameEngineMethods, GameEngineProps } from './GameEngine.nitro.js';
|
|
2
2
|
/**
|
|
3
3
|
* A game engine view component that renders the game world.
|
|
4
4
|
* Size it using the style prop like any other React Native view.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GameEngine.d.ts","sourceRoot":"","sources":["../../../src/GameEngine.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"GameEngine.d.ts","sourceRoot":"","sources":["../../../src/GameEngine.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,uBAAoB,CAAC;AAE7E;;;;;;;;GAQG;;AACH,wBAGE"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Entity, EntityUpdate, ScreenUpdate } from './nativeTypes';
|
|
2
|
-
import type { Config } from './types';
|
|
1
|
+
import type { Entity, EntityUpdate, ScreenUpdate } from './nativeTypes.js';
|
|
2
|
+
import type { Config } from './types.js';
|
|
3
3
|
/** Sets up the game engine with the given configuration. Call this before anything else. */
|
|
4
4
|
export declare const configure: ({ world, screen, entities, systems, paused, }: Config) => void;
|
|
5
5
|
/** Pauses the game loop. Systems will stop running. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GameMethods.d.ts","sourceRoot":"","sources":["../../../src/GameMethods.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAU,MAAM,
|
|
1
|
+
{"version":3,"file":"GameMethods.d.ts","sourceRoot":"","sources":["../../../src/GameMethods.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAU,MAAM,kBAAe,CAAC;AAChF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAS,CAAC;AAGtC,4FAA4F;AAC5F,eAAO,MAAM,SAAS,GAAI,+CAMvB,MAAM,SAyBR,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,KAAK,YAA4B,CAAC;AAE/C,6BAA6B;AAC7B,eAAO,MAAM,MAAM,YAA6B,CAAC;AAEjD,0EAA0E;AAC1E,eAAO,MAAM,KAAK,GAAI,UAAU,MAAM,GAAG,MAAM,EAAE,SAGhD,CAAC;AAEF,2HAA2H;AAC3H,eAAO,MAAM,OAAO,GAAI,IAAI,MAAM,SAA4B,CAAC;AAE/D,+HAA+H;AAC/H,eAAO,MAAM,YAAY,GAAI,cAAc,YAAY,SAEtD,CAAC;AAEF,oGAAoG;AACpG,eAAO,MAAM,cAAc,GAAI,eAAe,YAAY,EAAE,SAE3D,CAAC;AAEF,gEAAgE;AAChE,eAAO,MAAM,YAAY,GAAI,cAAc,YAAY,SAEtD,CAAC;AA2CF;;yEAEyE;AACzE,eAAO,MAAM,UAAU,GAAU,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChE,QAAQ,CAAC,KACR,OAAO,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,GAAE,CASpC,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { HybridObject } from 'react-native-nitro-modules';
|
|
2
|
-
import type { Entity, EntityUpdate, System, Screen, World, ScreenUpdate } from './nativeTypes';
|
|
2
|
+
import type { Entity, EntityUpdate, System, Screen, World, ScreenUpdate } from './nativeTypes.js';
|
|
3
3
|
interface GameMethods extends HybridObject<{
|
|
4
4
|
ios: 'c++';
|
|
5
5
|
android: 'c++';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GameMethods.nitro.d.ts","sourceRoot":"","sources":["../../../src/GameMethods.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EACV,MAAM,EACN,YAAY,EACZ,MAAM,EACN,MAAM,EACN,KAAK,EACL,YAAY,EACb,MAAM,
|
|
1
|
+
{"version":3,"file":"GameMethods.nitro.d.ts","sourceRoot":"","sources":["../../../src/GameMethods.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EACV,MAAM,EACN,YAAY,EACZ,MAAM,EACN,MAAM,EACN,KAAK,EACL,YAAY,EACb,MAAM,kBAAe,CAAC;AAGvB,UAAU,WAAY,SAAQ,YAAY,CAAC;IACzC,GAAG,EAAE,KAAK,CAAC;IACX,OAAO,EAAE,KAAK,CAAC;CAChB,CAAC;IACA,4BAA4B;IAC5B,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAC7B,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACtC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAEpC,2BAA2B;IAC3B,KAAK,IAAI,IAAI,CAAC;IACd,MAAM,IAAI,IAAI,CAAC;IAEf,4BAA4B;IAC5B,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAChC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,cAAc,CAAC,aAAa,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;IAEpD,4BAA4B;IAC5B,YAAY,CAAC,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;IAE/C,oBAAoB;IACpB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IACnC,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1D,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3D;AAED,eAAO,MAAM,WAAW,aACqC,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import GameEngine from './GameEngine';
|
|
2
|
-
export * from './GameMethods';
|
|
3
|
-
export * from './types';
|
|
4
|
-
export type { World, Screen, Entity, CollisionPair, Collision, EntityUpdate, SystemContext, } from './nativeTypes';
|
|
1
|
+
import GameEngine from './GameEngine.js';
|
|
2
|
+
export * from './GameMethods.js';
|
|
3
|
+
export * from './types.js';
|
|
4
|
+
export type { World, Screen, Entity, CollisionPair, Collision, EntityUpdate, SystemContext, } from './nativeTypes.js';
|
|
5
5
|
export { GameEngine };
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,iBAAc,CAAC;AAEtC,cAAc,kBAAe,CAAC;AAC9B,cAAc,YAAS,CAAC;AACxB,YAAY,EACV,KAAK,EACL,MAAM,EACN,MAAM,EACN,aAAa,EACb,SAAS,EACT,YAAY,EACZ,aAAa,GACd,MAAM,kBAAe,CAAC;AACvB,OAAO,EAAE,UAAU,EAAE,CAAC"}
|
|
@@ -31,8 +31,10 @@ interface Renderable {
|
|
|
31
31
|
flipV?: boolean;
|
|
32
32
|
/** Animation progress between 0 and 1, automatically advanced each tick for Lottie assets. */
|
|
33
33
|
progress?: number;
|
|
34
|
-
/** Playback speed multiplier for
|
|
34
|
+
/** Playback speed multiplier for Lottie assets (1 = normal speed). */
|
|
35
35
|
speed?: number;
|
|
36
|
+
/** Whether the Lottie animation should restart automatically upon completion. */
|
|
37
|
+
loop?: boolean;
|
|
36
38
|
}
|
|
37
39
|
interface Kinematic {
|
|
38
40
|
/** Horizontal velocity in game units per second. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nativeTypes.d.ts","sourceRoot":"","sources":["../../../src/nativeTypes.ts"],"names":[],"mappings":"AAAA,UAAU,UAAU;IAClB,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,UAAU,IAAI;IACZ,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,MAAM;IACd,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,MAAM;IACd,2BAA2B;IAC3B,KAAK,EAAE,IAAI,GAAG,MAAM,CAAC;IACrB,6GAA6G;IAC7G,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,UAAU,UAAU;IAClB,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,qDAAqD;IACrD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,8FAA8F;IAC9F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,
|
|
1
|
+
{"version":3,"file":"nativeTypes.d.ts","sourceRoot":"","sources":["../../../src/nativeTypes.ts"],"names":[],"mappings":"AAAA,UAAU,UAAU;IAClB,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,UAAU,IAAI;IACZ,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,MAAM;IACd,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,MAAM;IACd,2BAA2B;IAC3B,KAAK,EAAE,IAAI,GAAG,MAAM,CAAC;IACrB,6GAA6G;IAC7G,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,UAAU,UAAU;IAClB,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,qDAAqD;IACrD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,8FAA8F;IAC9F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,UAAU,SAAS;IACjB,oDAAoD;IACpD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,kDAAkD;IAClD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,gEAAgE;IAChE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,8DAA8D;IAC9D,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,+BAA+B;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,KAAK;IACpB,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,4EAA4E;IAC5E,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,MAAO,SAAQ,UAAU,EAAE,IAAI,EAAE,UAAU;CAAG;AAE/D,MAAM,WAAW,MAAO,SAAQ,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS;IACvE,oFAAoF;IACpF,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,YAAa,SAAQ,OAAO,CAC3C,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,CAC7C;IACC,6DAA6D;IAC7D,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,YAAa,SAAQ,OAAO,CAAC,MAAM,CAAC;CAAG;AAExD,MAAM,WAAW,aAAa;IAC5B,wDAAwD;IACxD,CAAC,EAAE,MAAM,CAAC;IACV,yDAAyD;IACzD,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,SAAS;IACxB,wDAAwD;IACxD,CAAC,EAAE,MAAM,CAAC;IACV,yDAAyD;IACzD,CAAC,EAAE,MAAM,CAAC;IACV,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,qIAAqI;IACrI,EAAE,EAAE,MAAM,CAAC;IACX,qIAAqI;IACrI,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,gEAAgE;IAChE,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,MAAM;IACrB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;IAC7B,mEAAmE;IACnE,MAAM,EAAE,CAAC,aAAa,EAAE,aAAa,KAAK,MAAM,CAAC;CAClD"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { System as NativeSystem, Screen, Entity, World, SystemContext } from './nativeTypes';
|
|
1
|
+
import type { System as NativeSystem, Screen, Entity, World, SystemContext } from './nativeTypes.js';
|
|
2
2
|
export type System = Omit<NativeSystem, 'onTick'> & {
|
|
3
3
|
/** Called every tick with the resolved entities and collisions. */
|
|
4
4
|
onTick: (systemContext: SystemContext) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,IAAI,YAAY,EACtB,MAAM,EACN,MAAM,EACN,KAAK,EACL,aAAa,EACd,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,IAAI,YAAY,EACtB,MAAM,EACN,MAAM,EACN,KAAK,EACL,aAAa,EACd,MAAM,kBAAe,CAAC;AAEvB,MAAM,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,GAAG;IAClD,mEAAmE;IACnE,MAAM,EAAE,CAAC,aAAa,EAAE,aAAa,KAAK,IAAI,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACnB,6CAA6C;IAC7C,KAAK,EAAE,KAAK,CAAC;IACb,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,8GAA8G;IAC9G,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,wDAAwD;IACxD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC"}
|
|
@@ -15,38 +15,55 @@ namespace margelo::nitro::rngine::views {
|
|
|
15
15
|
using namespace facebook;
|
|
16
16
|
using ConcreteStateData = react::ConcreteState<HybridGameEngineState>;
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
std::shared_ptr<const HybridGameEngineProps> JHybridGameEngineStateUpdater::getPropsFromStateWrapper(
|
|
19
|
+
jni::alias_ref<JStateWrapper::javaobject> stateWrapper) {
|
|
20
|
+
if (stateWrapper.get() == nullptr) {
|
|
21
|
+
return nullptr;
|
|
22
|
+
}
|
|
23
23
|
// Get concrete StateWrapperImpl from passed StateWrapper interface object
|
|
24
|
-
jobject rawStateWrapper =
|
|
25
|
-
if (!
|
|
26
|
-
|
|
24
|
+
jobject rawStateWrapper = stateWrapper.get();
|
|
25
|
+
if (!stateWrapper->isInstanceOf(react::StateWrapperImpl::javaClassStatic())) [[unlikely]] {
|
|
26
|
+
throw std::runtime_error("StateWrapper is not a StateWrapperImpl");
|
|
27
|
+
}
|
|
28
|
+
auto stateWrapperImpl = jni::alias_ref<react::StateWrapperImpl::javaobject>{
|
|
29
|
+
static_cast<react::StateWrapperImpl::javaobject>(rawStateWrapper)
|
|
30
|
+
};
|
|
31
|
+
std::shared_ptr<const react::State> state = stateWrapperImpl->cthis()->getState();
|
|
32
|
+
if (state == nullptr) {
|
|
33
|
+
return nullptr;
|
|
27
34
|
}
|
|
28
|
-
auto stateWrapper = jni::alias_ref<react::StateWrapperImpl::javaobject>{
|
|
29
|
-
static_cast<react::StateWrapperImpl::javaobject>(rawStateWrapper)};
|
|
30
|
-
std::shared_ptr<const react::State> state = stateWrapper->cthis()->getState();
|
|
31
35
|
auto concreteState = std::static_pointer_cast<const ConcreteStateData>(state);
|
|
32
36
|
const HybridGameEngineState& data = concreteState->getData();
|
|
33
|
-
const std::shared_ptr<HybridGameEngineProps>& props = data.getProps();
|
|
37
|
+
const std::shared_ptr<const HybridGameEngineProps>& props = data.getProps();
|
|
34
38
|
if (props == nullptr) [[unlikely]] {
|
|
35
|
-
// Props aren't set yet!
|
|
36
39
|
throw std::runtime_error("HybridGameEngineState's data doesn't contain any props!");
|
|
37
40
|
}
|
|
41
|
+
return props;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
void JHybridGameEngineStateUpdater::updateViewProps(jni::alias_ref<jni::JClass> /* class */,
|
|
45
|
+
jni::alias_ref<JHybridGameEngineSpec::JavaPart> javaView,
|
|
46
|
+
jni::alias_ref<JStateWrapper::javaobject> newState,
|
|
47
|
+
jni::alias_ref<JStateWrapper::javaobject> oldState) {
|
|
48
|
+
std::shared_ptr<JHybridGameEngineSpec> hybridView = javaView->getJHybridGameEngineSpec();
|
|
49
|
+
std::shared_ptr<const HybridGameEngineProps> newProps = getPropsFromStateWrapper(newState);
|
|
50
|
+
std::shared_ptr<const HybridGameEngineProps> oldProps = getPropsFromStateWrapper(oldState);
|
|
51
|
+
if (newProps == nullptr) [[unlikely]] {
|
|
52
|
+
throw std::runtime_error("Current StateWrapper doesn't contain any props!");
|
|
53
|
+
}
|
|
38
54
|
|
|
39
|
-
// Update
|
|
55
|
+
// Update only props that differ from the previous State snapshot.
|
|
40
56
|
|
|
41
57
|
|
|
42
58
|
// Update hybridRef if it changed
|
|
43
|
-
if (
|
|
59
|
+
if (oldProps == nullptr
|
|
60
|
+
? newProps->hybridRef.isProvided()
|
|
61
|
+
: !newProps->hybridRef.hasSameValue(oldProps->hybridRef)) {
|
|
44
62
|
// hybridRef changed - call it with new this
|
|
45
|
-
const auto& maybeFunc =
|
|
63
|
+
const auto& maybeFunc = newProps->hybridRef.get();
|
|
46
64
|
if (maybeFunc.has_value()) {
|
|
47
65
|
maybeFunc.value()(hybridView);
|
|
48
66
|
}
|
|
49
|
-
props->hybridRef.isDirty = false;
|
|
50
67
|
}
|
|
51
68
|
}
|
|
52
69
|
|
|
@@ -31,7 +31,12 @@ public:
|
|
|
31
31
|
public:
|
|
32
32
|
static void updateViewProps(jni::alias_ref<jni::JClass> /* class */,
|
|
33
33
|
jni::alias_ref<JHybridGameEngineSpec::JavaPart> view,
|
|
34
|
-
jni::alias_ref<JStateWrapper::javaobject>
|
|
34
|
+
jni::alias_ref<JStateWrapper::javaobject> newState,
|
|
35
|
+
jni::alias_ref<JStateWrapper::javaobject> oldState);
|
|
36
|
+
|
|
37
|
+
private:
|
|
38
|
+
static std::shared_ptr<const HybridGameEngineProps> getPropsFromStateWrapper(
|
|
39
|
+
jni::alias_ref<JStateWrapper::javaobject> stateWrapper);
|
|
35
40
|
|
|
36
41
|
public:
|
|
37
42
|
static void registerNatives() {
|
|
@@ -10,6 +10,7 @@ package com.margelo.nitro.rngine
|
|
|
10
10
|
import androidx.annotation.Keep
|
|
11
11
|
import com.facebook.jni.HybridData
|
|
12
12
|
import com.facebook.proguard.annotations.DoNotStrip
|
|
13
|
+
import dalvik.annotation.optimization.FastNative
|
|
13
14
|
import com.margelo.nitro.core.HybridObject
|
|
14
15
|
import com.margelo.nitro.views.HybridView
|
|
15
16
|
|
|
@@ -41,6 +42,7 @@ abstract class HybridGameEngineSpec: HybridView() {
|
|
|
41
42
|
@Keep
|
|
42
43
|
protected open class CxxPart(javaPart: HybridGameEngineSpec): HybridObject.CxxPart(javaPart) {
|
|
43
44
|
// C++ JHybridGameEngineSpec::CxxPart::initHybrid(...)
|
|
45
|
+
@FastNative
|
|
44
46
|
external override fun initHybrid(): HybridData
|
|
45
47
|
}
|
|
46
48
|
override fun createCxxPart(): CxxPart {
|
package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngine/views/HybridGameEngineManager.kt
CHANGED
|
@@ -20,6 +20,14 @@ import com.margelo.nitro.rngine.*
|
|
|
20
20
|
* Represents the React Native `ViewManager` for the "GameEngine" Nitro HybridView.
|
|
21
21
|
*/
|
|
22
22
|
public class HybridGameEngineManager: SimpleViewManager<View>() {
|
|
23
|
+
/**
|
|
24
|
+
* Represents the View and its last state snapshot (mutable)
|
|
25
|
+
*/
|
|
26
|
+
private class HybridViewHolder(
|
|
27
|
+
val hybridView: GameEngine,
|
|
28
|
+
var lastState: StateWrapper? = null,
|
|
29
|
+
)
|
|
30
|
+
|
|
23
31
|
init {
|
|
24
32
|
if (RecyclableView::class.java.isAssignableFrom(GameEngine::class.java)) {
|
|
25
33
|
// Enable view recycling
|
|
@@ -34,33 +42,41 @@ public class HybridGameEngineManager: SimpleViewManager<View>() {
|
|
|
34
42
|
override fun createViewInstance(reactContext: ThemedReactContext): View {
|
|
35
43
|
val hybridView = GameEngine(reactContext)
|
|
36
44
|
val view = hybridView.view
|
|
37
|
-
view.setTag(associated_hybrid_view_tag, hybridView)
|
|
45
|
+
view.setTag(associated_hybrid_view_tag, HybridViewHolder(hybridView))
|
|
38
46
|
return view
|
|
39
47
|
}
|
|
40
48
|
|
|
41
49
|
override fun updateState(view: View, props: ReactStylesDiffMap, stateWrapper: StateWrapper): Any? {
|
|
42
|
-
val
|
|
50
|
+
val holder = getHybridViewHolder(view)
|
|
43
51
|
?: throw Error("Couldn't find view $view in local views table!")
|
|
52
|
+
val hybridView = holder.hybridView
|
|
53
|
+
val oldState = holder.lastState
|
|
54
|
+
val newState = stateWrapper
|
|
44
55
|
|
|
45
56
|
// 1. Update each prop individually
|
|
46
57
|
hybridView.beforeUpdate()
|
|
47
|
-
HybridGameEngineStateUpdater.updateViewProps(hybridView,
|
|
58
|
+
HybridGameEngineStateUpdater.updateViewProps(hybridView, newState, oldState)
|
|
48
59
|
hybridView.afterUpdate()
|
|
60
|
+
holder.lastState = newState
|
|
49
61
|
|
|
50
62
|
// 2. Continue in base View props
|
|
51
|
-
return super.updateState(view, props,
|
|
63
|
+
return super.updateState(view, props, newState)
|
|
52
64
|
}
|
|
53
65
|
|
|
54
66
|
override fun onDropViewInstance(view: View) {
|
|
55
|
-
val
|
|
56
|
-
|
|
67
|
+
val holder = getHybridViewHolder(view)
|
|
68
|
+
holder?.lastState = null
|
|
69
|
+
holder?.hybridView?.onDropView()
|
|
57
70
|
return super.onDropViewInstance(view)
|
|
58
71
|
}
|
|
59
72
|
|
|
60
73
|
protected override fun prepareToRecycleView(reactContext: ThemedReactContext, view: View): View? {
|
|
61
|
-
super.prepareToRecycleView(reactContext, view)
|
|
62
|
-
|
|
74
|
+
val preparedView = super.prepareToRecycleView(reactContext, view)
|
|
75
|
+
?: return null
|
|
76
|
+
val holder = getHybridViewHolder(preparedView)
|
|
63
77
|
?: return null
|
|
78
|
+
val hybridView = holder.hybridView
|
|
79
|
+
holder.lastState = null
|
|
64
80
|
|
|
65
81
|
@Suppress("USELESS_IS_CHECK")
|
|
66
82
|
if (hybridView is RecyclableView) {
|
|
@@ -74,7 +90,7 @@ public class HybridGameEngineManager: SimpleViewManager<View>() {
|
|
|
74
90
|
}
|
|
75
91
|
}
|
|
76
92
|
|
|
77
|
-
private fun
|
|
78
|
-
return view.getTag(associated_hybrid_view_tag) as?
|
|
93
|
+
private fun getHybridViewHolder(view: View): HybridViewHolder? {
|
|
94
|
+
return view.getTag(associated_hybrid_view_tag) as? HybridViewHolder
|
|
79
95
|
}
|
|
80
96
|
}
|
|
@@ -14,10 +14,10 @@ internal class HybridGameEngineStateUpdater {
|
|
|
14
14
|
companion object {
|
|
15
15
|
/**
|
|
16
16
|
* Updates the props for [view] through C++.
|
|
17
|
-
* The [
|
|
17
|
+
* The [newState] prop is expected to contain [view]'s props as wrapped Fabric state.
|
|
18
18
|
*/
|
|
19
19
|
@Suppress("KotlinJniMissingFunction")
|
|
20
20
|
@JvmStatic
|
|
21
|
-
external fun updateViewProps(view: HybridGameEngineSpec,
|
|
21
|
+
external fun updateViewProps(view: HybridGameEngineSpec, newState: StateWrapper, oldState: StateWrapper?)
|
|
22
22
|
}
|
|
23
23
|
}
|
|
@@ -37,6 +37,7 @@ using namespace margelo::nitro::rngine::views;
|
|
|
37
37
|
|
|
38
38
|
@implementation HybridGameEngineComponent {
|
|
39
39
|
std::shared_ptr<HybridGameEngineSpecSwift> _hybridView;
|
|
40
|
+
BOOL _didDropView;
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
+ (void) load {
|
|
@@ -50,6 +51,7 @@ using namespace margelo::nitro::rngine::views;
|
|
|
50
51
|
|
|
51
52
|
- (instancetype) init {
|
|
52
53
|
if (self = [super init]) {
|
|
54
|
+
_props = HybridGameEngineShadowNode::defaultSharedProps();
|
|
53
55
|
std::shared_ptr<HybridGameEngineSpec> hybridView = Rngine::RngineAutolinking::createGameEngine();
|
|
54
56
|
_hybridView = std::dynamic_pointer_cast<HybridGameEngineSpecSwift>(hybridView);
|
|
55
57
|
[self updateView];
|
|
@@ -69,31 +71,50 @@ using namespace margelo::nitro::rngine::views;
|
|
|
69
71
|
[self setContentView:view];
|
|
70
72
|
}
|
|
71
73
|
|
|
74
|
+
- (void) notifyOnDropView {
|
|
75
|
+
// A recycled component can later be invalidated. Notify only once per mount.
|
|
76
|
+
if (_didDropView) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
Rngine::HybridGameEngineSpec_cxx& swiftPart = _hybridView->getSwiftPart();
|
|
80
|
+
swiftPart.onDropView();
|
|
81
|
+
_didDropView = YES;
|
|
82
|
+
}
|
|
83
|
+
|
|
72
84
|
- (void) updateProps:(const std::shared_ptr<const react::Props>&)props
|
|
73
85
|
oldProps:(const std::shared_ptr<const react::Props>&)oldProps {
|
|
86
|
+
// A props update marks a newly mounted or still-active component.
|
|
87
|
+
_didDropView = NO;
|
|
88
|
+
|
|
74
89
|
// 1. Downcast props
|
|
75
|
-
const auto&
|
|
76
|
-
auto
|
|
90
|
+
const auto& newViewProps = *std::static_pointer_cast<const HybridGameEngineProps>(props);
|
|
91
|
+
const auto* oldViewProps = static_cast<const HybridGameEngineProps*>(oldProps.get());
|
|
77
92
|
Rngine::HybridGameEngineSpec_cxx& swiftPart = _hybridView->getSwiftPart();
|
|
78
93
|
|
|
79
|
-
// 2. Update
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
// hybridRef
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
94
|
+
// 2. Update only props that differ from the previous Props snapshot.
|
|
95
|
+
const bool hasTransactionPropChanges = oldViewProps == nullptr
|
|
96
|
+
? newViewProps.hasAnyProvidedProps()
|
|
97
|
+
: !newViewProps.hasSameProps(*oldViewProps);
|
|
98
|
+
if (hasTransactionPropChanges) {
|
|
99
|
+
swiftPart.beforeUpdate();
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
// Update hybridRef if it changed
|
|
104
|
+
if (oldViewProps == nullptr
|
|
105
|
+
? newViewProps.hybridRef.isProvided()
|
|
106
|
+
: !newViewProps.hybridRef.hasSameValue(oldViewProps->hybridRef)) {
|
|
107
|
+
// hybridRef changed - call it with new this
|
|
108
|
+
const auto& maybeFunc = newViewProps.hybridRef.get();
|
|
109
|
+
if (maybeFunc.has_value()) {
|
|
110
|
+
maybeFunc.value()(_hybridView);
|
|
111
|
+
}
|
|
92
112
|
}
|
|
93
|
-
|
|
113
|
+
|
|
114
|
+
swiftPart.afterUpdate();
|
|
94
115
|
}
|
|
95
116
|
|
|
96
|
-
//
|
|
117
|
+
// 3. Continue in base class
|
|
97
118
|
[super updateProps:props oldProps:oldProps];
|
|
98
119
|
}
|
|
99
120
|
|
|
@@ -102,6 +123,7 @@ using namespace margelo::nitro::rngine::views;
|
|
|
102
123
|
}
|
|
103
124
|
|
|
104
125
|
- (void)prepareForRecycle {
|
|
126
|
+
[self notifyOnDropView];
|
|
105
127
|
[super prepareForRecycle];
|
|
106
128
|
Rngine::HybridGameEngineSpec_cxx& swiftPart = _hybridView->getSwiftPart();
|
|
107
129
|
swiftPart.maybePrepareForRecycle();
|
|
@@ -109,8 +131,7 @@ using namespace margelo::nitro::rngine::views;
|
|
|
109
131
|
|
|
110
132
|
#ifdef ENABLE_RCT_COMPONENT_VIEW_INVALIDATE
|
|
111
133
|
- (void)invalidate {
|
|
112
|
-
|
|
113
|
-
swiftPart.onDropView();
|
|
134
|
+
[self notifyOnDropView];
|
|
114
135
|
[super invalidate];
|
|
115
136
|
}
|
|
116
137
|
#endif
|
|
@@ -57,6 +57,7 @@ namespace margelo::nitro::rngine {
|
|
|
57
57
|
std::optional<bool> flipV SWIFT_PRIVATE;
|
|
58
58
|
std::optional<double> progress SWIFT_PRIVATE;
|
|
59
59
|
std::optional<double> speed SWIFT_PRIVATE;
|
|
60
|
+
std::optional<bool> loop SWIFT_PRIVATE;
|
|
60
61
|
std::optional<double> vx SWIFT_PRIVATE;
|
|
61
62
|
std::optional<double> vy SWIFT_PRIVATE;
|
|
62
63
|
std::optional<double> ax SWIFT_PRIVATE;
|
|
@@ -65,7 +66,7 @@ namespace margelo::nitro::rngine {
|
|
|
65
66
|
|
|
66
67
|
public:
|
|
67
68
|
Entity() = default;
|
|
68
|
-
explicit Entity(std::string id, double px, double py, std::variant<Rect, Circle> shape, std::optional<bool> isSensor, std::optional<std::string> color, std::optional<double> asset, std::optional<bool> flipH, std::optional<bool> flipV, std::optional<double> progress, std::optional<double> speed, std::optional<double> vx, std::optional<double> vy, std::optional<double> ax, std::optional<double> ay, std::optional<double> mass): id(id), px(px), py(py), shape(shape), isSensor(isSensor), color(color), asset(asset), flipH(flipH), flipV(flipV), progress(progress), speed(speed), vx(vx), vy(vy), ax(ax), ay(ay), mass(mass) {}
|
|
69
|
+
explicit Entity(std::string id, double px, double py, std::variant<Rect, Circle> shape, std::optional<bool> isSensor, std::optional<std::string> color, std::optional<double> asset, std::optional<bool> flipH, std::optional<bool> flipV, std::optional<double> progress, std::optional<double> speed, std::optional<bool> loop, std::optional<double> vx, std::optional<double> vy, std::optional<double> ax, std::optional<double> ay, std::optional<double> mass): id(id), px(px), py(py), shape(shape), isSensor(isSensor), color(color), asset(asset), flipH(flipH), flipV(flipV), progress(progress), speed(speed), loop(loop), vx(vx), vy(vy), ax(ax), ay(ay), mass(mass) {}
|
|
69
70
|
|
|
70
71
|
public:
|
|
71
72
|
friend bool operator==(const Entity& lhs, const Entity& rhs) = default;
|
|
@@ -92,6 +93,7 @@ namespace margelo::nitro {
|
|
|
92
93
|
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipV"))),
|
|
93
94
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "progress"))),
|
|
94
95
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "speed"))),
|
|
96
|
+
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "loop"))),
|
|
95
97
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vx"))),
|
|
96
98
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vy"))),
|
|
97
99
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "ax"))),
|
|
@@ -112,6 +114,7 @@ namespace margelo::nitro {
|
|
|
112
114
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "flipV"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.flipV));
|
|
113
115
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "progress"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.progress));
|
|
114
116
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "speed"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.speed));
|
|
117
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "loop"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.loop));
|
|
115
118
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "vx"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.vx));
|
|
116
119
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "vy"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.vy));
|
|
117
120
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "ax"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.ax));
|
|
@@ -138,6 +141,7 @@ namespace margelo::nitro {
|
|
|
138
141
|
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipV")))) return false;
|
|
139
142
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "progress")))) return false;
|
|
140
143
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "speed")))) return false;
|
|
144
|
+
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "loop")))) return false;
|
|
141
145
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vx")))) return false;
|
|
142
146
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vy")))) return false;
|
|
143
147
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "ax")))) return false;
|
|
@@ -57,6 +57,7 @@ namespace margelo::nitro::rngine {
|
|
|
57
57
|
std::optional<bool> flipV SWIFT_PRIVATE;
|
|
58
58
|
std::optional<double> progress SWIFT_PRIVATE;
|
|
59
59
|
std::optional<double> speed SWIFT_PRIVATE;
|
|
60
|
+
std::optional<bool> loop SWIFT_PRIVATE;
|
|
60
61
|
std::optional<double> vx SWIFT_PRIVATE;
|
|
61
62
|
std::optional<double> vy SWIFT_PRIVATE;
|
|
62
63
|
std::optional<double> ax SWIFT_PRIVATE;
|
|
@@ -65,7 +66,7 @@ namespace margelo::nitro::rngine {
|
|
|
65
66
|
|
|
66
67
|
public:
|
|
67
68
|
EntityUpdate() = default;
|
|
68
|
-
explicit EntityUpdate(std::string id, std::optional<double> px, std::optional<double> py, std::optional<std::variant<Rect, Circle>> shape, std::optional<bool> isSensor, std::optional<std::string> color, std::optional<double> asset, std::optional<bool> flipH, std::optional<bool> flipV, std::optional<double> progress, std::optional<double> speed, std::optional<double> vx, std::optional<double> vy, std::optional<double> ax, std::optional<double> ay, std::optional<double> mass): id(id), px(px), py(py), shape(shape), isSensor(isSensor), color(color), asset(asset), flipH(flipH), flipV(flipV), progress(progress), speed(speed), vx(vx), vy(vy), ax(ax), ay(ay), mass(mass) {}
|
|
69
|
+
explicit EntityUpdate(std::string id, std::optional<double> px, std::optional<double> py, std::optional<std::variant<Rect, Circle>> shape, std::optional<bool> isSensor, std::optional<std::string> color, std::optional<double> asset, std::optional<bool> flipH, std::optional<bool> flipV, std::optional<double> progress, std::optional<double> speed, std::optional<bool> loop, std::optional<double> vx, std::optional<double> vy, std::optional<double> ax, std::optional<double> ay, std::optional<double> mass): id(id), px(px), py(py), shape(shape), isSensor(isSensor), color(color), asset(asset), flipH(flipH), flipV(flipV), progress(progress), speed(speed), loop(loop), vx(vx), vy(vy), ax(ax), ay(ay), mass(mass) {}
|
|
69
70
|
|
|
70
71
|
public:
|
|
71
72
|
friend bool operator==(const EntityUpdate& lhs, const EntityUpdate& rhs) = default;
|
|
@@ -92,6 +93,7 @@ namespace margelo::nitro {
|
|
|
92
93
|
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipV"))),
|
|
93
94
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "progress"))),
|
|
94
95
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "speed"))),
|
|
96
|
+
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "loop"))),
|
|
95
97
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vx"))),
|
|
96
98
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vy"))),
|
|
97
99
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "ax"))),
|
|
@@ -112,6 +114,7 @@ namespace margelo::nitro {
|
|
|
112
114
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "flipV"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.flipV));
|
|
113
115
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "progress"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.progress));
|
|
114
116
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "speed"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.speed));
|
|
117
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "loop"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.loop));
|
|
115
118
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "vx"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.vx));
|
|
116
119
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "vy"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.vy));
|
|
117
120
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "ax"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.ax));
|
|
@@ -138,6 +141,7 @@ namespace margelo::nitro {
|
|
|
138
141
|
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipV")))) return false;
|
|
139
142
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "progress")))) return false;
|
|
140
143
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "speed")))) return false;
|
|
144
|
+
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "loop")))) return false;
|
|
141
145
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vx")))) return false;
|
|
142
146
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "vy")))) return false;
|
|
143
147
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "ax")))) return false;
|
|
@@ -50,10 +50,11 @@ namespace margelo::nitro::rngine {
|
|
|
50
50
|
std::optional<bool> flipV SWIFT_PRIVATE;
|
|
51
51
|
std::optional<double> progress SWIFT_PRIVATE;
|
|
52
52
|
std::optional<double> speed SWIFT_PRIVATE;
|
|
53
|
+
std::optional<bool> loop SWIFT_PRIVATE;
|
|
53
54
|
|
|
54
55
|
public:
|
|
55
56
|
Screen() = default;
|
|
56
|
-
explicit Screen(double px, double py, double width, double height, std::optional<std::string> color, std::optional<double> asset, std::optional<bool> flipH, std::optional<bool> flipV, std::optional<double> progress, std::optional<double> speed): px(px), py(py), width(width), height(height), color(color), asset(asset), flipH(flipH), flipV(flipV), progress(progress), speed(speed) {}
|
|
57
|
+
explicit Screen(double px, double py, double width, double height, std::optional<std::string> color, std::optional<double> asset, std::optional<bool> flipH, std::optional<bool> flipV, std::optional<double> progress, std::optional<double> speed, std::optional<bool> loop): px(px), py(py), width(width), height(height), color(color), asset(asset), flipH(flipH), flipV(flipV), progress(progress), speed(speed), loop(loop) {}
|
|
57
58
|
|
|
58
59
|
public:
|
|
59
60
|
friend bool operator==(const Screen& lhs, const Screen& rhs) = default;
|
|
@@ -78,7 +79,8 @@ namespace margelo::nitro {
|
|
|
78
79
|
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipH"))),
|
|
79
80
|
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipV"))),
|
|
80
81
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "progress"))),
|
|
81
|
-
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "speed")))
|
|
82
|
+
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "speed"))),
|
|
83
|
+
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "loop")))
|
|
82
84
|
);
|
|
83
85
|
}
|
|
84
86
|
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::rngine::Screen& arg) {
|
|
@@ -93,6 +95,7 @@ namespace margelo::nitro {
|
|
|
93
95
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "flipV"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.flipV));
|
|
94
96
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "progress"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.progress));
|
|
95
97
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "speed"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.speed));
|
|
98
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "loop"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.loop));
|
|
96
99
|
return obj;
|
|
97
100
|
}
|
|
98
101
|
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
@@ -113,6 +116,7 @@ namespace margelo::nitro {
|
|
|
113
116
|
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipV")))) return false;
|
|
114
117
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "progress")))) return false;
|
|
115
118
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "speed")))) return false;
|
|
119
|
+
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "loop")))) return false;
|
|
116
120
|
return true;
|
|
117
121
|
}
|
|
118
122
|
};
|
|
@@ -50,10 +50,11 @@ namespace margelo::nitro::rngine {
|
|
|
50
50
|
std::optional<bool> flipV SWIFT_PRIVATE;
|
|
51
51
|
std::optional<double> progress SWIFT_PRIVATE;
|
|
52
52
|
std::optional<double> speed SWIFT_PRIVATE;
|
|
53
|
+
std::optional<bool> loop SWIFT_PRIVATE;
|
|
53
54
|
|
|
54
55
|
public:
|
|
55
56
|
ScreenUpdate() = default;
|
|
56
|
-
explicit ScreenUpdate(std::optional<double> px, std::optional<double> py, std::optional<double> width, std::optional<double> height, std::optional<std::string> color, std::optional<double> asset, std::optional<bool> flipH, std::optional<bool> flipV, std::optional<double> progress, std::optional<double> speed): px(px), py(py), width(width), height(height), color(color), asset(asset), flipH(flipH), flipV(flipV), progress(progress), speed(speed) {}
|
|
57
|
+
explicit ScreenUpdate(std::optional<double> px, std::optional<double> py, std::optional<double> width, std::optional<double> height, std::optional<std::string> color, std::optional<double> asset, std::optional<bool> flipH, std::optional<bool> flipV, std::optional<double> progress, std::optional<double> speed, std::optional<bool> loop): px(px), py(py), width(width), height(height), color(color), asset(asset), flipH(flipH), flipV(flipV), progress(progress), speed(speed), loop(loop) {}
|
|
57
58
|
|
|
58
59
|
public:
|
|
59
60
|
friend bool operator==(const ScreenUpdate& lhs, const ScreenUpdate& rhs) = default;
|
|
@@ -78,7 +79,8 @@ namespace margelo::nitro {
|
|
|
78
79
|
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipH"))),
|
|
79
80
|
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipV"))),
|
|
80
81
|
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "progress"))),
|
|
81
|
-
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "speed")))
|
|
82
|
+
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "speed"))),
|
|
83
|
+
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "loop")))
|
|
82
84
|
);
|
|
83
85
|
}
|
|
84
86
|
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::rngine::ScreenUpdate& arg) {
|
|
@@ -93,6 +95,7 @@ namespace margelo::nitro {
|
|
|
93
95
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "flipV"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.flipV));
|
|
94
96
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "progress"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.progress));
|
|
95
97
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "speed"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.speed));
|
|
98
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "loop"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.loop));
|
|
96
99
|
return obj;
|
|
97
100
|
}
|
|
98
101
|
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
@@ -113,6 +116,7 @@ namespace margelo::nitro {
|
|
|
113
116
|
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipV")))) return false;
|
|
114
117
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "progress")))) return false;
|
|
115
118
|
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "speed")))) return false;
|
|
119
|
+
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "loop")))) return false;
|
|
116
120
|
return true;
|
|
117
121
|
}
|
|
118
122
|
};
|
|
@@ -7,35 +7,20 @@
|
|
|
7
7
|
|
|
8
8
|
#include "HybridGameEngineComponent.hpp"
|
|
9
9
|
|
|
10
|
-
#include <
|
|
11
|
-
#include <
|
|
12
|
-
#include <utility>
|
|
13
|
-
#include <NitroModules/NitroDefines.hpp>
|
|
14
|
-
#include <NitroModules/JSIConverter.hpp>
|
|
15
|
-
#include <NitroModules/PropNameIDCache.hpp>
|
|
16
|
-
#include <react/renderer/core/RawValue.h>
|
|
17
|
-
#include <react/renderer/core/ShadowNode.h>
|
|
18
|
-
#include <react/renderer/core/ComponentDescriptor.h>
|
|
19
|
-
#include <react/renderer/components/view/ViewProps.h>
|
|
10
|
+
#include <NitroModules/NitroHash.hpp>
|
|
11
|
+
#include <NitroModules/ReactProp.hpp>
|
|
20
12
|
|
|
21
13
|
namespace margelo::nitro::rngine::views {
|
|
22
14
|
|
|
15
|
+
using namespace facebook;
|
|
16
|
+
|
|
23
17
|
extern const char HybridGameEngineComponentName[] = "GameEngine";
|
|
24
18
|
|
|
25
19
|
HybridGameEngineProps::HybridGameEngineProps(const react::PropsParserContext& context,
|
|
26
20
|
const HybridGameEngineProps& sourceProps,
|
|
27
21
|
const react::RawProps& rawProps):
|
|
28
22
|
react::ViewProps(context, sourceProps, rawProps, filterObjectKeys),
|
|
29
|
-
hybridRef(
|
|
30
|
-
try {
|
|
31
|
-
const react::RawValue* rawValue = rawProps.at("hybridRef", nullptr, nullptr);
|
|
32
|
-
if (rawValue == nullptr) return sourceProps.hybridRef;
|
|
33
|
-
const auto& [runtime, value] = (std::pair<jsi::Runtime*, jsi::Value>)*rawValue;
|
|
34
|
-
return CachedProp<std::optional<std::function<void(const std::shared_ptr<HybridGameEngineSpec>& /* ref */)>>>::fromRawValue(*runtime, value.asObject(*runtime).getProperty(*runtime, PropNameIDCache::get(*runtime, "f")), sourceProps.hybridRef);
|
|
35
|
-
} catch (const std::exception& exc) {
|
|
36
|
-
throw std::runtime_error(std::string("GameEngine.hybridRef: ") + exc.what());
|
|
37
|
-
}
|
|
38
|
-
}()) { }
|
|
23
|
+
hybridRef(nitro::ReactProp<std::optional<std::function<void(const std::shared_ptr<HybridGameEngineSpec>& /* ref */)>>>::fromRawValue("GameEngine", "hybridRef", rawProps, sourceProps.hybridRef)) { }
|
|
39
24
|
|
|
40
25
|
bool HybridGameEngineProps::filterObjectKeys(const std::string& propName) {
|
|
41
26
|
switch (hashString(propName)) {
|
|
@@ -44,29 +29,4 @@ namespace margelo::nitro::rngine::views {
|
|
|
44
29
|
}
|
|
45
30
|
}
|
|
46
31
|
|
|
47
|
-
HybridGameEngineComponentDescriptor::HybridGameEngineComponentDescriptor(const react::ComponentDescriptorParameters& parameters)
|
|
48
|
-
: ConcreteComponentDescriptor(parameters,
|
|
49
|
-
react::RawPropsParser(/* enableJsiParser */ true)) {}
|
|
50
|
-
|
|
51
|
-
std::shared_ptr<const react::Props> HybridGameEngineComponentDescriptor::cloneProps(const react::PropsParserContext& context,
|
|
52
|
-
const std::shared_ptr<const react::Props>& props,
|
|
53
|
-
react::RawProps rawProps) const {
|
|
54
|
-
// 1. Prepare raw props parser
|
|
55
|
-
rawProps.parse(rawPropsParser_);
|
|
56
|
-
// 2. Copy props with Nitro's cached copy constructor
|
|
57
|
-
return HybridGameEngineShadowNode::Props(context, /* & */ rawProps, props);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
#ifdef ANDROID
|
|
61
|
-
void HybridGameEngineComponentDescriptor::adopt(react::ShadowNode& shadowNode) const {
|
|
62
|
-
// This is called immediately after `ShadowNode` is created, cloned or in progress.
|
|
63
|
-
// On Android, we need to wrap props in our state, which gets routed through Java and later unwrapped in JNI/C++.
|
|
64
|
-
auto& concreteShadowNode = static_cast<HybridGameEngineShadowNode&>(shadowNode);
|
|
65
|
-
const std::shared_ptr<const HybridGameEngineProps>& constProps = concreteShadowNode.getConcreteSharedProps();
|
|
66
|
-
const std::shared_ptr<HybridGameEngineProps>& props = std::const_pointer_cast<HybridGameEngineProps>(constProps);
|
|
67
|
-
HybridGameEngineState state{props};
|
|
68
|
-
concreteShadowNode.setStateData(std::move(state));
|
|
69
|
-
}
|
|
70
|
-
#endif
|
|
71
|
-
|
|
72
32
|
} // namespace margelo::nitro::rngine::views
|
|
@@ -7,14 +7,15 @@
|
|
|
7
7
|
|
|
8
8
|
#pragma once
|
|
9
9
|
|
|
10
|
-
#include <
|
|
11
|
-
#include <NitroModules/
|
|
12
|
-
#include <NitroModules/
|
|
13
|
-
#include <NitroModules/CachedProp.hpp>
|
|
14
|
-
#include <react/renderer/core/ConcreteComponentDescriptor.h>
|
|
15
|
-
#include <react/renderer/core/PropsParserContext.h>
|
|
10
|
+
#include <NitroModules/ReactProp.hpp>
|
|
11
|
+
#include <NitroModules/ViewComponentDescriptor.hpp>
|
|
12
|
+
#include <NitroModules/ViewPropsHolderState.hpp>
|
|
16
13
|
#include <react/renderer/components/view/ConcreteViewShadowNode.h>
|
|
17
14
|
#include <react/renderer/components/view/ViewProps.h>
|
|
15
|
+
#include <react/renderer/core/PropsParserContext.h>
|
|
16
|
+
#include <react/renderer/core/RawProps.h>
|
|
17
|
+
|
|
18
|
+
#include <string>
|
|
18
19
|
|
|
19
20
|
#include <memory>
|
|
20
21
|
#include "HybridGameEngineSpec.hpp"
|
|
@@ -41,7 +42,17 @@ namespace margelo::nitro::rngine::views {
|
|
|
41
42
|
const react::RawProps& rawProps);
|
|
42
43
|
|
|
43
44
|
public:
|
|
44
|
-
|
|
45
|
+
nitro::ReactProp<std::optional<std::function<void(const std::shared_ptr<HybridGameEngineSpec>& /* ref */)>>> hybridRef;
|
|
46
|
+
|
|
47
|
+
[[nodiscard]]
|
|
48
|
+
bool hasSameProps(const HybridGameEngineProps& other) const noexcept {
|
|
49
|
+
return hybridRef.hasSameValue(other.hybridRef);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
[[nodiscard]]
|
|
53
|
+
bool hasAnyProvidedProps() const noexcept {
|
|
54
|
+
return hybridRef.isProvided();
|
|
55
|
+
}
|
|
45
56
|
|
|
46
57
|
private:
|
|
47
58
|
static bool filterObjectKeys(const std::string& propName);
|
|
@@ -50,32 +61,7 @@ namespace margelo::nitro::rngine::views {
|
|
|
50
61
|
/**
|
|
51
62
|
* State for the "GameEngine" View.
|
|
52
63
|
*/
|
|
53
|
-
|
|
54
|
-
public:
|
|
55
|
-
HybridGameEngineState() = default;
|
|
56
|
-
explicit HybridGameEngineState(const std::shared_ptr<HybridGameEngineProps>& props):
|
|
57
|
-
_props(props) {}
|
|
58
|
-
|
|
59
|
-
public:
|
|
60
|
-
[[nodiscard]]
|
|
61
|
-
const std::shared_ptr<HybridGameEngineProps>& getProps() const {
|
|
62
|
-
return _props;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
public:
|
|
66
|
-
#ifdef ANDROID
|
|
67
|
-
HybridGameEngineState(const HybridGameEngineState& /* previousState */, folly::dynamic /* data */) {}
|
|
68
|
-
folly::dynamic getDynamic() const {
|
|
69
|
-
throw std::runtime_error("HybridGameEngineState does not support folly!");
|
|
70
|
-
}
|
|
71
|
-
react::MapBuffer getMapBuffer() const {
|
|
72
|
-
throw std::runtime_error("HybridGameEngineState does not support MapBuffer!");
|
|
73
|
-
};
|
|
74
|
-
#endif
|
|
75
|
-
|
|
76
|
-
private:
|
|
77
|
-
std::shared_ptr<HybridGameEngineProps> _props;
|
|
78
|
-
};
|
|
64
|
+
using HybridGameEngineState = nitro::ViewPropsHolderState<HybridGameEngineProps>;
|
|
79
65
|
|
|
80
66
|
/**
|
|
81
67
|
* The Shadow Node for the "GameEngine" View.
|
|
@@ -88,21 +74,7 @@ namespace margelo::nitro::rngine::views {
|
|
|
88
74
|
/**
|
|
89
75
|
* The Component Descriptor for the "GameEngine" View.
|
|
90
76
|
*/
|
|
91
|
-
|
|
92
|
-
public:
|
|
93
|
-
explicit HybridGameEngineComponentDescriptor(const react::ComponentDescriptorParameters& parameters);
|
|
94
|
-
|
|
95
|
-
public:
|
|
96
|
-
/**
|
|
97
|
-
* A faster path for cloning props - reuses the caching logic from `HybridGameEngineProps`.
|
|
98
|
-
*/
|
|
99
|
-
std::shared_ptr<const react::Props> cloneProps(const react::PropsParserContext& context,
|
|
100
|
-
const std::shared_ptr<const react::Props>& props,
|
|
101
|
-
react::RawProps rawProps) const override;
|
|
102
|
-
#ifdef ANDROID
|
|
103
|
-
void adopt(react::ShadowNode& shadowNode) const override;
|
|
104
|
-
#endif
|
|
105
|
-
};
|
|
77
|
+
using HybridGameEngineComponentDescriptor = nitro::ViewComponentDescriptor<HybridGameEngineShadowNode>;
|
|
106
78
|
|
|
107
79
|
/* The actual view for "GameEngine" needs to be implemented in platform-specific code. */
|
|
108
80
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rngine",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "React Native 2D game engine powered by Nitro Modules",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
|
@@ -28,9 +28,6 @@
|
|
|
28
28
|
"!android/gradlew",
|
|
29
29
|
"!android/gradlew.bat",
|
|
30
30
|
"!android/local.properties",
|
|
31
|
-
"!**/__tests__",
|
|
32
|
-
"!**/__fixtures__",
|
|
33
|
-
"!**/__mocks__",
|
|
34
31
|
"!**/.*"
|
|
35
32
|
],
|
|
36
33
|
"scripts": {
|
|
@@ -39,11 +36,7 @@
|
|
|
39
36
|
"prepare": "bob build && node scripts/nitrogen-patch.js",
|
|
40
37
|
"nitrogen": "nitrogen",
|
|
41
38
|
"typecheck": "tsc",
|
|
42
|
-
"lint": "eslint \"**/*.{js,ts,tsx}\""
|
|
43
|
-
"test": "jest",
|
|
44
|
-
"release": "release-it --only-version",
|
|
45
|
-
"web": "vite",
|
|
46
|
-
"build:web": "vite build"
|
|
39
|
+
"lint": "eslint \"**/*.{js,ts,tsx}\""
|
|
47
40
|
},
|
|
48
41
|
"keywords": [
|
|
49
42
|
"react-native",
|
|
@@ -64,39 +57,33 @@
|
|
|
64
57
|
"registry": "https://registry.npmjs.org/"
|
|
65
58
|
},
|
|
66
59
|
"devDependencies": {
|
|
67
|
-
"@commitlint/config-conventional": "^
|
|
68
|
-
"@eslint/compat": "^2.
|
|
69
|
-
"@eslint/eslintrc": "^3.3.
|
|
60
|
+
"@commitlint/config-conventional": "^21.2.3",
|
|
61
|
+
"@eslint/compat": "^2.1.1",
|
|
62
|
+
"@eslint/eslintrc": "^3.3.7",
|
|
70
63
|
"@eslint/js": "^10.0.1",
|
|
71
|
-
"@
|
|
72
|
-
"@react-native/
|
|
73
|
-
"@react
|
|
74
|
-
"
|
|
75
|
-
"@release-it/conventional-changelog": "^10.0.6",
|
|
76
|
-
"@types/react": "^19.2.0",
|
|
77
|
-
"commitlint": "^20.5.0",
|
|
64
|
+
"@react-native/babel-preset": "^0.87.1",
|
|
65
|
+
"@react-native/eslint-config": "^0.87.1",
|
|
66
|
+
"@types/react": "^19.3.0",
|
|
67
|
+
"commitlint": "^21.2.3",
|
|
78
68
|
"del-cli": "^7.0.0",
|
|
79
|
-
"eslint": "
|
|
69
|
+
"eslint": "9.39.5",
|
|
80
70
|
"eslint-config-prettier": "^10.1.8",
|
|
81
71
|
"eslint-plugin-ft-flow": "^3.0.11",
|
|
82
|
-
"eslint-plugin-prettier": "^5.5.
|
|
83
|
-
"
|
|
84
|
-
"
|
|
85
|
-
"
|
|
86
|
-
"prettier": "^3.8.1",
|
|
72
|
+
"eslint-plugin-prettier": "^5.5.6",
|
|
73
|
+
"lefthook": "^2.1.14",
|
|
74
|
+
"nitrogen": "^0.37.1",
|
|
75
|
+
"prettier": "^3.9.8",
|
|
87
76
|
"react": "19.2.3",
|
|
88
|
-
"react-native": "0.85.
|
|
89
|
-
"react-native-builder-bob": "^0.
|
|
90
|
-
"react-native-nitro-modules": "^0.
|
|
91
|
-
"
|
|
92
|
-
"release-it": "^19.2.4",
|
|
93
|
-
"turbo": "^2.8.21",
|
|
77
|
+
"react-native": "0.85.3",
|
|
78
|
+
"react-native-builder-bob": "^0.43.1",
|
|
79
|
+
"react-native-nitro-modules": "^0.37.1",
|
|
80
|
+
"turbo": "^2.11.2",
|
|
94
81
|
"typescript": "^6.0.2"
|
|
95
82
|
},
|
|
96
83
|
"peerDependencies": {
|
|
97
84
|
"react": "*",
|
|
98
85
|
"react-native": "*",
|
|
99
|
-
"react-native-nitro-modules": "^0.
|
|
86
|
+
"react-native-nitro-modules": "^0.37.1"
|
|
100
87
|
},
|
|
101
88
|
"workspaces": [
|
|
102
89
|
"example"
|
|
@@ -134,50 +121,21 @@
|
|
|
134
121
|
"trailingComma": "es5",
|
|
135
122
|
"useTabs": false
|
|
136
123
|
},
|
|
137
|
-
"jest": {
|
|
138
|
-
"preset": "@react-native/jest-preset",
|
|
139
|
-
"modulePathIgnorePatterns": [
|
|
140
|
-
"<rootDir>/example/node_modules",
|
|
141
|
-
"<rootDir>/lib/"
|
|
142
|
-
]
|
|
143
|
-
},
|
|
144
124
|
"commitlint": {
|
|
145
125
|
"extends": [
|
|
146
126
|
"@commitlint/config-conventional"
|
|
147
127
|
]
|
|
148
128
|
},
|
|
149
|
-
"release-it": {
|
|
150
|
-
"git": {
|
|
151
|
-
"commitMessage": "chore: release ${version}",
|
|
152
|
-
"tagName": "v${version}"
|
|
153
|
-
},
|
|
154
|
-
"npm": {
|
|
155
|
-
"publish": true
|
|
156
|
-
},
|
|
157
|
-
"github": {
|
|
158
|
-
"release": true
|
|
159
|
-
},
|
|
160
|
-
"plugins": {
|
|
161
|
-
"@release-it/conventional-changelog": {
|
|
162
|
-
"preset": {
|
|
163
|
-
"name": "angular"
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
},
|
|
168
129
|
"create-react-native-library": {
|
|
169
130
|
"type": "nitro-view",
|
|
170
131
|
"languages": "kotlin-swift",
|
|
171
132
|
"tools": [
|
|
172
133
|
"eslint",
|
|
173
|
-
"
|
|
174
|
-
"lefthook",
|
|
175
|
-
"release-it",
|
|
176
|
-
"vite"
|
|
134
|
+
"lefthook"
|
|
177
135
|
],
|
|
178
136
|
"version": "0.61.0"
|
|
179
137
|
},
|
|
180
138
|
"dependencies": {
|
|
181
|
-
"react-native-skia-android": "^
|
|
139
|
+
"react-native-skia-android": "^154.0.0"
|
|
182
140
|
}
|
|
183
141
|
}
|
package/shared/GameLoop.cpp
CHANGED
|
@@ -185,7 +185,7 @@ void GameLoop::updateStats(double deltaTime) {
|
|
|
185
185
|
void GameLoop::updateScreen(double deltaTime) {
|
|
186
186
|
std::lock_guard<std::mutex> lock(_mutex);
|
|
187
187
|
if (_screen.asset.has_value()) {
|
|
188
|
-
AssetUtils::updateProgress(_screen.progress, _screen.speed,
|
|
188
|
+
AssetUtils::updateProgress(_screen.progress, _screen.speed, _screen.loop,
|
|
189
189
|
_screen.asset.value(), deltaTime);
|
|
190
190
|
}
|
|
191
191
|
}
|
|
@@ -220,7 +220,7 @@ void GameLoop::updateEntities(double deltaTime) {
|
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
if (entity.asset.has_value()) {
|
|
223
|
-
AssetUtils::updateProgress(entity.progress, entity.speed,
|
|
223
|
+
AssetUtils::updateProgress(entity.progress, entity.speed, entity.loop,
|
|
224
224
|
entity.asset.value(), deltaTime);
|
|
225
225
|
}
|
|
226
226
|
}
|
package/shared/GameMethods.cpp
CHANGED
|
@@ -134,6 +134,7 @@ void GameMethods::updateEntities(
|
|
|
134
134
|
patch(entityUpdate.asset, entity->asset);
|
|
135
135
|
patch(entityUpdate.progress, entity->progress);
|
|
136
136
|
patch(entityUpdate.speed, entity->speed);
|
|
137
|
+
patch(entityUpdate.loop, entity->loop);
|
|
137
138
|
patch(entityUpdate.color, entity->color);
|
|
138
139
|
patch(entityUpdate.flipH, entity->flipH);
|
|
139
140
|
patch(entityUpdate.flipV, entity->flipV);
|
|
@@ -163,6 +164,7 @@ void GameMethods::updateScreen(const ScreenUpdate &screenUpdate) {
|
|
|
163
164
|
patch(screenUpdate.asset, screen.asset);
|
|
164
165
|
patch(screenUpdate.progress, screen.progress);
|
|
165
166
|
patch(screenUpdate.speed, screen.speed);
|
|
167
|
+
patch(screenUpdate.loop, screen.loop);
|
|
166
168
|
patch(screenUpdate.color, screen.color);
|
|
167
169
|
patch(screenUpdate.flipH, screen.flipH);
|
|
168
170
|
patch(screenUpdate.flipV, screen.flipV);
|
|
@@ -73,16 +73,23 @@ void drawAsset(SkCanvas *canvas, double asset, float targetWidth,
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
void updateProgress(std::optional<double> &progress,
|
|
76
|
-
std::optional<double> &speed,
|
|
77
|
-
double
|
|
76
|
+
const std::optional<double> &speed,
|
|
77
|
+
const std::optional<bool> &loop, const double asset,
|
|
78
|
+
const double deltaTime) {
|
|
78
79
|
if (asset < 0) {
|
|
79
80
|
auto &lottieCache = GameRenderer::getInstance().getLottieCacheInternal();
|
|
80
81
|
auto it = lottieCache.find(asset);
|
|
81
82
|
if (it != lottieCache.end() && it->second) {
|
|
82
83
|
if (speed.has_value() && speed.value() > 0) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
double newProgress =
|
|
85
|
+
progress.value_or(0.0) +
|
|
86
|
+
(deltaTime * speed.value()) / it->second->duration();
|
|
87
|
+
|
|
88
|
+
if (loop.value_or(false)) {
|
|
89
|
+
progress = std::fmod(newProgress, 1.0);
|
|
90
|
+
} else {
|
|
91
|
+
progress = std::min(newProgress, 1.0);
|
|
92
|
+
}
|
|
86
93
|
}
|
|
87
94
|
}
|
|
88
95
|
} else if (progress.has_value()) {
|
|
@@ -6,6 +6,7 @@ namespace margelo::nitro::rngine::AssetUtils {
|
|
|
6
6
|
void drawAsset(SkCanvas *canvas, double asset, float targetWidth,
|
|
7
7
|
float targetHeight, bool flipH, bool flipV, double progress);
|
|
8
8
|
void updateProgress(std::optional<double> &progress,
|
|
9
|
-
std::optional<double> &speed,
|
|
10
|
-
double
|
|
9
|
+
const std::optional<double> &speed,
|
|
10
|
+
const std::optional<bool> &loop, const double asset,
|
|
11
|
+
const double deltaTime);
|
|
11
12
|
} // namespace margelo::nitro::rngine::AssetUtils
|
package/src/nativeTypes.ts
CHANGED
|
@@ -35,8 +35,10 @@ interface Renderable {
|
|
|
35
35
|
flipV?: boolean;
|
|
36
36
|
/** Animation progress between 0 and 1, automatically advanced each tick for Lottie assets. */
|
|
37
37
|
progress?: number;
|
|
38
|
-
/** Playback speed multiplier for
|
|
38
|
+
/** Playback speed multiplier for Lottie assets (1 = normal speed). */
|
|
39
39
|
speed?: number;
|
|
40
|
+
/** Whether the Lottie animation should restart automatically upon completion. */
|
|
41
|
+
loop?: boolean;
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
interface Kinematic {
|
package/android/kls_database.db
DELETED
|
Binary file
|