onejs-react 0.1.11 → 0.1.14
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 +21 -0
- package/package.json +1 -1
- package/src/__tests__/mocks.ts +1 -0
- package/src/components.tsx +23 -15
- package/src/host-config.ts +23 -7
- package/src/types.ts +13 -6
package/README.md
CHANGED
|
@@ -258,6 +258,27 @@ type MeshGenerationContext = CS.UnityEngine.UIElements.MeshGenerationContext
|
|
|
258
258
|
type GenerateVisualContentCallback = (context: MeshGenerationContext) => void
|
|
259
259
|
```
|
|
260
260
|
|
|
261
|
+
## C# Interop Utilities
|
|
262
|
+
|
|
263
|
+
### `toArray<T>(collection): T[]`
|
|
264
|
+
|
|
265
|
+
Converts C# collections (`List<T>`, arrays) to JavaScript arrays. C# collections exposed through the OneJS proxy have `.Count`/`.Length` and indexers but lack `.map()`, `.filter()`, and other array methods.
|
|
266
|
+
|
|
267
|
+
```tsx
|
|
268
|
+
import { toArray } from "onejs-react"
|
|
269
|
+
|
|
270
|
+
// Convert a C# List for use in JSX
|
|
271
|
+
{toArray<Item>(inventory.Items).map(item => <ItemView key={item.Id} item={item} />)}
|
|
272
|
+
|
|
273
|
+
// Convert a C# array
|
|
274
|
+
const resolutions = toArray<Resolution>(Screen.resolutions)
|
|
275
|
+
|
|
276
|
+
// Safe with null — returns []
|
|
277
|
+
const npcs = toArray(currentPlace?.NPCs)
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
Supports objects with `.Count` (List, IList) or `.Length` (C# arrays). Returns `[]` for null/undefined.
|
|
281
|
+
|
|
261
282
|
## Dependencies
|
|
262
283
|
|
|
263
284
|
- `react-reconciler@0.31.x` (React 19 compatible)
|
package/package.json
CHANGED
package/src/__tests__/mocks.ts
CHANGED
package/src/components.tsx
CHANGED
|
@@ -27,8 +27,8 @@ declare function useExtensions(typeRef: any): void
|
|
|
27
27
|
// Register ImageConversion extension methods so tex.LoadImage(bytes) works
|
|
28
28
|
useExtensions(CS.UnityEngine.ImageConversion)
|
|
29
29
|
|
|
30
|
-
// Module-level
|
|
31
|
-
const
|
|
30
|
+
// Module-level image cache shared across all Image instances
|
|
31
|
+
const _imageCache = new Map<string, any>()
|
|
32
32
|
|
|
33
33
|
function _resolveAssetPath(src: string): string {
|
|
34
34
|
const Path = CS.System.IO.Path
|
|
@@ -41,8 +41,8 @@ function _resolveAssetPath(src: string): string {
|
|
|
41
41
|
return Path.Combine(CS.UnityEngine.Application.streamingAssetsPath, "onejs", "assets", src)
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
function
|
|
45
|
-
const cached =
|
|
44
|
+
function _loadImageAsset(src: string): any | null {
|
|
45
|
+
const cached = _imageCache.get(src)
|
|
46
46
|
if (cached) return cached
|
|
47
47
|
|
|
48
48
|
const fullPath = _resolveAssetPath(src)
|
|
@@ -51,20 +51,28 @@ function _loadTexture(src: string): any | null {
|
|
|
51
51
|
return null
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
let result: any
|
|
55
|
+
if (src.toLowerCase().endsWith(".svg")) {
|
|
56
|
+
const svgText = CS.System.IO.File.ReadAllText(fullPath)
|
|
57
|
+
result = CS.OneJS.SVGUtils.LoadFromString(svgText)
|
|
58
|
+
} else {
|
|
59
|
+
const bytes = CS.System.IO.File.ReadAllBytes(fullPath)
|
|
60
|
+
const tex = new CS.UnityEngine.Texture2D(2, 2)
|
|
61
|
+
tex.LoadImage(bytes)
|
|
62
|
+
tex.filterMode = CS.UnityEngine.FilterMode.Bilinear
|
|
63
|
+
result = tex
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
_imageCache.set(src, result)
|
|
67
|
+
return result
|
|
60
68
|
}
|
|
61
69
|
|
|
62
70
|
/**
|
|
63
|
-
* Clear the Image component's
|
|
71
|
+
* Clear the Image component's image cache.
|
|
64
72
|
* Call this if you need to force-reload images (e.g., after replacing files on disk).
|
|
65
73
|
*/
|
|
66
74
|
export function clearImageCache(): void {
|
|
67
|
-
|
|
75
|
+
_imageCache.clear()
|
|
68
76
|
}
|
|
69
77
|
|
|
70
78
|
// Props with ref support for intrinsic elements
|
|
@@ -152,11 +160,11 @@ export const ScrollView = forwardRef<ScrollViewElement, ScrollViewProps>((props,
|
|
|
152
160
|
ScrollView.displayName = 'ScrollView';
|
|
153
161
|
|
|
154
162
|
export const Image = forwardRef<ImageElement, ImageProps>(({ src, image, ...rest }, ref) => {
|
|
155
|
-
const
|
|
156
|
-
if (src) return
|
|
163
|
+
const resolved = useMemo(() => {
|
|
164
|
+
if (src) return _loadImageAsset(src)
|
|
157
165
|
return image
|
|
158
166
|
}, [src, image])
|
|
159
|
-
return <ojs-image ref={ref} image={
|
|
167
|
+
return <ojs-image ref={ref} image={resolved} {...rest} />;
|
|
160
168
|
});
|
|
161
169
|
Image.displayName = 'Image';
|
|
162
170
|
|
package/src/host-config.ts
CHANGED
|
@@ -65,6 +65,7 @@ declare const CS: {
|
|
|
65
65
|
GPU: {
|
|
66
66
|
GPUBridge: {
|
|
67
67
|
SetElementBackgroundImage: (element: CSObject, rtHandle: number) => void;
|
|
68
|
+
SetElementBackgroundFromObject: (element: CSObject, obj: CSObject) => void;
|
|
68
69
|
ClearElementBackgroundImage: (element: CSObject) => void;
|
|
69
70
|
};
|
|
70
71
|
};
|
|
@@ -350,12 +351,18 @@ function applyStyle(element: CSObject, style: ViewStyle | undefined): Set<string
|
|
|
350
351
|
s[prop] = parsed;
|
|
351
352
|
appliedKeys.add(prop);
|
|
352
353
|
}
|
|
353
|
-
} else if (key === "backgroundImage"
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
354
|
+
} else if (key === "backgroundImage") {
|
|
355
|
+
if (value == null) {
|
|
356
|
+
CS.OneJS.GPU.GPUBridge.ClearElementBackgroundImage(element);
|
|
357
|
+
} else if (isRenderTextureHandle(value)) {
|
|
358
|
+
// GPU compute RenderTexture handles (via rt.getUnityObject())
|
|
359
|
+
const handle = getRenderTextureHandle(value);
|
|
360
|
+
if (handle >= 0) {
|
|
361
|
+
CS.OneJS.GPU.GPUBridge.SetElementBackgroundImage(element, handle);
|
|
362
|
+
}
|
|
363
|
+
} else if (typeof value === "object" && "__csHandle" in value) {
|
|
364
|
+
// C# objects: Texture2D, Sprite, VectorImage, RenderTexture
|
|
365
|
+
CS.OneJS.GPU.GPUBridge.SetElementBackgroundFromObject(element, value);
|
|
359
366
|
}
|
|
360
367
|
appliedKeys.add(key);
|
|
361
368
|
} else {
|
|
@@ -642,7 +649,16 @@ function applyToggleProps(element: CSObject, props: Record<string, unknown>) {
|
|
|
642
649
|
// Apply Image-specific properties
|
|
643
650
|
function applyImageProps(element: CSObject, props: Record<string, unknown>) {
|
|
644
651
|
const el = element as any;
|
|
645
|
-
if (props.image !== undefined)
|
|
652
|
+
if (props.image !== undefined) {
|
|
653
|
+
const img = props.image;
|
|
654
|
+
if (img != null && (img as any).GetType?.().Name === "VectorImage") {
|
|
655
|
+
el.image = null;
|
|
656
|
+
el.vectorImage = img;
|
|
657
|
+
} else {
|
|
658
|
+
el.vectorImage = null;
|
|
659
|
+
el.image = img;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
646
662
|
if (props.sprite !== undefined) el.sprite = props.sprite;
|
|
647
663
|
if (props.vectorImage !== undefined) el.vectorImage = props.vectorImage;
|
|
648
664
|
if (props.scaleMode !== undefined) {
|
package/src/types.ts
CHANGED
|
@@ -82,10 +82,19 @@ export interface ViewStyle {
|
|
|
82
82
|
/** Background color. Examples: "#3498db", "rgba(0,0,0,0.5)", "red" */
|
|
83
83
|
backgroundColor?: StyleColor;
|
|
84
84
|
/**
|
|
85
|
-
* Background image - accepts
|
|
85
|
+
* Background image - accepts Texture2D, Sprite, VectorImage, RenderTexture,
|
|
86
|
+
* or a GPU compute RenderTexture handle.
|
|
86
87
|
*
|
|
87
|
-
* For GPU compute RenderTextures, you can pass the RenderTexture object directly:
|
|
88
88
|
* @example
|
|
89
|
+
* // Texture2D
|
|
90
|
+
* const tex = loadImage("images/card-bg.png")
|
|
91
|
+
* <View style={{ backgroundImage: tex }} />
|
|
92
|
+
*
|
|
93
|
+
* // Sprite from C#
|
|
94
|
+
* const sprite = getSpriteFromCSharp()
|
|
95
|
+
* <View style={{ backgroundImage: sprite }} />
|
|
96
|
+
*
|
|
97
|
+
* // GPU compute RenderTexture
|
|
89
98
|
* const rt = compute.renderTexture({ width: 100, height: 100 })
|
|
90
99
|
* <View style={{ backgroundImage: rt }} />
|
|
91
100
|
*/
|
|
@@ -528,14 +537,12 @@ export interface ScrollViewProps extends BaseProps {
|
|
|
528
537
|
}
|
|
529
538
|
|
|
530
539
|
export interface ImageProps extends BaseProps {
|
|
531
|
-
/** Path to image asset relative to the assets/ folder
|
|
540
|
+
/** Path to image asset relative to the assets/ folder. Supports PNG, JPG, and SVG files. */
|
|
532
541
|
src?: string;
|
|
533
|
-
/** Pre-loaded Texture2D
|
|
542
|
+
/** Pre-loaded Texture2D or VectorImage object. Type is auto-detected at runtime. */
|
|
534
543
|
image?: object;
|
|
535
544
|
/** Sprite to display (alternative to image) */
|
|
536
545
|
sprite?: object;
|
|
537
|
-
/** Vector image to display */
|
|
538
|
-
vectorImage?: object;
|
|
539
546
|
/** How the image scales to fit the element */
|
|
540
547
|
scaleMode?: 'StretchToFill' | 'ScaleAndCrop' | 'ScaleToFit';
|
|
541
548
|
/** Tint color applied to the image */
|