rngine 0.8.2 → 0.9.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/README.md +28 -21
- package/android/CMakeLists.txt +5 -2
- package/android/kls_database.db +0 -0
- package/android/src/main/java/com/margelo/nitro/rngine/ImageLoaderHelper.kt +56 -0
- package/lib/module/GameMethods.js +23 -10
- package/lib/module/GameMethods.js.map +1 -1
- package/lib/module/GameMethods.nitro.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/GameMethods.d.ts +11 -4
- package/lib/typescript/src/GameMethods.d.ts.map +1 -1
- package/lib/typescript/src/GameMethods.nitro.d.ts +9 -3
- package/lib/typescript/src/GameMethods.nitro.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/nativeTypes.d.ts +12 -2
- package/lib/typescript/src/nativeTypes.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +2 -2
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/nitrogen/generated/shared/c++/HybridGameMethodsSpec.cpp +3 -2
- package/nitrogen/generated/shared/c++/HybridGameMethodsSpec.hpp +6 -2
- package/nitrogen/generated/shared/c++/Screen.hpp +9 -1
- package/nitrogen/generated/shared/c++/ScreenUpdate.hpp +120 -0
- package/nitrogen/generated/shared/c++/System.hpp +8 -11
- package/nitrogen/generated/shared/c++/SystemContext.hpp +99 -0
- package/package.json +1 -1
- package/shared/GameLoop.cpp +16 -33
- package/shared/GameMethods.cpp +124 -92
- package/shared/GameMethods.hpp +5 -3
- package/shared/GameRenderer.cpp +27 -81
- package/shared/GameRenderer.hpp +8 -5
- package/shared/utils/AssetUtils.cpp +92 -0
- package/shared/utils/AssetUtils.hpp +11 -0
- package/shared/{CollisionUtils.cpp → utils/CollisionUtils.cpp} +9 -8
- package/shared/utils/CollisionUtils.hpp +10 -0
- package/src/GameMethods.nitro.ts +12 -2
- package/src/GameMethods.ts +23 -11
- package/src/index.tsx +1 -0
- package/src/nativeTypes.ts +13 -2
- package/src/types.ts +2 -2
- package/android/src/main/java/com/margelo/nitro/rngine/SvgLoaderHelper.kt +0 -24
- package/shared/CollisionUtils.hpp +0 -21
- /package/shared/{ColorUtils.cpp → utils/ColorUtils.cpp} +0 -0
- /package/shared/{ColorUtils.hpp → utils/ColorUtils.hpp} +0 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// ScreenUpdate.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#if __has_include(<NitroModules/JSIConverter.hpp>)
|
|
11
|
+
#include <NitroModules/JSIConverter.hpp>
|
|
12
|
+
#else
|
|
13
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
14
|
+
#endif
|
|
15
|
+
#if __has_include(<NitroModules/NitroDefines.hpp>)
|
|
16
|
+
#include <NitroModules/NitroDefines.hpp>
|
|
17
|
+
#else
|
|
18
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
19
|
+
#endif
|
|
20
|
+
#if __has_include(<NitroModules/JSIHelpers.hpp>)
|
|
21
|
+
#include <NitroModules/JSIHelpers.hpp>
|
|
22
|
+
#else
|
|
23
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
24
|
+
#endif
|
|
25
|
+
#if __has_include(<NitroModules/PropNameIDCache.hpp>)
|
|
26
|
+
#include <NitroModules/PropNameIDCache.hpp>
|
|
27
|
+
#else
|
|
28
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
29
|
+
#endif
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
#include <optional>
|
|
34
|
+
#include <string>
|
|
35
|
+
|
|
36
|
+
namespace margelo::nitro::rngine {
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* A struct which can be represented as a JavaScript object (ScreenUpdate).
|
|
40
|
+
*/
|
|
41
|
+
struct ScreenUpdate final {
|
|
42
|
+
public:
|
|
43
|
+
std::optional<double> px SWIFT_PRIVATE;
|
|
44
|
+
std::optional<double> py SWIFT_PRIVATE;
|
|
45
|
+
std::optional<double> width SWIFT_PRIVATE;
|
|
46
|
+
std::optional<double> height SWIFT_PRIVATE;
|
|
47
|
+
std::optional<std::string> color SWIFT_PRIVATE;
|
|
48
|
+
std::optional<double> asset SWIFT_PRIVATE;
|
|
49
|
+
std::optional<bool> flipH SWIFT_PRIVATE;
|
|
50
|
+
std::optional<bool> flipV SWIFT_PRIVATE;
|
|
51
|
+
std::optional<double> progress SWIFT_PRIVATE;
|
|
52
|
+
std::optional<double> speed SWIFT_PRIVATE;
|
|
53
|
+
|
|
54
|
+
public:
|
|
55
|
+
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
|
+
|
|
58
|
+
public:
|
|
59
|
+
friend bool operator==(const ScreenUpdate& lhs, const ScreenUpdate& rhs) = default;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
} // namespace margelo::nitro::rngine
|
|
63
|
+
|
|
64
|
+
namespace margelo::nitro {
|
|
65
|
+
|
|
66
|
+
// C++ ScreenUpdate <> JS ScreenUpdate (object)
|
|
67
|
+
template <>
|
|
68
|
+
struct JSIConverter<margelo::nitro::rngine::ScreenUpdate> final {
|
|
69
|
+
static inline margelo::nitro::rngine::ScreenUpdate fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
70
|
+
jsi::Object obj = arg.asObject(runtime);
|
|
71
|
+
return margelo::nitro::rngine::ScreenUpdate(
|
|
72
|
+
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "px"))),
|
|
73
|
+
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "py"))),
|
|
74
|
+
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "width"))),
|
|
75
|
+
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "height"))),
|
|
76
|
+
JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "color"))),
|
|
77
|
+
JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "asset"))),
|
|
78
|
+
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipH"))),
|
|
79
|
+
JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipV"))),
|
|
80
|
+
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
|
+
);
|
|
83
|
+
}
|
|
84
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::rngine::ScreenUpdate& arg) {
|
|
85
|
+
jsi::Object obj(runtime);
|
|
86
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "px"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.px));
|
|
87
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "py"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.py));
|
|
88
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "width"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.width));
|
|
89
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "height"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.height));
|
|
90
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "color"), JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.color));
|
|
91
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "asset"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.asset));
|
|
92
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "flipH"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.flipH));
|
|
93
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "flipV"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.flipV));
|
|
94
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "progress"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.progress));
|
|
95
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "speed"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.speed));
|
|
96
|
+
return obj;
|
|
97
|
+
}
|
|
98
|
+
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
99
|
+
if (!value.isObject()) {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
jsi::Object obj = value.getObject(runtime);
|
|
103
|
+
if (!nitro::isPlainObject(runtime, obj)) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "px")))) return false;
|
|
107
|
+
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "py")))) return false;
|
|
108
|
+
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "width")))) return false;
|
|
109
|
+
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "height")))) return false;
|
|
110
|
+
if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "color")))) return false;
|
|
111
|
+
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "asset")))) return false;
|
|
112
|
+
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipH")))) return false;
|
|
113
|
+
if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "flipV")))) return false;
|
|
114
|
+
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "progress")))) return false;
|
|
115
|
+
if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "speed")))) return false;
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
} // namespace margelo::nitro
|
|
@@ -30,18 +30,15 @@
|
|
|
30
30
|
|
|
31
31
|
// Forward declaration of `CollisionPair` to properly resolve imports.
|
|
32
32
|
namespace margelo::nitro::rngine { struct CollisionPair; }
|
|
33
|
-
// Forward declaration of `
|
|
34
|
-
namespace margelo::nitro::rngine { struct
|
|
35
|
-
// Forward declaration of `Collision` to properly resolve imports.
|
|
36
|
-
namespace margelo::nitro::rngine { struct Collision; }
|
|
33
|
+
// Forward declaration of `SystemContext` to properly resolve imports.
|
|
34
|
+
namespace margelo::nitro::rngine { struct SystemContext; }
|
|
37
35
|
|
|
38
36
|
#include <string>
|
|
39
37
|
#include <vector>
|
|
40
38
|
#include <optional>
|
|
41
39
|
#include "CollisionPair.hpp"
|
|
42
40
|
#include <NitroModules/Promise.hpp>
|
|
43
|
-
#include "
|
|
44
|
-
#include "Collision.hpp"
|
|
41
|
+
#include "SystemContext.hpp"
|
|
45
42
|
#include <functional>
|
|
46
43
|
|
|
47
44
|
namespace margelo::nitro::rngine {
|
|
@@ -53,11 +50,11 @@ namespace margelo::nitro::rngine {
|
|
|
53
50
|
public:
|
|
54
51
|
std::optional<std::vector<std::string>> entities SWIFT_PRIVATE;
|
|
55
52
|
std::optional<std::vector<CollisionPair>> collisions SWIFT_PRIVATE;
|
|
56
|
-
std::function<std::shared_ptr<Promise<double>>(const
|
|
53
|
+
std::function<std::shared_ptr<Promise<double>>(const SystemContext& /* systemContext */)> onTick SWIFT_PRIVATE;
|
|
57
54
|
|
|
58
55
|
public:
|
|
59
56
|
System() = default;
|
|
60
|
-
explicit System(std::optional<std::vector<std::string>> entities, std::optional<std::vector<CollisionPair>> collisions, std::function<std::shared_ptr<Promise<double>>(const
|
|
57
|
+
explicit System(std::optional<std::vector<std::string>> entities, std::optional<std::vector<CollisionPair>> collisions, std::function<std::shared_ptr<Promise<double>>(const SystemContext& /* systemContext */)> onTick): entities(entities), collisions(collisions), onTick(onTick) {}
|
|
61
58
|
|
|
62
59
|
public:
|
|
63
60
|
// System is not equatable because these properties are not equatable: onTick
|
|
@@ -75,14 +72,14 @@ namespace margelo::nitro {
|
|
|
75
72
|
return margelo::nitro::rngine::System(
|
|
76
73
|
JSIConverter<std::optional<std::vector<std::string>>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "entities"))),
|
|
77
74
|
JSIConverter<std::optional<std::vector<margelo::nitro::rngine::CollisionPair>>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "collisions"))),
|
|
78
|
-
JSIConverter<std::function<std::shared_ptr<Promise<double>>(const
|
|
75
|
+
JSIConverter<std::function<std::shared_ptr<Promise<double>>(const margelo::nitro::rngine::SystemContext&)>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "onTick")))
|
|
79
76
|
);
|
|
80
77
|
}
|
|
81
78
|
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::rngine::System& arg) {
|
|
82
79
|
jsi::Object obj(runtime);
|
|
83
80
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "entities"), JSIConverter<std::optional<std::vector<std::string>>>::toJSI(runtime, arg.entities));
|
|
84
81
|
obj.setProperty(runtime, PropNameIDCache::get(runtime, "collisions"), JSIConverter<std::optional<std::vector<margelo::nitro::rngine::CollisionPair>>>::toJSI(runtime, arg.collisions));
|
|
85
|
-
obj.setProperty(runtime, PropNameIDCache::get(runtime, "onTick"), JSIConverter<std::function<std::shared_ptr<Promise<double>>(const
|
|
82
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "onTick"), JSIConverter<std::function<std::shared_ptr<Promise<double>>(const margelo::nitro::rngine::SystemContext&)>>::toJSI(runtime, arg.onTick));
|
|
86
83
|
return obj;
|
|
87
84
|
}
|
|
88
85
|
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
@@ -95,7 +92,7 @@ namespace margelo::nitro {
|
|
|
95
92
|
}
|
|
96
93
|
if (!JSIConverter<std::optional<std::vector<std::string>>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "entities")))) return false;
|
|
97
94
|
if (!JSIConverter<std::optional<std::vector<margelo::nitro::rngine::CollisionPair>>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "collisions")))) return false;
|
|
98
|
-
if (!JSIConverter<std::function<std::shared_ptr<Promise<double>>(const
|
|
95
|
+
if (!JSIConverter<std::function<std::shared_ptr<Promise<double>>(const margelo::nitro::rngine::SystemContext&)>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "onTick")))) return false;
|
|
99
96
|
return true;
|
|
100
97
|
}
|
|
101
98
|
};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// SystemContext.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#if __has_include(<NitroModules/JSIConverter.hpp>)
|
|
11
|
+
#include <NitroModules/JSIConverter.hpp>
|
|
12
|
+
#else
|
|
13
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
14
|
+
#endif
|
|
15
|
+
#if __has_include(<NitroModules/NitroDefines.hpp>)
|
|
16
|
+
#include <NitroModules/NitroDefines.hpp>
|
|
17
|
+
#else
|
|
18
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
19
|
+
#endif
|
|
20
|
+
#if __has_include(<NitroModules/JSIHelpers.hpp>)
|
|
21
|
+
#include <NitroModules/JSIHelpers.hpp>
|
|
22
|
+
#else
|
|
23
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
24
|
+
#endif
|
|
25
|
+
#if __has_include(<NitroModules/PropNameIDCache.hpp>)
|
|
26
|
+
#include <NitroModules/PropNameIDCache.hpp>
|
|
27
|
+
#else
|
|
28
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
29
|
+
#endif
|
|
30
|
+
|
|
31
|
+
// Forward declaration of `Screen` to properly resolve imports.
|
|
32
|
+
namespace margelo::nitro::rngine { struct Screen; }
|
|
33
|
+
// Forward declaration of `Entity` to properly resolve imports.
|
|
34
|
+
namespace margelo::nitro::rngine { struct Entity; }
|
|
35
|
+
// Forward declaration of `Collision` to properly resolve imports.
|
|
36
|
+
namespace margelo::nitro::rngine { struct Collision; }
|
|
37
|
+
|
|
38
|
+
#include "Screen.hpp"
|
|
39
|
+
#include "Entity.hpp"
|
|
40
|
+
#include <vector>
|
|
41
|
+
#include "Collision.hpp"
|
|
42
|
+
|
|
43
|
+
namespace margelo::nitro::rngine {
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* A struct which can be represented as a JavaScript object (SystemContext).
|
|
47
|
+
*/
|
|
48
|
+
struct SystemContext final {
|
|
49
|
+
public:
|
|
50
|
+
Screen screen SWIFT_PRIVATE;
|
|
51
|
+
std::vector<Entity> entities SWIFT_PRIVATE;
|
|
52
|
+
std::vector<Collision> collisions SWIFT_PRIVATE;
|
|
53
|
+
|
|
54
|
+
public:
|
|
55
|
+
SystemContext() = default;
|
|
56
|
+
explicit SystemContext(Screen screen, std::vector<Entity> entities, std::vector<Collision> collisions): screen(screen), entities(entities), collisions(collisions) {}
|
|
57
|
+
|
|
58
|
+
public:
|
|
59
|
+
friend bool operator==(const SystemContext& lhs, const SystemContext& rhs) = default;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
} // namespace margelo::nitro::rngine
|
|
63
|
+
|
|
64
|
+
namespace margelo::nitro {
|
|
65
|
+
|
|
66
|
+
// C++ SystemContext <> JS SystemContext (object)
|
|
67
|
+
template <>
|
|
68
|
+
struct JSIConverter<margelo::nitro::rngine::SystemContext> final {
|
|
69
|
+
static inline margelo::nitro::rngine::SystemContext fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
70
|
+
jsi::Object obj = arg.asObject(runtime);
|
|
71
|
+
return margelo::nitro::rngine::SystemContext(
|
|
72
|
+
JSIConverter<margelo::nitro::rngine::Screen>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "screen"))),
|
|
73
|
+
JSIConverter<std::vector<margelo::nitro::rngine::Entity>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "entities"))),
|
|
74
|
+
JSIConverter<std::vector<margelo::nitro::rngine::Collision>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "collisions")))
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::rngine::SystemContext& arg) {
|
|
78
|
+
jsi::Object obj(runtime);
|
|
79
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "screen"), JSIConverter<margelo::nitro::rngine::Screen>::toJSI(runtime, arg.screen));
|
|
80
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "entities"), JSIConverter<std::vector<margelo::nitro::rngine::Entity>>::toJSI(runtime, arg.entities));
|
|
81
|
+
obj.setProperty(runtime, PropNameIDCache::get(runtime, "collisions"), JSIConverter<std::vector<margelo::nitro::rngine::Collision>>::toJSI(runtime, arg.collisions));
|
|
82
|
+
return obj;
|
|
83
|
+
}
|
|
84
|
+
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
85
|
+
if (!value.isObject()) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
jsi::Object obj = value.getObject(runtime);
|
|
89
|
+
if (!nitro::isPlainObject(runtime, obj)) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
if (!JSIConverter<margelo::nitro::rngine::Screen>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "screen")))) return false;
|
|
93
|
+
if (!JSIConverter<std::vector<margelo::nitro::rngine::Entity>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "entities")))) return false;
|
|
94
|
+
if (!JSIConverter<std::vector<margelo::nitro::rngine::Collision>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "collisions")))) return false;
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
} // namespace margelo::nitro
|
package/package.json
CHANGED
package/shared/GameLoop.cpp
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
#include "GameLoop.hpp"
|
|
2
|
+
#include "AssetUtils.hpp"
|
|
2
3
|
#include "Collision.hpp"
|
|
3
4
|
#include "CollisionUtils.hpp"
|
|
4
5
|
#include "Entity.hpp"
|
|
5
6
|
#include "GameRenderer.hpp"
|
|
7
|
+
#include "SystemContext.hpp"
|
|
6
8
|
#include <android/log.h>
|
|
7
9
|
#include <chrono>
|
|
8
10
|
#include <cinttypes>
|
|
@@ -105,14 +107,15 @@ void GameLoop::runGameLoop() {
|
|
|
105
107
|
void GameLoop::runSystems() {
|
|
106
108
|
for (size_t systemIndex = 0; systemIndex < _systems.size(); ++systemIndex) {
|
|
107
109
|
auto &system = _systems[systemIndex];
|
|
108
|
-
|
|
109
|
-
|
|
110
|
+
SystemContext systemContext;
|
|
111
|
+
|
|
112
|
+
systemContext.screen = _screen;
|
|
110
113
|
|
|
111
114
|
if (system.entities.has_value()) {
|
|
112
115
|
for (const auto &id : system.entities.value()) {
|
|
113
116
|
auto resolvedEntitiesInternal = resolveEntitiesInternal(id);
|
|
114
117
|
for (auto *entity : resolvedEntitiesInternal)
|
|
115
|
-
entities.push_back(*entity);
|
|
118
|
+
systemContext.entities.push_back(*entity);
|
|
116
119
|
}
|
|
117
120
|
}
|
|
118
121
|
|
|
@@ -124,7 +127,7 @@ void GameLoop::runSystems() {
|
|
|
124
127
|
bool matchesReverse =
|
|
125
128
|
entityIdMatches(c.a, pair.b) && entityIdMatches(c.b, pair.a);
|
|
126
129
|
if (matchesForward || matchesReverse) {
|
|
127
|
-
collisions.push_back(c);
|
|
130
|
+
systemContext.collisions.push_back(c);
|
|
128
131
|
}
|
|
129
132
|
}
|
|
130
133
|
}
|
|
@@ -133,10 +136,10 @@ void GameLoop::runSystems() {
|
|
|
133
136
|
__android_log_print(
|
|
134
137
|
ANDROID_LOG_DEBUG, "GameLoop",
|
|
135
138
|
"System Index: %zu, Entities: %zu, Collisions: %zu, Calling onTick",
|
|
136
|
-
systemIndex, entities.size(),
|
|
139
|
+
systemIndex, systemContext.entities.size(),
|
|
140
|
+
systemContext.collisions.size());
|
|
137
141
|
|
|
138
|
-
std::shared_ptr<Promise<double>> promise =
|
|
139
|
-
system.onTick(entities, collisions);
|
|
142
|
+
std::shared_ptr<Promise<double>> promise = system.onTick(systemContext);
|
|
140
143
|
std::future<double> future = promise->await();
|
|
141
144
|
double duration = future.get();
|
|
142
145
|
|
|
@@ -179,19 +182,9 @@ void GameLoop::updateStats(double deltaTime) {
|
|
|
179
182
|
|
|
180
183
|
void GameLoop::updateScreen(double deltaTime) {
|
|
181
184
|
std::lock_guard<std::mutex> lock(_mutex);
|
|
182
|
-
if (_screen.asset.has_value()
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
if (it != lottieCache.end() && it->second) {
|
|
186
|
-
if (_screen.speed.has_value() && _screen.speed.value() > 0) {
|
|
187
|
-
_screen.progress = fmod(_screen.progress.value_or(0.0) +
|
|
188
|
-
(deltaTime * _screen.speed.value()) /
|
|
189
|
-
it->second->duration(),
|
|
190
|
-
1.0);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
} else if (_screen.progress.has_value()) {
|
|
194
|
-
_screen.progress.reset();
|
|
185
|
+
if (_screen.asset.has_value()) {
|
|
186
|
+
AssetUtils::updateProgress(_screen.progress, _screen.speed,
|
|
187
|
+
_screen.asset.value(), deltaTime);
|
|
195
188
|
}
|
|
196
189
|
}
|
|
197
190
|
|
|
@@ -224,19 +217,9 @@ void GameLoop::updateEntities(double deltaTime) {
|
|
|
224
217
|
entity.py += entity.vy.value() * deltaTime;
|
|
225
218
|
}
|
|
226
219
|
|
|
227
|
-
if (entity.asset.has_value()
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
if (it != lottieCache.end() && it->second) {
|
|
231
|
-
if (entity.speed.has_value() && entity.speed.value() > 0) {
|
|
232
|
-
entity.progress = fmod(entity.progress.value_or(0.0) +
|
|
233
|
-
(deltaTime * entity.speed.value()) /
|
|
234
|
-
it->second->duration(),
|
|
235
|
-
1.0);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
} else if (entity.progress.has_value()) {
|
|
239
|
-
entity.progress.reset();
|
|
220
|
+
if (entity.asset.has_value()) {
|
|
221
|
+
AssetUtils::updateProgress(entity.progress, entity.speed,
|
|
222
|
+
entity.asset.value(), deltaTime);
|
|
240
223
|
}
|
|
241
224
|
}
|
|
242
225
|
}
|
package/shared/GameMethods.cpp
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
#include "EntityUpdate.hpp"
|
|
3
3
|
#include "GameLoop.hpp"
|
|
4
4
|
#include "GameRenderer.hpp"
|
|
5
|
+
#include "include/core/SkImage.h"
|
|
5
6
|
#include "include/core/SkStream.h"
|
|
6
7
|
#include <android/log.h>
|
|
7
8
|
#include <fbjni/fbjni.h>
|
|
@@ -105,80 +106,78 @@ void GameMethods::despawn(const std::string &id) {
|
|
|
105
106
|
}
|
|
106
107
|
}
|
|
107
108
|
|
|
108
|
-
void
|
|
109
|
+
static void patch(const auto &field, auto &target) {
|
|
110
|
+
if (field.has_value()) {
|
|
111
|
+
target = field.value();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
void GameMethods::updateEntities(
|
|
116
|
+
const std::vector<EntityUpdate> &entityUpdates) {
|
|
109
117
|
auto &instance = GameLoop::getInstance();
|
|
110
118
|
std::lock_guard<std::mutex> lock(instance.getMutexInternal());
|
|
111
|
-
for (const auto &
|
|
119
|
+
for (const auto &entityUpdate : entityUpdates) {
|
|
112
120
|
auto resolvedEntitiesInternals =
|
|
113
|
-
instance.resolveEntitiesInternal(
|
|
121
|
+
instance.resolveEntitiesInternal(entityUpdate.id);
|
|
114
122
|
if (resolvedEntitiesInternals.empty()) {
|
|
115
123
|
__android_log_print(ANDROID_LOG_WARN, "GameMethods",
|
|
116
|
-
"
|
|
117
|
-
|
|
124
|
+
"entityUpdate: no entity found for id=%s",
|
|
125
|
+
entityUpdate.id.c_str());
|
|
118
126
|
continue;
|
|
119
127
|
}
|
|
120
128
|
|
|
121
129
|
for (auto *entity : resolvedEntitiesInternals) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
if (update.progress.has_value()) {
|
|
138
|
-
entity->progress = update.progress.value();
|
|
139
|
-
}
|
|
140
|
-
if (update.speed.has_value()) {
|
|
141
|
-
entity->speed = update.speed.value();
|
|
142
|
-
}
|
|
143
|
-
if (update.color.has_value()) {
|
|
144
|
-
entity->color = update.color.value();
|
|
145
|
-
}
|
|
146
|
-
if (update.flipH.has_value()) {
|
|
147
|
-
entity->flipH = update.flipH.value();
|
|
148
|
-
}
|
|
149
|
-
if (update.flipV.has_value()) {
|
|
150
|
-
entity->flipV = update.flipV.value();
|
|
151
|
-
}
|
|
152
|
-
if (update.vx.has_value()) {
|
|
153
|
-
entity->vx = update.vx.value();
|
|
154
|
-
}
|
|
155
|
-
if (update.vy.has_value()) {
|
|
156
|
-
entity->vy = update.vy.value();
|
|
157
|
-
}
|
|
158
|
-
if (update.ax.has_value()) {
|
|
159
|
-
entity->ax = update.ax.value();
|
|
160
|
-
}
|
|
161
|
-
if (update.ay.has_value()) {
|
|
162
|
-
entity->ay = update.ay.value();
|
|
163
|
-
}
|
|
164
|
-
if (update.mass.has_value()) {
|
|
165
|
-
entity->mass = update.mass.value();
|
|
166
|
-
}
|
|
130
|
+
patch(entityUpdate.px, entity->px);
|
|
131
|
+
patch(entityUpdate.py, entity->py);
|
|
132
|
+
patch(entityUpdate.shape, entity->shape);
|
|
133
|
+
patch(entityUpdate.isSensor, entity->isSensor);
|
|
134
|
+
patch(entityUpdate.asset, entity->asset);
|
|
135
|
+
patch(entityUpdate.progress, entity->progress);
|
|
136
|
+
patch(entityUpdate.speed, entity->speed);
|
|
137
|
+
patch(entityUpdate.color, entity->color);
|
|
138
|
+
patch(entityUpdate.flipH, entity->flipH);
|
|
139
|
+
patch(entityUpdate.flipV, entity->flipV);
|
|
140
|
+
patch(entityUpdate.vx, entity->vx);
|
|
141
|
+
patch(entityUpdate.vy, entity->vy);
|
|
142
|
+
patch(entityUpdate.ax, entity->ax);
|
|
143
|
+
patch(entityUpdate.ay, entity->ay);
|
|
144
|
+
patch(entityUpdate.mass, entity->mass);
|
|
167
145
|
}
|
|
168
146
|
|
|
169
147
|
__android_log_print(ANDROID_LOG_INFO, "GameMethods",
|
|
170
|
-
"
|
|
171
|
-
resolvedEntitiesInternals.size(),
|
|
148
|
+
"entityUpdateEntities: patched %zu entities for id=%s",
|
|
149
|
+
resolvedEntitiesInternals.size(),
|
|
150
|
+
entityUpdate.id.c_str());
|
|
172
151
|
}
|
|
173
152
|
}
|
|
174
153
|
|
|
154
|
+
void GameMethods::updateScreen(const ScreenUpdate &screenUpdate) {
|
|
155
|
+
auto &instance = GameLoop::getInstance();
|
|
156
|
+
std::lock_guard<std::mutex> lock(instance.getMutexInternal());
|
|
157
|
+
auto &screen = instance.getScreenInternal();
|
|
158
|
+
|
|
159
|
+
patch(screenUpdate.px, screen.px);
|
|
160
|
+
patch(screenUpdate.py, screen.py);
|
|
161
|
+
patch(screenUpdate.width, screen.width);
|
|
162
|
+
patch(screenUpdate.height, screen.height);
|
|
163
|
+
patch(screenUpdate.asset, screen.asset);
|
|
164
|
+
patch(screenUpdate.progress, screen.progress);
|
|
165
|
+
patch(screenUpdate.speed, screen.speed);
|
|
166
|
+
patch(screenUpdate.color, screen.color);
|
|
167
|
+
patch(screenUpdate.flipH, screen.flipH);
|
|
168
|
+
patch(screenUpdate.flipV, screen.flipV);
|
|
169
|
+
|
|
170
|
+
__android_log_print(ANDROID_LOG_INFO, "GameMethods",
|
|
171
|
+
"updateScreen: patched screen");
|
|
172
|
+
}
|
|
173
|
+
|
|
175
174
|
bool GameMethods::isAssetLoaded(double id) {
|
|
176
175
|
auto &gameRenderer = GameRenderer::getInstance();
|
|
177
176
|
|
|
178
177
|
if (id > 0) {
|
|
179
|
-
auto &
|
|
180
|
-
auto it =
|
|
181
|
-
return it !=
|
|
178
|
+
auto &imageCache = gameRenderer.getImageCacheInternal();
|
|
179
|
+
auto it = imageCache.find(id);
|
|
180
|
+
return it != imageCache.end();
|
|
182
181
|
}
|
|
183
182
|
|
|
184
183
|
if (id < 0) {
|
|
@@ -213,53 +212,86 @@ GameMethods::loadLottie(double id, const std::string &jsonStr) {
|
|
|
213
212
|
});
|
|
214
213
|
};
|
|
215
214
|
|
|
216
|
-
std::shared_ptr<Promise<bool>>
|
|
217
|
-
|
|
215
|
+
std::shared_ptr<Promise<bool>>
|
|
216
|
+
GameMethods::loadImage(double id, const std::string &imageUri) {
|
|
218
217
|
return Promise<bool>::async([=]() -> bool {
|
|
219
|
-
|
|
218
|
+
__android_log_print(ANDROID_LOG_DEBUG, "GameMethods",
|
|
219
|
+
"loadImage: start id=%.0f uri=%s", id,
|
|
220
|
+
imageUri.c_str());
|
|
221
|
+
std::string imageStr;
|
|
220
222
|
|
|
221
223
|
using namespace facebook::jni;
|
|
222
224
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
225
|
+
try {
|
|
226
|
+
ThreadScope::WithClassLoader([&] {
|
|
227
|
+
static const auto helperClass =
|
|
228
|
+
findClassStatic("com/margelo/nitro/rngine/ImageLoaderHelper");
|
|
229
|
+
|
|
230
|
+
local_ref<JArrayByte> byteArray;
|
|
231
|
+
|
|
232
|
+
if (imageUri.rfind("http://", 0) == 0 ||
|
|
233
|
+
imageUri.rfind("https://", 0) == 0) {
|
|
234
|
+
static const auto method =
|
|
235
|
+
helperClass->getStaticMethod<JArrayByte(local_ref<JString>)>(
|
|
236
|
+
"loadFromUrl");
|
|
237
|
+
byteArray = method(helperClass, make_jstring(imageUri));
|
|
238
|
+
} else {
|
|
239
|
+
static const auto method =
|
|
240
|
+
helperClass->getStaticMethod<JArrayByte(local_ref<JString>)>(
|
|
241
|
+
"loadFromResource");
|
|
242
|
+
byteArray = method(helperClass, make_jstring(imageUri));
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (!byteArray) {
|
|
246
|
+
throw std::runtime_error("Failed to load image bytes for: " +
|
|
247
|
+
imageUri);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
size_t len = byteArray->size();
|
|
251
|
+
imageStr.resize(len);
|
|
252
|
+
byteArray->getRegion(0, len,
|
|
253
|
+
reinterpret_cast<int8_t *>(imageStr.data()));
|
|
254
|
+
});
|
|
255
|
+
} catch (const std::exception &e) {
|
|
256
|
+
__android_log_print(ANDROID_LOG_ERROR, "GameMethods",
|
|
257
|
+
"loadImage: JNI fetch failed id=%.0f: %s", id,
|
|
258
|
+
e.what());
|
|
254
259
|
return false;
|
|
255
260
|
}
|
|
256
261
|
|
|
262
|
+
__android_log_print(ANDROID_LOG_DEBUG, "GameMethods",
|
|
263
|
+
"loadImage: fetched %zu bytes id=%.0f", imageStr.size(),
|
|
264
|
+
id);
|
|
265
|
+
|
|
257
266
|
auto &gameRenderer = GameRenderer::getInstance();
|
|
258
|
-
auto &
|
|
267
|
+
auto &imageCache = gameRenderer.getImageCacheInternal();
|
|
259
268
|
|
|
260
|
-
|
|
269
|
+
auto stream = SkMemoryStream::MakeDirect(imageStr.data(), imageStr.size());
|
|
270
|
+
auto svgDom = SkSVGDOM::MakeFromStream(*stream);
|
|
261
271
|
|
|
262
|
-
|
|
272
|
+
if (svgDom) {
|
|
273
|
+
__android_log_print(ANDROID_LOG_DEBUG, "GameMethods",
|
|
274
|
+
"loadImage: parsed as SVG id=%.0f", id);
|
|
275
|
+
imageCache[id] = std::move(svgDom);
|
|
276
|
+
return true;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
auto data = SkData::MakeWithCopy(imageStr.data(), imageStr.size());
|
|
280
|
+
auto raster = SkImages::DeferredFromEncodedData(std::move(data));
|
|
281
|
+
|
|
282
|
+
if (raster) {
|
|
283
|
+
__android_log_print(ANDROID_LOG_DEBUG, "GameMethods",
|
|
284
|
+
"loadImage: parsed as raster id=%.0f", id);
|
|
285
|
+
imageCache[id] = std::move(raster);
|
|
286
|
+
return true;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
__android_log_print(ANDROID_LOG_ERROR, "GameMethods",
|
|
290
|
+
"loadImage: both SVG parse and raster decode failed "
|
|
291
|
+
"id=%.0f",
|
|
292
|
+
id);
|
|
293
|
+
|
|
294
|
+
return false;
|
|
263
295
|
});
|
|
264
296
|
};
|
|
265
297
|
} // namespace margelo::nitro::rngine
|