@hology/core 0.0.211 → 0.0.213
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/dist/effects/sequence/index.d.ts +1 -0
- package/dist/effects/sequence/index.js +1 -1
- package/dist/effects/sequence/sequence-action.d.ts +5 -0
- package/dist/effects/sequence/sequence-actor.d.ts +7 -0
- package/dist/effects/sequence/sequence-actor.js +1 -1
- package/dist/effects/sequence/sequence-animation-retiming.js +1 -1
- package/dist/effects/sequence/sequence-data.d.ts +9 -0
- package/dist/effects/sequence/sequence-data.js +1 -1
- package/dist/effects/sequence/sequence-player.d.ts +12 -1
- package/dist/effects/sequence/sequence-player.js +1 -1
- package/dist/effects/sequence/sequence-transform.d.ts +10 -0
- package/dist/effects/sequence/sequence-transform.js +4 -0
- package/dist/effects/sequence/sequence-value-lane.d.ts +2 -0
- package/dist/effects/sequence/sequence-value-lane.js +1 -1
- package/dist/effects/vfx/initializsers.d.ts +8 -1
- package/dist/effects/vfx/initializsers.js +1 -1
- package/dist/effects/vfx/vfx-actor.d.ts +5 -0
- package/dist/effects/vfx/vfx-actor.js +1 -1
- package/dist/effects/vfx/vfx-asset.d.ts +2 -1
- package/dist/effects/vfx/vfx-asset.js +1 -1
- package/dist/effects/vfx/vfx-collision-behaviour.js +1 -1
- package/dist/effects/vfx/vfx-defs.d.ts +10 -1
- package/dist/effects/vfx/vfx-defs.js +1 -1
- package/dist/effects/vfx/vfx-materializer.js +1 -1
- package/dist/effects/vfx/vfx-renderers.d.ts +2 -0
- package/dist/effects/vfx/vfx-renderers.js +1 -1
- package/dist/gameplay/actors/actor.d.ts +21 -1
- package/dist/gameplay/actors/actor.js +1 -1
- package/dist/gameplay/actors/builtin/components/character/character-animation.d.ts +3 -0
- package/dist/gameplay/actors/builtin/components/character/character-animation.js +1 -1
- package/dist/gameplay/actors/builtin/components/character/character-movement-like.d.ts +25 -0
- package/dist/gameplay/actors/builtin/components/character/character-movement-like.js +4 -0
- package/dist/gameplay/actors/builtin/components/character/character-movement-policy.d.ts +26 -0
- package/dist/gameplay/actors/builtin/components/character/character-movement-policy.js +4 -0
- package/dist/gameplay/actors/builtin/components/character/character-movement.d.ts +158 -55
- package/dist/gameplay/actors/builtin/components/character/character-movement.js +1 -1
- package/dist/gameplay/actors/builtin/components/character/net-character-movement-protocol.d.ts +128 -0
- package/dist/gameplay/actors/builtin/components/character/net-character-movement-protocol.js +4 -0
- package/dist/gameplay/actors/builtin/components/character/old-character-movement.d.ts +100 -0
- package/dist/gameplay/actors/builtin/components/character/old-character-movement.js +4 -0
- package/dist/gameplay/actors/builtin/components/index.d.ts +2 -0
- package/dist/gameplay/actors/builtin/components/index.js +1 -1
- package/dist/gameplay/actors/builtin/components/mesh-component.d.ts +1 -0
- package/dist/gameplay/actors/builtin/components/mesh-component.js +1 -1
- package/dist/gameplay/actors/builtin/components/tween-component.js +1 -1
- package/dist/gameplay/actors/builtin/navmesh-actor.d.ts +2 -0
- package/dist/gameplay/actors/builtin/navmesh-actor.js +1 -1
- package/dist/gameplay/actors/builtin/trigger-volume.d.ts +3 -3
- package/dist/gameplay/actors/builtin/trigger-volume.js +1 -1
- package/dist/gameplay/actors/camera/camera-component.d.ts +1 -3
- package/dist/gameplay/actors/camera/camera-component.js +1 -1
- package/dist/gameplay/actors/camera/third-person-camera-component.d.ts +3 -0
- package/dist/gameplay/actors/camera/third-person-camera-component.js +1 -1
- package/dist/gameplay/actors/component.d.ts +3 -0
- package/dist/gameplay/actors/component.js +1 -1
- package/dist/gameplay/actors/controller/actor-controller.d.ts +16 -0
- package/dist/gameplay/actors/controller/actor-controller.js +4 -0
- package/dist/gameplay/actors/factory.d.ts +3 -0
- package/dist/gameplay/actors/factory.js +1 -1
- package/dist/gameplay/actors/index.d.ts +4 -0
- package/dist/gameplay/actors/index.js +1 -1
- package/dist/gameplay/actors/internal/component-init.js +1 -1
- package/dist/gameplay/actors/type-registry.d.ts +10 -0
- package/dist/gameplay/actors/type-registry.js +4 -0
- package/dist/gameplay/ai/behavior-tree/move.d.ts +2 -2
- package/dist/gameplay/animation/retarget.d.ts +50 -0
- package/dist/gameplay/animation/retarget.js +4 -0
- package/dist/gameplay/animation/root-motion.js +1 -1
- package/dist/gameplay/event-graph/actor-transform-properties.d.ts +6 -0
- package/dist/gameplay/event-graph/actor-transform-properties.js +4 -0
- package/dist/gameplay/event-graph/asset-actor-types.d.ts +3 -0
- package/dist/gameplay/event-graph/asset-actor-types.js +4 -0
- package/dist/gameplay/event-graph/asset-references.d.ts +12 -0
- package/dist/gameplay/event-graph/asset-references.js +4 -0
- package/dist/gameplay/event-graph/compiler.d.ts +107 -0
- package/dist/gameplay/event-graph/compiler.js +4 -0
- package/dist/gameplay/event-graph/decorators.d.ts +74 -0
- package/dist/gameplay/event-graph/decorators.js +4 -0
- package/dist/gameplay/event-graph/document-compiler.d.ts +107 -0
- package/dist/gameplay/event-graph/document-compiler.js +4 -0
- package/dist/gameplay/event-graph/event-graph-demo.d.ts +2 -0
- package/dist/gameplay/event-graph/event-graph-demo.js +4 -0
- package/dist/gameplay/event-graph/graph.d.ts +106 -0
- package/dist/gameplay/event-graph/graph.js +4 -0
- package/dist/gameplay/event-graph/index.d.ts +13 -0
- package/dist/gameplay/event-graph/index.js +4 -0
- package/dist/gameplay/event-graph/model.d.ts +71 -0
- package/dist/gameplay/event-graph/model.js +4 -0
- package/dist/gameplay/event-graph/nodes/execution-nodes.d.ts +115 -0
- package/dist/gameplay/event-graph/nodes/execution-nodes.js +4 -0
- package/dist/gameplay/event-graph/nodes/gameplay-nodes.d.ts +208 -0
- package/dist/gameplay/event-graph/nodes/gameplay-nodes.js +4 -0
- package/dist/gameplay/event-graph/nodes/index.d.ts +4 -0
- package/dist/gameplay/event-graph/nodes/index.js +4 -0
- package/dist/gameplay/event-graph/nodes/value-nodes.d.ts +53 -0
- package/dist/gameplay/event-graph/nodes/value-nodes.js +4 -0
- package/dist/gameplay/event-graph/registry.d.ts +33 -0
- package/dist/gameplay/event-graph/registry.js +4 -0
- package/dist/gameplay/event-graph/runtime-assets.d.ts +21 -0
- package/dist/gameplay/event-graph/runtime-assets.js +4 -0
- package/dist/gameplay/event-graph/runtime.d.ts +160 -0
- package/dist/gameplay/event-graph/runtime.js +4 -0
- package/dist/gameplay/event-graph/type-inference.d.ts +41 -0
- package/dist/gameplay/event-graph/type-inference.js +4 -0
- package/dist/gameplay/event-graph/types.d.ts +77 -0
- package/dist/gameplay/event-graph/types.js +4 -0
- package/dist/gameplay/index.d.ts +17 -2
- package/dist/gameplay/index.js +1 -1
- package/dist/gameplay/initiate.d.ts +4 -0
- package/dist/gameplay/initiate.js +1 -1
- package/dist/gameplay/input/input.d.ts +22 -17
- package/dist/gameplay/input/input.js +1 -1
- package/dist/gameplay/net/browser/index.d.ts +147 -0
- package/dist/gameplay/net/browser/index.js +4 -0
- package/dist/gameplay/net/index.d.ts +7 -0
- package/dist/gameplay/net/index.js +4 -0
- package/dist/gameplay/net/net-connection.d.ts +25 -0
- package/dist/gameplay/net/net-connection.js +4 -0
- package/dist/gameplay/net/net-session.d.ts +70 -0
- package/dist/gameplay/net/net-session.js +4 -0
- package/dist/gameplay/net/service/net-actor-role.d.ts +12 -0
- package/dist/gameplay/net/service/net-actor-role.js +4 -0
- package/dist/gameplay/net/service/net-decorator.d.ts +29 -0
- package/dist/gameplay/net/service/net-decorator.js +4 -0
- package/dist/gameplay/net/service/net-serializer.d.ts +15 -0
- package/dist/gameplay/net/service/net-serializer.js +4 -0
- package/dist/gameplay/net/service/net-service.d.ts +171 -0
- package/dist/gameplay/net/service/net-service.js +4 -0
- package/dist/gameplay/net/service/net-utils.d.ts +8 -0
- package/dist/gameplay/net/service/net-utils.js +4 -0
- package/dist/gameplay/net/service/replication.d.ts +31 -0
- package/dist/gameplay/net/service/replication.js +4 -0
- package/dist/gameplay/net/service/rpc-decorator.d.ts +21 -0
- package/dist/gameplay/net/service/rpc-decorator.js +4 -0
- package/dist/gameplay/net/service/rpc.d.ts +35 -0
- package/dist/gameplay/net/service/rpc.js +4 -0
- package/dist/gameplay/services/asset-loader.d.ts +10 -2
- package/dist/gameplay/services/asset-loader.js +1 -1
- package/dist/gameplay/services/physics/physics-system.d.ts +16 -1
- package/dist/gameplay/services/physics/physics-system.js +1 -1
- package/dist/gameplay/services/world.d.ts +25 -2
- package/dist/gameplay/services/world.js +1 -1
- package/dist/rendering/color-pass.js +1 -1
- package/dist/rendering.d.ts +2 -0
- package/dist/rendering.js +1 -1
- package/dist/scene/asset-resource-loader.d.ts +7 -1
- package/dist/scene/asset-resource-loader.js +1 -1
- package/dist/scene/batched-mesh-2.d.ts +9 -0
- package/dist/scene/batched-mesh-2.js +1 -1
- package/dist/scene/bootstrap.d.ts +2 -0
- package/dist/scene/bootstrap.js +1 -1
- package/dist/scene/custom-param-deserialize.js +1 -1
- package/dist/scene/custom-param-runtime-types.js +1 -1
- package/dist/scene/materializer.d.ts +29 -0
- package/dist/scene/materializer.js +1 -1
- package/dist/scene/model.d.ts +114 -2
- package/dist/scene/model.js +1 -1
- package/dist/scene/objects/prefab.js +1 -1
- package/dist/scene/storage/storage.d.ts +1 -1
- package/dist/scene/storage/storage.js +1 -1
- package/dist/shader/builtin/standard-shader.js +1 -1
- package/dist/shader/builtin/toon-shader.js +1 -1
- package/dist/shader/builtin/unlit-shader.js +1 -1
- package/dist/shader/color-layer.js +1 -1
- package/dist/shader/graph/compiler.d.ts +3 -0
- package/dist/shader/graph/compiler.js +1 -1
- package/dist/shader/graph/model.d.ts +1 -1
- package/dist/shader/graph/registry.js +1 -1
- package/dist/shader/parameter.d.ts +1 -1
- package/dist/shader/parameter.js +1 -1
- package/dist/shader-nodes/depth.js +1 -1
- package/dist/shader-nodes/scene-sample.js +1 -1
- package/dist/test/animation-retarget.test.d.ts +2 -0
- package/dist/test/animation-retarget.test.js +4 -0
- package/dist/test/batched-mesh-2.test.d.ts +2 -0
- package/dist/test/batched-mesh-2.test.js +4 -0
- package/dist/test/browser-net-session.test.d.ts +2 -0
- package/dist/test/browser-net-session.test.js +4 -0
- package/dist/test/event-graph-generated-code.test.d.ts +2 -0
- package/dist/test/event-graph-generated-code.test.js +4 -0
- package/dist/test/event-graph-types.test.d.ts +2 -0
- package/dist/test/event-graph-types.test.js +4 -0
- package/dist/test/event-graph.test.d.ts +2 -0
- package/dist/test/event-graph.test.js +4 -0
- package/dist/test/first-person-camera-component.test.js +1 -1
- package/dist/test/input.test.d.ts +2 -0
- package/dist/test/input.test.js +4 -0
- package/dist/test/net-character-movement.test.d.ts +2 -0
- package/dist/test/net-character-movement.test.js +4 -0
- package/dist/test/net-property-snapshot.test.d.ts +2 -0
- package/dist/test/net-property-snapshot.test.js +4 -0
- package/dist/test/prefab-instance-params.test.js +1 -1
- package/dist/test/sequence-animation-retiming.test.js +1 -1
- package/dist/test/sequence-camera-control.test.js +1 -1
- package/dist/test/sequence-scene-binding.test.d.ts +2 -0
- package/dist/test/sequence-scene-binding.test.js +4 -0
- package/dist/test/sequence-transform.test.d.ts +2 -0
- package/dist/test/sequence-transform.test.js +4 -0
- package/dist/test/shader-graph.test.js +1 -1
- package/dist/test/vfx-random-color-initializer.test.d.ts +2 -0
- package/dist/test/vfx-random-color-initializer.test.js +4 -0
- package/dist/test/world-prefab-spawn.test.d.ts +2 -0
- package/dist/test/world-prefab-spawn.test.js +4 -0
- package/dist/utils/three/placeholder-texture.d.ts +3 -0
- package/dist/utils/three/placeholder-texture.js +4 -0
- package/package.json +18 -2
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Type } from '../../utils/type.js';
|
|
2
|
+
import type { BaseActor } from '../actors/actor.js';
|
|
3
|
+
import { type EventGraphCallableInfo, type EventGraphEventSourceInfo, type EventGraphPropertyInfo } from './decorators.js';
|
|
4
|
+
import type { EventGraphDocument } from './model.js';
|
|
5
|
+
import { type EventGraphType } from './types.js';
|
|
6
|
+
export interface EventGraphTypeContext {
|
|
7
|
+
/** Resolves a prefab-local actor id, including `$self`, to its concrete class. */
|
|
8
|
+
resolveActorClass?(actorId: string): Type<BaseActor> | undefined;
|
|
9
|
+
/** When present, an undefined result means the referenced asset is missing. */
|
|
10
|
+
resolveAssetType?(assetId: string): string | undefined;
|
|
11
|
+
}
|
|
12
|
+
/** Creates the class resolver shared by prefab editors and build-time compilation. */
|
|
13
|
+
export declare function createEventGraphTypeContext(actorClassesById: ReadonlyMap<string, Type<BaseActor>>, mainActorId?: string): EventGraphTypeContext;
|
|
14
|
+
export interface EventGraphTypeDiagnostic {
|
|
15
|
+
severity: 'error' | 'warning';
|
|
16
|
+
nodeId: string;
|
|
17
|
+
port?: string;
|
|
18
|
+
message: string;
|
|
19
|
+
}
|
|
20
|
+
export interface EventGraphNodeTypeInfo {
|
|
21
|
+
inputs: Readonly<Record<string, EventGraphType>>;
|
|
22
|
+
outputs: Readonly<Record<string, EventGraphType>>;
|
|
23
|
+
}
|
|
24
|
+
export interface EventGraphTypeAnalysis {
|
|
25
|
+
nodes: ReadonlyMap<string, EventGraphNodeTypeInfo>;
|
|
26
|
+
diagnostics: readonly EventGraphTypeDiagnostic[];
|
|
27
|
+
getInputType(nodeId: string, port: string): EventGraphType;
|
|
28
|
+
getOutputType(nodeId: string, port: string): EventGraphType;
|
|
29
|
+
}
|
|
30
|
+
export interface EventGraphTypeMembers {
|
|
31
|
+
properties: readonly EventGraphPropertyInfo[];
|
|
32
|
+
callables: readonly EventGraphCallableInfo[];
|
|
33
|
+
eventSources: readonly EventGraphEventSourceInfo[];
|
|
34
|
+
}
|
|
35
|
+
/** Returns the exposed members an editor can offer after resolving a data-pin type. */
|
|
36
|
+
export declare function getEventGraphMembersForType(type: EventGraphType): EventGraphTypeMembers;
|
|
37
|
+
/** Infers data-port types and reports issues without requiring a compilable document. */
|
|
38
|
+
export declare function analyzeEventGraphTypes(graph: EventGraphDocument, context?: EventGraphTypeContext): EventGraphTypeAnalysis;
|
|
39
|
+
/** Performs type analysis and throws a combined error for compiler-facing use. */
|
|
40
|
+
export declare function assertEventGraphTypes(graph: EventGraphDocument, context?: EventGraphTypeContext): EventGraphTypeAnalysis;
|
|
41
|
+
//# sourceMappingURL=type-inference.d.ts.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{getActorClassById as e,getComponentClassById as t}from"../actors/type-registry.js";import{getEventGraphCallableInfo as r,getEventGraphCallableInfos as n,getEventGraphEventSourceInfo as s,getEventGraphEventSourceInfos as o,getEventGraphPropertyInfo as a,getEventGraphPropertyInfos as i}from"./decorators.js";import{EVENT_GRAPH_ACTOR_TRANSFORM_PROPERTIES as u,getEventGraphActorTransformPropertyInfo as l,isEventGraphActorTransformProperty as c}from"./actor-transform-properties.js";import{isEventGraphAssetReference as p}from"./asset-references.js";import{SEQUENCE_ACTOR_TYPE_ID as d,VFX_ACTOR_TYPE_ID as v}from"./asset-actor-types.js";import{getEventGraphInputDefault as h,getEventGraphNodePorts as y}from"./registry.js";import{EVENT_GRAPH_ACTOR_TYPE as f,EVENT_GRAPH_ANY_TYPE as m,EVENT_GRAPH_BOOLEAN_TYPE as g,EVENT_GRAPH_COMPONENT_TYPE as b,EVENT_GRAPH_NUMBER_TYPE as k,EVENT_GRAPH_OBJECT_TYPE as T,EVENT_GRAPH_ROTATION_TYPE as $,EVENT_GRAPH_STRING_TYPE as I,EVENT_GRAPH_VECTOR2_TYPE as S,EVENT_GRAPH_VECTOR3_TYPE as V,eventGraphActorType as C,eventGraphAssetType as N,eventGraphOptionalType as w,eventGraphTypeName as x,inferEventGraphLiteralType as A,isTweenableEventGraphType as O,isEventGraphLiteralAssignableToType as q,isEventGraphTypeAssignable as E}from"./types.js";export function createEventGraphTypeContext(e,t){return{resolveActorClass(r){const n="$self"===r?t:r;return null!=n?e.get(n):void 0}}}export function getEventGraphMembersForType(e){const t=P(e),r=null!=t?i(t):[];return{properties:"actor"===e.kind?[...u,...r.filter(e=>!c(e.propertyName))]:r,callables:null!=t?n(t):[],eventSources:null!=t?o(t):[]}}export function analyzeEventGraphTypes(e,t={}){return new M(e,t).analyze()}export function assertEventGraphTypes(e,t={}){const r=analyzeEventGraphTypes(e,t),n=r.diagnostics.filter(e=>"error"===e.severity);if(n.length>0)throw new Error(`Event graph type errors:\n${n.map(U).join("\n")}`);return r}class M{constructor(e,t){this.graph=e,this.context=t,this.graphNodes=new Map,this.variables=new Map,this.incoming=new Map,this.nodeTypes=new Map,this.resolving=new Set,this.diagnostics=[],this.diagnosticKeys=new Set;for(const t of e.nodes)this.graphNodes.set(t.id,t);for(const t of e.variables??[])this.variables.set(t.name,t.type??A(t.defaultValue));for(const t of e.edges)this.isDataPort(t.from.nodeId,t.from.port,"outputs")&&this.incoming.set(K(t.to),t.from)}analyze(){for(const e of this.graph.nodes)this.inferNode(e);for(const e of this.graph.nodes)this.validateInputs(e);const e=this.nodeTypes;return{nodes:e,diagnostics:this.diagnostics,getInputType:(t,r)=>e.get(t)?.inputs[r]??m,getOutputType:(t,r)=>e.get(t)?.outputs[r]??m}}inferNode(e){const t=this.nodeTypes.get(e.id);if(null!=t)return t;if(this.resolving.has(e.id))return{inputs:{},outputs:{}};this.resolving.add(e.id);const r={inputs:Object.fromEntries(y(e,"inputs").filter(e=>"data"===e.kind).map(e=>[e.name,e.type??m])),outputs:Object.fromEntries(y(e,"outputs").filter(e=>"data"===e.kind).map(e=>[e.name,e.type??m]))};this.nodeTypes.set(e.id,r);try{return this.inferSpecializedNode(e,r),r}finally{this.resolving.delete(e.id)}}inferSpecializedNode(r,n){switch(r.kind){case"constant.boolean":return void(n.outputs.value=g);case"constant.number":return void(n.outputs.value=k);case"constant.string":return void(n.outputs.value=I);case"constant.vector2":return void(n.outputs.value=S);case"constant.vector3":return void(n.outputs.value=V);case"event.update":return void(n.outputs.deltaTime=k);case"event.observable":{const e=this.observableTargetType(r),t=this.propertyInfo(e,R(r,"property"));return void("observable"===t?.type.kind?n.outputs.value=t.type.value:"any"===t?.type.kind?n.outputs.value=m:null!=t?this.error(r,"value",`${t.label} is not an Observable`):null!=P(e)&&this.error(r,"value",`Property ${JSON.stringify(R(r,"property"))} is not exposed to event graphs`))}case"event.source":{const e=this.observableTargetType(r),t=this.eventSourceInfo(e,R(r,"source"));return void(null!=t?(n.outputs.value=this.eventSourcePayloadType(r,t),this.validateStaticEventSourceArguments(r,t)):null!=P(e)&&this.error(r,"value",`Event source ${JSON.stringify(R(r,"source"))} is not exposed to event graphs`))}case"flow.switch":{const e=this.inputValueType(r,"value");return void("vector2"!==e.kind&&"vector3"!==e.kind||this.error(r,"value",`Switch does not support ${x(e)} values`))}case"flow.isValid":{const e=this.inputValueType(r,"value");return n.inputs.value=e,void(n.outputs.value="optional"===e.kind?e.value:"null"===e.kind?m:e)}case"variable.get":return void(n.outputs.value=this.variableType(r));case"variable.set":return void(n.inputs.value=this.variableType(r));case"actor.reference":{const e=R(r,"actorId"),t=null!=e?this.context.resolveActorClass?.(e):void 0;return void(n.outputs.value=null!=t?C(t):f)}case"actor.spawnClass":{const t=e(R(r,"classId")??"");return void(n.outputs.value=null!=t?C(t):f)}case"flow.forEach":{const e=this.inputValueType(r,"array"),t="array"===e.kind?e:{kind:"array",element:m};return n.inputs.array=t,n.outputs.arrayElement=t.element,void(n.outputs.arrayIndex=k)}case"actor.findByType":case"actor.findAllByType":{const e=this.actorClassInputType(r,"actorClass");n.inputs.actorClass=e;const t=null!=e.classId?{kind:"actor",classId:e.classId}:f;return void(n.outputs.value="actor.findByType"===r.kind?w(t):{kind:"array",element:t})}case"asset.reference":{const e=r.params?.reference;return void(p(e)?n.outputs.value=N(e.assetType):this.error(r,void 0,"Asset Reference requires a valid asset"))}case"vfx.play":return void(n.outputs.value={kind:"actor",classId:v});case"sequence.play":return void(n.outputs.value={kind:"actor",classId:d});case"actor.component":{n.inputs.target=f;const e=t(R(r,"componentTypeId")??"");if(null!=e)return void(n.outputs.value={kind:"component",classId:e.__componentId??e.name});const s=this.propertyInfo(this.inputValueType(r,"target"),R(r,"property"));return void("component"===s?.type.kind?n.outputs.value=s.type:null!=s&&this.error(r,"target",`${s.label} is not an actor component`))}case"actor.getProperty":{const e=this.inputValueType(r,"target"),t=this.propertyInfo(e,R(r,"property"));return void(null!=t?n.outputs.value=t.type:null!=P(e)&&this.error(r,"target",`Property ${JSON.stringify(R(r,"property"))} is not exposed to event graphs`))}case"actor.setProperty":{const e=this.inputValueType(r,"target"),t=this.propertyInfo(e,R(r,"property"));return void(null!=t?(n.inputs.value=t.type,t.writable||this.error(r,"value",`${t.label} is read-only`)):null!=P(e)&&this.error(r,"target",`Property ${JSON.stringify(R(r,"property"))} is not exposed to event graphs`))}case"actor.tweenProperty":{const e=this.inputValueType(r,"target"),t=R(r,"property"),s=this.propertyInfo(e,t);return void(null!=s?(n.inputs.to=s.type,s.writable||this.error(r,"to",`${s.label} is read-only`),O(s.type)||this.error(r,"to",`${s.label} cannot be tweened`)):null==t?this.error(r,"target","Tween Property requires a property"):null!=P(e)&&this.error(r,"target",`Property ${JSON.stringify(t)} is not exposed to event graphs`))}case"actor.callMethod":case"actor.tryCallMethod":{const e=this.inputValueType(r,"target"),t=this.callableInfo(e,R(r,"method")),s=G(r,"argumentCount")??0;for(let e=0;e<s;e++)n.inputs[`arg${e}`]=t?.parameters[e]?.type??m;if(null!=t){if(n.outputs.value=t.returnType,t.parametersKnown){const e=t.parameters.filter(e=>!0!==e.optional).length;(s<e||s>t.parameters.length)&&this.error(r,void 0,`${t.label} expects ${e===t.parameters.length?e:`${e}-${t.parameters.length}`} arguments, received ${s}`)}t.awaitResult&&!0!==r.params?.awaitResult&&this.error(r,void 0,`${t.label} is asynchronous and must be awaited`)}else null!=P(e)&&this.error(r,"target",`Method ${JSON.stringify(R(r,"method"))} is not exposed to event graphs`);return}case"event.bindSource":{n.inputs.target=null!=R(r,"component")||null!=R(r,"componentTypeId")?f:T;const e=this.eventBindSourceTargetType(r),t=this.eventSourceInfo(e,R(r,"source")),s=G(r,"argumentCount")??0;if(null!=t){n.outputs.value=this.eventSourcePayloadType(r,t);let e=0;for(const r of t.parameters)"actorClass"!==r.type.kind&&(n.inputs["arg"+e++]=r.type);t.parametersKnown&&s!==e&&this.error(r,void 0,`${t.label} expects ${e} connected arguments, received ${s}`),this.validateEventSourceActorClassArguments(r,t)}else null!=P(e)&&this.error(r,"target",`Event source ${JSON.stringify(R(r,"source"))} is not exposed to event graphs`);return}case"math.add":case"math.subtract":case"math.multiply":case"math.divide":case"math.modulo":return void this.inferMathNode(r,n);case"vector.length":case"vector.lengthSquared":return void this.inferVectorUnaryNode(r,n,k);case"vector.normalize":return void this.inferVectorUnaryNode(r,n,m);case"vector.distance":case"vector.distanceSquared":case"vector.dot":return void this.inferVectorBinaryNode(r,n,k);case"vector.lerp":return this.inferVectorBinaryNode(r,n,m),void(n.inputs.alpha=k);case"vector.cross":return n.inputs.a=V,n.inputs.b=V,void(n.outputs.value=V);case"vector.applyRotation":return n.inputs.value=V,n.inputs.rotation=$,void(n.outputs.value=V);case"boolean.and":case"boolean.or":return n.inputs.a=g,n.inputs.b=g,void(n.outputs.value=g);case"boolean.not":return n.inputs.value=g,void(n.outputs.value=g);case"compare.greaterThan":case"compare.greaterThanOrEqual":case"compare.lessThan":case"compare.lessThanOrEqual":{const e=(s=this.inputValueType(r,"a"),o=this.inputValueType(r,"b"),"string"===s.kind||"string"===o.kind?I:k);return n.inputs.a=e,n.inputs.b=e,void(n.outputs.value=g)}case"compare.equal":case"compare.notEqual":{const e=this.inputValueType(r,"a"),t=this.inputValueType(r,"b");return"vector2"!==e.kind&&"vector3"!==e.kind||!this.inputLiteralMatches(r,"b",e)?"vector2"!==t.kind&&"vector3"!==t.kind||!this.inputLiteralMatches(r,"a",t)?(n.inputs.a="any"===t.kind?e:t,n.inputs.b="any"===e.kind?t:e,void(n.outputs.value=g)):(n.inputs.a=t,n.inputs.b=t,void(n.outputs.value=g)):(n.inputs.a=e,n.inputs.b=e,void(n.outputs.value=g))}}var s,o}validateInputs(e){const t=this.inferNode(e);for(const[r,n]of Object.entries(t.inputs)){const t=this.input(e,r);if(null==t)continue;const s="value"in t?A(t.value):this.outputType(t);("value"in t?q(t.value,n):E(s,n))||this.error(e,r,`Expected ${x(n)}, received ${x(s)}`)}}inputValueType(e,t){const r=this.input(e,t);return null==r?m:"value"in r?A(r.value):this.outputType(r)}outputType(e){const t=this.graphNodes.get(e.nodeId);return null!=t?this.inferNode(t).outputs[e.port]??m:m}input(e,t){const r=this.incoming.get(K({nodeId:e.id,port:t}))??e.inputs?.[t];if(null!=r)return r;const n=h(e,t);return void 0!==n?{value:n}:void 0}inputLiteralMatches(e,t,r){const n=this.input(e,t);return null!=n&&"value"in n&&q(n.value,r)}inferMathNode(e,t){const r=this.inputValueType(e,"a"),n=this.inputValueType(e,"b"),s=this.vectorOperandType(e,"a",r),o=this.vectorOperandType(e,"b",n),a=function(e){switch(e){case"math.add":return"Add";case"math.subtract":return"Subtract";case"math.multiply":return"Multiply";case"math.divide":return"Divide";case"math.modulo":return"Modulo";default:return"Math"}}(e.kind);if("math.add"===e.kind){const s=function(e,t){return"string"!==e.kind||"string"!==t.kind&&"any"!==t.kind?"string"===t.kind&&"any"===e.kind?I:void 0:I}(r,n);if(null!=s)return t.inputs.a=s,t.inputs.b=s,void(t.outputs.value=s);if("string"===r.kind||"string"===n.kind)return t.inputs.a=m,t.inputs.b=m,t.outputs.value=m,void this.error(e,void 0,`Add requires two numbers, two strings, or vector-compatible operands, received ${x(r)} and ${x(n)}`)}const i=j(s,o);return"mismatch"===i?(t.inputs.a=s??m,t.inputs.b=o??m,t.outputs.value=m,void this.error(e,void 0,`${a} requires vector operands to have the same dimension, received ${x(s)} and ${x(o)}`)):null!=i?(t.inputs.a=J(r,s,i),t.inputs.b=J(n,o,i),t.outputs.value=i,void(B(r,s,i)&&B(n,o,i)||this.error(e,void 0,`${a} requires numbers or ${x(i)} values, received ${x(r)} and ${x(n)}`))):(t.inputs.a=k,t.inputs.b=k,t.outputs.value=k,void(D(r)&&D(n)||this.error(e,void 0,`${a} requires number or vector operands, received ${x(r)} and ${x(n)}`)))}vectorOperandType(e,t,r){if("vector2"===r.kind)return S;if("vector3"===r.kind)return V;const n=this.input(e,t);return null!=n&&"value"in n?q(n.value,S)?S:q(n.value,V)?V:void 0:void 0}inferVectorUnaryNode(e,t,r){const n=this.inputValueType(e,"value"),s=this.vectorOperandType(e,"value",n);t.inputs.value=s??m,t.outputs.value="any"===r.kind?s??m:r,null==s&&"any"!==n.kind&&this.error(e,"value",`${L(e.kind)} requires a Vector2 or Vector3, received ${x(n)}`)}inferVectorBinaryNode(e,t,r){const n=this.inputValueType(e,"a"),s=this.inputValueType(e,"b"),o=this.vectorOperandType(e,"a",n),a=this.vectorOperandType(e,"b",s),i=j(o,a);return"mismatch"===i?(t.inputs.a=o??m,t.inputs.b=a??m,t.outputs.value=r,void this.error(e,void 0,`${L(e.kind)} requires matching vector dimensions, received ${x(o)} and ${x(a)}`)):null!=i?(t.inputs.a=z(n,o,i),t.inputs.b=z(s,a,i),void(t.outputs.value="any"===r.kind?i:r)):(t.inputs.a=m,t.inputs.b=m,t.outputs.value=r,void("any"!==n.kind&&"any"!==s.kind&&this.error(e,void 0,`${L(e.kind)} requires Vector2 or Vector3 inputs, received ${x(n)} and ${x(s)}`)))}observableTargetType(e){const t=R(e,"actorId"),r=null!=t?this.context.resolveActorClass?.(t):void 0;let n=null!=r?C(r):f;const s=R(e,"component"),o=R(e,"componentTypeId");return this.componentTargetType(n,s,o)}actorClassInputType(t,r){const n=this.input(t,r);if(null==n)return{kind:"actorClass"};if("value"in n)return"string"!=typeof n.value||0===n.value.length?{kind:"actorClass"}:null==e(n.value)?(this.error(t,r,`Actor class ${JSON.stringify(n.value)} does not exist`),{kind:"actorClass"}):{kind:"actorClass",classId:n.value};const s=this.outputType(n);return"actorClass"===s.kind?s:{kind:"actorClass"}}eventBindSourceTargetType(e){const t=this.inputValueType(e,"target"),r=R(e,"component"),n=R(e,"componentTypeId");return this.componentTargetType(t,r,n)}componentTargetType(e,t,r){if(null!=t){const r=this.propertyInfo(e,t)?.type;if(null!=r)return r}return null!=r?{kind:"component",classId:r}:null!=t?b:e}eventSourceInfo(e,t){if(null==t)return;const r=P(e);return null!=r?s(r,t):void 0}eventSourcePayloadType(e,t){let r=t.valueType,n=0;for(let s=0;s<t.parameters.length;s++){const o=t.parameters[s];if("actor"===r.kind&&"actorClass"===o.type.kind){const t=R(e,`arg${s}ActorClassId`);null!=t&&(r={kind:"actor",classId:t})}else if("actor"===r.kind&&"actor"===o.type.kind)if("event.source"===e.kind){const t=R(e,`arg${s}ActorId`),n=null!=t?this.context.resolveActorClass?.(t):void 0;null!=n&&(r=C(n))}else{const t=this.inputValueType(e,`arg${n}`);"actor"===t.kind&&null!=t.classId&&(r=t)}"actorClass"!==o.type.kind&&n++}return r}validateStaticEventSourceArguments(t,r){for(let n=0;n<r.parameters.length;n++){const s=r.parameters[n];if("actorClass"===s.type.kind){const o=R(t,`arg${n}ActorClassId`);null==o?this.error(t,void 0,`${r.label} requires an actor class for ${s.name}`):null==e(o)&&this.error(t,void 0,`Actor class ${JSON.stringify(o)} does not exist`);continue}if("actor"===s.type.kind){const e=R(t,`arg${n}ActorId`);null==e?this.error(t,void 0,`${r.label} requires an actor for ${s.name}`):null!=this.context.resolveActorClass&&null==this.context.resolveActorClass(e)&&this.error(t,void 0,`Actor ${JSON.stringify(e)} does not exist`);continue}this.error(t,void 0,`${r.label} parameter ${s.name} cannot be authored on a static event source`)}}validateEventSourceActorClassArguments(t,r){for(let n=0;n<r.parameters.length;n++){const s=r.parameters[n];if("actorClass"!==s.type.kind)continue;const o=R(t,`arg${n}ActorClassId`);null==o?this.error(t,void 0,`${r.label} requires an actor class for ${s.name}`):null==e(o)&&this.error(t,void 0,`Actor class ${JSON.stringify(o)} does not exist`)}}propertyInfo(e,t){if(null==t)return;if("actor"===e.kind){const e=l(t);if(null!=e)return e}const r=P(e);return null!=r?a(r,t):void 0}callableInfo(e,t){if(null==t)return;const n=P(e);return null!=n?r(n,t):void 0}variableType(e){return this.variables.get(R(e,"variable")??"")??m}isDataPort(e,t,r){const n=this.graphNodes.get(e);return null!=n&&y(n,r).some(e=>e.name===t&&"data"===e.kind)}error(e,t,r){const n=`${e.id}:${t??""}:${r}`;this.diagnosticKeys.has(n)||(this.diagnosticKeys.add(n),this.diagnostics.push({severity:"error",nodeId:e.id,...null!=t?{port:t}:{},message:r}))}}function P(r){return"actor"===r.kind&&null!=r.classId?e(r.classId):"component"===r.kind&&null!=r.classId?t(r.classId):void 0}function j(e,t){return null==e?t:null==t||e.kind===t.kind?e:"mismatch"}function J(e,t,r){return null!=t?t.kind===r.kind?r:t:"number"===e.kind?k:(e.kind,m)}function z(e,t,r){return null!=t?t.kind===r.kind?r:t:"any"===e.kind?r:m}function B(e,t,r){return"any"===e.kind||"number"===e.kind||t?.kind===r.kind}function D(e){return"number"===e.kind||"any"===e.kind}function L(e){switch(e){case"vector.length":return"Length";case"vector.lengthSquared":return"Length Squared";case"vector.distance":return"Distance";case"vector.distanceSquared":return"Distance Squared";case"vector.normalize":return"Normalize";case"vector.dot":return"Dot Product";case"vector.cross":return"Cross Product";case"vector.lerp":return"Lerp";case"vector.applyRotation":return"Apply Rotation";default:return"Vector"}}function R(e,t){const r=e.params?.[t];return"string"==typeof r&&r.length>0?r:void 0}function G(e,t){const r=e.params?.[t];return"number"==typeof r?r:void 0}function K(e){return`${e.nodeId}:${e.port}`}function U(e){return`- ${null==e.port?e.nodeId:`${e.nodeId}:${e.port}`}: ${e.message}`}/*
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
|
+
* See the LICENSE.md file for details.
|
|
4
|
+
*/
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { EventGraphAssetKind } from './model.js';
|
|
2
|
+
export type EventGraphType = {
|
|
3
|
+
kind: 'any';
|
|
4
|
+
} | {
|
|
5
|
+
kind: 'void';
|
|
6
|
+
} | {
|
|
7
|
+
kind: 'null';
|
|
8
|
+
} | {
|
|
9
|
+
kind: 'boolean';
|
|
10
|
+
} | {
|
|
11
|
+
kind: 'number';
|
|
12
|
+
} | {
|
|
13
|
+
kind: 'string';
|
|
14
|
+
} | {
|
|
15
|
+
kind: 'vector2';
|
|
16
|
+
} | {
|
|
17
|
+
kind: 'vector3';
|
|
18
|
+
} | {
|
|
19
|
+
kind: 'euler';
|
|
20
|
+
} | {
|
|
21
|
+
kind: 'asset';
|
|
22
|
+
assetType: EventGraphAssetKind;
|
|
23
|
+
} | {
|
|
24
|
+
kind: 'optional';
|
|
25
|
+
value: EventGraphType;
|
|
26
|
+
} | {
|
|
27
|
+
kind: 'object';
|
|
28
|
+
classId?: string;
|
|
29
|
+
} | {
|
|
30
|
+
kind: 'actor';
|
|
31
|
+
classId?: string;
|
|
32
|
+
} | {
|
|
33
|
+
kind: 'actorClass';
|
|
34
|
+
classId?: string;
|
|
35
|
+
} | {
|
|
36
|
+
kind: 'component';
|
|
37
|
+
classId?: string;
|
|
38
|
+
} | {
|
|
39
|
+
kind: 'observable';
|
|
40
|
+
value: EventGraphType;
|
|
41
|
+
} | {
|
|
42
|
+
kind: 'array';
|
|
43
|
+
element: EventGraphType;
|
|
44
|
+
};
|
|
45
|
+
export type EventGraphTypeSource = EventGraphType | Function;
|
|
46
|
+
export declare const EVENT_GRAPH_ANY_TYPE: EventGraphType;
|
|
47
|
+
export declare const EVENT_GRAPH_VOID_TYPE: EventGraphType;
|
|
48
|
+
export declare const EVENT_GRAPH_BOOLEAN_TYPE: EventGraphType;
|
|
49
|
+
export declare const EVENT_GRAPH_NUMBER_TYPE: EventGraphType;
|
|
50
|
+
export declare const EVENT_GRAPH_STRING_TYPE: EventGraphType;
|
|
51
|
+
export declare const EVENT_GRAPH_VECTOR2_TYPE: EventGraphType;
|
|
52
|
+
export declare const EVENT_GRAPH_VECTOR3_TYPE: EventGraphType;
|
|
53
|
+
export declare const EVENT_GRAPH_ROTATION_TYPE: EventGraphType;
|
|
54
|
+
/** @deprecated Use EVENT_GRAPH_ROTATION_TYPE. */
|
|
55
|
+
export declare const EVENT_GRAPH_EULER_TYPE: {
|
|
56
|
+
kind: "euler";
|
|
57
|
+
};
|
|
58
|
+
export declare const EVENT_GRAPH_OBJECT_TYPE: EventGraphType;
|
|
59
|
+
export declare const EVENT_GRAPH_ACTOR_TYPE: EventGraphType;
|
|
60
|
+
export declare const EVENT_GRAPH_ACTOR_CLASS_TYPE: EventGraphType;
|
|
61
|
+
export declare const EVENT_GRAPH_COMPONENT_TYPE: EventGraphType;
|
|
62
|
+
export declare function isTweenableEventGraphType(type: EventGraphType): boolean;
|
|
63
|
+
export declare function eventGraphAssetType(assetType: EventGraphAssetKind): EventGraphType;
|
|
64
|
+
export declare function eventGraphOptionalType(value: EventGraphType): EventGraphType;
|
|
65
|
+
export declare function eventGraphActorType(type?: Function): EventGraphType;
|
|
66
|
+
export declare function eventGraphActorClassType(type?: Function): EventGraphType;
|
|
67
|
+
export declare function eventGraphComponentType(type?: Function): EventGraphType;
|
|
68
|
+
export declare function resolveEventGraphType(source?: EventGraphTypeSource | null): EventGraphType;
|
|
69
|
+
export declare function eventGraphTypeFromConstructor(type?: Function | null): EventGraphType;
|
|
70
|
+
export declare function inferEventGraphLiteralType(value: unknown): EventGraphType;
|
|
71
|
+
export declare function isEventGraphType(value: unknown): value is EventGraphType;
|
|
72
|
+
/** Returns true when a value of `actual` can connect to a port expecting `expected`. */
|
|
73
|
+
export declare function isEventGraphTypeAssignable(actual: EventGraphType, expected: EventGraphType): boolean;
|
|
74
|
+
/** Validates a serialized literal against its contextual graph type. */
|
|
75
|
+
export declare function isEventGraphLiteralAssignableToType(value: unknown, expected: EventGraphType): boolean;
|
|
76
|
+
export declare function eventGraphTypeName(type: EventGraphType): string;
|
|
77
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{Observable as e}from"rxjs";import{Euler as n,Vector2 as t,Vector3 as r}from"three";import{getActorClassById as s,getActorClassId as a,getComponentClassById as o,getComponentClassId as i}from"../actors/type-registry.js";import{isEventGraphAssetReference as p}from"./asset-references.js";export const EVENT_GRAPH_ANY_TYPE=Object.freeze({kind:"any"});export const EVENT_GRAPH_VOID_TYPE=Object.freeze({kind:"void"});export const EVENT_GRAPH_BOOLEAN_TYPE=Object.freeze({kind:"boolean"});export const EVENT_GRAPH_NUMBER_TYPE=Object.freeze({kind:"number"});export const EVENT_GRAPH_STRING_TYPE=Object.freeze({kind:"string"});export const EVENT_GRAPH_VECTOR2_TYPE=Object.freeze({kind:"vector2"});export const EVENT_GRAPH_VECTOR3_TYPE=Object.freeze({kind:"vector3"});export const EVENT_GRAPH_ROTATION_TYPE=Object.freeze({kind:"euler"});export const EVENT_GRAPH_EULER_TYPE=EVENT_GRAPH_ROTATION_TYPE;export const EVENT_GRAPH_OBJECT_TYPE=Object.freeze({kind:"object"});export const EVENT_GRAPH_ACTOR_TYPE=Object.freeze({kind:"actor"});export const EVENT_GRAPH_ACTOR_CLASS_TYPE=Object.freeze({kind:"actorClass"});export const EVENT_GRAPH_COMPONENT_TYPE=Object.freeze({kind:"component"});export function isTweenableEventGraphType(e){return"number"===e.kind||"vector2"===e.kind||"vector3"===e.kind||"euler"===e.kind}export function eventGraphAssetType(e){return{kind:"asset",assetType:e}}export function eventGraphOptionalType(e){return{kind:"optional",value:e}}export function eventGraphActorType(e){return{kind:"actor",...null!=e?{classId:a(e)??e.name}:{}}}export function eventGraphActorClassType(e){return{kind:"actorClass",...null!=e?{classId:a(e)??e.name}:{}}}export function eventGraphComponentType(e){return{kind:"component",...null!=e?{classId:i(e)??e.name}:{}}}export function resolveEventGraphType(e){return null==e?EVENT_GRAPH_ANY_TYPE:isEventGraphType(e)?e:eventGraphTypeFromConstructor(e)}export function eventGraphTypeFromConstructor(s){return null==s?EVENT_GRAPH_VOID_TYPE:s===Number?EVENT_GRAPH_NUMBER_TYPE:s===String?EVENT_GRAPH_STRING_TYPE:s===Boolean?EVENT_GRAPH_BOOLEAN_TYPE:s===t?EVENT_GRAPH_VECTOR2_TYPE:s===r?EVENT_GRAPH_VECTOR3_TYPE:s===n?EVENT_GRAPH_ROTATION_TYPE:s===Array?{kind:"array",element:EVENT_GRAPH_ANY_TYPE}:s===e||null!=s.prototype&&s.prototype instanceof e?{kind:"observable",value:EVENT_GRAPH_ANY_TYPE}:null!=a(s)||!0===s.__isActor?eventGraphActorType(s):null!=i(s)||!0===s.__isActorComponent?eventGraphComponentType(s):s===Object||s===Promise?EVENT_GRAPH_OBJECT_TYPE:{kind:"object",classId:s.name||void 0}}export function inferEventGraphLiteralType(e){if(void 0===e)return EVENT_GRAPH_ANY_TYPE;if(null===e)return{kind:"null"};if("boolean"==typeof e)return EVENT_GRAPH_BOOLEAN_TYPE;if("number"==typeof e)return EVENT_GRAPH_NUMBER_TYPE;if("string"==typeof e)return EVENT_GRAPH_STRING_TYPE;if(p(e))return eventGraphAssetType(e.assetType);if(Array.isArray(e)){return{kind:"array",element:e.length>0?inferEventGraphLiteralType(e[0]):EVENT_GRAPH_ANY_TYPE}}return EVENT_GRAPH_OBJECT_TYPE}export function isEventGraphType(e){if(null==e||"object"!=typeof e||"string"!=typeof e.kind)return!1;const n=e;switch(n.kind){case"any":case"void":case"null":case"boolean":case"number":case"string":case"vector2":case"vector3":case"euler":return!0;case"asset":return"prefab"===n.assetType||"vfx"===n.assetType||"sequence"===n.assetType;case"optional":return isEventGraphType(n.value)&&"void"!==n.value.kind;case"object":case"actor":case"actorClass":case"component":return null==n.classId||"string"==typeof n.classId;case"observable":return isEventGraphType(n.value);case"array":return isEventGraphType(n.element);default:return!1}}export function isEventGraphTypeAssignable(e,n){return"any"===e.kind||"any"===n.kind||("optional"===n.kind?"null"===e.kind||isEventGraphTypeAssignable("optional"===e.kind?e.value:e,n.value):"optional"!==e.kind&&("object"===n.kind?null==n.classId?"object"===e.kind||"actor"===e.kind||"component"===e.kind||"vector2"===e.kind||"vector3"===e.kind:"object"===e.kind&&(null==e.classId||e.classId===n.classId):e.kind===n.kind&&("asset"===e.kind&&"asset"===n.kind?e.assetType===n.assetType:"actor"===e.kind&&"actor"===n.kind||"actorClass"===e.kind&&"actorClass"===n.kind?l(e.classId,n.classId,s):"component"===e.kind&&"component"===n.kind?l(e.classId,n.classId,o):"observable"===e.kind&&"observable"===n.kind?isEventGraphTypeAssignable(e.value,n.value):"array"!==e.kind||"array"!==n.kind||isEventGraphTypeAssignable(e.element,n.element))))}export function isEventGraphLiteralAssignableToType(e,n){return"any"===n.kind?c(e):"actorClass"===n.kind?"string"==typeof e&&e.length>0:"vector2"===n.kind?T(e,2):"vector3"===n.kind||"euler"===n.kind?T(e,3):"asset"===n.kind?p(e)&&e.assetType===n.assetType&&e.assetId.length>0:"optional"===n.kind?null===e||isEventGraphLiteralAssignableToType(e,n.value):"array"===n.kind?Array.isArray(e)&&e.every(e=>isEventGraphLiteralAssignableToType(e,n.element)):c(e)&&isEventGraphTypeAssignable(inferEventGraphLiteralType(e),n)}export function eventGraphTypeName(e){return"actor"===e.kind||"component"===e.kind||"object"===e.kind?e.classId??e.kind:"actorClass"===e.kind?null!=e.classId?`${e.classId} Class`:"Actor Class":"observable"===e.kind?`Observable<${eventGraphTypeName(e.value)}>`:"array"===e.kind?`${eventGraphTypeName(e.element)}[]`:"asset"===e.kind?"vfx"===e.assetType?"VFX Asset":`${e.assetType[0].toUpperCase()}${e.assetType.slice(1)} Asset`:"optional"===e.kind?`${eventGraphTypeName(e.value)}?`:"euler"===e.kind?"Rotation":e.kind}function l(e,n,t){if(null==n||null==e)return!0;if(e===n)return!0;const r=t(e),s=t(n);return null!=r&&null!=s&&r.prototype instanceof s}function c(e){return"number"==typeof e?Number.isFinite(e):Array.isArray(e)?e.every(c):null==e||"object"!=typeof e||Object.values(e).every(c)}function T(e,n){return Array.isArray(e)&&e.length===n&&e.every(e=>"number"==typeof e&&Number.isFinite(e))}/*
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
|
+
* See the LICENSE.md file for details.
|
|
4
|
+
*/
|
package/dist/gameplay/index.d.ts
CHANGED
|
@@ -4,8 +4,8 @@ export * from './initiate.js';
|
|
|
4
4
|
export * from './inject.js';
|
|
5
5
|
export { Service, Inject } from 'typedi';
|
|
6
6
|
export { ActorFactory } from './actors/factory.js';
|
|
7
|
-
export { Actor, BaseActor } from './actors/actor.js';
|
|
8
|
-
export { Component, ActorComponent, type ComponentOptions, attach, Attach } from './actors/component.js';
|
|
7
|
+
export { Actor, BaseActor, getActorClassById, getActorClassId, getRegisteredActorClasses } from './actors/actor.js';
|
|
8
|
+
export { Component, ActorComponent, type ComponentOptions, attach, Attach, getComponentClassById, getComponentClassId, getRegisteredComponentClasses } from './actors/component.js';
|
|
9
9
|
export * from './services/world.js';
|
|
10
10
|
export * from './services/game-time-scheduler.js';
|
|
11
11
|
export * from './services/camera-shake.js';
|
|
@@ -13,6 +13,7 @@ export * from './services/render.js';
|
|
|
13
13
|
export * from './services/physics/physics-system.js';
|
|
14
14
|
export * from './animation/anim-sm.js';
|
|
15
15
|
export * from './animation/root-motion.js';
|
|
16
|
+
export * from './animation/retarget.js';
|
|
16
17
|
export * from './services/asset-loader.js';
|
|
17
18
|
export * from './services/pointer-events.js';
|
|
18
19
|
export { VisualEffect } from '../effects/vfx/vfx-param.js';
|
|
@@ -21,4 +22,18 @@ export * from '../shader/parameter.js';
|
|
|
21
22
|
export * from './ai/index.js';
|
|
22
23
|
export * from '../effects/vfx/index.js';
|
|
23
24
|
export * from './services/shader-provider.js';
|
|
25
|
+
export { EventGraphCallable, EventGraphEventSource, EventGraphProperty, getEventGraphCallableInfo, getEventGraphCallableInfos, getEventGraphCallableMethods, getEventGraphEventSourceInfo, getEventGraphEventSourceInfos, getEventGraphEventSourceMethods, getEventGraphPropertyInfo, getEventGraphPropertyInfos, getEventGraphProperties, isEventGraphEventSource, } from './event-graph/decorators.js';
|
|
26
|
+
export type { EventGraphCallableInfo, EventGraphCallableOptions, EventGraphEventSourceInfo, EventGraphEventSourceOptions, EventGraphParameterInfo, EventGraphPropertyInfo, EventGraphPropertyOptions, } from './event-graph/decorators.js';
|
|
27
|
+
export { EventGraphCompiler, validateEventGraphDocument } from './event-graph/document-compiler.js';
|
|
28
|
+
export type { CompiledEventGraph, CompiledEventGraphHandler, CompiledEventSourceArgument, CompiledEventSourceEvent, CompiledObservableEvent, EventGraphExecutionContext, EventGraphHandler, EventGraphDiagnostic, EventGraphValidationResult, } from './event-graph/document-compiler.js';
|
|
29
|
+
export type { EventGraphDocument, EventGraphEdge, EventGraphInput, EventGraphNode, EventGraphNodeKind, EventGraphSocketRef, EventGraphVariable, EventGraphVector2Literal, EventGraphVector3Literal, } from './event-graph/model.js';
|
|
30
|
+
export { createDefaultEventGraphDocument, hasExecutableEventGraphDocument } from './event-graph/model.js';
|
|
31
|
+
export { EVENT_GRAPH_NODE_DEFINITIONS, getEventGraphNodePorts, getEventGraphPortDefinition } from './event-graph/registry.js';
|
|
32
|
+
export { EventGraphInstance } from './event-graph/runtime.js';
|
|
33
|
+
export { analyzeEventGraphTypes, assertEventGraphTypes, createEventGraphTypeContext, getEventGraphMembersForType, } from './event-graph/type-inference.js';
|
|
34
|
+
export type { EventGraphNodeTypeInfo, EventGraphTypeAnalysis, EventGraphTypeContext, EventGraphTypeDiagnostic, EventGraphTypeMembers, } from './event-graph/type-inference.js';
|
|
35
|
+
export { EVENT_GRAPH_ACTOR_TYPE, EVENT_GRAPH_ACTOR_CLASS_TYPE, EVENT_GRAPH_ANY_TYPE, EVENT_GRAPH_BOOLEAN_TYPE, EVENT_GRAPH_COMPONENT_TYPE, EVENT_GRAPH_NUMBER_TYPE, EVENT_GRAPH_OBJECT_TYPE, EVENT_GRAPH_STRING_TYPE, EVENT_GRAPH_VOID_TYPE, EVENT_GRAPH_VECTOR2_TYPE, EVENT_GRAPH_VECTOR3_TYPE, eventGraphActorClassType, eventGraphActorType, eventGraphComponentType, eventGraphTypeName, isEventGraphTypeAssignable, } from './event-graph/types.js';
|
|
36
|
+
export type { EventGraphType, EventGraphTypeSource } from './event-graph/types.js';
|
|
37
|
+
export * from './net/net-connection.js';
|
|
38
|
+
export * from './net/net-session.js';
|
|
24
39
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/gameplay/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import"reflect-metadata";export{Container as DIContainer}from"typedi";export*from"./initiate.js";export*from"./inject.js";export{Service,Inject}from"typedi";export{ActorFactory}from"./actors/factory.js";export{Actor,BaseActor}from"./actors/actor.js";export{Component,ActorComponent,attach,Attach}from"./actors/component.js";export*from"./services/world.js";export*from"./services/game-time-scheduler.js";export*from"./services/camera-shake.js";export*from"./services/render.js";export*from"./services/physics/physics-system.js";export*from"./animation/anim-sm.js";export*from"./animation/root-motion.js";export*from"./services/asset-loader.js";export*from"./services/pointer-events.js";export{VisualEffect}from"../effects/vfx/vfx-param.js";export{DataAssetRef}from"../scene/objects/data-asset.js";export*from"../shader/parameter.js";export*from"./ai/index.js";export*from"../effects/vfx/index.js";export*from"./services/shader-provider.js";/*
|
|
1
|
+
import"reflect-metadata";export{Container as DIContainer}from"typedi";export*from"./initiate.js";export*from"./inject.js";export{Service,Inject}from"typedi";export{ActorFactory}from"./actors/factory.js";export{Actor,BaseActor,getActorClassById,getActorClassId,getRegisteredActorClasses}from"./actors/actor.js";export{Component,ActorComponent,attach,Attach,getComponentClassById,getComponentClassId,getRegisteredComponentClasses}from"./actors/component.js";export*from"./services/world.js";export*from"./services/game-time-scheduler.js";export*from"./services/camera-shake.js";export*from"./services/render.js";export*from"./services/physics/physics-system.js";export*from"./animation/anim-sm.js";export*from"./animation/root-motion.js";export*from"./animation/retarget.js";export*from"./services/asset-loader.js";export*from"./services/pointer-events.js";export{VisualEffect}from"../effects/vfx/vfx-param.js";export{DataAssetRef}from"../scene/objects/data-asset.js";export*from"../shader/parameter.js";export*from"./ai/index.js";export*from"../effects/vfx/index.js";export*from"./services/shader-provider.js";export{EventGraphCallable,EventGraphEventSource,EventGraphProperty,getEventGraphCallableInfo,getEventGraphCallableInfos,getEventGraphCallableMethods,getEventGraphEventSourceInfo,getEventGraphEventSourceInfos,getEventGraphEventSourceMethods,getEventGraphPropertyInfo,getEventGraphPropertyInfos,getEventGraphProperties,isEventGraphEventSource}from"./event-graph/decorators.js";export{EventGraphCompiler,validateEventGraphDocument}from"./event-graph/document-compiler.js";export{createDefaultEventGraphDocument,hasExecutableEventGraphDocument}from"./event-graph/model.js";export{EVENT_GRAPH_NODE_DEFINITIONS,getEventGraphNodePorts,getEventGraphPortDefinition}from"./event-graph/registry.js";export{EventGraphInstance}from"./event-graph/runtime.js";export{analyzeEventGraphTypes,assertEventGraphTypes,createEventGraphTypeContext,getEventGraphMembersForType}from"./event-graph/type-inference.js";export{EVENT_GRAPH_ACTOR_TYPE,EVENT_GRAPH_ACTOR_CLASS_TYPE,EVENT_GRAPH_ANY_TYPE,EVENT_GRAPH_BOOLEAN_TYPE,EVENT_GRAPH_COMPONENT_TYPE,EVENT_GRAPH_NUMBER_TYPE,EVENT_GRAPH_OBJECT_TYPE,EVENT_GRAPH_STRING_TYPE,EVENT_GRAPH_VOID_TYPE,EVENT_GRAPH_VECTOR2_TYPE,EVENT_GRAPH_VECTOR3_TYPE,eventGraphActorClassType,eventGraphActorType,eventGraphComponentType,eventGraphTypeName,isEventGraphTypeAssignable}from"./event-graph/types.js";export*from"./net/net-connection.js";export*from"./net/net-session.js";/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -4,6 +4,7 @@ import { World } from './services/world.js';
|
|
|
4
4
|
import { type DynamicResolutionOptions, type UpscalingOptions } from '../rendering.js';
|
|
5
5
|
import { Observable } from 'rxjs';
|
|
6
6
|
import { DetailTier } from "../scene/model.js";
|
|
7
|
+
import { NetSession } from "./net/net-session.js";
|
|
7
8
|
import type { ParameterType } from "../shader/parameter.js";
|
|
8
9
|
type GameClass<T> = Constructable<T>;
|
|
9
10
|
export type InitiateGameConfig = {
|
|
@@ -51,6 +52,9 @@ export type InitiateGameConfig = {
|
|
|
51
52
|
enabled?: boolean;
|
|
52
53
|
};
|
|
53
54
|
}>;
|
|
55
|
+
multi?: {
|
|
56
|
+
session: NetSession;
|
|
57
|
+
};
|
|
54
58
|
};
|
|
55
59
|
export declare function initiateGame<T_Game>(gameClass: GameClass<T_Game>, config: InitiateGameConfig): HologyRuntime<T_Game>;
|
|
56
60
|
export declare abstract class GameInstance {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import e from"typedi";import{loadScene as t}from"../scene/bootstrap.js";import{ActorFactory as s}from"./actors/factory.js";import{World as n}from"./services/world.js";import{SceneMaterializer as
|
|
1
|
+
import e from"typedi";import{loadScene as t}from"../scene/bootstrap.js";import{ActorFactory as s}from"./actors/factory.js";import{World as n}from"./services/world.js";import{SceneMaterializer as o}from"../scene/materializer.js";import{ViewController as r}from"./services/render.js";import{RenderingView as i}from"../rendering.js";import{PhysicsSystem as a}from"./services/physics/physics-system.js";import{MeshComponent as c}from"./actors/builtin/components/mesh-component.js";import{builtInComponents as d}from"./actors/builtin/components/index.js";import{activeContainerInstance as m}from"./actors/internal/container-map.js";import{InputService as l}from"./input/index.js";import{RuntimeAssetsService as p}from"../scene/runtime-asset-service.js";import{AssetResourceLoader as h}from"../scene/asset-resource-loader.js";import{AssetLoader as u}from"./services/asset-loader.js";import{polyfillClient as f}from"./polyfill.js";import{Subject as g}from"rxjs";import{PointerEvents as w}from"./services/pointer-events.js";import{RuntimeBundledBackendService as v}from"../scene/runtime-bundled-backend-service.js";import{Scene as b}from"three";import{ShaderProvider as j}from"./services/shader-provider.js";import{SceneDataService as S}from"../scene/scene-data-service.js";import{NetMode as y}from"./net/net-session.js";import{AssetsProvider as x}from"../scene/assets-provider.js";export function initiateGame(g,I){if(f(),0!=I.element.childNodes.length)return console.error("Can not initialize the game with a non-empty html element"),null;e.has(r);const E=e.of("default"),R=new HologyRuntime(E),G=new s(E,{inEditor:!1});var P;G.classes=I.actors,e.set(s,G),P=I.element,Object.assign(P.style,{position:"absolute",top:"0",left:"0",width:"100%",height:"100%",overflow:"hidden"});const D=new i(I.element,{enableXR:!0===I.xr?.enabled,maxPixelRatio:I.rendering?.maxPixelRatio,resolutionScale:I.rendering?.resolutionScale,dynamicResolution:I.rendering?.dynamicResolution,upscaling:I.rendering?.upscaling,msaa:I.rendering?.msaa,fpsCap:I.rendering?.fpsCap,depthPrepass:{enabled:!0===I.rendering?.depthPrepass?.enabled},bloom:{enabled:!1!==I?.rendering?.bloom?.enabled},reflection:{enabled:!1!==I?.rendering?.reflection?.enabled},shadows:{cascadeUpdateIntervals:[22,40,60,120]}});D.renderer.shadowMap.enabled=I.rendering?.shadows?.enabled??!0,D.renderer.shadowMap.autoUpdate=I.rendering?.shadows?.autoUpdate??!0,D.renderer.debug.checkShaderErrors=!1,e.set(i,D);const M=new r(D);e.set(r,M);const z=new v,A=new p(z),O=new h;O.setDataDir(I.dataDir),O.initKtx2(D.renderer);const C=Object.entries(I.shaders).map(([e,t])=>({name:e,type:t})),H=Object.entries(I.actors).map(([e,t])=>({name:e,type:t})),N={...d,...I.components??{}},T=Object.entries(N).map(([e,t])=>({name:e,type:t})),U=new j(C);e.set(j,U);const k=new u(O,A,C);e.set(x,A),e.set(h,O),e.set(u,k);const F=new b,W=new o(F,new S,A,O,D,C,H,G,T);W.inEditor=!1,W.netMode=I.multi?.session?.mode??y.none,e.set(o,W);const _=e.get(n);return e.set(n,_),_.materializer=W,(async()=>{const s=e.get(a);if(await s.start(),R.isShutdown)return;if(await z.preloadData(),R.isShutdown)return;if(_.scene=F,null!=I.multi?.session){const{NetService:e}=await import("./net/service/net-service.js"),t=E.get(e);t.session=I.multi.session,t.start(),R.shutdownStarted.subscribe(()=>t.stop())}const{scene:n,actors:o,materializer:r}=await t(D,I.sceneName,I.dataDir,I.shaders,I.actors,N,G,z,A,O,{detailTier:I.detailTier,nodeMode:I.multi?.session?.mode??y.none});_.scene=n,s.scene=_.scene;for(const e of F.children)_.scene.add(e);if(R.isShutdown)return void D.stop();e.import([c]);for(const e of o)_.addActor(e);s.addFromScene(n),await _.startSceneEventGraphs(r),console.log("Start compile shaders"),console.time("compile shaders"),await D.compileAsync(),console.timeEnd("compile shaders"),console.log("Finished compile shaders. Programs: ",D.renderer.info.programs?.length??0),console.log("Start init scene textures"),console.time("init scene textures"),D.initTextures(),console.timeEnd("init scene textures");const i=E.get(l);D.loop(e=>{i.update(e)}),R.status=5,R.shutdownStarted.subscribe(()=>{O.disposeAll()}),m.value=E,E.remove(g),E.set({id:g,type:g});const d=E.get(g);m.value=null,R.gameInstance=d,E.get(w).start(),d instanceof GameInstance&&await d.onStart(),R._resolver(!0)})(),R}export class GameInstance{onStart(){}onShutdown(){}}export function createHologyScene(){}export class HologyRuntime{constructor(e){this.containerInstance=e,this.status=0,this.isShutdown=!1,this.shutdownStarted=new g,this.ready=new Promise(e=>{this._resolver=e})}getWorld(){return this.containerInstance.get(n)}getService(e){return this.containerInstance.get(e)}shutdown(){this.isShutdown=!0;const e=this.shutdownStarted;e.next(),e.complete(),this.gameInstance instanceof GameInstance&&this.gameInstance.onShutdown(),this.containerInstance.get(l).stop();const t=this.containerInstance.get(i);t?.stop();const s=this.getWorld();s.stopSceneEventGraphs();const n=this.containerInstance.get(r);n.setMuted(!0),n.dispose();for(const e of[...s.actors])s.removeActor(e);this.containerInstance.get(a).stop(),this.containerInstance.get(o).dispose(),this.containerInstance.get(w).stop(),this.containerInstance.reset(),this.shutdownStarted.complete()}}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -11,20 +11,34 @@ export declare class AxisInput {
|
|
|
11
11
|
readonly setY: (value: number) => void;
|
|
12
12
|
}
|
|
13
13
|
type Callback = () => void;
|
|
14
|
+
export type ButtonInputMode = 'hold' | 'toggle';
|
|
14
15
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
16
|
+
* ButtonInput stores a boolean activation state from key/button press/release events.
|
|
17
|
+
*
|
|
18
|
+
* In hold mode, the input stays active while the key/button is down.
|
|
19
|
+
* In toggle mode, the input flips each time the key/button is released.
|
|
20
|
+
* Start/end callbacks are emitted after activated has changed.
|
|
20
21
|
*/
|
|
21
|
-
export declare class
|
|
22
|
+
export declare class ButtonInput {
|
|
23
|
+
mode: ButtonInputMode;
|
|
22
24
|
private readonly emitter;
|
|
23
25
|
activated: boolean;
|
|
26
|
+
constructor(mode?: ButtonInputMode, activated?: boolean);
|
|
27
|
+
setActivated(active: boolean): void;
|
|
24
28
|
readonly toggle: (active: boolean) => void;
|
|
25
29
|
onStart(cb: Callback): void;
|
|
26
30
|
onEnd(cb: Callback): void;
|
|
27
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* ActionInput is for activating state while holding down a key.
|
|
34
|
+
* Example use case:
|
|
35
|
+
* - Sprinting temporarily
|
|
36
|
+
* - Jump
|
|
37
|
+
* - Shoot
|
|
38
|
+
*/
|
|
39
|
+
export declare class ActionInput extends ButtonInput {
|
|
40
|
+
constructor(activated?: boolean);
|
|
41
|
+
}
|
|
28
42
|
/**
|
|
29
43
|
* ToggleInput will be activated after a keypress. It is used
|
|
30
44
|
* for state that should be activated or deactivated without continuously
|
|
@@ -34,21 +48,12 @@ export declare class ActionInput {
|
|
|
34
48
|
* A ToggleInput may be for something slower paced or for something that should
|
|
35
49
|
* persist longer.
|
|
36
50
|
*
|
|
37
|
-
*
|
|
51
|
+
* Example use case:
|
|
38
52
|
* - Switch between running to normal walking speed.
|
|
39
53
|
* - Turning on a flash light.
|
|
40
54
|
*/
|
|
41
|
-
export declare class ToggleInput {
|
|
42
|
-
private readonly emitter;
|
|
43
|
-
activated: boolean;
|
|
55
|
+
export declare class ToggleInput extends ButtonInput {
|
|
44
56
|
constructor(activated?: boolean);
|
|
45
|
-
/**
|
|
46
|
-
* When called with true, does nothing if already activated.
|
|
47
|
-
* When called with false, toggles the state and emits the appropriate event.
|
|
48
|
-
*/
|
|
49
|
-
readonly toggle: (active: boolean) => void;
|
|
50
|
-
onStart(cb: Callback): void;
|
|
51
|
-
onEnd(cb: Callback): void;
|
|
52
57
|
}
|
|
53
58
|
export declare class RotationInput {
|
|
54
59
|
readonly rotation: Euler;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{Euler as t,Vector2 as i}from"three";import{ArrayMap as s}from"../../utils/collections.js";import{clamp as
|
|
1
|
+
import{Euler as t,Vector2 as i}from"three";import{ArrayMap as s}from"../../utils/collections.js";import{clamp as o}from"../../utils/math.js";export class AxisInput{constructor(){this.vector=new i,this.togglePositiveY=t=>{this.vector.y=t?1:Math.min(this.vector.y,0)},this.toggleNegativeY=t=>{this.vector.y=t?-1:Math.max(this.vector.y,0)},this.togglePositiveX=t=>{this.vector.x=t?1:Math.min(this.vector.x,0)},this.toggleNegativeX=t=>{this.vector.x=t?-1:Math.max(this.vector.x,0)},this.setX=t=>{this.vector.x=t},this.setY=t=>{this.vector.y=t}}get horizontal(){return this.vector.x}get vertical(){return this.vector.y}}class e{constructor(){this.map=new s}emit(t){this.map.get(t).forEach(t=>t())}add(t,i){this.map.push(t,i)}}export class ButtonInput{constructor(t="hold",i=!1){this.mode=t,this.emitter=new e,this.activated=!1,this.toggle=t=>{if("toggle"!==this.mode)this.setActivated(t);else{if(t)return;this.setActivated(!this.activated)}},this.activated=i}setActivated(t){t!==this.activated&&(this.activated=t,this.activated?this.emitter.emit("start"):this.emitter.emit("end"))}onStart(t){this.emitter.add("start",t)}onEnd(t){this.emitter.add("end",t)}}export class ActionInput extends ButtonInput{constructor(t=!1){super("hold",t)}}export class ToggleInput extends ButtonInput{constructor(t=!1){super("toggle",t)}}const h=2*Math.PI;export class RotationInput{constructor(){this.rotation=new t,this.rotateX=t=>{this.rotation.x=(this.rotation.x+t)%h},this.rotateY=t=>{this.rotation.y=(this.rotation.y+t)%h},this.rotateZ=t=>{this.rotation.z=(this.rotation.z+t)%h}}}export class RestrictedRotationInput extends RotationInput{constructor(i=-1/0,s=1/0,e=-1/0,h=1/0,r=-1/0,a=1/0){super(),this.minX=i,this.maxX=s,this.minY=e,this.maxY=h,this.minZ=r,this.maxZ=a,this.rotation=new t,this.rotateX=t=>{this.rotation.x=o(this.rotation.x+t,this.minX,this.maxX)},this.rotateY=t=>{this.rotation.y=o(this.rotation.y+t,this.minY,this.maxY)},this.rotateZ=t=>{this.rotation.z=o(this.rotation.z+t,this.minZ,this.maxZ)}}}export class DecimalInput{constructor(t=0,i,s){this.min=i,this.max=s,this.increment=t=>{this.value=o(this.value+t,this.min,this.max)},this.set=t=>{this.value=t},this.value=t}}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { BehaviorSubject, Subject } from 'rxjs';
|
|
2
|
+
import { NetReceivedMessage, NetSession, NetMode } from '../net-session';
|
|
3
|
+
import { NetConnection } from '../net-connection';
|
|
4
|
+
export type BrowserNetSimulationOptions = {
|
|
5
|
+
/**
|
|
6
|
+
* Fixed one-way latency applied to outgoing messages from this session.
|
|
7
|
+
*/
|
|
8
|
+
latencyMs?: number;
|
|
9
|
+
/**
|
|
10
|
+
* Random +/- latency added on top of latencyMs.
|
|
11
|
+
*/
|
|
12
|
+
jitterMs?: number;
|
|
13
|
+
/**
|
|
14
|
+
* Drop chance for unreliable messages, from 0 to 1.
|
|
15
|
+
*/
|
|
16
|
+
packetLoss?: number;
|
|
17
|
+
/**
|
|
18
|
+
* Optional drop chance for reliable messages. Defaults to 0 so reliable
|
|
19
|
+
* traffic remains reliable unless a test deliberately breaks it.
|
|
20
|
+
*/
|
|
21
|
+
reliablePacketLoss?: number;
|
|
22
|
+
};
|
|
23
|
+
export type BrowserNetSessionOptions = BrowserNetSimulationOptions & {
|
|
24
|
+
/**
|
|
25
|
+
* How often this tab refreshes its membership entry. Set to 0 to disable.
|
|
26
|
+
*/
|
|
27
|
+
heartbeatIntervalMs?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Members without a recent heartbeat are removed from the local view.
|
|
30
|
+
*/
|
|
31
|
+
memberTimeoutMs?: number;
|
|
32
|
+
/**
|
|
33
|
+
* Prevents a paused consumer from growing the inbound queue forever.
|
|
34
|
+
*/
|
|
35
|
+
maxQueuedMessages?: number;
|
|
36
|
+
};
|
|
37
|
+
export declare class BrowserNetSession implements NetSession {
|
|
38
|
+
/** The id of the session */
|
|
39
|
+
private sessionId;
|
|
40
|
+
/** The ID used by this node. */
|
|
41
|
+
private localId;
|
|
42
|
+
/**
|
|
43
|
+
* A unique ID for this sessions
|
|
44
|
+
*/
|
|
45
|
+
id: string;
|
|
46
|
+
/**
|
|
47
|
+
* The network mode from this player's point of view.
|
|
48
|
+
*/
|
|
49
|
+
readonly mode: NetMode;
|
|
50
|
+
/**
|
|
51
|
+
* Convenience function to check if mode === NetworkRole.client
|
|
52
|
+
*/
|
|
53
|
+
get isClient(): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Convenience function to check if you are authoritative
|
|
56
|
+
*/
|
|
57
|
+
get isServer(): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Convenience function to check if mode === NetworkRole.dedicatedServer
|
|
60
|
+
*/
|
|
61
|
+
get isDedicatedServer(): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* The server holds connections to all other clients.
|
|
64
|
+
*/
|
|
65
|
+
get clients(): NetConnection[];
|
|
66
|
+
/**
|
|
67
|
+
* Clients hold a connection to the server
|
|
68
|
+
*/
|
|
69
|
+
get server(): NetConnection;
|
|
70
|
+
readonly playerLeft: Subject<NetConnection>;
|
|
71
|
+
readonly playerJoined: Subject<NetConnection>;
|
|
72
|
+
readonly receivedMessageCount: BehaviorSubject<number>;
|
|
73
|
+
constructor(
|
|
74
|
+
/** Initialize with a specific role */
|
|
75
|
+
mode: NetMode,
|
|
76
|
+
/** The id of the session */
|
|
77
|
+
sessionId: string,
|
|
78
|
+
/** The ID used by this node. */
|
|
79
|
+
localId: number, options?: BrowserNetSessionOptions);
|
|
80
|
+
/**
|
|
81
|
+
* Adjust local network simulation at runtime. The settings only affect
|
|
82
|
+
* messages sent by this BrowserNetSession instance.
|
|
83
|
+
*/
|
|
84
|
+
configureNetworkSimulation(options: BrowserNetSimulationOptions): void;
|
|
85
|
+
/**
|
|
86
|
+
* Attempt to reconnect back to a session.
|
|
87
|
+
*/
|
|
88
|
+
reconnect(): void;
|
|
89
|
+
/**
|
|
90
|
+
* Leave the session and disonnect from other clients/server
|
|
91
|
+
*/
|
|
92
|
+
disconnect(): void;
|
|
93
|
+
sendMessage(receiver: NetConnection, reliable: boolean, buffer: ArrayBufferLike): void;
|
|
94
|
+
/**
|
|
95
|
+
* Use this method to check if there is any messages to read.
|
|
96
|
+
* Returns the number of messages available.
|
|
97
|
+
*/
|
|
98
|
+
hasMessage(): number;
|
|
99
|
+
/**
|
|
100
|
+
* Consumes a received message and removes it
|
|
101
|
+
*/
|
|
102
|
+
readMessage(): NetReceivedMessage | null;
|
|
103
|
+
connect(): void;
|
|
104
|
+
private readonly storageKey;
|
|
105
|
+
private readonly channelName;
|
|
106
|
+
private readonly heartbeatIntervalMs;
|
|
107
|
+
private readonly memberTimeoutMs;
|
|
108
|
+
private readonly maxQueuedMessages;
|
|
109
|
+
private simulation;
|
|
110
|
+
private connected;
|
|
111
|
+
private storage;
|
|
112
|
+
private channel;
|
|
113
|
+
private heartbeatTimer;
|
|
114
|
+
private receivedMessages;
|
|
115
|
+
private readonly knownMemberIds;
|
|
116
|
+
private readonly pendingDeliveryTimers;
|
|
117
|
+
private readonly reliableQueues;
|
|
118
|
+
private messageSequence;
|
|
119
|
+
private readonly onStorage;
|
|
120
|
+
private readonly onChannelMessage;
|
|
121
|
+
private readonly onBeforeUnload;
|
|
122
|
+
private readonly onUnload;
|
|
123
|
+
private sendOrSimulateMessage;
|
|
124
|
+
private deliverMessage;
|
|
125
|
+
private enqueueReceivedMessage;
|
|
126
|
+
private consumeMessage;
|
|
127
|
+
private connectionForMessage;
|
|
128
|
+
private enqueueReliableDelivery;
|
|
129
|
+
private scheduleReliableDelivery;
|
|
130
|
+
private flushReliableDelivery;
|
|
131
|
+
private shouldDropMessage;
|
|
132
|
+
private simulatedDelayMs;
|
|
133
|
+
private startHeartbeat;
|
|
134
|
+
private stopHeartbeat;
|
|
135
|
+
private cancelPendingDeliveries;
|
|
136
|
+
private mergeMember;
|
|
137
|
+
private removeMember;
|
|
138
|
+
private setMembers;
|
|
139
|
+
private currentMembers;
|
|
140
|
+
private activeMembers;
|
|
141
|
+
private createLocalMember;
|
|
142
|
+
private createMessageId;
|
|
143
|
+
private broadcast;
|
|
144
|
+
private getLocalStorage;
|
|
145
|
+
private writeLocalStorage;
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{BehaviorSubject as e,Subject as s}from"rxjs";import{NetMode as t}from"../net-session";const n=0,i=0,r=0,o=0;export class BrowserNetSession{get isClient(){return this.mode===t.client}get isServer(){return this.mode<t.client}get isDedicatedServer(){return this.mode===t.dedicatedServer}get clients(){return this.isServer?this.currentMembers().filter(e=>e.mode===t.client).map(e=>a(e)):[]}get server(){if(!this.isServer){const e=this.currentMembers().find(e=>e.mode<t.client);if(null!=e)return a(e)}return null}constructor(t,n,i,r={}){this.sessionId=n,this.localId=i,this.playerLeft=new s,this.playerJoined=new s,this.receivedMessageCount=new e(0),this.storageKey=`net_session_${this.sessionId}`,this.channelName=`net_session_${this.sessionId}`,this.connected=!1,this.storage=null,this.channel=null,this.heartbeatTimer=null,this.receivedMessages=[],this.knownMemberIds=new Set,this.pendingDeliveryTimers=new Set,this.reliableQueues=new Map,this.messageSequence=0,this.onStorage=e=>{if(e.key!==this.storageKey)return;const s=this.getLocalStorage();this.setMembers(s?.members??[],!0)},this.onChannelMessage=e=>{const s=e.data;if(function(e){if(null==e||"object"!=typeof e)return!1;const s=e.kind;return"join"===s||"leave"===s||"heartbeat"===s||"members-request"===s||"members"===s||"message"===s}(s)&&s.sessionId===this.sessionId&&s.sourceConnectionId!==this.localId)switch(s.kind){case"join":case"heartbeat":this.mergeMember(s.member,!0);break;case"leave":this.removeMember(s.member.connectionId,!0);break;case"members-request":this.broadcast({kind:"members",sessionId:this.sessionId,sourceConnectionId:this.localId,members:this.currentMembers()});break;case"members":this.setMembers([...this.currentMembers(),...s.members],!0);break;case"message":this.mergeMember(s.fromMember,!0),s.message.toConnectionId===this.localId&&this.enqueueReceivedMessage(s.message)}},this.onBeforeUnload=()=>{this.disconnect()},this.onUnload=()=>{this.disconnect()},this.mode=t,this.id=n,this.simulation=l(r),this.heartbeatIntervalMs=Math.max(0,r.heartbeatIntervalMs??2e3),this.memberTimeoutMs=Math.max(1,r.memberTimeoutMs??1e4),this.maxQueuedMessages=Math.max(1,r.maxQueuedMessages??1e4)}configureNetworkSimulation(e){this.simulation=l({...this.simulation,...e})}reconnect(){this.disconnect(),this.connect()}disconnect(){this.connected&&this.broadcast({kind:"leave",sessionId:this.sessionId,sourceConnectionId:this.localId,member:this.createLocalMember()}),this.stopHeartbeat(),this.cancelPendingDeliveries(),this.connected&&(window.removeEventListener("storage",this.onStorage),window.removeEventListener("beforeunload",this.onBeforeUnload),window.removeEventListener("unload",this.onUnload),this.channel?.removeEventListener("message",this.onChannelMessage),this.channel?.close(),this.channel=null,this.connected=!1);const e=this.getLocalStorage(),s=(e?.members??this.storage?.members??[]).filter(e=>e.connectionId!==this.localId);this.writeLocalStorage({members:this.activeMembers(s)}),this.storage=null,this.knownMemberIds.clear(),this.receivedMessages=[],this.receivedMessageCount.next(0)}sendMessage(e,s,t){const n=function(e){const s=(e.id,Number(e.id));return Number.isFinite(s)?s:null}(e);if(null==n)return void console.error(`BrowserNetSession can only send to numeric connection ids. Received ${e.id}`);const i={id:this.createMessageId(),fromConnectionId:this.localId,toConnectionId:n,reliable:s,sentAt:Date.now(),buffer:c(t)};this.sendOrSimulateMessage(i,s)}hasMessage(){return this.receivedMessages.length}readMessage(){const e=this.consumeMessage();if(null!=e){const s=this.connectionForMessage(e);return null==s?(console.error(`No connection found with id ${e.fromConnectionId}`),null):{from:s,buffer:e.buffer}}return null}connect(){if(this.connected)return;if("undefined"==typeof BroadcastChannel)throw new Error("BrowserNetSession requires BroadcastChannel support");this.channel=new BroadcastChannel(this.channelName),this.channel.addEventListener("message",this.onChannelMessage),window.addEventListener("storage",this.onStorage),window.addEventListener("beforeunload",this.onBeforeUnload),window.addEventListener("unload",this.onUnload),this.connected=!0;const e=this.getLocalStorage()??{members:[]},s=this.activeMembers([...e.members,this.createLocalMember()]);this.setMembers(s,!1),this.writeLocalStorage({members:s}),this.broadcast({kind:"join",sessionId:this.sessionId,sourceConnectionId:this.localId,member:this.createLocalMember()}),this.broadcast({kind:"members-request",sessionId:this.sessionId,sourceConnectionId:this.localId}),this.startHeartbeat()}sendOrSimulateMessage(e,s){if(this.shouldDropMessage(s))return;if(s)return void this.enqueueReliableDelivery(e);const t=this.simulatedDelayMs();if(t<=0)return void this.deliverMessage(e);const n=window.setTimeout(()=>{this.pendingDeliveryTimers.delete(n),this.deliverMessage(e)},t);this.pendingDeliveryTimers.add(n)}deliverMessage(e){e.toConnectionId!==this.localId?this.broadcast({kind:"message",sessionId:this.sessionId,sourceConnectionId:this.localId,fromMember:this.createLocalMember(),message:e}):this.enqueueReceivedMessage(e)}enqueueReceivedMessage(e){this.receivedMessages.length>=this.maxQueuedMessages&&this.receivedMessages.shift(),this.receivedMessages.push(e),this.receivedMessageCount.next(this.receivedMessages.length)}consumeMessage(){const e=this.receivedMessages.shift()??null;return this.receivedMessageCount.next(this.receivedMessages.length),e}connectionForMessage(e){const s=this.server;if(s?.id===e.fromConnectionId)return s;const t=this.clients.find(s=>s.id===e.fromConnectionId);if(null!=t)return t;const n=this.currentMembers().find(s=>s.connectionId===e.fromConnectionId);return null!=n?a(n):null}enqueueReliableDelivery(e){const s=this.simulatedDelayMs(),t=this.reliableQueues.get(e.toConnectionId);if((null==t||0===t.messages.length)&&s<=0)return void this.deliverMessage(e);const n=Date.now(),i=t??{messages:[],timer:null},r=i.messages[i.messages.length-1]?.deliveryAt??n,o=Math.max(n+s,r);i.messages.push({message:e,deliveryAt:o}),this.reliableQueues.set(e.toConnectionId,i),this.scheduleReliableDelivery(e.toConnectionId,i)}scheduleReliableDelivery(e,s){if(null!=s.timer||0===s.messages.length)return;const t=Math.max(0,s.messages[0].deliveryAt-Date.now()),n=window.setTimeout(()=>{this.pendingDeliveryTimers.delete(n),s.timer=null,this.flushReliableDelivery(e)},t);s.timer=n,this.pendingDeliveryTimers.add(n)}flushReliableDelivery(e){const s=this.reliableQueues.get(e);if(null==s)return;const t=Date.now();for(;s.messages.length>0&&s.messages[0].deliveryAt<=t+1;)this.deliverMessage(s.messages.shift().message);s.messages.length>0?this.scheduleReliableDelivery(e,s):this.reliableQueues.delete(e)}shouldDropMessage(e){const s=e?this.simulation.reliablePacketLoss:this.simulation.packetLoss;return s>0&&Math.random()<s}simulatedDelayMs(){const e=this.simulation.jitterMs>0?(2*Math.random()-1)*this.simulation.jitterMs:0;return Math.max(0,this.simulation.latencyMs+e)}startHeartbeat(){this.heartbeatIntervalMs<=0||null!=this.heartbeatTimer||(this.heartbeatTimer=window.setInterval(()=>{const e=this.activeMembers([...this.currentMembers(),this.createLocalMember()]);this.setMembers(e,!0),this.writeLocalStorage({members:e}),this.broadcast({kind:"heartbeat",sessionId:this.sessionId,sourceConnectionId:this.localId,member:this.createLocalMember()})},this.heartbeatIntervalMs))}stopHeartbeat(){null!=this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}cancelPendingDeliveries(){this.pendingDeliveryTimers.forEach(e=>clearTimeout(e)),this.pendingDeliveryTimers.clear(),this.reliableQueues.clear()}mergeMember(e,s){this.setMembers([...this.currentMembers(),e],s)}removeMember(e,s){this.setMembers(this.currentMembers().filter(s=>s.connectionId!==e),s)}setMembers(e,s){const t=this.storage?.members??[],n=this.activeMembers(this.connected?[...e,this.createLocalMember()]:e);if(s){const e=new Set(n.map(e=>e.connectionId));n.filter(e=>e.connectionId!==this.localId&&!this.knownMemberIds.has(e.connectionId)).forEach(e=>this.playerJoined.next(a(e))),this.knownMemberIds.forEach(s=>{if(s===this.localId||e.has(s))return;const n=t.find(e=>e.connectionId===s);null!=n&&this.playerLeft.next(a(n))})}this.storage={members:n},this.knownMemberIds.clear(),n.forEach(e=>this.knownMemberIds.add(e.connectionId))}currentMembers(){return this.activeMembers(this.storage?.members??this.getLocalStorage()?.members??[])}activeMembers(e){const s=Date.now();return function(e){const s=new Map;for(const t of e){if(!Number.isFinite(t.connectionId))continue;const e=s.get(t.connectionId);(null==e||(t.lastSeenAt??0)>=(e.lastSeenAt??0))&&s.set(t.connectionId,t)}return[...s.values()].sort((e,s)=>e.connectionId-s.connectionId)}(e).filter(e=>e.connectionId===this.localId||null!=e.lastSeenAt&&s-e.lastSeenAt<=this.memberTimeoutMs)}createLocalMember(){return{connectionId:this.localId,mode:this.mode,player:{id:this.localId.toString()},lastSeenAt:Date.now()}}createMessageId(){const e=window.crypto?.randomUUID;return"function"==typeof e?e.call(window.crypto):`${this.localId}-${Date.now()}-${this.messageSequence++}`}broadcast(e){this.channel?.postMessage(e)}getLocalStorage(){const e=localStorage.getItem(this.storageKey);if(null!=e)try{const s=JSON.parse(e);if(Array.isArray(s?.members))return{members:s.members}}catch(e){console.warn(`Failed to parse browser net session ${this.sessionId}`,e)}return null}writeLocalStorage(e){const s=this.activeMembers(e.members);0!==s.length?localStorage.setItem(this.storageKey,JSON.stringify({members:s})):localStorage.removeItem(this.storageKey)}}function a(e){return{id:e.connectionId,player:e.player}}function c(e){const s=new Uint8Array(e),t=new Uint8Array(s.byteLength);return t.set(s),t.buffer}function l(e){return{latencyMs:Math.max(0,e.latencyMs??n),jitterMs:Math.max(0,e.jitterMs??i),packetLoss:h(e.packetLoss??r),reliablePacketLoss:h(e.reliablePacketLoss??o)}}function h(e){return Math.min(1,Math.max(0,e))}/*
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
|
+
* See the LICENSE.md file for details.
|
|
4
|
+
*/
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from './service/rpc-decorator.js';
|
|
2
|
+
export * from './service/rpc.js';
|
|
3
|
+
export * from './service/net-service.js';
|
|
4
|
+
export * from './service/replication.js';
|
|
5
|
+
export * from './service/net-decorator.js';
|
|
6
|
+
export * from './service/net-actor-role.js';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export*from"./service/rpc-decorator.js";export*from"./service/rpc.js";export*from"./service/net-service.js";export*from"./service/replication.js";export*from"./service/net-decorator.js";export*from"./service/net-actor-role.js";/*
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
|
+
* See the LICENSE.md file for details.
|
|
4
|
+
*/
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Each participant in a networked game including clients, dedicated servers and listen servers,
|
|
3
|
+
* each are represented by a single connection.
|
|
4
|
+
*/
|
|
5
|
+
export interface NetConnection {
|
|
6
|
+
readonly id: string | bigint | number;
|
|
7
|
+
/**
|
|
8
|
+
* Player connected to this client.
|
|
9
|
+
* Not present for dedicated servers
|
|
10
|
+
*/
|
|
11
|
+
readonly player?: NetPlayerInfo;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Information that represents the player.
|
|
15
|
+
*/
|
|
16
|
+
export interface NetPlayerInfo {
|
|
17
|
+
/**
|
|
18
|
+
* An ID of a player. This may refer to an account id or some other persistent information.
|
|
19
|
+
* This can be used by the server to load data for this user.
|
|
20
|
+
* The NetSession implementation is responsible for authenticating users and providing
|
|
21
|
+
* the player ID.
|
|
22
|
+
*/
|
|
23
|
+
readonly id: string;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=net-connection.d.ts.map
|