vehicle-path2 1.0.6 → 1.0.7
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/react/hooks/useAnimation.d.ts +1 -0
- package/dist/react/hooks/useVehicleSimulation.d.ts +1 -0
- package/dist/react.cjs +1 -1
- package/dist/react.js +1 -1
- package/dist/useVehicleEvents-CCCiLoAw.cjs +3 -0
- package/dist/useVehicleEvents-DcNmJGRn.js +941 -0
- package/dist/vehicle-path.cjs +1 -1
- package/dist/vehicle-path.js +1 -1
- package/package.json +1 -1
- package/dist/useVehicleEvents-5-uvxZme.js +0 -931
- package/dist/useVehicleEvents-DngnyUej.cjs +0 -3
|
@@ -40,6 +40,7 @@ export declare function useAnimation({ vehicles, lines, vehicleQueues, getVehicl
|
|
|
40
40
|
prepare: () => boolean;
|
|
41
41
|
tick: (distance: number) => boolean;
|
|
42
42
|
reset: () => void;
|
|
43
|
+
resetVehicle: (vehicleId: string) => void;
|
|
43
44
|
continueVehicle: (vehicleId: string) => boolean;
|
|
44
45
|
isMoving: () => boolean;
|
|
45
46
|
isPrepared: boolean;
|
|
@@ -62,6 +62,7 @@ export interface UseVehicleSimulationResult {
|
|
|
62
62
|
prepare: () => boolean;
|
|
63
63
|
tick: (distance: number) => boolean;
|
|
64
64
|
reset: () => void;
|
|
65
|
+
resetVehicle: (vehicleId: string) => void;
|
|
65
66
|
continueVehicle: (vehicleId: string) => boolean;
|
|
66
67
|
isMoving: () => boolean;
|
|
67
68
|
loadFromDSL: (dsl: string) => SimulationResult;
|
package/dist/react.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./useVehicleEvents-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./useVehicleEvents-CCCiLoAw.cjs");exports.VehicleEventContext=e.VehicleEventContext;exports.VehicleEventProvider=e.VehicleEventProvider;exports.useAnimation=e.useAnimation;exports.useCreateVehicleEventEmitter=e.useCreateVehicleEventEmitter;exports.useInitialMovement=e.useInitialMovement;exports.useMovement=e.useMovementQueue;exports.useMovementQueue=e.useMovementQueue;exports.useMovementSequence=e.useMovementSequence;exports.useScene=e.useScene;exports.useSceneDefinition=e.useSceneDefinition;exports.useVehicleEvent=e.useVehicleEvent;exports.useVehicleEventEmitter=e.useVehicleEventEmitter;exports.useVehicleMovement=e.useAnimation;exports.useVehicleSimulation=e.useVehicleSimulation;exports.useVehicles=e.useVehicles;
|
package/dist/react.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { V as t, a as i, u as a, b as n, c as u, d as c, d as o, e as v, f as l, g as m, h, i as V, u as r, j as E, k as M } from "./useVehicleEvents-
|
|
1
|
+
import { V as t, a as i, u as a, b as n, c as u, d as c, d as o, e as v, f as l, g as m, h, i as V, u as r, j as E, k as M } from "./useVehicleEvents-DcNmJGRn.js";
|
|
2
2
|
export {
|
|
3
3
|
t as VehicleEventContext,
|
|
4
4
|
i as VehicleEventProvider,
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";const o=require("react"),R=require("./core.cjs"),A=require("./vehicle-helpers-82D2V4MI.cjs"),te=require("react/jsx-runtime");function G(s){return Array.isArray(s)?{x:s[0],y:s[1]}:s}function K(s){return{id:s.id,start:G(s.start),end:G(s.end)}}function U(s){const i=s.fromIsPercentage!==!1,x=s.toIsPercentage!==!1;return{fromLineId:s.from,toLineId:s.to,fromOffset:s.fromPosition,fromIsPercentage:s.fromPosition!==void 0?i:void 0,toOffset:s.toPosition,toIsPercentage:s.toPosition!==void 0?x:void 0}}function H(s){const i=s.position??0,x=s.isPercentage!==!1;return{vehicleId:s.id,lineId:s.lineId,offset:i,isPercentage:x}}function J(s){const i=s.isPercentage!==!1,x=s.targetPosition??1;return{vehicleId:s.vehicleId,targetLineId:s.targetLineId,targetOffset:x,isPercentage:i,awaitConfirmation:s.wait,payload:s.payload}}function se(s){const i=[],x=new Set;for(const r of s.lines)x.has(r.id)&&i.push(`Duplicate line ID: ${r.id}`),x.add(r.id);if(s.connections)for(const r of s.connections){x.has(r.from)||i.push(`Connection references non-existent line: ${r.from}`),x.has(r.to)||i.push(`Connection references non-existent line: ${r.to}`);const m=r.fromIsPercentage!==!1,t=r.toIsPercentage!==!1;!m&&r.fromPosition===void 0&&i.push("fromPosition is required when fromIsPercentage is false"),!t&&r.toPosition===void 0&&i.push("toPosition is required when toIsPercentage is false"),r.fromPosition!==void 0&&(m&&(r.fromPosition<0||r.fromPosition>1)?i.push(`Invalid fromPosition: ${r.fromPosition} (must be 0-1 for percentage)`):!m&&r.fromPosition<0&&i.push(`Invalid fromPosition: ${r.fromPosition} (must be >= 0 for absolute distance)`)),r.toPosition!==void 0&&(t&&(r.toPosition<0||r.toPosition>1)?i.push(`Invalid toPosition: ${r.toPosition} (must be 0-1 for percentage)`):!t&&r.toPosition<0&&i.push(`Invalid toPosition: ${r.toPosition} (must be >= 0 for absolute distance)`))}return{valid:i.length===0,errors:i}}function B(){const[s,i]=o.useState([]),[x,r]=o.useState([]),[m,t]=o.useState(null),f=o.useCallback((n,h)=>{i(n),r(h),t(null)},[]),C=o.useCallback(n=>{const h=se(n);if(!h.valid)return t(h.errors.join("; ")),{success:!1,errors:h.errors};const l=n.lines.map(K),g=n.connections?.map(U)||[];return f(l,g),{success:!0}},[f]),D=o.useCallback(n=>{if(s.some(l=>l.id===n.id)){const l=`Line with ID '${n.id}' already exists`;return t(l),{success:!1,error:l}}return i(l=>[...l,K(n)]),t(null),{success:!0}},[s]),q=o.useCallback((n,h)=>{if(s.findIndex(g=>g.id===n)===-1){const g=`Line with ID '${n}' not found`;return t(g),{success:!1,error:g}}return i(g=>g.map(S=>S.id!==n?S:{...S,start:h.start?G(h.start):S.start,end:h.end?G(h.end):S.end})),t(null),{success:!0}},[s]),w=o.useCallback(n=>{if(!s.some(l=>l.id===n)){const l=`Line with ID '${n}' not found`;return t(l),{success:!1,error:l}}return i(l=>l.filter(g=>g.id!==n)),r(l=>l.filter(g=>g.fromLineId!==n&&g.toLineId!==n)),t(null),{success:!0}},[s]),V=o.useCallback(n=>{const h=s.some(d=>d.id===n.from),l=s.some(d=>d.id===n.to);if(!h){const d=`Line '${n.from}' not found`;return t(d),{success:!1,error:d}}if(!l){const d=`Line '${n.to}' not found`;return t(d),{success:!1,error:d}}const g=n.fromIsPercentage!==!1,S=n.toIsPercentage!==!1;if(!g&&n.fromPosition===void 0){const d="fromPosition is required when fromIsPercentage is false";return t(d),{success:!1,error:d}}if(!S&&n.toPosition===void 0){const d="toPosition is required when toIsPercentage is false";return t(d),{success:!1,error:d}}if(x.some(d=>d.fromLineId===n.from&&d.toLineId===n.to)){const d=`Connection from '${n.from}' to '${n.to}' already exists`;return t(d),{success:!1,error:d}}return r(d=>[...d,U(n)]),t(null),{success:!0}},[s,x]),p=o.useCallback((n,h,l)=>{const g=x.findIndex(e=>e.fromLineId===n&&e.toLineId===h);if(g===-1){const e=`Connection from '${n}' to '${h}' not found`;return t(e),{success:!1,error:e}}const S=x[g],Q=l.fromIsPercentage??S.fromIsPercentage,d=l.toIsPercentage??S.toIsPercentage;let $;l.fromOffset!==void 0?$=l.fromOffset:S.fromOffset!==void 0&&($=S.fromOffset);let b;if(l.toOffset!==void 0?b=l.toOffset:S.toOffset!==void 0&&(b=S.toOffset),$!==void 0){if(Q!==!1&&($<0||$>1)){const e=`Invalid fromOffset: ${$} (must be 0-1 for percentage)`;return t(e),{success:!1,error:e}}if(Q===!1&&$<0){const e=`Invalid fromOffset: ${$} (must be >= 0 for absolute distance)`;return t(e),{success:!1,error:e}}}if(b!==void 0){if(d!==!1&&(b<0||b>1)){const e=`Invalid toOffset: ${b} (must be 0-1 for percentage)`;return t(e),{success:!1,error:e}}if(d===!1&&b<0){const e=`Invalid toOffset: ${b} (must be >= 0 for absolute distance)`;return t(e),{success:!1,error:e}}}if(Q===!1&&$===void 0){const e="fromOffset is required when fromIsPercentage is false";return t(e),{success:!1,error:e}}if(d===!1&&b===void 0){const e="toOffset is required when toIsPercentage is false";return t(e),{success:!1,error:e}}const j={from:n,to:h,fromPosition:$,fromIsPercentage:Q,toPosition:b,toIsPercentage:d};return r(e=>e.map((c,u)=>u===g?U(j):c)),t(null),{success:!0}},[x]),P=o.useCallback((n,h)=>{if(!x.some(g=>g.fromLineId===n&&g.toLineId===h)){const g=`Connection from '${n}' to '${h}' not found`;return t(g),{success:!1,error:g}}return r(g=>g.filter(S=>!(S.fromLineId===n&&S.toLineId===h))),t(null),{success:!0}},[x]),a=o.useCallback(()=>{i([]),r([]),t(null)},[]);return{lines:s,curves:x,setScene:C,addLine:D,updateLine:q,removeLine:w,addConnection:V,updateConnection:p,removeConnection:P,clear:a,error:m,_loadScene:f}}function W({lines:s,wheelbase:i}){const[x,r]=o.useState([]),[m,t]=o.useState(null),f=o.useRef([]),C=o.useCallback(p=>{f.current=p,r(p),t(null)},[]),D=o.useCallback(p=>{const P=Array.isArray(p)?p:[p],a=[];for(const g of P)f.current.some(Q=>Q.id===g.id)&&a.push(`Vehicle with ID '${g.id}' already exists`);if(a.length>0)return t(a.join("; ")),{success:!1,errors:a};const n=P.map(H),{vehicles:h,errors:l}=A.validateAndCreateVehicles(n,s,i);return l.length>0?(t(l.join("; ")),{success:!1,errors:l}):(f.current=[...f.current,...h],r(f.current),t(null),{success:!0})},[s,i]),q=o.useCallback((p,P)=>{const a=f.current.findIndex(b=>b.id===p);if(a===-1){const b=`Vehicle with ID '${p}' not found`;return t(b),{success:!1,error:b}}const n=f.current[a];if(n.state!=="idle"){const b=`Cannot update vehicle '${p}' while it is ${n.state}. Vehicle must be idle.`;return t(b),{success:!1,error:b}}const h=P.lineId??n.lineId;if(!s.find(b=>b.id===h)){const b=`Line '${h}' not found`;return t(b),{success:!1,error:b}}let g,S;P.lineId!==void 0&&P.position===void 0?(g=0,S=!0):P.position!==void 0?(g=P.position,S=P.isPercentage??!0):(g=n.offset,S=n.isPercentage);const Q={vehicleId:p,lineId:h,offset:g,isPercentage:S},{vehicles:d,errors:$}=A.validateAndCreateVehicles([Q],s,i);return $.length>0?(t($.join("; ")),{success:!1,error:$.join("; ")}):(f.current=f.current.map((b,j)=>j===a?d[0]:b),r(f.current),t(null),{success:!0})},[s,i]),w=o.useCallback(p=>{if(!f.current.some(a=>a.id===p)){const a=`Vehicle with ID '${p}' not found`;return t(a),{success:!1,error:a}}return f.current=f.current.filter(a=>a.id!==p),r(f.current),t(null),{success:!0}},[]),V=o.useCallback(()=>{f.current=[],r([]),t(null)},[]);return{vehicles:x,addVehicles:D,updateVehicle:q,removeVehicle:w,clear:V,error:m,_loadVehicles:C}}function X({vehicles:s,lines:i}){const[x,r]=o.useState(new Map),[m,t]=o.useState(null),f=o.useRef(new Map),C=o.useCallback(()=>f.current,[]),D=o.useCallback(V=>{f.current=V,r(V),t(null)},[]),q=o.useCallback((V,p)=>{if(!s.some(d=>d.id===V)){const d=`Vehicle '${V}' not found`;return t(d),{success:!1,error:d}}const a=i.find(d=>d.id===p.targetLineId);if(!a){const d=`Line '${p.targetLineId}' not found`;return t(d),{success:!1,error:d}}const n=p.isPercentage!==!1,h=R.distance(a.start,a.end);if(!n&&p.targetPosition===void 0){const d="targetPosition is required when isPercentage is false";return t(d),{success:!1,error:d}}const l=p.targetPosition??1;if(n){if(l<0||l>1){const d=`Invalid targetPosition: ${l} (must be 0-1 for percentage)`;return t(d),{success:!1,error:d}}}else{if(l<0){const d=`Invalid targetPosition: ${l} (must be >= 0 for absolute distance)`;return t(d),{success:!1,error:d}}if(l>h){const d=`Position ${l} exceeds line length ${h}`;return t(d),{success:!1,error:d}}}const g=J({vehicleId:V,...p}),S=new Map(f.current),Q=S.get(V)||[];return S.set(V,[...Q,g]),f.current=S,r(S),t(null),{success:!0}},[s,i]),w=o.useCallback(V=>{if(V!==void 0){if(!s.some(a=>a.id===V)){const a=`Vehicle '${V}' not found`;return t(a),{success:!1,error:a}}const P=new Map(f.current);P.delete(V),f.current=P,r(P)}else f.current=new Map,r(new Map);return t(null),{success:!0}},[s]);return{vehicleQueues:x,getVehicleQueues:C,queueMovement:q,clearQueue:w,error:m,_loadQueues:D}}function Z({vehicles:s,lines:i,vehicleQueues:x,getVehicleQueues:r,wheelbase:m,tangentMode:t,curves:f,eventEmitter:C}){const[D,q]=o.useState([]),w=o.useRef([]),V=o.useCallback(e=>{typeof e=="function"?q(c=>{const u=e(c);return w.current=u,u}):(w.current=e,q(e))},[]),p=o.useCallback(()=>w.current,[]),P=o.useMemo(()=>({wheelbase:m,tangentMode:t}),[m,t]),a=o.useMemo(()=>new Map(i.map(e=>[e.id,e])),[i]),n=o.useRef(new Map);o.useEffect(()=>{const{movingVehicles:e,stateMap:c}=R.initializeAllVehicles(s,a);n.current=c;const u=setTimeout(()=>{V(e)},0);return()=>clearTimeout(u)},[s,a]);const h=o.useRef(null);o.useEffect(()=>{i.length>0&&(h.current=R.buildGraph(i,f,P))},[i,f,P]);const l=o.useRef(0),g=o.useRef(!1),S=o.useCallback(e=>{if(!g.current)return!1;let c=!1;for(const[,M]of n.current)if(M.vehicle.state==="moving"){c=!0;break}if(!c)return!1;const u=[];for(const[M,I]of n.current){if(I.vehicle.state!=="moving"||!I.execution)continue;const v=I.execution;let E;if(v.front.currentSegmentIndex<v.path.segments.length){const k=v.path.segments[v.front.currentSegmentIndex];if(k.type==="line"){const L=a.get(k.lineId);L&&(E=Math.sqrt(Math.pow(L.end.x-L.start.x,2)+Math.pow(L.end.y-L.start.y,2)))}}const T=R.updateAxlePosition(I.vehicle.rear,v.rear,v.path,e,a,v.curveDataMap),y=R.updateAxlePosition(I.vehicle.front,v.front,v.path,e,a,v.curveDataMap,E);if(I.vehicle={...I.vehicle,rear:T.axleState,front:y.axleState},I.execution.rear=T.execution,I.execution.front=y.execution,T.completed){const k={linesMap:a,config:P,vehicleQueues:x,curves:f,graphRef:h,prepareCommandPath:R.prepareCommandPath,onCommandComplete:F=>u.push({type:"commandComplete",data:F}),onCommandStart:F=>u.push({type:"commandStart",data:F})},L=R.handleArrival(I,k);I.vehicle=L.vehicle,L.newExecution!==void 0&&(I.execution=L.newExecution),L.vehicle.state!=="moving"&&u.push({type:"stateChange",data:{vehicleId:M,from:"moving",to:L.vehicle.state}});const O=L.vehicle.rear.position,_=L.vehicle.front.position;u.push({type:"positionUpdate",data:{vehicleId:M,rear:O,front:_,center:{x:(O.x+_.x)/2,y:(O.y+_.y)/2},angle:Math.atan2(_.y-O.y,_.x-O.x)}})}}if(V(M=>M.map(I=>{const v=n.current.get(I.id);return v?v.vehicle:I})),C&&u.length>0){const M=l.current;setTimeout(()=>{l.current===M&&u.forEach(({type:I,data:v})=>{C.emit(I,v)})},0)}for(const[,M]of n.current)if(M.vehicle.state==="moving")return!0;return g.current=!1,!1},[a,f,P,x,C]),Q=o.useCallback(()=>{const e=h.current;if(!e)return!1;const c=r?r():x,u=[];let M=!1;for(const[I,v]of n.current){const E=v.vehicle;if(E.state==="moving")continue;const T=c.get(I);if(!T||T.length===0)continue;const y=T[0],k={graph:e,linesMap:a,curves:f,config:P},L=R.prepareCommandPath(E,y,k);if(!L){console.warn(`No path found for vehicle ${I}`);continue}const O=R.calculateFrontAxlePosition(L.path,0,0,m);n.current.set(I,{...v,execution:{path:L.path,curveDataMap:L.curveDataMap,currentCommandIndex:0,rear:{currentSegmentIndex:0,segmentDistance:0},front:O?{currentSegmentIndex:O.segmentIndex,segmentDistance:O.segmentDistance}:{currentSegmentIndex:0,segmentDistance:0}},vehicle:{...E,state:"moving"}}),M=!0,u.push({id:I,fromState:E.state,command:y,startPosition:{lineId:E.rear.lineId,absoluteOffset:E.rear.absoluteOffset,position:E.rear.position}})}if(!M)return!1;if(g.current=!0,V(I=>I.map(v=>{const E=n.current.get(v.id);return E?E.vehicle:v})),C&&u.length>0){const I=l.current;setTimeout(()=>{l.current===I&&u.forEach(({id:v,fromState:E,command:T,startPosition:y})=>{C.emit("commandStart",{vehicleId:v,command:T,commandIndex:0,startPosition:y}),C.emit("stateChange",{vehicleId:v,from:E,to:"moving"})})},0)}return!0},[a,f,x,r,P,m,C]),d=o.useCallback(()=>{l.current++,g.current=!1;const{movingVehicles:e,stateMap:c}=R.initializeAllVehicles(s,a);n.current=c,V(e)},[s,a]),$=o.useCallback(e=>{const c=s.find(v=>v.id===e);if(!c||!a.get(c.lineId))return;const M=R.initializeMovingVehicle(c),I=R.createInitialMovementState(M);n.current.set(e,I),V(v=>v.map(E=>E.id===e?M:E))},[s,a]),b=o.useCallback(e=>{const c=n.current.get(e);if(!c||c.vehicle.state!=="waiting")return!1;const u=x.get(e),M=c.execution;if(!M)return!1;const I=M.currentCommandIndex+1;if(u&&I<u.length){const v=h.current;if(v){const E=u[I],T={graph:v,linesMap:a,curves:f,config:P},y=R.prepareCommandPath(c.vehicle,E,T);if(y){const k=R.calculateFrontAxlePosition(y.path,0,0,m);if(c.execution={path:y.path,curveDataMap:y.curveDataMap,currentCommandIndex:I,rear:{currentSegmentIndex:0,segmentDistance:0},front:k?{currentSegmentIndex:k.segmentIndex,segmentDistance:k.segmentDistance}:{currentSegmentIndex:0,segmentDistance:0}},c.vehicle={...c.vehicle,state:"moving"},V(L=>L.map(O=>O.id===e?c.vehicle:O)),C){const L=l.current;setTimeout(()=>{l.current===L&&C.emit("stateChange",{vehicleId:e,from:"waiting",to:"moving"})},0)}return!0}}}if(c.vehicle={...c.vehicle,state:"idle"},c.execution=null,V(v=>v.map(E=>E.id===e?c.vehicle:E)),C){const v=l.current;setTimeout(()=>{l.current===v&&C.emit("stateChange",{vehicleId:e,from:"waiting",to:"idle"})},0)}return!0},[x,a,f,P,m,C]),j=o.useCallback(()=>{for(const[,e]of n.current)if(e.vehicle.state==="moving")return!0;return!1},[]);return{movingVehicles:D,getMovingVehicles:p,prepare:Q,tick:S,reset:d,resetVehicle:$,continueVehicle:b,isMoving:j,isPrepared:g.current}}function re({wheelbase:s,tangentMode:i="proportional-40",eventEmitter:x}){const r=B(),m=W({lines:r.lines,wheelbase:s}),t=X({vehicles:m.vehicles,lines:r.lines,curves:r.curves}),f=Z({vehicles:m.vehicles,lines:r.lines,vehicleQueues:t.vehicleQueues,getVehicleQueues:t.getVehicleQueues,wheelbase:s,tangentMode:i,curves:r.curves,eventEmitter:x}),C=o.useCallback(e=>m.vehicles.filter(c=>c.lineId===e||c.rear.lineId===e),[m.vehicles]),D=o.useCallback(e=>C(e).length>0,[C]),q=o.useCallback(e=>{const c=r.addLine(e);return c.success?{success:!0}:{success:!1,error:c.error}},[r]),w=o.useCallback((e,c)=>{const u=r.updateLine(e,c);return u.success?{success:!0}:{success:!1,error:u.error}},[r]),V=o.useCallback(e=>{const c=[],u=C(e);u.length>0&&(c.push({type:"vehicle_on_removed_line",message:`${u.length} vehicle(s) are on line '${e}'`,details:{lineId:e,vehicleIds:u.map(v=>v.id)}}),u.forEach(v=>{m.removeVehicle(v.id),t.clearQueue(v.id)}));const M=r.curves.filter(v=>v.fromLineId===e||v.toLineId===e);M.length>0&&c.push({type:"orphaned_connection",message:`${M.length} connection(s) will be removed`,details:{lineId:e,connectionCount:M.length}});const I=r.removeLine(e);return I.success?{success:!0,warnings:c.length>0?c:void 0}:{success:!1,error:I.error}},[r,C,m,t]),p=o.useCallback(()=>{r.clear(),m.clear(),t.clearQueue()},[r,m,t]),P=o.useCallback((e,c,u)=>{const M=r.addConnection({from:e,to:c,fromPosition:u?.fromOffset,fromIsPercentage:u?.fromIsPercentage,toPosition:u?.toOffset,toIsPercentage:u?.toIsPercentage});return M.success?{success:!0}:{success:!1,error:M.error}},[r]),a=o.useCallback((e,c,u)=>{const M=r.updateConnection(e,c,u);return M.success?{success:!0}:{success:!1,error:M.error}},[r]),n=o.useCallback((e,c)=>{const u=r.removeConnection(e,c);return u.success?{success:!0}:{success:!1,error:u.error}},[r]),h=o.useCallback(e=>{const c=m.addVehicles(e);return c.success?{success:!0}:{success:!1,error:c.errors?.join("; ")}},[m]),l=o.useCallback((e,c)=>{const u=m.updateVehicle(e,c);return u.success?{success:!0}:{success:!1,error:u.error}},[m]),g=o.useCallback(e=>{const c=[],u=t.vehicleQueues.get(e);u&&u.length>0&&(c.push({type:"movement_queue_cleared",message:`${u.length} queued movement(s) will be cleared for vehicle '${e}'`,details:{vehicleId:e}}),t.clearQueue(e));const M=m.removeVehicle(e);return M.success?{success:!0,warnings:c.length>0?c:void 0}:{success:!1,error:M.error}},[m,t]),S=o.useCallback(()=>{m.clear(),t.clearQueue()},[m,t]),Q=o.useCallback(e=>{const c={targetLineId:e.lineId,targetPosition:e.position??1,isPercentage:e.isPercentage,wait:e.wait,payload:e.payload},u=t.queueMovement(e.id,c);return u.success?{success:!0}:{success:!1,error:u.error}},[t]),d=o.useCallback(e=>{const c=t.clearQueue(e);return c.success?{success:!0}:{success:!1,error:c.error}},[t]),$=o.useCallback(e=>{const c=[],u=[],{scene:M,vehicles:I,movements:v}=A.parseAllDSL(e);M.errors.length>0&&u.push(...M.errors),I.errors.length>0&&u.push(...I.errors),v.errors.length>0&&u.push(...v.errors);const E=M.data.lines.map(K),T=(M.data.connections||[]).map(U),y=I.data.map(H),{vehicles:k,errors:L}=A.validateAndCreateVehicles(y,E,s);L.length>0&&u.push(...L);const O=new Map;for(const _ of v.data){const F=O.get(_.vehicleId)||[];F.push(J(_)),O.set(_.vehicleId,F)}return r._loadScene(E,T),m._loadVehicles(k),t._loadQueues(O),u.length>0&&c.push({type:"dsl_parse_error",message:`DSL loading had ${u.length} error(s)`,details:{errors:u}}),{success:!0,warnings:c.length>0?c:void 0}},[r,m,t,s]),b=o.useCallback(e=>{const c=[],u=[],M=e.lines.map(K),I=(e.connections||[]).map(U),v=(e.vehicles||[]).map(H),{vehicles:E,errors:T}=A.validateAndCreateVehicles(v,M,s);T.length>0&&u.push(...T);const y=new Map;for(const k of e.movements||[]){const L=y.get(k.vehicleId)||[];L.push(J({vehicleId:k.vehicleId,targetLineId:k.targetLineId,targetPosition:k.targetPosition,isPercentage:k.isPercentage,wait:k.wait,payload:k.payload})),y.set(k.vehicleId,L)}return r._loadScene(M,I),m._loadVehicles(E),t._loadQueues(y),u.length>0&&c.push({type:"dsl_parse_error",message:`JSON loading had ${u.length} error(s)`,details:{errors:u}}),{success:!0,warnings:c.length>0?c:void 0}},[r,m,t,s]),j=o.useMemo(()=>r.error||m.error||t.error,[r.error,m.error,t.error]);return{lines:r.lines,curves:r.curves,vehicles:m.vehicles,movingVehicles:f.movingVehicles,getMovingVehicles:f.getMovingVehicles,vehicleQueues:t.vehicleQueues,error:j,addLine:q,updateLine:w,removeLine:V,clearScene:p,connect:P,updateConnection:a,disconnect:n,addVehicles:h,updateVehicle:l,removeVehicle:g,clearVehicles:S,goto:Q,clearQueue:d,prepare:f.prepare,tick:f.tick,reset:f.reset,resetVehicle:f.resetVehicle,continueVehicle:f.continueVehicle,isMoving:f.isMoving,loadFromDSL:$,loadFromJSON:b,getVehiclesOnLine:C,hasVehiclesOnLine:D}}function z(s){return s.map(i=>({id:i.id,start:i.start,end:i.end}))}function N(s){return s.map(i=>({from:i.fromLineId,to:i.toLineId,fromPosition:i.fromOffset,fromIsPercentage:i.fromIsPercentage,toPosition:i.toOffset,toIsPercentage:i.toIsPercentage}))}function ne(){const[s,i]=o.useState(""),[x,r]=o.useState(null),{lines:m,curves:t,setScene:f}=B(),C=o.useRef(!1),D=o.useRef("");o.useEffect(()=>{D.current=s},[s]),o.useEffect(()=>{if(C.current)return;const p={lines:z(m),connections:t.length>0?N(t):void 0},P=A.generateSceneDSL(p);P!==D.current&&(C.current=!0,i(P),setTimeout(()=>{C.current=!1},50))},[m,t]);const q=o.useCallback(p=>{C.current=!0,i(p);try{const{data:P,errors:a}=A.parseSceneDSL(p);a.length>0&&r(a.join("; "));const n=f(P);!n.success&&n.errors?r(h=>h?`${h}; ${n.errors.join("; ")}`:n.errors.join("; ")):a.length===0&&r(null)}catch(P){r(P instanceof Error?P.message:"Invalid scene definition")}setTimeout(()=>{C.current=!1},50)},[f]),w=o.useCallback(p=>{const P=typeof p=="function"?p(m):p,a=N(t);f({lines:z(P),connections:a.length>0?a:void 0});const n={lines:z(P),connections:a.length>0?a:void 0},h=A.generateSceneDSL(n);C.current=!0,i(h),setTimeout(()=>{C.current=!1},50)},[m,t,f]),V=o.useCallback(p=>{const P=typeof p=="function"?p(t):p,a=N(P);f({lines:z(m),connections:a.length>0?a:void 0});const n={lines:z(m),connections:a.length>0?a:void 0},h=A.generateSceneDSL(n);C.current=!0,i(h),setTimeout(()=>{C.current=!1},50)},[m,t,f]);return{lines:m,curves:t,sceneDefinitionText:s,sceneError:x,isDebouncing:!1,debounceKey:0,setLines:w,setCurves:V,setSceneDefinitionText:q}}function oe({lines:s,wheelbase:i}){const[x,r]=o.useState(""),[m,t]=o.useState(null),{vehicles:f,addVehicles:C,clear:D,error:q}=W({lines:s,wheelbase:i}),w=o.useRef(!1),V=o.useCallback(p=>{w.current=!0,r(p);try{const{data:P,errors:a}=A.parseVehiclesDSL(p),n=[...a];D();for(const h of P){const l=C(h);!l.success&&l.errors&&n.push(...l.errors)}n.length>0?t(n.join(`
|
|
2
|
+
`)):t(null)}catch(P){t(P instanceof Error?P.message:"Invalid initial movement")}setTimeout(()=>{w.current=!1},50)},[C,D]);return{vehicles:f,initialMovementText:x,movementError:m||q,isDebouncing:!1,debounceKey:0,setInitialMovementText:V}}function ce({lines:s,vehicles:i}){const[x,r]=o.useState(""),[m,t]=o.useState([]),[f,C]=o.useState(null),{vehicleQueues:D,queueMovement:q,clearQueue:w,error:V}=X({vehicles:i,lines:s}),p=o.useRef(!1),P=o.useCallback(a=>{p.current=!0,r(a);try{const{data:n,errors:h}=A.parseMovementDSL(a),l=[...h];w();for(const g of n){const S=q(g.vehicleId,{targetLineId:g.targetLineId,targetPosition:g.targetPosition,isPercentage:g.isPercentage,wait:g.wait,payload:g.payload});!S.success&&S.error&&l.push(S.error)}t(n),l.length>0?C(l.join(`
|
|
3
|
+
`)):C(null)}catch(n){C(n instanceof Error?n.message:"Invalid movement sequence"),t([])}setTimeout(()=>{p.current=!1},50)},[q,w]);return{movementSequenceText:x,gotoCommands:m,vehicleQueues:D,sequenceError:f||V,isDebouncing:!1,debounceKey:0,setMovementSequenceText:P}}const Y=o.createContext(null);function ee(){const s=o.useContext(Y);if(!s)throw new Error("useVehicleEventEmitter must be used within a VehicleEventProvider");return s}function ie(){return o.useMemo(()=>new A.VehicleEventEmitter,[])}function ae(s,i,x=[]){const r=ee();o.useEffect(()=>r.on(s,i),[r,s,...x])}function ue({children:s}){const i=o.useMemo(()=>new A.VehicleEventEmitter,[]);return te.jsx(Y.Provider,{value:i,children:s})}exports.VehicleEventContext=Y;exports.VehicleEventProvider=ue;exports.useAnimation=Z;exports.useCreateVehicleEventEmitter=ie;exports.useInitialMovement=oe;exports.useMovementQueue=X;exports.useMovementSequence=ce;exports.useScene=B;exports.useSceneDefinition=ne;exports.useVehicleEvent=ae;exports.useVehicleEventEmitter=ee;exports.useVehicleSimulation=re;exports.useVehicles=W;
|