rngine 0.11.2 → 0.11.4

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.
Files changed (33) hide show
  1. package/android/CMakeLists.txt +2 -0
  2. package/lib/module/GameMethods.js +1 -14
  3. package/lib/module/GameMethods.js.map +1 -1
  4. package/lib/module/index.js.map +1 -1
  5. package/lib/typescript/src/GameMethods.d.ts +1 -1
  6. package/lib/typescript/src/GameMethods.d.ts.map +1 -1
  7. package/lib/typescript/src/GameMethods.nitro.d.ts +1 -1
  8. package/lib/typescript/src/GameMethods.nitro.d.ts.map +1 -1
  9. package/lib/typescript/src/index.d.ts +0 -1
  10. package/lib/typescript/src/index.d.ts.map +1 -1
  11. package/lib/typescript/src/types.d.ts +126 -3
  12. package/lib/typescript/src/types.d.ts.map +1 -1
  13. package/nitrogen/generated/shared/c++/HybridGameMethodsSpec.hpp +1 -3
  14. package/package.json +1 -1
  15. package/shared/GameLoop.cpp +14 -17
  16. package/shared/custom/Collision.hpp +136 -0
  17. package/shared/custom/CollisionPair.hpp +100 -0
  18. package/shared/custom/System.hpp +166 -0
  19. package/shared/custom/SystemContext.hpp +139 -0
  20. package/shared/utils/AssetUtils.cpp +77 -62
  21. package/src/GameMethods.nitro.ts +1 -1
  22. package/src/GameMethods.ts +2 -17
  23. package/src/index.tsx +0 -9
  24. package/src/types.ts +152 -12
  25. package/lib/module/nativeTypes.js +0 -2
  26. package/lib/module/nativeTypes.js.map +0 -1
  27. package/lib/typescript/src/nativeTypes.d.ts +0 -114
  28. package/lib/typescript/src/nativeTypes.d.ts.map +0 -1
  29. package/nitrogen/generated/shared/c++/Collision.hpp +0 -99
  30. package/nitrogen/generated/shared/c++/CollisionPair.hpp +0 -87
  31. package/nitrogen/generated/shared/c++/System.hpp +0 -100
  32. package/nitrogen/generated/shared/c++/SystemContext.hpp +0 -99
  33. package/src/nativeTypes.ts +0 -128
