@nayan-ui/engine 0.0.0-stage → 1.0.0-beta.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 (198) hide show
  1. package/LICENSE +21 -0
  2. package/NayanEngine.podspec +28 -0
  3. package/README.md +308 -2
  4. package/lib/module/assets/AssetBytesCache.js +76 -0
  5. package/lib/module/assets/AssetCache.js +19 -0
  6. package/lib/module/assets/AssetLoader.js +52 -0
  7. package/lib/module/assets/CacheGeneration.js +7 -0
  8. package/lib/module/assets/IndexedDbCache.web.js +149 -0
  9. package/lib/module/assets/ProceduralCache.js +249 -0
  10. package/lib/module/assets/font.js +139 -0
  11. package/lib/module/assets/loft.js +142 -0
  12. package/lib/module/assets/model.js +96 -0
  13. package/lib/module/assets/modelling.js +254 -0
  14. package/lib/module/assets/shape.js +926 -0
  15. package/lib/module/assets/source.js +58 -0
  16. package/lib/module/assets/source.web.js +22 -0
  17. package/lib/module/assets/storage.js +4 -0
  18. package/lib/module/assets/storage.shared.js +38 -0
  19. package/lib/module/assets/storage.web.js +38 -0
  20. package/lib/module/assets/surface.js +47 -0
  21. package/lib/module/assets/texture.js +69 -0
  22. package/lib/module/drawing/DrawingCanvas.js +38 -0
  23. package/lib/module/drawing/DrawingCanvas.web.js +206 -0
  24. package/lib/module/drawing/DrawingDocument.js +256 -0
  25. package/lib/module/drawing/types.js +4 -0
  26. package/lib/module/globals.d.ts +12 -0
  27. package/lib/module/index.js +39 -0
  28. package/lib/module/input/Joystick.js +84 -0
  29. package/lib/module/input/Joystick.web.js +93 -0
  30. package/lib/module/input/keyboard.js +250 -0
  31. package/lib/module/media/audio-worklet.js +34 -0
  32. package/lib/module/media/audio.js +97 -0
  33. package/lib/module/media/haptics.js +82 -0
  34. package/lib/module/media/output.web.js +66 -0
  35. package/lib/module/native/BrowserEngine.js +568 -0
  36. package/lib/module/native/EngineBridge.js +4 -0
  37. package/lib/module/native/NativeNayanEngine.js +7 -0
  38. package/lib/module/native/NativeNayanEngine.web.js +62 -0
  39. package/lib/module/native/prepare.js +7 -0
  40. package/lib/module/native/prepare.web.js +17 -0
  41. package/lib/module/native/spec/NativeNayanEngine.js +17 -0
  42. package/lib/module/package.json +1 -0
  43. package/lib/module/render/GameView.js +317 -0
  44. package/lib/module/render/camera.js +34 -0
  45. package/lib/module/render/host.js +39 -0
  46. package/lib/module/render/host.web.js +104 -0
  47. package/lib/module/render/light.js +24 -0
  48. package/lib/module/render/meshes.js +159 -0
  49. package/lib/module/render/quality.js +119 -0
  50. package/lib/module/render/responder.js +4 -0
  51. package/lib/module/render/responder.web.js +97 -0
  52. package/lib/module/render/touch.js +185 -0
  53. package/lib/module/render/useWorld.js +72 -0
  54. package/lib/module/types.js +30 -0
  55. package/lib/module/world/Scoreboard.js +161 -0
  56. package/lib/module/world/TransformBatch.js +128 -0
  57. package/lib/module/world/World.js +704 -0
  58. package/lib/module/world/color.js +80 -0
  59. package/lib/module/world/desc.js +187 -0
  60. package/lib/module/world/effects.js +463 -0
  61. package/lib/module/world/quat.js +86 -0
  62. package/lib/module/world/types.js +4 -0
  63. package/lib/typescript/package.json +1 -0
  64. package/lib/typescript/src/assets/AssetBytesCache.d.ts +7 -0
  65. package/lib/typescript/src/assets/AssetCache.d.ts +9 -0
  66. package/lib/typescript/src/assets/AssetLoader.d.ts +11 -0
  67. package/lib/typescript/src/assets/CacheGeneration.d.ts +3 -0
  68. package/lib/typescript/src/assets/IndexedDbCache.web.d.ts +20 -0
  69. package/lib/typescript/src/assets/ProceduralCache.d.ts +45 -0
  70. package/lib/typescript/src/assets/font.d.ts +53 -0
  71. package/lib/typescript/src/assets/loft.d.ts +31 -0
  72. package/lib/typescript/src/assets/model.d.ts +58 -0
  73. package/lib/typescript/src/assets/modelling.d.ts +157 -0
  74. package/lib/typescript/src/assets/shape.d.ts +203 -0
  75. package/lib/typescript/src/assets/source.d.ts +10 -0
  76. package/lib/typescript/src/assets/source.web.d.ts +8 -0
  77. package/lib/typescript/src/assets/storage.d.ts +2 -0
  78. package/lib/typescript/src/assets/storage.shared.d.ts +7 -0
  79. package/lib/typescript/src/assets/storage.web.d.ts +7 -0
  80. package/lib/typescript/src/assets/surface.d.ts +17 -0
  81. package/lib/typescript/src/assets/texture.d.ts +30 -0
  82. package/lib/typescript/src/drawing/DrawingCanvas.d.ts +5 -0
  83. package/lib/typescript/src/drawing/DrawingCanvas.web.d.ts +4 -0
  84. package/lib/typescript/src/drawing/DrawingDocument.d.ts +210 -0
  85. package/lib/typescript/src/drawing/types.d.ts +12 -0
  86. package/lib/typescript/src/index.d.ts +45 -0
  87. package/lib/typescript/src/input/Joystick.d.ts +20 -0
  88. package/lib/typescript/src/input/Joystick.web.d.ts +13 -0
  89. package/lib/typescript/src/input/keyboard.d.ts +17 -0
  90. package/lib/typescript/src/media/audio.d.ts +46 -0
  91. package/lib/typescript/src/media/haptics.d.ts +22 -0
  92. package/lib/typescript/src/media/output.web.d.ts +4 -0
  93. package/lib/typescript/src/native/BrowserEngine.d.ts +8 -0
  94. package/lib/typescript/src/native/EngineBridge.d.ts +26 -0
  95. package/lib/typescript/src/native/NativeNayanEngine.d.ts +5 -0
  96. package/lib/typescript/src/native/NativeNayanEngine.web.d.ts +10 -0
  97. package/lib/typescript/src/native/prepare.d.ts +3 -0
  98. package/lib/typescript/src/native/prepare.web.d.ts +2 -0
  99. package/lib/typescript/src/native/spec/NativeNayanEngine.d.ts +211 -0
  100. package/lib/typescript/src/render/GameView.d.ts +107 -0
  101. package/lib/typescript/src/render/camera.d.ts +6 -0
  102. package/lib/typescript/src/render/host.d.ts +29 -0
  103. package/lib/typescript/src/render/host.web.d.ts +16 -0
  104. package/lib/typescript/src/render/light.d.ts +12 -0
  105. package/lib/typescript/src/render/meshes.d.ts +45 -0
  106. package/lib/typescript/src/render/quality.d.ts +48 -0
  107. package/lib/typescript/src/render/responder.d.ts +2 -0
  108. package/lib/typescript/src/render/responder.web.d.ts +40 -0
  109. package/lib/typescript/src/render/touch.d.ts +26 -0
  110. package/lib/typescript/src/render/useWorld.d.ts +20 -0
  111. package/lib/typescript/src/types.d.ts +81 -0
  112. package/lib/typescript/src/world/Scoreboard.d.ts +75 -0
  113. package/lib/typescript/src/world/TransformBatch.d.ts +39 -0
  114. package/lib/typescript/src/world/World.d.ts +207 -0
  115. package/lib/typescript/src/world/color.d.ts +18 -0
  116. package/lib/typescript/src/world/desc.d.ts +17 -0
  117. package/lib/typescript/src/world/effects.d.ts +157 -0
  118. package/lib/typescript/src/world/quat.d.ts +31 -0
  119. package/lib/typescript/src/world/types.d.ts +238 -0
  120. package/lib/web/audio-worklet.js +29 -0
  121. package/lib/web/engine_core_bg.wasm +0 -0
  122. package/lib/web/index.js +8240 -0
  123. package/lib/web/types/src/assets/AssetBytesCache.d.ts +6 -0
  124. package/lib/web/types/src/assets/AssetCache.d.ts +8 -0
  125. package/lib/web/types/src/assets/AssetLoader.d.ts +10 -0
  126. package/lib/web/types/src/assets/CacheGeneration.d.ts +2 -0
  127. package/lib/web/types/src/assets/IndexedDbCache.d.ts +19 -0
  128. package/lib/web/types/src/assets/ProceduralCache.d.ts +44 -0
  129. package/lib/web/types/src/assets/font.d.ts +52 -0
  130. package/lib/web/types/src/assets/loft.d.ts +30 -0
  131. package/lib/web/types/src/assets/model.d.ts +57 -0
  132. package/lib/web/types/src/assets/modelling.d.ts +156 -0
  133. package/lib/web/types/src/assets/shape.d.ts +202 -0
  134. package/lib/web/types/src/assets/source.d.ts +7 -0
  135. package/lib/web/types/src/assets/storage.d.ts +6 -0
  136. package/lib/web/types/src/assets/storage.shared.d.ts +6 -0
  137. package/lib/web/types/src/assets/surface.d.ts +16 -0
  138. package/lib/web/types/src/assets/texture.d.ts +29 -0
  139. package/lib/web/types/src/drawing/DrawingCanvas.d.ts +3 -0
  140. package/lib/web/types/src/drawing/DrawingDocument.d.ts +209 -0
  141. package/lib/web/types/src/drawing/types.d.ts +11 -0
  142. package/lib/web/types/src/index.d.ts +44 -0
  143. package/lib/web/types/src/input/Joystick.d.ts +12 -0
  144. package/lib/web/types/src/input/keyboard.d.ts +16 -0
  145. package/lib/web/types/src/media/audio.d.ts +45 -0
  146. package/lib/web/types/src/media/haptics.d.ts +21 -0
  147. package/lib/web/types/src/media/output.d.ts +3 -0
  148. package/lib/web/types/src/native/BrowserEngine.d.ts +7 -0
  149. package/lib/web/types/src/native/EngineBridge.d.ts +25 -0
  150. package/lib/web/types/src/native/NativeNayanEngine.d.ts +9 -0
  151. package/lib/web/types/src/native/prepare.d.ts +1 -0
  152. package/lib/web/types/src/native/spec/NativeNayanEngine.d.ts +210 -0
  153. package/lib/web/types/src/render/GameView.d.ts +106 -0
  154. package/lib/web/types/src/render/camera.d.ts +5 -0
  155. package/lib/web/types/src/render/host.d.ts +15 -0
  156. package/lib/web/types/src/render/light.d.ts +11 -0
  157. package/lib/web/types/src/render/meshes.d.ts +44 -0
  158. package/lib/web/types/src/render/quality.d.ts +47 -0
  159. package/lib/web/types/src/render/responder.d.ts +39 -0
  160. package/lib/web/types/src/render/touch.d.ts +25 -0
  161. package/lib/web/types/src/render/useWorld.d.ts +19 -0
  162. package/lib/web/types/src/types.d.ts +80 -0
  163. package/lib/web/types/src/world/Scoreboard.d.ts +74 -0
  164. package/lib/web/types/src/world/TransformBatch.d.ts +38 -0
  165. package/lib/web/types/src/world/World.d.ts +206 -0
  166. package/lib/web/types/src/world/color.d.ts +17 -0
  167. package/lib/web/types/src/world/desc.d.ts +16 -0
  168. package/lib/web/types/src/world/effects.d.ts +156 -0
  169. package/lib/web/types/src/world/quat.d.ts +30 -0
  170. package/lib/web/types/src/world/types.d.ts +237 -0
  171. package/native/android/CMakeLists.txt +34 -0
  172. package/native/android/NayanEngineSpec.h +15 -0
  173. package/native/android/build.gradle +26 -0
  174. package/native/android/codegen/CMakeLists.txt +3 -0
  175. package/native/android/proguard-rules.pro +2 -0
  176. package/native/android/src/main/java/com/nayanui/engine/EngineSurfaceView.java +295 -0
  177. package/native/android/src/main/java/com/nayanui/engine/EngineSurfaceViewManager.java +45 -0
  178. package/native/android/src/main/java/com/nayanui/engine/NayanEnginePackage.java +24 -0
  179. package/native/core/build/EngineCore.xcframework/Info.plist +43 -0
  180. package/native/core/build/EngineCore.xcframework/ios-arm64/libengine_core.a +0 -0
  181. package/native/core/build/EngineCore.xcframework/ios-arm64-simulator/libengine_core.a +0 -0
  182. package/native/core/build/android/arm64-v8a/libengine_core.a +0 -0
  183. package/native/core/build/android/armeabi-v7a/libengine_core.a +0 -0
  184. package/native/core/build/android/x86/libengine_core.a +0 -0
  185. package/native/core/build/android/x86_64/libengine_core.a +0 -0
  186. package/native/core/include/drawing-licenses.txt +58 -0
  187. package/native/core/include/engine_core.h +331 -0
  188. package/native/cpp/NayanEngineModule.cpp +998 -0
  189. package/native/cpp/NayanEngineModule.h +174 -0
  190. package/native/cpp/generated/NayanEngineSpecJSI.cpp +2 -0
  191. package/native/cpp/generated/NayanEngineSpecJSI.h +1026 -0
  192. package/native/ios/NayanEngineProvider.h +5 -0
  193. package/native/ios/NayanEngineProvider.mm +21 -0
  194. package/native/ios/NayanEngineSurface.mm +252 -0
  195. package/native/scripts/check-package.mjs +39 -0
  196. package/package.json +162 -4
  197. package/react-native.config.js +18 -0
  198. package/src/native/spec/NativeNayanEngine.ts +265 -0
