@vulfram/engine 0.5.8-alpha → 0.17.1-alpha
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 +106 -0
- package/package.json +55 -4
- package/src/core.ts +14 -0
- package/src/ecs.ts +1 -0
- package/src/engine/api.ts +234 -23
- package/src/engine/bridge/dispatch.ts +265 -40
- package/src/engine/bridge/guards.ts +4 -1
- package/src/engine/bridge/protocol.ts +72 -54
- package/src/engine/ecs/index.ts +187 -42
- package/src/engine/state.ts +133 -2
- package/src/engine/systems/command-intent.ts +153 -3
- package/src/engine/systems/constraint-solve.ts +167 -0
- package/src/engine/systems/core-command-builder.ts +9 -265
- package/src/engine/systems/diagnostics.ts +20 -19
- package/src/engine/systems/index.ts +3 -1
- package/src/engine/systems/input-mirror.ts +101 -3
- package/src/engine/systems/resource-upload.ts +96 -44
- package/src/engine/systems/response-decode.ts +69 -15
- package/src/engine/systems/scene-sync.ts +306 -0
- package/src/engine/systems/ui-bridge.ts +360 -0
- package/src/engine/systems/utils.ts +43 -1
- package/src/engine/systems/world-lifecycle.ts +72 -103
- package/src/engine/window/manager.ts +168 -0
- package/src/engine/world/entities.ts +931 -33
- package/src/engine/world/mount.ts +174 -0
- package/src/engine/world/types.ts +71 -0
- package/src/engine/world/world-ui.ts +266 -0
- package/src/engine/world/world3d.ts +280 -0
- package/src/index.ts +30 -1
- package/src/mount.ts +2 -0
- package/src/types/cmds/audio.ts +189 -0
- package/src/types/cmds/camera.ts +18 -13
- package/src/types/cmds/environment.ts +47 -4
- package/src/types/cmds/geometry.ts +18 -16
- package/src/types/cmds/index.ts +203 -132
- package/src/types/cmds/light.ts +17 -13
- package/src/types/cmds/material.ts +14 -13
- package/src/types/cmds/model.ts +40 -16
- package/src/types/cmds/realm.ts +25 -0
- package/src/types/cmds/render-graph.ts +49 -0
- package/src/types/cmds/resources.ts +4 -0
- package/src/types/cmds/shadow.ts +7 -7
- package/src/types/cmds/system.ts +29 -0
- package/src/types/cmds/target.ts +82 -0
- package/src/types/cmds/texture.ts +19 -5
- package/src/types/cmds/ui.ts +220 -0
- package/src/types/cmds/window.ts +41 -204
- package/src/types/events/index.ts +4 -1
- package/src/types/events/pointer.ts +42 -13
- package/src/types/events/system.ts +150 -7
- package/src/types/events/ui.ts +21 -0
- package/src/types/index.ts +1 -0
- package/src/types/json.ts +15 -0
- package/src/types/kinds.ts +3 -0
- package/src/window.ts +8 -0
- package/src/world-ui.ts +2 -0
- package/src/world3d.ts +10 -0
- package/tsconfig.json +0 -29
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CmdTargetLayerDisposeArgs,
|
|
3
|
+
CmdTargetLayerUpsertArgs,
|
|
4
|
+
CmdTargetUpsertArgs,
|
|
5
|
+
TargetLayerLayout,
|
|
6
|
+
} from '../../types/cmds/target';
|
|
7
|
+
import { engineState } from '../state';
|
|
8
|
+
import {
|
|
9
|
+
bindWorldToTarget,
|
|
10
|
+
isWorldReady,
|
|
11
|
+
unbindWorldFromTarget,
|
|
12
|
+
upsertTarget,
|
|
13
|
+
} from './entities';
|
|
14
|
+
import type { CommandId, TargetId, WindowId, WorldId } from './types';
|
|
15
|
+
import {
|
|
16
|
+
asCommandId,
|
|
17
|
+
asTargetId,
|
|
18
|
+
asWorldNumber,
|
|
19
|
+
} from './types';
|
|
20
|
+
|
|
21
|
+
type MountTargetConfig = Omit<CmdTargetUpsertArgs, 'targetId'>;
|
|
22
|
+
|
|
23
|
+
export type MountWorldArgs = {
|
|
24
|
+
target: MountTargetConfig;
|
|
25
|
+
targetId?: TargetId;
|
|
26
|
+
layout?: TargetLayerLayout;
|
|
27
|
+
cameraId?: number;
|
|
28
|
+
environmentId?: number;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export type WaitWorldReadyOptions = {
|
|
32
|
+
timeoutMs?: number;
|
|
33
|
+
pollIntervalMs?: number;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Returns whether the world has resolved its internal core realm and can be mounted.
|
|
38
|
+
*/
|
|
39
|
+
export function isWorldMountReady(worldId: WorldId): boolean {
|
|
40
|
+
return isWorldReady(asWorldNumber(worldId));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Waits until a world reports mount readiness.
|
|
45
|
+
*
|
|
46
|
+
* Note: this helper only polls local readiness; callers still must keep
|
|
47
|
+
* driving `tick(...)` while waiting.
|
|
48
|
+
*
|
|
49
|
+
* @returns `true` when ready, or `false` when timeout is reached.
|
|
50
|
+
*/
|
|
51
|
+
export async function waitWorldReady(
|
|
52
|
+
worldId: WorldId,
|
|
53
|
+
options: WaitWorldReadyOptions = {},
|
|
54
|
+
): Promise<boolean> {
|
|
55
|
+
const timeoutMs = options.timeoutMs ?? 5_000;
|
|
56
|
+
const pollIntervalMs = options.pollIntervalMs ?? 16;
|
|
57
|
+
const start = Date.now();
|
|
58
|
+
|
|
59
|
+
while (Date.now() - start < timeoutMs) {
|
|
60
|
+
if (isWorldMountReady(worldId)) {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
64
|
+
}
|
|
65
|
+
return isWorldMountReady(worldId);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function allocateTargetId(): TargetId {
|
|
69
|
+
return asTargetId(engineState.nextGlobalId++);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function defaultLayout(): TargetLayerLayout {
|
|
73
|
+
return {
|
|
74
|
+
left: { unit: 'percent', value: 0 },
|
|
75
|
+
top: { unit: 'percent', value: 0 },
|
|
76
|
+
width: { unit: 'percent', value: 100 },
|
|
77
|
+
height: { unit: 'percent', value: 100 },
|
|
78
|
+
zIndex: 0,
|
|
79
|
+
blendMode: 0,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Mounts a world into any target supported by core.
|
|
85
|
+
*
|
|
86
|
+
* This function hides realm details from the public API. Internally it:
|
|
87
|
+
* 1) creates/updates target (`cmd-target-upsert`)
|
|
88
|
+
* 2) enqueues layer bind (`cmd-target-layer-upsert`) in the same frame
|
|
89
|
+
* so command order remains deterministic and avoids duplicate binds.
|
|
90
|
+
*
|
|
91
|
+
* @param worldId World to be mounted.
|
|
92
|
+
* @param args Target configuration and optional layout/camera/environment overrides.
|
|
93
|
+
* @returns Generated target id and command ids for upsert + bind.
|
|
94
|
+
*/
|
|
95
|
+
export function mountWorld(
|
|
96
|
+
worldId: WorldId,
|
|
97
|
+
args: MountWorldArgs,
|
|
98
|
+
): {
|
|
99
|
+
targetId: TargetId;
|
|
100
|
+
targetCommandId: CommandId;
|
|
101
|
+
mountCommandId: CommandId;
|
|
102
|
+
} {
|
|
103
|
+
const targetId = args.targetId ?? allocateTargetId();
|
|
104
|
+
const world = asWorldNumber(worldId);
|
|
105
|
+
|
|
106
|
+
const targetCommandId = upsertTarget(world, {
|
|
107
|
+
targetId: targetId as number,
|
|
108
|
+
...args.target,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
const bindArgs = {
|
|
112
|
+
targetId: targetId as number,
|
|
113
|
+
layout: args.layout ?? defaultLayout(),
|
|
114
|
+
cameraId: args.cameraId,
|
|
115
|
+
environmentId: args.environmentId,
|
|
116
|
+
};
|
|
117
|
+
const mountCommandId = bindWorldToTarget(world, bindArgs);
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
targetId,
|
|
121
|
+
targetCommandId: asCommandId(targetCommandId),
|
|
122
|
+
mountCommandId: asCommandId(mountCommandId),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Convenience wrapper for mounting a world directly into a window target.
|
|
128
|
+
*/
|
|
129
|
+
export function mountWorldToWindow(
|
|
130
|
+
worldId: WorldId,
|
|
131
|
+
windowId: WindowId,
|
|
132
|
+
options: Omit<MountWorldArgs, 'target'> = {},
|
|
133
|
+
): {
|
|
134
|
+
targetId: TargetId;
|
|
135
|
+
targetCommandId: CommandId;
|
|
136
|
+
mountCommandId: CommandId;
|
|
137
|
+
} {
|
|
138
|
+
return mountWorld(worldId, {
|
|
139
|
+
...options,
|
|
140
|
+
target: {
|
|
141
|
+
kind: 'window',
|
|
142
|
+
windowId: windowId as number,
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Unmounts a world from a target.
|
|
149
|
+
*
|
|
150
|
+
* @param worldId Mounted world identifier.
|
|
151
|
+
* @param targetId Target to unbind.
|
|
152
|
+
* @returns Command id for unbind request.
|
|
153
|
+
*/
|
|
154
|
+
export function unmountWorld(worldId: WorldId, targetId: TargetId): CommandId {
|
|
155
|
+
const commandId = unbindWorldFromTarget(asWorldNumber(worldId), {
|
|
156
|
+
targetId: targetId as number,
|
|
157
|
+
} as Omit<CmdTargetLayerDisposeArgs, 'realmId'>);
|
|
158
|
+
return asCommandId(commandId);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Remounts an existing world->target binding with a new layer layout/camera/environment.
|
|
163
|
+
*
|
|
164
|
+
* @param worldId Mounted world identifier.
|
|
165
|
+
* @param args Layer update payload.
|
|
166
|
+
* @returns Command id for target-layer upsert.
|
|
167
|
+
*/
|
|
168
|
+
export function remountWorld(
|
|
169
|
+
worldId: WorldId,
|
|
170
|
+
args: Omit<CmdTargetLayerUpsertArgs, 'realmId'>,
|
|
171
|
+
): CommandId {
|
|
172
|
+
const commandId = bindWorldToTarget(asWorldNumber(worldId), args);
|
|
173
|
+
return asCommandId(commandId);
|
|
174
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic branded numeric IDs used by the public API to avoid mixing domains.
|
|
3
|
+
*
|
|
4
|
+
* Example:
|
|
5
|
+
* `type WindowId = number & { __WINDOW_ID__: null }`
|
|
6
|
+
*/
|
|
7
|
+
export type WorldId = number & { __WORLD_ID__: null };
|
|
8
|
+
export type World3DId = WorldId & { __WORLD_3D_ID__: null };
|
|
9
|
+
export type WorldUIId = WorldId & { __WORLD_UI_ID__: null };
|
|
10
|
+
export type WindowId = number & { __WINDOW_ID__: null };
|
|
11
|
+
export type TargetId = number & { __TARGET_ID__: null };
|
|
12
|
+
export type EntityId = number & { __ENTITY_ID__: null };
|
|
13
|
+
export type MaterialId = number & { __MATERIAL_ID__: null };
|
|
14
|
+
export type GeometryId = number & { __GEOMETRY_ID__: null };
|
|
15
|
+
export type TextureId = number & { __TEXTURE_ID__: null };
|
|
16
|
+
export type CommandId = number & { __COMMAND_ID__: null };
|
|
17
|
+
|
|
18
|
+
/** Casts a numeric value to a branded world id. */
|
|
19
|
+
export function asWorldId(value: number): WorldId {
|
|
20
|
+
return value as WorldId;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Casts a numeric value to a branded 3D world id. */
|
|
24
|
+
export function asWorld3DId(value: number): World3DId {
|
|
25
|
+
return value as World3DId;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Casts a numeric value to a branded UI world id. */
|
|
29
|
+
export function asWorldUIId(value: number): WorldUIId {
|
|
30
|
+
return value as WorldUIId;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Casts a numeric value to a branded window id. */
|
|
34
|
+
export function asWindowId(value: number): WindowId {
|
|
35
|
+
return value as WindowId;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Casts a numeric value to a branded target id. */
|
|
39
|
+
export function asTargetId(value: number): TargetId {
|
|
40
|
+
return value as TargetId;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Casts a numeric value to a branded entity id. */
|
|
44
|
+
export function asEntityId(value: number): EntityId {
|
|
45
|
+
return value as EntityId;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Casts a numeric value to a branded material id. */
|
|
49
|
+
export function asMaterialId(value: number): MaterialId {
|
|
50
|
+
return value as MaterialId;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Casts a numeric value to a branded geometry id. */
|
|
54
|
+
export function asGeometryId(value: number): GeometryId {
|
|
55
|
+
return value as GeometryId;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Casts a numeric value to a branded texture id. */
|
|
59
|
+
export function asTextureId(value: number): TextureId {
|
|
60
|
+
return value as TextureId;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Casts a numeric value to a branded command id. */
|
|
64
|
+
export function asCommandId(value: number): CommandId {
|
|
65
|
+
return value as CommandId;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Returns raw numeric world id from branded world id variants. */
|
|
69
|
+
export function asWorldNumber(worldId: WorldId | World3DId | WorldUIId | number): number {
|
|
70
|
+
return worldId as number;
|
|
71
|
+
}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { createWorldUI as createWorldUIRaw } from '../api';
|
|
2
|
+
import type { UiFocusCycleMode } from '../ecs';
|
|
3
|
+
import type {
|
|
4
|
+
CmdUiAccessKitActionRequestArgs,
|
|
5
|
+
CmdUiApplyOpsArgs,
|
|
6
|
+
CmdUiClipboardPasteArgs,
|
|
7
|
+
CmdUiDebugSetArgs,
|
|
8
|
+
CmdUiDocumentCreateArgs,
|
|
9
|
+
CmdUiDocumentDisposeArgs,
|
|
10
|
+
CmdUiDocumentGetLayoutRectsArgs,
|
|
11
|
+
CmdUiDocumentGetTreeArgs,
|
|
12
|
+
CmdUiDocumentSetRectArgs,
|
|
13
|
+
CmdUiDocumentSetThemeArgs,
|
|
14
|
+
CmdUiEventTraceSetArgs,
|
|
15
|
+
CmdUiFocusGetArgs,
|
|
16
|
+
CmdUiFocusSetArgs,
|
|
17
|
+
CmdUiImageCreateFromBufferArgs,
|
|
18
|
+
CmdUiImageDisposeArgs,
|
|
19
|
+
CmdUiScreenshotReplyArgs,
|
|
20
|
+
CmdUiThemeDefineArgs,
|
|
21
|
+
CmdUiThemeDisposeArgs,
|
|
22
|
+
} from '../../types/cmds/ui';
|
|
23
|
+
import type { UiEvent } from '../../types/events/ui';
|
|
24
|
+
import { EngineError } from '../errors';
|
|
25
|
+
import { getWorldOrThrow } from '../bridge/guards';
|
|
26
|
+
import {
|
|
27
|
+
getUiEvents as getUiEventsRaw,
|
|
28
|
+
uiAccessKitActionRequest as uiAccessKitActionRequestRaw,
|
|
29
|
+
uiApplyOps as uiApplyOpsRaw,
|
|
30
|
+
uiClipboardPaste as uiClipboardPasteRaw,
|
|
31
|
+
uiCreateDocument as uiCreateDocumentRaw,
|
|
32
|
+
uiCreateImageFromBuffer as uiCreateImageFromBufferRaw,
|
|
33
|
+
uiDefineTheme as uiDefineThemeRaw,
|
|
34
|
+
uiDisposeDocument as uiDisposeDocumentRaw,
|
|
35
|
+
uiDisposeImage as uiDisposeImageRaw,
|
|
36
|
+
uiDisposeTheme as uiDisposeThemeRaw,
|
|
37
|
+
uiFieldsetDispose as uiFieldsetDisposeRaw,
|
|
38
|
+
uiFieldsetUpsert as uiFieldsetUpsertRaw,
|
|
39
|
+
uiFocusableDispose as uiFocusableDisposeRaw,
|
|
40
|
+
uiFocusableUpsert as uiFocusableUpsertRaw,
|
|
41
|
+
uiFocusNext as uiFocusNextRaw,
|
|
42
|
+
uiFormDispose as uiFormDisposeRaw,
|
|
43
|
+
uiFormUpsert as uiFormUpsertRaw,
|
|
44
|
+
uiGetDocumentTree as uiGetDocumentTreeRaw,
|
|
45
|
+
uiGetFocus as uiGetFocusRaw,
|
|
46
|
+
uiGetLayoutRects as uiGetLayoutRectsRaw,
|
|
47
|
+
uiScreenshotReply as uiScreenshotReplyRaw,
|
|
48
|
+
uiSetDebug as uiSetDebugRaw,
|
|
49
|
+
uiSetDocumentRect as uiSetDocumentRectRaw,
|
|
50
|
+
uiSetDocumentTheme as uiSetDocumentThemeRaw,
|
|
51
|
+
uiSetEventTrace as uiSetEventTraceRaw,
|
|
52
|
+
uiSetFocus as uiSetFocusRaw,
|
|
53
|
+
} from './entities';
|
|
54
|
+
import type { WorldUIId } from './types';
|
|
55
|
+
import { asWorldNumber, asWorldUIId } from './types';
|
|
56
|
+
|
|
57
|
+
type CreateUIWorldOptions = {
|
|
58
|
+
outputSurfaceId?: number;
|
|
59
|
+
importance?: number;
|
|
60
|
+
cachePolicy?: number;
|
|
61
|
+
flags?: number;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
type UIFormUpsertArgs = {
|
|
65
|
+
formId: string;
|
|
66
|
+
documentId: number;
|
|
67
|
+
disabled?: boolean;
|
|
68
|
+
cycleMode?: UiFocusCycleMode;
|
|
69
|
+
activeFieldsetId?: string;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
type UIFocusNextArgs = {
|
|
73
|
+
backwards?: boolean;
|
|
74
|
+
formId?: string;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
function resolveWorldUIContext(worldId: number): { windowId: number; realmId: number } {
|
|
78
|
+
const world = getWorldOrThrow(worldId);
|
|
79
|
+
const realmId = world.coreRealmId;
|
|
80
|
+
if (realmId === undefined) {
|
|
81
|
+
throw new EngineError(
|
|
82
|
+
'WorldNotReady',
|
|
83
|
+
`World ${worldId} has no core realm available yet.`,
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (world.primaryWindowId !== undefined) {
|
|
88
|
+
return { windowId: world.primaryWindowId, realmId };
|
|
89
|
+
}
|
|
90
|
+
for (const windowId of world.targetWindowBindings.values()) {
|
|
91
|
+
return { windowId, realmId };
|
|
92
|
+
}
|
|
93
|
+
if (world.realmCreateArgs.hostWindowId !== undefined) {
|
|
94
|
+
return { windowId: world.realmCreateArgs.hostWindowId, realmId };
|
|
95
|
+
}
|
|
96
|
+
throw new EngineError(
|
|
97
|
+
'WindowNotFound',
|
|
98
|
+
`World ${worldId} has no window binding available for UI operation.`,
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Creates a UI world.
|
|
104
|
+
*
|
|
105
|
+
* The world is realm-backed internally, but realm details are hidden from this API.
|
|
106
|
+
* Use `Mount.mountWorld(...)` to present this world in one or more targets.
|
|
107
|
+
*/
|
|
108
|
+
export function createUIWorld(options?: CreateUIWorldOptions): WorldUIId {
|
|
109
|
+
return asWorldUIId(createWorldUIRaw(options));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** Defines a theme in a UI world. */
|
|
113
|
+
export function defineUITheme(worldId: WorldUIId, args: CmdUiThemeDefineArgs): void {
|
|
114
|
+
uiDefineThemeRaw(asWorldNumber(worldId), args);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** Disposes a theme in a UI world. */
|
|
118
|
+
export function disposeUITheme(worldId: WorldUIId, args: CmdUiThemeDisposeArgs): void {
|
|
119
|
+
uiDisposeThemeRaw(asWorldNumber(worldId), args);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** Creates a document in a UI world. */
|
|
123
|
+
export function createUIDocument(worldId: WorldUIId, args: CmdUiDocumentCreateArgs): void {
|
|
124
|
+
uiCreateDocumentRaw(asWorldNumber(worldId), args);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** Disposes a document in a UI world. */
|
|
128
|
+
export function disposeUIDocument(worldId: WorldUIId, args: CmdUiDocumentDisposeArgs): void {
|
|
129
|
+
uiDisposeDocumentRaw(asWorldNumber(worldId), args);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** Sets document rect in a UI world. */
|
|
133
|
+
export function setUIDocumentRect(worldId: WorldUIId, args: CmdUiDocumentSetRectArgs): void {
|
|
134
|
+
uiSetDocumentRectRaw(asWorldNumber(worldId), args);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** Sets document theme in a UI world. */
|
|
138
|
+
export function setUIDocumentTheme(worldId: WorldUIId, args: CmdUiDocumentSetThemeArgs): void {
|
|
139
|
+
uiSetDocumentThemeRaw(asWorldNumber(worldId), args);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** Applies UI ops batch in a UI world. */
|
|
143
|
+
export function applyUIOps(worldId: WorldUIId, args: CmdUiApplyOpsArgs): void {
|
|
144
|
+
uiApplyOpsRaw(asWorldNumber(worldId), args);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** Requests UI document tree. */
|
|
148
|
+
export function getUIDocumentTree(worldId: WorldUIId, args: CmdUiDocumentGetTreeArgs): void {
|
|
149
|
+
uiGetDocumentTreeRaw(asWorldNumber(worldId), args);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** Requests UI layout rects. */
|
|
153
|
+
export function getUILayoutRects(worldId: WorldUIId, args: CmdUiDocumentGetLayoutRectsArgs): void {
|
|
154
|
+
uiGetLayoutRectsRaw(asWorldNumber(worldId), args);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** Configures UI debug flags. */
|
|
158
|
+
export function setUIDebug(worldId: WorldUIId, args: CmdUiDebugSetArgs): void {
|
|
159
|
+
uiSetDebugRaw(asWorldNumber(worldId), args);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** Sets focus in a UI world. */
|
|
163
|
+
export function setUIFocus(worldId: WorldUIId, args: CmdUiFocusSetArgs): void {
|
|
164
|
+
uiSetFocusRaw(asWorldNumber(worldId), args);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** Requests focus state in a UI world. */
|
|
168
|
+
export function getUIFocus(worldId: WorldUIId, args: CmdUiFocusGetArgs = {}): void {
|
|
169
|
+
uiGetFocusRaw(asWorldNumber(worldId), args);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/** Configures UI event trace in a UI world. */
|
|
173
|
+
export function setUIEventTrace(worldId: WorldUIId, args: CmdUiEventTraceSetArgs): void {
|
|
174
|
+
uiSetEventTraceRaw(asWorldNumber(worldId), args);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/** Creates UI image from a previously uploaded buffer. */
|
|
178
|
+
export function createUIImageFromBuffer(worldId: WorldUIId, args: CmdUiImageCreateFromBufferArgs): void {
|
|
179
|
+
uiCreateImageFromBufferRaw(asWorldNumber(worldId), args);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/** Disposes UI image resource. */
|
|
183
|
+
export function disposeUIImage(worldId: WorldUIId, args: CmdUiImageDisposeArgs): void {
|
|
184
|
+
uiDisposeImageRaw(asWorldNumber(worldId), args);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** Sends clipboard paste payload to UI world. */
|
|
188
|
+
export function pasteUIClipboard(worldId: WorldUIId, args: CmdUiClipboardPasteArgs): void {
|
|
189
|
+
uiClipboardPasteRaw(asWorldNumber(worldId), args);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/** Replies to UI screenshot request. */
|
|
193
|
+
export function replyUIScreenshot(worldId: WorldUIId, args: CmdUiScreenshotReplyArgs): void {
|
|
194
|
+
uiScreenshotReplyRaw(asWorldNumber(worldId), args);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/** Sends AccessKit action request. */
|
|
198
|
+
export function requestUIAccessKitAction(worldId: WorldUIId, args: CmdUiAccessKitActionRequestArgs): void {
|
|
199
|
+
uiAccessKitActionRequestRaw(asWorldNumber(worldId), args);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Upserts UI form metadata.
|
|
204
|
+
*
|
|
205
|
+
* `windowId` and `realmId` are resolved internally from world bindings.
|
|
206
|
+
*/
|
|
207
|
+
export function upsertUIForm(worldId: WorldUIId, form: UIFormUpsertArgs): void {
|
|
208
|
+
const rawWorldId = asWorldNumber(worldId);
|
|
209
|
+
const context = resolveWorldUIContext(rawWorldId);
|
|
210
|
+
uiFormUpsertRaw(rawWorldId, {
|
|
211
|
+
...form,
|
|
212
|
+
windowId: context.windowId,
|
|
213
|
+
realmId: context.realmId,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** Disposes UI form metadata. */
|
|
218
|
+
export function disposeUIForm(worldId: WorldUIId, formId: string): void {
|
|
219
|
+
uiFormDisposeRaw(asWorldNumber(worldId), formId);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/** Upserts UI fieldset metadata. */
|
|
223
|
+
export function upsertUIFieldset(worldId: WorldUIId, args: Parameters<typeof uiFieldsetUpsertRaw>[1]): void {
|
|
224
|
+
uiFieldsetUpsertRaw(asWorldNumber(worldId), args);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** Disposes UI fieldset metadata. */
|
|
228
|
+
export function disposeUIFieldset(worldId: WorldUIId, args: { formId: string; fieldsetId: string }): void {
|
|
229
|
+
uiFieldsetDisposeRaw(asWorldNumber(worldId), args.formId, args.fieldsetId);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/** Upserts focusable metadata. */
|
|
233
|
+
export function upsertUIFocusable(worldId: WorldUIId, args: Parameters<typeof uiFocusableUpsertRaw>[1]): void {
|
|
234
|
+
uiFocusableUpsertRaw(asWorldNumber(worldId), args);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/** Disposes focusable metadata. */
|
|
238
|
+
export function disposeUIFocusable(worldId: WorldUIId, nodeId: number): void {
|
|
239
|
+
uiFocusableDisposeRaw(asWorldNumber(worldId), nodeId);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Requests moving focus to next/previous focusable.
|
|
244
|
+
*
|
|
245
|
+
* `windowId` is resolved internally from world bindings.
|
|
246
|
+
*/
|
|
247
|
+
export function focusUINext(
|
|
248
|
+
worldId: WorldUIId,
|
|
249
|
+
args: UIFocusNextArgs = {},
|
|
250
|
+
): void {
|
|
251
|
+
const rawWorldId = asWorldNumber(worldId);
|
|
252
|
+
const context = resolveWorldUIContext(rawWorldId);
|
|
253
|
+
uiFocusNextRaw(rawWorldId, {
|
|
254
|
+
...args,
|
|
255
|
+
windowId: context.windowId,
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Returns UI events mirrored from the latest processed frame.
|
|
261
|
+
*
|
|
262
|
+
* This accessor is read-only from the host perspective; events are replaced each tick.
|
|
263
|
+
*/
|
|
264
|
+
export function getUIEvents(worldId: WorldUIId): UiEvent[] {
|
|
265
|
+
return getUiEventsRaw(asWorldNumber(worldId));
|
|
266
|
+
}
|