@@ -0,0 +1,166 @@
1
+ #pragma once
2
+
3
+ #if __has_include(<NitroModules/JSIConverter.hpp>)
4
+ #include <NitroModules/JSIConverter.hpp>
5
+ #else
6
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
7
+ #endif
8
+ #if __has_include(<NitroModules/NitroDefines.hpp>)
9
+ #include <NitroModules/NitroDefines.hpp>
10
+ #else
11
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
12
+ #endif
13
+ #if __has_include(<NitroModules/JSIHelpers.hpp>)
14
+ #include <NitroModules/JSIHelpers.hpp>
15
+ #else
16
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
17
+ #endif
18
+ #if __has_include(<NitroModules/PropNameIDCache.hpp>)
19
+ #include <NitroModules/PropNameIDCache.hpp>
20
+ #else
21
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
22
+ #endif
23
+
24
+ #include "CollisionPair.hpp"
25
+ #include "SystemContext.hpp"
26
+ #include <NitroModules/Promise.hpp>
27
+ #include <functional>
28
+ #include <optional>
29
+ #include <string>
30
+ #include <vector>
31
+
32
+ namespace margelo::nitro::rngine {
33
+
34
+ struct System final {
35
+ public:
36
+ std::optional<bool> world SWIFT_PRIVATE;
37
+ std::optional<bool> screen SWIFT_PRIVATE;
38
+ std::optional<std::vector<std::string>> entities SWIFT_PRIVATE;
39
+ std::optional<std::vector<CollisionPair>> collisions SWIFT_PRIVATE;
40
+ std::function<std::shared_ptr<Promise<void>>(const SystemContext &)> onTick
41
+ SWIFT_PRIVATE;
42
+
43
+ public:
44
+ System() = default;
45
+ explicit System(
46
+ std::optional<bool> world, std::optional<bool> screen,
47
+ std::optional<std::vector<std::string>> entities,
48
+ std::optional<std::vector<CollisionPair>> collisions,
49
+ std::function<std::shared_ptr<Promise<void>>(const SystemContext &)>
50
+ onTick)
51
+ : world(world), screen(screen), entities(entities),
52
+ collisions(collisions), onTick(onTick) {}
53
+ };
54
+
55
+ } // namespace margelo::nitro::rngine
56
+
57
+ namespace margelo::nitro {
58
+
59
+ template <> struct JSIConverter<rngine::System> final {
60
+ using OnTick = std::function<std::shared_ptr<Promise<void>>(
61
+ const rngine::SystemContext &)>;
62
+
63
+ static inline OnTick makeOnTick(jsi::Runtime &runtime,
64
+ const jsi::Value &value) {
65
+ jsi::Function fn = value.asObject(runtime).asFunction(runtime);
66
+
67
+ BorrowingReference<jsi::Function> shared;
68
+ {
69
+ JSICacheReference cache = JSICache::getOrCreateCache(runtime);
70
+ shared = cache.makeShared(std::move(fn));
71
+ }
72
+
73
+ SyncJSCallback<void(const rngine::SystemContext &)> sync(runtime,
74
+ std::move(shared));
75
+ auto dispatcher = Dispatcher::getRuntimeGlobalDispatcher(runtime);
76
+ AsyncJSCallback<void(const rngine::SystemContext &)> async(std::move(sync),
77
+ dispatcher);
78
+
79
+ return [async = std::move(async)](const rngine::SystemContext &ctx) {
80
+ return async.call(ctx);
81
+ };
82
+ }
83
+
84
+ static inline rngine::System fromJSI(jsi::Runtime &runtime,
85
+ const jsi::Value &arg) {
86
+ jsi::Object obj = arg.asObject(runtime);
87
+ return rngine::System(
88
+ JSIConverter<std::optional<bool>>::fromJSI(
89
+ runtime,
90
+ obj.getProperty(runtime, PropNameIDCache::get(runtime, "world"))),
91
+ JSIConverter<std::optional<bool>>::fromJSI(
92
+ runtime,
93
+ obj.getProperty(runtime, PropNameIDCache::get(runtime, "screen"))),
94
+ JSIConverter<std::optional<std::vector<std::string>>>::fromJSI(
95
+ runtime, obj.getProperty(
96
+ runtime, PropNameIDCache::get(runtime, "entities"))),
97
+ JSIConverter<std::optional<std::vector<rngine::CollisionPair>>>::
98
+ fromJSI(runtime,
99
+ obj.getProperty(
100
+ runtime, PropNameIDCache::get(runtime, "collisions"))),
101
+ makeOnTick(runtime, obj.getProperty(runtime, PropNameIDCache::get(
102
+ runtime, "onTick"))));
103
+ }
104
+
105
+ static inline jsi::Value toJSI(jsi::Runtime &runtime,
106
+ const rngine::System &arg) {
107
+ jsi::Object obj(runtime);
108
+ obj.setProperty(
109
+ runtime, PropNameIDCache::get(runtime, "world"),
110
+ JSIConverter<std::optional<bool>>::toJSI(runtime, arg.world));
111
+ obj.setProperty(
112
+ runtime, PropNameIDCache::get(runtime, "screen"),
113
+ JSIConverter<std::optional<bool>>::toJSI(runtime, arg.screen));
114
+ obj.setProperty(
115
+ runtime, PropNameIDCache::get(runtime, "entities"),
116
+ JSIConverter<std::optional<std::vector<std::string>>>::toJSI(
117
+ runtime, arg.entities));
118
+ obj.setProperty(
119
+ runtime, PropNameIDCache::get(runtime, "collisions"),
120
+ JSIConverter<std::optional<std::vector<rngine::CollisionPair>>>::toJSI(
121
+ runtime, arg.collisions));
122
+ obj.setProperty(
123
+ runtime, PropNameIDCache::get(runtime, "onTick"),
124
+ JSIConverter<std::function<std::shared_ptr<Promise<void>>(
125
+ const rngine::SystemContext &)>>::toJSI(runtime, arg.onTick));
126
+ return obj;
127
+ }
128
+
129
+ static inline bool canConvert(jsi::Runtime &runtime,
130
+ const jsi::Value &value) {
131
+ if (!value.isObject()) {
132
+ return false;
133
+ }
134
+ jsi::Object obj = value.getObject(runtime);
135
+ if (!nitro::isPlainObject(runtime, obj)) {
136
+ return false;
137
+ }
138
+ if (!JSIConverter<std::optional<bool>>::canConvert(
139
+ runtime,
140
+ obj.getProperty(runtime, PropNameIDCache::get(runtime, "world"))))
141
+ return false;
142
+ if (!JSIConverter<std::optional<bool>>::canConvert(
143
+ runtime,
144
+ obj.getProperty(runtime, PropNameIDCache::get(runtime, "screen"))))
145
+ return false;
146
+ if (!JSIConverter<std::optional<std::vector<std::string>>>::canConvert(
147
+ runtime, obj.getProperty(
148
+ runtime, PropNameIDCache::get(runtime, "entities"))))
149
+ return false;
150
+ if (!JSIConverter<std::optional<std::vector<rngine::CollisionPair>>>::
151
+ canConvert(runtime,
152
+ obj.getProperty(runtime, PropNameIDCache::get(
153
+ runtime, "collisions"))))
154
+ return false;
155
+ if (!JSIConverter<std::function<std::shared_ptr<Promise<void>>(
156
+ const rngine::SystemContext &)>>::
157
+ canConvert(runtime,
158
+ obj.getProperty(
159
+ runtime, PropNameIDCache::get(runtime, "onTick"))))
160
+ return false;
161
+
162
+ return true;
163
+ }
164
+ };
165
+
166
+ } // namespace margelo::nitro
@@ -0,0 +1,139 @@
1
+ #pragma once
2
+
3
+ #include <optional>
4
+ #if __has_include(<NitroModules/JSIConverter.hpp>)
5
+ #include <NitroModules/JSIConverter.hpp>
6
+ #else
7
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
8
+ #endif
9
+ #if __has_include(<NitroModules/NitroDefines.hpp>)
10
+ #include <NitroModules/NitroDefines.hpp>
11
+ #else
12
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
13
+ #endif
14
+ #if __has_include(<NitroModules/JSIHelpers.hpp>)
15
+ #include <NitroModules/JSIHelpers.hpp>
16
+ #else
17
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
18
+ #endif
19
+ #if __has_include(<NitroModules/PropNameIDCache.hpp>)
20
+ #include <NitroModules/PropNameIDCache.hpp>
21
+ #else
22
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
23
+ #endif
24
+
25
+ #include "Collision.hpp"
26
+ #include "Entity.hpp"
27
+ #include "Screen.hpp"
28
+ #include "World.hpp"
29
+ #include <vector>
30
+
31
+ namespace margelo::nitro::rngine {
32
+
33
+ struct SystemContext final {
34
+ public:
35
+ std::optional<World> world SWIFT_PRIVATE;
36
+ std::optional<Screen> screen SWIFT_PRIVATE;
37
+ std::optional<std::vector<Entity>> entities SWIFT_PRIVATE;
38
+ std::optional<std::vector<Collision>> collisions SWIFT_PRIVATE;
39
+
40
+ public:
41
+ SystemContext() = default;
42
+ explicit SystemContext(std::optional<World> world,
43
+ std::optional<Screen> screen,
44
+ std::optional<std::vector<Entity>> entities,
45
+ std::optional<std::vector<Collision>> collisions)
46
+ : world(world), screen(screen), entities(entities),
47
+ collisions(collisions) {}
48
+
49
+ public:
50
+ friend bool operator==(const SystemContext &lhs,
51
+ const SystemContext &rhs) = default;
52
+ };
53
+
54
+ } // namespace margelo::nitro::rngine
55
+
56
+ namespace margelo::nitro {
57
+
58
+ template <> struct JSIConverter<rngine::SystemContext> final {
59
+ static inline rngine::SystemContext fromJSI(jsi::Runtime &runtime,
60
+ const jsi::Value &arg) {
61
+ jsi::Object obj = arg.asObject(runtime);
62
+
63
+ return rngine::SystemContext(
64
+ JSIConverter<std::optional<rngine::World>>::fromJSI(
65
+ runtime,
66
+ obj.getProperty(runtime, PropNameIDCache::get(runtime, "world"))),
67
+ JSIConverter<std::optional<rngine::Screen>>::fromJSI(
68
+ runtime,
69
+ obj.getProperty(runtime, PropNameIDCache::get(runtime, "screen"))),
70
+ JSIConverter<std::optional<std::vector<rngine::Entity>>>::fromJSI(
71
+ runtime, obj.getProperty(
72
+ runtime, PropNameIDCache::get(runtime, "entities"))),
73
+ JSIConverter<std::optional<std::vector<rngine::Collision>>>::fromJSI(
74
+ runtime, obj.getProperty(runtime, PropNameIDCache::get(
75
+ runtime, "collisions"))));
76
+ }
77
+
78
+ static inline jsi::Value toJSI(jsi::Runtime &runtime,
79
+ const rngine::SystemContext &arg) {
80
+ jsi::Object obj(runtime);
81
+
82
+ obj.setProperty(
83
+ runtime, PropNameIDCache::get(runtime, "world"),
84
+ JSIConverter<std::optional<rngine::World>>::toJSI(runtime, arg.world));
85
+
86
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "screen"),
87
+ JSIConverter<std::optional<rngine::Screen>>::toJSI(
88
+ runtime, arg.screen));
89
+
90
+ obj.setProperty(
91
+ runtime, PropNameIDCache::get(runtime, "entities"),
92
+ JSIConverter<std::optional<std::vector<rngine::Entity>>>::toJSI(
93
+ runtime, arg.entities));
94
+
95
+ obj.setProperty(
96
+ runtime, PropNameIDCache::get(runtime, "collisions"),
97
+ JSIConverter<std::optional<std::vector<rngine::Collision>>>::toJSI(
98
+ runtime, arg.collisions));
99
+
100
+ return obj;
101
+ }
102
+
103
+ static inline bool canConvert(jsi::Runtime &runtime,
104
+ const jsi::Value &value) {
105
+ if (!value.isObject()) {
106
+ return false;
107
+ }
108
+
109
+ jsi::Object obj = value.getObject(runtime);
110
+ if (!nitro::isPlainObject(runtime, obj)) {
111
+ return false;
112
+ }
113
+
114
+ if (!JSIConverter<std::optional<rngine::World>>::canConvert(
115
+ runtime,
116
+ obj.getProperty(runtime, PropNameIDCache::get(runtime, "world"))))
117
+ return false;
118
+
119
+ if (!JSIConverter<std::optional<rngine::Screen>>::canConvert(
120
+ runtime,
121
+ obj.getProperty(runtime, PropNameIDCache::get(runtime, "screen"))))
122
+ return false;
123
+
124
+ if (!JSIConverter<std::optional<std::vector<rngine::Entity>>>::canConvert(
125
+ runtime, obj.getProperty(
126
+ runtime, PropNameIDCache::get(runtime, "entities"))))
127
+ return false;
128
+
129
+ if (!JSIConverter<std::optional<std::vector<rngine::Collision>>>::
130
+ canConvert(runtime,
131
+ obj.getProperty(runtime, PropNameIDCache::get(
132
+ runtime, "collisions"))))
133
+ return false;
134
+
135
+ return true;
136
+ }
137
+ };
138
+
139
+ } // namespace margelo::nitro
@@ -1,6 +1,7 @@
1
1
  #include "AssetUtils.hpp"