@@ -0,0 +1,5 @@
1
+ #import <Foundation/Foundation.h>
2
+ #import <ReactCommon/RCTTurboModule.h>
3
+
4
+ @interface NayanEngineProvider : NSObject <RCTModuleProvider>
5
+ @end
@@ -0,0 +1,21 @@
1
+ #import "NayanEngineProvider.h"
2
+
3
+ #import <ReactCommon/CallInvoker.h>
4
+ #import <ReactCommon/TurboModule.h>
5
+
6
+ #include "NayanEngineModule.h"
7
+ #include <engine_core.h>
8
+ #import <Foundation/Foundation.h>
9
+
10
+ @implementation NayanEngineProvider
11
+
12
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
13
+ (const facebook::react::ObjCTurboModule::InitParams &)params
14
+ {
15
+ NSURL *support = [[[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask] firstObject];
16
+ NSData *path = [support.path dataUsingEncoding:NSUTF8StringEncoding];
17
+ if (path != nil) engine_cache_directory(static_cast<const uint8_t *>(path.bytes), path.length);
18
+ return std::make_shared<facebook::react::NayanEngineModule>(params.jsInvoker);
19
+ }
20
+
21
+ @end
@@ -0,0 +1,252 @@
1
+ // The EngineSurface view: a CAMetalLayer the Rust renderer draws into with Metal. JS refers to it by
2
+ // `surfaceId`. A display link asks the game for each frame on the JS thread (`deliverFrame`); the
3
+ // frames it publishes are drawn on the engine's render thread.
4
+ #import <QuartzCore/CAMetalLayer.h>
5
+ #import <QuartzCore/CADisplayLink.h>
6
+ #import <React/RCTViewManager.h>
7
+ #import <UIKit/UIKit.h>
8
+
9
+ #include <engine_core.h>
10
+
11
+ namespace facebook::react {
12
+ void deliverFrame(int surface, double timeMs); // NayanEngineModule.cpp
13
+ }
14
+
15
+ @interface NayanEngineSurfaceView : UIView <UIGestureRecognizerDelegate>
16
+ @property (nonatomic, assign) NSInteger surfaceId;
17
+ @property (nonatomic, assign) NSInteger drawingId;
18
+ @property (nonatomic, assign) NSInteger drawingMode;
19
+ @property (nonatomic, assign) NSInteger drawingBackground;
20
+ @property (nonatomic, copy) RCTDirectEventBlock onDrawingChange;
21
+ @end
22
+
23
+ @implementation NayanEngineSurfaceView {
24
+ BOOL _attached;
25
+ CADisplayLink *_drawingClock;
26
+ CADisplayLink *_clock;
27
+ UITouch *_drawingTouch;
28
+ UIPinchGestureRecognizer *_drawingPinch;
29
+ UIPanGestureRecognizer *_drawingPan;
30
+ CFTimeInterval _lastDrawingEvent;
31
+ }
32
+
33
+ + (Class)layerClass
34
+ {
35
+ return [CAMetalLayer class];
36
+ }
37
+
38
+ - (instancetype)initWithFrame:(CGRect)frame
39
+ {
40
+ if (self = [super initWithFrame:frame]) {
41
+ _surfaceId = -1;
42
+ _drawingId = -1;
43
+ _drawingBackground = 0xffffff;
44
+ self.multipleTouchEnabled = YES;
45
+ _drawingPinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchDrawing:)];
46
+ _drawingPan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panDrawing:)];
47
+ _drawingPinch.delegate = self;
48
+ _drawingPan.delegate = self;
49
+ _drawingPan.minimumNumberOfTouches = 2;
50
+ _drawingPinch.enabled = NO;
51
+ _drawingPan.enabled = NO;
52
+ [self addGestureRecognizer:_drawingPinch];
53
+ [self addGestureRecognizer:_drawingPan];
54
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(stopDrawingClock) name:UIApplicationWillResignActiveNotification object:nil];
55
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(startDrawingClock) name:UIApplicationDidBecomeActiveNotification object:nil];
56
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(stopClock) name:UIApplicationWillResignActiveNotification object:nil];
57
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(startClock) name:UIApplicationDidBecomeActiveNotification object:nil];
58
+ self.layer.opaque = YES;
59
+ }
60
+ return self;
61
+ }
62
+
63
+ - (void)setSurfaceId:(NSInteger)surfaceId
64
+ {
65
+ if (surfaceId == _surfaceId) {
66
+ return;
67
+ }
68
+ [self detach];
69
+ _surfaceId = surfaceId;
70
+ [self attach];
71
+ }
72
+
73
+ - (void)attach
74
+ {
75
+ CGFloat scale = self.window.screen.scale ?: UIScreen.mainScreen.scale;
76
+ CGSize size = self.bounds.size;
77
+ if (_surfaceId < 0 || self.window == nil || size.width <= 0 || size.height <= 0) {
78
+ return;
79
+ }
80
+ self.layer.contentsScale = scale;
81
+ _attached = engine_render_attach(
82
+ (int32_t)_surfaceId, (__bridge void *)self.layer, (uint32_t)(size.width * scale), (uint32_t)(size.height * scale)) == 1;
83
+ if (_drawingId >= 0) engine_drawing_invalidate((int32_t)_drawingId);
84
+ [self startDrawingClock];
85
+ [self startClock];
86
+ }
87
+
88
+ - (void)detach
89
+ {
90
+ [self stopClock];
91
+ [self stopDrawingClock];
92
+ if (_attached) {
93
+ engine_render_detach((int32_t)_surfaceId);
94
+ _attached = NO;
95
+ }
96
+ }
97
+
98
+ - (void)layoutSubviews
99
+ {
100
+ [super layoutSubviews];
101
+ [self attach];
102
+ }
103
+
104
+ - (void)didMoveToWindow
105
+ {
106
+ [super didMoveToWindow];
107
+ if (self.window == nil) {
108
+ [self detach];
109
+ } else {
110
+ [self attach];
111
+ }
112
+ }
113
+
114
+ - (void)dealloc
115
+ {
116
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
117
+ [self detach];
118
+ }
119
+
120
+ - (void)setDrawingId:(NSInteger)value {
121
+ if (_drawingId == value) return;
122
+ [self stopDrawingClock];
123
+ _drawingId = value;
124
+ _drawingPinch.enabled = value >= 0;
125
+ _drawingPan.enabled = value >= 0;
126
+ if (value >= 0) engine_drawing_invalidate((int32_t)value);
127
+ [self startDrawingClock];
128
+ }
129
+ - (void)setDrawingMode:(NSInteger)value {
130
+ if (_drawingTouch != nil) engine_drawing_touch((int32_t)_drawingId, 3, 0, 0, 1);
131
+ _drawingTouch = nil;
132
+ _drawingMode = value;
133
+ _drawingPan.minimumNumberOfTouches = value == 0 ? 2 : 1;
134
+ }
135
+ - (void)setDrawingBackground:(NSInteger)value {
136
+ _drawingBackground = value;
137
+ if (_drawingId >= 0) engine_drawing_invalidate((int32_t)_drawingId);
138
+ }
139
+ /**
140
+ * The game's display clock: once per refresh while the surface is attached, on screen and the app is
141
+ * active, the engine is asked for its next frame on the JS thread. 60 a second, also on ProMotion
142
+ * screens, so a JS game loop isn't run twice as often.
143
+ */
144
+ - (void)startClock {
145
+ if (_clock != nil || _surfaceId < 0 || self.window == nil || !_attached || UIApplication.sharedApplication.applicationState != UIApplicationStateActive) return;
146
+ _clock = [CADisplayLink displayLinkWithTarget:self selector:@selector(tick:)];
147
+ if (@available(iOS 15.0, *)) _clock.preferredFrameRateRange = CAFrameRateRangeMake(30, 60, 60);
148
+ else _clock.preferredFramesPerSecond = 60;
149
+ [_clock addToRunLoop:NSRunLoop.mainRunLoop forMode:NSRunLoopCommonModes];
150
+ }
151
+ - (void)stopClock {
152
+ [_clock invalidate];
153
+ _clock = nil;
154
+ }
155
+ - (void)tick:(CADisplayLink *)link {
156
+ if (_surfaceId >= 0) facebook::react::deliverFrame((int)_surfaceId, link.timestamp * 1000.0);
157
+ }
158
+ - (void)startDrawingClock {
159
+ if (_drawingClock != nil || _drawingId < 0 || self.window == nil || !_attached || UIApplication.sharedApplication.applicationState != UIApplicationStateActive) return;
160
+ _drawingClock = [CADisplayLink displayLinkWithTarget:self selector:@selector(presentDrawing)];
161
+ if (@available(iOS 15.0, *)) _drawingClock.preferredFrameRateRange = CAFrameRateRangeMake(30, 120, 120);
162
+ [_drawingClock addToRunLoop:NSRunLoop.mainRunLoop forMode:NSRunLoopCommonModes];
163
+ }
164
+ - (void)stopDrawingClock {
165
+ [_drawingClock invalidate];
166
+ _drawingClock = nil;
167
+ if (_drawingTouch != nil) {
168
+ CGPoint point = [_drawingTouch locationInView:self];
169
+ engine_drawing_touch((int32_t)_drawingId, 2, point.x, point.y, 1);
170
+ _drawingTouch = nil;
171
+ }
172
+ }
173
+ - (void)presentDrawing {
174
+ engine_drawing_present((int32_t)_drawingId, (int32_t)_surfaceId, self.bounds.size.width, self.bounds.size.height, (uint32_t)_drawingBackground);
175
+ CFTimeInterval now = CACurrentMediaTime();
176
+ if (_onDrawingChange != nil && now - _lastDrawingEvent >= 0.1) {
177
+ _lastDrawingEvent = now;
178
+ char *event = engine_drawing_take_event((int32_t)_drawingId);
179
+ if (event != nullptr) {
180
+ NSString *state = [NSString stringWithUTF8String:event];
181
+ engine_drawing_result_free(event);
182
+ _onDrawingChange(@{@"state": state ?: @"{}", @"documentId": @(_drawingId)});
183
+ }
184
+ }
185
+ }
186
+ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gesture { return _drawingTouch == nil || _drawingTouch.type != UITouchTypePencil; }
187
+ - (BOOL)gestureRecognizer:(UIGestureRecognizer *)a shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)b { return YES; }
188
+ - (void)pinchDrawing:(UIPinchGestureRecognizer *)gesture {
189
+ if (gesture.state == UIGestureRecognizerStateChanged) {
190
+ engine_drawing_transform((int32_t)_drawingId, 0, 0, gesture.scale);
191
+ gesture.scale = 1;
192
+ }
193
+ }
194
+ - (void)panDrawing:(UIPanGestureRecognizer *)gesture {
195
+ if (gesture.state == UIGestureRecognizerStateChanged) {
196
+ CGPoint delta = [gesture translationInView:self];
197
+ engine_drawing_transform((int32_t)_drawingId, delta.x, delta.y, 1);
198
+ [gesture setTranslation:CGPointZero inView:self];
199
+ }
200
+ }
201
+ - (void)sampleDrawing:(UITouch *)touch phase:(int32_t)phase {
202
+ CGPoint point = [touch locationInView:self];
203
+ CGFloat pressure = touch.type == UITouchTypePencil && touch.maximumPossibleForce > 0 ? touch.force / touch.maximumPossibleForce : 1;
204
+ engine_drawing_touch((int32_t)_drawingId, phase, point.x, point.y, pressure);
205
+ }
206
+ - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
207
+ if (_drawingId < 0) { [super touchesBegan:touches withEvent:event]; return; }
208
+ if (_drawingMode != 0 || _drawingTouch != nil) return;
209
+ UITouch *touch = touches.anyObject;
210
+ for (UITouch *candidate in touches) if (candidate.type == UITouchTypePencil) { touch = candidate; break; }
211
+ // A Pencil is tracked independently; fingers arriving during its stroke are palm touches.
212
+ if (touch.type != UITouchTypePencil && event.allTouches.count != 1) return;
213
+ _drawingTouch = touch;
214
+ [self sampleDrawing:touch phase:0];
215
+ }
216
+ - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
217
+ if (_drawingId < 0) { [super touchesMoved:touches withEvent:event]; return; }
218
+ if (_drawingTouch == nil || ![touches containsObject:_drawingTouch]) return;
219
+ NSArray<UITouch *> *samples = [event coalescedTouchesForTouch:_drawingTouch];
220
+ if (samples.count == 0) [self sampleDrawing:_drawingTouch phase:1];
221
+ else for (UITouch *sample in samples) [self sampleDrawing:sample phase:1];
222
+ }
223
+ - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
224
+ if (_drawingId < 0) { [super touchesEnded:touches withEvent:event]; return; }
225
+ if (_drawingTouch != nil && [touches containsObject:_drawingTouch]) { [self sampleDrawing:_drawingTouch phase:2]; _drawingTouch = nil; }
226
+ }
227
+ - (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
228
+ if (_drawingId < 0) { [super touchesCancelled:touches withEvent:event]; return; }
229
+ if (_drawingTouch != nil && [touches containsObject:_drawingTouch]) { engine_drawing_touch((int32_t)_drawingId, 3, 0, 0, 1); _drawingTouch = nil; }
230
+ }
231
+
232
+ @end
233
+
234
+ @interface NayanEngineSurfaceManager : RCTViewManager
235
+ @end
236
+
237
+ @implementation NayanEngineSurfaceManager
238
+
239
+ RCT_EXPORT_MODULE(NayanEngineSurface)
240
+
241
+ - (UIView *)view
242
+ {
243
+ return [NayanEngineSurfaceView new];
244
+ }
245
+
246
+ RCT_EXPORT_VIEW_PROPERTY(surfaceId, NSInteger)
247
+ RCT_EXPORT_VIEW_PROPERTY(drawingId, NSInteger)
248
+ RCT_EXPORT_VIEW_PROPERTY(drawingMode, NSInteger)
249
+ RCT_EXPORT_VIEW_PROPERTY(drawingBackground, NSInteger)
250
+ RCT_EXPORT_VIEW_PROPERTY(onDrawingChange, RCTDirectEventBlock)
251
+
252
+ @end
@@ -0,0 +1,39 @@
1
+ import { readFile, stat } from 'node:fs/promises';
2
+ import { resolve } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+
5
+ const root = resolve(fileURLToPath(new URL('../..', import.meta.url)));
6
+ const metadata = JSON.parse(await readFile(resolve(root, 'package.json'), 'utf8'));
7
+ const required = new Set([
8
+ 'README.md',
9
+ 'NayanEngine.podspec',
10
+ 'react-native.config.js',
11
+ 'src/native/spec/NativeNayanEngine.ts',
12
+ 'native/cpp/generated/NayanEngineSpecJSI.h',
13
+ 'native/core/include/engine_core.h',
14
+ 'native/core/build/EngineCore.xcframework/Info.plist',
15
+ 'native/core/build/EngineCore.xcframework/ios-arm64/libengine_core.a',
16
+ 'native/core/build/EngineCore.xcframework/ios-arm64-simulator/libengine_core.a',
17
+ 'lib/web/engine_core_bg.wasm',
18
+ 'lib/web/audio-worklet.js'
19
+ ]);
20
+ for (const abi of ['arm64-v8a', 'armeabi-v7a', 'x86_64', 'x86']) required.add(`native/core/build/android/${abi}/libengine_core.a`);
21
+ function exportedFiles(value) {
22
+ if (typeof value === 'string') required.add(value);
23
+ else for (const item of Object.values(value)) exportedFiles(item);
24
+ }
25
+ exportedFiles(metadata.exports);
26
+ const missing = [];
27
+ for (const path of required) {
28
+ try {
29
+ const info = await stat(resolve(root, path));
30
+ if (!info.isFile() || info.size === 0) missing.push(path);
31
+ } catch {
32
+ missing.push(path);
33
+ }
34
+ }
35
+ if (missing.length)
36
+ throw new Error(
37
+ `Engine package is incomplete:\n${missing.map((path) => ` ${path}`).join('\n')}\nBuild the native core on macOS and run engine:build before packing or publishing.`
38
+ );
39
+ console.error(`Verified ${required.size} required engine package files for ${metadata.version}.`);
package/package.json CHANGED
@@ -1,6 +1,164 @@
1
1
  {
2
2
  "name": "@nayan-ui/engine",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.0-beta.4",
4
+ "description": "Fast 3D game engine for React and React Native: Rust and wgpu rendering, Rapier physics, animation, particle effects, audio, haptics and drawing.",
5
+ "keywords": [
6
+ "3d",
7
+ "android",
8
+ "drawing",
9
+ "game-engine",
10
+ "ios",
11
+ "metal",
12
+ "nayan-ui",
13
+ "particles",
14
+ "physics",
15
+ "rapier",
16
+ "react",
17
+ "react-game-engine",
18
+ "react-native",
19
+ "react-native-game-engine",
20
+ "rust",
21
+ "vulkan",
22
+ "web",
23
+ "webassembly",
24
+ "webgl",
25
+ "webgpu",
26
+ "wgpu"
27
+ ],
28
+ "homepage": "https://www.nayanui.com/game-engine",
29
+ "bugs": {
30
+ "url": "https://github.com/ursnj/nayan-ui/issues"
31
+ },
32
+ "license": "MIT",
33
+ "author": "Niranjan Devasani <niranjan.devasani@gmail.com> (https://github.com/ursnj)",
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/ursnj/nayan-ui.git"
37
+ },
38
+ "workspaces": [
39
+ "example"
40
+ ],
41
+ "files": [
42
+ "src/native/spec",
43
+ "lib",
44
+ "native/cpp",
45
+ "native/ios",
46
+ "native/android",
47
+ "*.podspec",
48
+ "react-native.config.js",
49
+ "native/core/include",
50
+ "native/core/build",
51
+ "!native/core/build/web",
52
+ "!**/.*",
53
+ "!**/*.map",
54
+ "!src/**/__tests__",
55
+ "native/scripts/check-package.mjs"
56
+ ],
57
+ "sideEffects": false,
58
+ "main": "./lib/module/index.js",
59
+ "browser": "./lib/web/index.js",
60
+ "types": "./lib/web/types/src/index.d.ts",
61
+ "exports": {
62
+ ".": {
63
+ "react-native": {
64
+ "source": "./src/index.ts",
65
+ "types": "./lib/typescript/src/index.d.ts",
66
+ "default": "./lib/module/index.js"
67
+ },
68
+ "react-native-strict-api": {
69
+ "source": "./src/index.ts",
70
+ "types": "./lib/typescript/src/index.d.ts",
71
+ "default": "./lib/module/index.js"
72
+ },
73
+ "browser": {
74
+ "types": "./lib/web/types/src/index.d.ts",
75
+ "default": "./lib/web/index.js"
76
+ },
77
+ "source": "./src/index.ts",
78
+ "types": "./lib/web/types/src/index.d.ts",
79
+ "default": "./lib/web/index.js"
80
+ },
81
+ "./package.json": "./package.json",
82
+ "./web": {
83
+ "types": "./lib/web/types/src/index.d.ts",
84
+ "default": "./lib/web/index.js"
85
+ }
86
+ },
87
+ "publishConfig": {
88
+ "registry": "https://registry.npmjs.org/"
89
+ },
90
+ "scripts": {
91
+ "example": "bun run --cwd example",
92
+ "clean": "del-cli lib",
93
+ "build": "bun run build:web && bob build",
94
+ "typecheck": "bun check && bun check -p tsconfig.test.json",
95
+ "core:test": "cargo test --manifest-path native/core/Cargo.toml",
96
+ "core:bench": "cargo run --release --example bench --manifest-path native/core/Cargo.toml",
97
+ "core:build": "native/core/scripts/build-ios.sh && native/core/scripts/build-android.sh",
98
+ "core:build:ios": "native/core/scripts/build-ios.sh",
99
+ "core:build:android": "native/core/scripts/build-android.sh",
100
+ "test": "bun test --isolate src",
101
+ "test:coverage": "bun test --isolate --coverage src native/tests && bun native/scripts/check-coverage.mjs",
102
+ "codegen": "node native/scripts/codegen-cxx.js",
103
+ "lint": "bun lint --no-script .",
104
+ "lint:fix": "bun lint --no-script --fix .",
105
+ "core:build:web": "native/core/scripts/build-web.sh",
106
+ "build:web": "bun run core:build:web && bun native/scripts/build-web.mjs",
107
+ "test:web": "bun test native/tests/web.test.ts",
108
+ "prepack": "node native/scripts/check-package.mjs"
109
+ },
110
+ "devDependencies": {
111
+ "@types/react": "~19.3.0",
112
+ "@types/react-dom": "^19.3.0",
113
+ "bun-types": "latest",
114
+ "del-cli": "^7.0.0",
115
+ "fake-indexeddb": "^6.2.6",
116
+ "happy-dom": "^21.0.4",
117
+ "react": "19.3.0",
118
+ "react-dom": "19.3.0",
119
+ "react-native": "0.88.0",
120
+ "react-native-builder-bob": "^0.43.1",
121
+ "typescript": "~6.0.3"
122
+ },
123
+ "peerDependencies": {
124
+ "expo-asset": "*",
125
+ "react": "*",
126
+ "react-native": "*"
127
+ },
128
+ "peerDependenciesMeta": {
129
+ "expo-asset": {
130
+ "optional": true
131
+ },
132
+ "react-native": {
133
+ "optional": true
134
+ }
135
+ },
136
+ "codegenConfig": {
137
+ "name": "NayanEngineSpec",
138
+ "type": "modules",
139
+ "jsSrcsDir": "src/native",
140
+ "ios": {
141
+ "modulesProvider": {
142
+ "NativeNayanEngine": "NayanEngineProvider"
143
+ }
144
+ }
145
+ },
146
+ "react-native-builder-bob": {
147
+ "source": "src",
148
+ "output": "lib",
149
+ "targets": [
150
+ [
151
+ "module",
152
+ {
153
+ "esm": true
154
+ }
155
+ ],
156
+ [
157
+ "typescript",
158
+ {
159
+ "project": "tsconfig.build.json"
160
+ }
161
+ ]
162
+ ]
163
+ }
164
+ }
@@ -0,0 +1,18 @@
1
+ // Autolinking. iOS uses NayanEngine.podspec; Android builds native/android/CMakeLists.txt into the app as a
2
+ // pure C++ TurboModule (the generated autolinking code instantiates NayanEngineModule).
3
+ module.exports = {
4
+ dependency: {
5
+ platforms: {
6
+ android: {
7
+ sourceDir: 'native/android',
8
+ // The EngineSurface view (native/android/src/main/java).
9
+ packageImportPath: 'import com.nayanui.engine.NayanEnginePackage;',
10
+ packageInstance: 'new NayanEnginePackage()',
11
+ cmakeListsPath: 'codegen/CMakeLists.txt',
12
+ cxxModuleCMakeListsModuleName: 'NayanEngine',
13
+ cxxModuleCMakeListsPath: 'CMakeLists.txt',
14
+ cxxModuleHeaderName: 'NayanEngineModule'
15
+ }
16
+ }
17
+ }
18
+ };