2
2
  #include "FitTransform.hpp"
3
3
  #include "GameRenderer.hpp"
4
+ #include "include/core/SkPictureRecorder.h"
4
5
  #include <variant>
5
6
 
6
7
  namespace margelo::nitro::rngine::AssetUtils {
@@ -84,7 +85,10 @@ static void drawSVG(SkCanvas *canvas, const sk_sp<SkSVGDOM> &svg,
84
85
 
85
86
  SkAutoCanvasRestore restore(canvas, true);
86
87
 
87
- bool isRepeating = (repeat != Repeat::NO_REPEAT);
88
+ bool isRepeating = (repeat != Repeat::NO_REPEAT) &&
89
+ (objectFit != ObjectFit::FILL) &&
90
+ (objectFit != ObjectFit::COVER);
91
+
88
92
  bool shouldClip = clip && (objectFit == ObjectFit::COVER ||
89
93
  objectFit == ObjectFit::NONE || isRepeating);
90
94
 
@@ -99,30 +103,35 @@ static void drawSVG(SkCanvas *canvas, const sk_sp<SkSVGDOM> &svg,
99
103
  return;
100
104
  }
101
105
 
102
- float startX = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_X)
103
- ? computeCenteredTileStart(targetWidth, tileW)
104
- : tf.translateX;
106
+ SkPictureRecorder recorder;
107
+ SkCanvas *recordingCanvas =
108
+ recorder.beginRecording(intrinsicSize.width(), intrinsicSize.height());
109
+ svg->render(recordingCanvas);
110
+ sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();
105
111
 
106
- float startY = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_Y)
107
- ? computeCenteredTileStart(targetHeight, tileH)
108
- : tf.translateY;
112
+ bool repX = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_X);
113
+ bool repY = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_Y);
109
114
 
110
- float endX = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_X)
111
- ? targetWidth
112
- : (startX + tileW);
115
+ SkTileMode tileX = repX ? SkTileMode::kRepeat : SkTileMode::kDecal;
116
+ SkTileMode tileY = repY ? SkTileMode::kRepeat : SkTileMode::kDecal;
113
117
 
114
- float endY = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_Y)
115
- ? targetHeight
116
- : (startY + tileH);
118
+ float offsetX =
119
+ repX ? computeCenteredTileStart(targetWidth, tileW) : tf.translateX;
120
+ float offsetY =
121
+ repY ? computeCenteredTileStart(targetHeight, tileH) : tf.translateY;
117
122
 
118
- for (float y = startY; y < endY; y += tileH) {
119
- for (float x = startX; x < endX; x += tileW) {
120
- SkAutoCanvasRestore tileRestore(canvas, true);
121
- canvas->translate(x, y);
122
- canvas->scale(tf.scaleX, tf.scaleY);
123
- svg->render(canvas);
124
- }
125
- }
123
+ SkMatrix localMatrix;
124
+ localMatrix.setScale(tf.scaleX, tf.scaleY);
125
+ localMatrix.postTranslate(offsetX, offsetY);
126
+
127
+ SkRect tileBounds =
128
+ SkRect::MakeWH(intrinsicSize.width(), intrinsicSize.height());
129
+ sk_sp<SkShader> shader = picture->makeShader(
130
+ tileX, tileY, SkFilterMode::kLinear, &localMatrix, &tileBounds);
131
+
132
+ SkPaint paint;
133
+ paint.setShader(shader);
134
+ canvas->drawRect(SkRect::MakeWH(targetWidth, targetHeight), paint);
126
135
  }
127
136
 
128
137
  static void drawRaster(SkCanvas *canvas, const sk_sp<SkImage> &raster,
@@ -138,7 +147,10 @@ static void drawRaster(SkCanvas *canvas, const sk_sp<SkImage> &raster,
138
147
 
139
148
  SkAutoCanvasRestore restore(canvas, true);
140
149
 
141
- bool isRepeating = (repeat != Repeat::NO_REPEAT);
150
+ bool isRepeating = (repeat != Repeat::NO_REPEAT) &&
151
+ (objectFit != ObjectFit::FILL) &&
152
+ (objectFit != ObjectFit::COVER);
153
+
142
154
  bool shouldClip = clip && (objectFit == ObjectFit::COVER ||
143
155
  objectFit == ObjectFit::NONE || isRepeating);
144
156
 
@@ -155,31 +167,25 @@ static void drawRaster(SkCanvas *canvas, const sk_sp<SkImage> &raster,
155
167
  return;
156
168
  }
157
169
 
158
- SkTileMode tileX = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_X)
159
- ? SkTileMode::kRepeat
160
- : SkTileMode::kClamp;
161
- SkTileMode tileY = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_Y)
162
- ? SkTileMode::kRepeat
163
- : SkTileMode::kClamp;
170
+ bool repX = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_X);
171
+ bool repY = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_Y);
172
+
173
+ SkTileMode tileX = repX ? SkTileMode::kRepeat : SkTileMode::kDecal;
174
+ SkTileMode tileY = repY ? SkTileMode::kRepeat : SkTileMode::kDecal;
164
175
 
165
176
  float tileW = intrinsicW * tf.scaleX;
166
177
  float tileH = intrinsicH * tf.scaleY;
167
178
 
168
- SkMatrix localMatrix = SkMatrix::Scale(tf.scaleX, tf.scaleY);
169
-
170
- float offsetX = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_X)
171
- ? computeCenteredTileStart(targetWidth, tileW)
172
- : tf.translateX;
173
- float offsetY = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_Y)
174
- ? computeCenteredTileStart(targetHeight, tileH)
175
- : tf.translateY;
179
+ float offsetX =
180
+ repX ? computeCenteredTileStart(targetWidth, tileW) : tf.translateX;
181
+ float offsetY =
182
+ repY ? computeCenteredTileStart(targetHeight, tileH) : tf.translateY;
176
183
 
184
+ SkMatrix localMatrix = SkMatrix::Scale(tf.scaleX, tf.scaleY);
177
185
  localMatrix.postTranslate(offsetX, offsetY);
178
186
 
179
- auto shader = raster->makeShader(tileX, tileY, sampling, localMatrix);
180
-
181
187
  SkPaint paint;
182
- paint.setShader(shader);
188
+ paint.setShader(raster->makeShader(tileX, tileY, sampling, localMatrix));
183
189
  canvas->drawRect(SkRect::MakeWH(targetWidth, targetHeight), paint);
184
190
  }
185
191
 
@@ -207,7 +213,10 @@ static void drawLottie(SkCanvas *canvas,
207
213
 
208
214
  SkAutoCanvasRestore restore(canvas, true);
209
215
 
210
- bool isRepeating = (repeat != Repeat::NO_REPEAT);
216
+ bool isRepeating = (repeat != Repeat::NO_REPEAT) &&
217
+ (objectFit != ObjectFit::FILL) &&
218
+ (objectFit != ObjectFit::COVER);
219
+
211
220
  bool shouldClip = clip && (objectFit == ObjectFit::COVER ||
212
221
  objectFit == ObjectFit::NONE || isRepeating);
213
222
 
@@ -224,28 +233,34 @@ static void drawLottie(SkCanvas *canvas,
224
233
  return;
225
234
  }
226
235
 
227
- float startX = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_X)
228
- ? computeCenteredTileStart(targetWidth, tileW)
229
- : tf.translateX;
230
- float startY = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_Y)
231
- ? computeCenteredTileStart(targetHeight, tileH)
232
- : tf.translateY;
233
-
234
- float endX = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_X)
235
- ? targetWidth
236
- : (startX + tileW);
237
- float endY = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_Y)
238
- ? targetHeight
239
- : (startY + tileH);
240
-
241
- for (float y = startY; y < endY; y += tileH) {
242
- for (float x = startX; x < endX; x += tileW) {
243
- SkAutoCanvasRestore tileRestore(canvas, true);
244
- canvas->translate(x, y);
245
- canvas->scale(tf.scaleX, tf.scaleY);
246
- lottie->render(canvas, &dstBounds);
247
- }
248
- }
236
+ SkPictureRecorder recorder;
237
+ SkCanvas *recordingCanvas =
238
+ recorder.beginRecording(intrinsicWidth, intrinsicHeight);
239
+ lottie->render(recordingCanvas, &dstBounds);
240
+ sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();
241
+
242
+ bool repX = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_X);
243
+ bool repY = (repeat == Repeat::REPEAT || repeat == Repeat::REPEAT_Y);
244
+
245
+ SkTileMode tileX = repX ? SkTileMode::kRepeat : SkTileMode::kDecal;
246
+ SkTileMode tileY = repY ? SkTileMode::kRepeat : SkTileMode::kDecal;
247
+
248
+ float offsetX =
249
+ repX ? computeCenteredTileStart(targetWidth, tileW) : tf.translateX;
250
+ float offsetY =
251
+ repY ? computeCenteredTileStart(targetHeight, tileH) : tf.translateY;
252
+
253
+ SkMatrix localMatrix;
254
+ localMatrix.setScale(tf.scaleX, tf.scaleY);
255
+ localMatrix.postTranslate(offsetX, offsetY);
256
+
257
+ SkRect tileBounds = SkRect::MakeWH(intrinsicWidth, intrinsicHeight);
258
+ sk_sp<SkShader> shader = picture->makeShader(
259
+ tileX, tileY, SkFilterMode::kLinear, &localMatrix, &tileBounds);
260
+
261
+ SkPaint paint;
262
+ paint.setShader(shader);
263
+ canvas->drawRect(SkRect::MakeWH(targetWidth, targetHeight), paint);
249
264
  }
250
265
 
251
266
  void drawAsset(SkCanvas *canvas, double asset, float targetWidth,
@@ -6,7 +6,7 @@ import type {
6
6
  Screen,
7
7
  World,
8
8
  ScreenUpdate,
9
- } from './nativeTypes';
9
+ } from './types';
10
10
  import { NitroModules } from 'react-native-nitro-modules';
11
11
 
12
12
  interface GameMethods extends HybridObject<{
@@ -1,5 +1,5 @@
1
1
  import { gameMethods } from './GameMethods.nitro';
2
- import type { Entity, EntityUpdate, ScreenUpdate, System } from './nativeTypes';
2
+ import type { Entity, EntityUpdate, ScreenUpdate } from './types';
3
3
  import type { Config } from './types';
4
4
  import { Image } from 'react-native';
5
5
 
@@ -11,25 +11,10 @@ export const configure = ({
11
11
  systems = [],
12
12
  paused = true,
13
13
  }: Config) => {
14
- let nativeSystems: System[] = [];
15
-
16
- for (const system of systems) {
17
- nativeSystems.push({
18
- entities: system.entities,
19
- collisions: system.collisions,
20
- onTick: (systemContext) => {
21
- const start = Date.now();
22
- system.onTick(systemContext);
23
- const finish = Date.now();
24
- return finish - start;
25
- },
26
- });
27
- }
28
-
29
14
  gameMethods.setWorld(world);
30
15
  gameMethods.setScreen(screen);
31
16
  gameMethods.setEntities(entities);
32
- gameMethods.setSystems(nativeSystems);
17
+ gameMethods.setSystems(systems);
33
18
  if (paused) {
34
19
  gameMethods.pause();
35
20
  } else {
package/src/index.tsx CHANGED
@@ -2,13 +2,4 @@ import GameEngine from './GameEngine';
2
2
 
3
3
  export * from './GameMethods';
4
4
  export * from './types';
5
- export type {
6
- World,
7
- Screen,
8
- Entity,
9
- CollisionPair,
10
- Collision,
11
- EntityUpdate,
12
- SystemContext,
13
- } from './nativeTypes';
14
5
  export { GameEngine };