vehicle-path2 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/dist/core.cjs +1 -1
- package/dist/core.js +7 -6
- package/dist/react/hooks/useAnimation.d.ts +3 -1
- package/dist/react/hooks/useMovementQueue.d.ts +2 -0
- package/dist/react.cjs +1 -1
- package/dist/react.js +1 -1
- package/dist/useVehicleEvents-GQ7zeGg6.cjs +3 -0
- package/dist/useVehicleEvents-Lf_yySwI.js +924 -0
- package/dist/utils/type-converters.d.ts +3 -0
- package/dist/utils.cjs +1 -1
- package/dist/utils.js +1 -1
- package/dist/{vehicle-helpers-DIcksrtO.cjs → vehicle-helpers-82D2V4MI.cjs} +1 -1
- package/dist/{vehicle-helpers-_72KxCqO.js → vehicle-helpers-BXX3GPzk.js} +3 -3
- package/dist/vehicle-path.cjs +1 -1
- package/dist/vehicle-path.js +2 -2
- package/package.json +1 -1
- package/dist/useVehicleEvents-B2JQFNjc.js +0 -923
- package/dist/useVehicleEvents-CBymulau.cjs +0 -3
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
"use strict";const o=require("react"),q=require("./core.cjs"),O=require("./vehicle-helpers-DIcksrtO.cjs"),te=require("react/jsx-runtime");function F(s){return Array.isArray(s)?{x:s[0],y:s[1]}:s}function z(s){return{id:s.id,start:F(s.start),end:F(s.end)}}function j(s){const c=s.fromIsPercentage!==!1,I=s.toIsPercentage!==!1;return{fromLineId:s.from,toLineId:s.to,fromOffset:s.fromPosition!==void 0?c?s.fromPosition*100:s.fromPosition:void 0,fromIsPercentage:s.fromPosition!==void 0?c:void 0,toOffset:s.toPosition!==void 0?I?s.toPosition*100:s.toPosition:void 0,toIsPercentage:s.toPosition!==void 0?I:void 0}}function N(s){const c=s.position??0,I=s.isPercentage!==!1;return{vehicleId:s.id,lineId:s.lineId,offset:I?c*100:c,isPercentage:I}}function H(s){const c=s.isPercentage!==!1,I=s.targetPosition??1;return{vehicleId:s.vehicleId,targetLineId:s.targetLineId,targetOffset:c?I*100:I,isPercentage:c,awaitConfirmation:s.wait,payload:s.payload}}function se(s){const c=[],I=new Set;for(const r of s.lines)I.has(r.id)&&c.push(`Duplicate line ID: ${r.id}`),I.add(r.id);if(s.connections)for(const r of s.connections){I.has(r.from)||c.push(`Connection references non-existent line: ${r.from}`),I.has(r.to)||c.push(`Connection references non-existent line: ${r.to}`);const m=r.fromIsPercentage!==!1,t=r.toIsPercentage!==!1;!m&&r.fromPosition===void 0&&c.push("fromPosition is required when fromIsPercentage is false"),!t&&r.toPosition===void 0&&c.push("toPosition is required when toIsPercentage is false"),r.fromPosition!==void 0&&(m&&(r.fromPosition<0||r.fromPosition>1)?c.push(`Invalid fromPosition: ${r.fromPosition} (must be 0-1 for percentage)`):!m&&r.fromPosition<0&&c.push(`Invalid fromPosition: ${r.fromPosition} (must be >= 0 for absolute distance)`)),r.toPosition!==void 0&&(t&&(r.toPosition<0||r.toPosition>1)?c.push(`Invalid toPosition: ${r.toPosition} (must be 0-1 for percentage)`):!t&&r.toPosition<0&&c.push(`Invalid toPosition: ${r.toPosition} (must be >= 0 for absolute distance)`))}return{valid:c.length===0,errors:c}}function J(){const[s,c]=o.useState([]),[I,r]=o.useState([]),[m,t]=o.useState(null),f=o.useCallback((n,P)=>{c(n),r(P),t(null)},[]),w=o.useCallback(n=>{const P=se(n);if(!P.valid)return t(P.errors.join("; ")),{success:!1,errors:P.errors};const i=n.lines.map(z),d=n.connections?.map(j)||[];return f(i,d),{success:!0}},[f]),$=o.useCallback(n=>{if(s.some(i=>i.id===n.id)){const i=`Line with ID '${n.id}' already exists`;return t(i),{success:!1,error:i}}return c(i=>[...i,z(n)]),t(null),{success:!0}},[s]),b=o.useCallback((n,P)=>{if(s.findIndex(d=>d.id===n)===-1){const d=`Line with ID '${n}' not found`;return t(d),{success:!1,error:d}}return c(d=>d.map(C=>C.id!==n?C:{...C,start:P.start?F(P.start):C.start,end:P.end?F(P.end):C.end})),t(null),{success:!0}},[s]),S=o.useCallback(n=>{if(!s.some(i=>i.id===n)){const i=`Line with ID '${n}' not found`;return t(i),{success:!1,error:i}}return c(i=>i.filter(d=>d.id!==n)),r(i=>i.filter(d=>d.fromLineId!==n&&d.toLineId!==n)),t(null),{success:!0}},[s]),L=o.useCallback(n=>{const P=s.some(a=>a.id===n.from),i=s.some(a=>a.id===n.to);if(!P){const a=`Line '${n.from}' not found`;return t(a),{success:!1,error:a}}if(!i){const a=`Line '${n.to}' not found`;return t(a),{success:!1,error:a}}const d=n.fromIsPercentage!==!1,C=n.toIsPercentage!==!1;if(!d&&n.fromPosition===void 0){const a="fromPosition is required when fromIsPercentage is false";return t(a),{success:!1,error:a}}if(!C&&n.toPosition===void 0){const a="toPosition is required when toIsPercentage is false";return t(a),{success:!1,error:a}}if(I.some(a=>a.fromLineId===n.from&&a.toLineId===n.to)){const a=`Connection from '${n.from}' to '${n.to}' already exists`;return t(a),{success:!1,error:a}}return r(a=>[...a,j(n)]),t(null),{success:!0}},[s,I]),g=o.useCallback((n,P,i)=>{const d=I.findIndex(e=>e.fromLineId===n&&e.toLineId===P);if(d===-1){const e=`Connection from '${n}' to '${P}' not found`;return t(e),{success:!1,error:e}}const C=I[d],V=i.fromIsPercentage??C.fromIsPercentage,a=i.toIsPercentage??C.toIsPercentage;let E;i.fromOffset!==void 0?E=i.fromOffset:C.fromOffset!==void 0&&(E=C.fromIsPercentage!==!1?C.fromOffset/100:C.fromOffset);let h;if(i.toOffset!==void 0?h=i.toOffset:C.toOffset!==void 0&&(h=C.toIsPercentage!==!1?C.toOffset/100:C.toOffset),E!==void 0){if(V!==!1&&(E<0||E>1)){const e=`Invalid fromOffset: ${E} (must be 0-1 for percentage)`;return t(e),{success:!1,error:e}}if(V===!1&&E<0){const e=`Invalid fromOffset: ${E} (must be >= 0 for absolute distance)`;return t(e),{success:!1,error:e}}}if(h!==void 0){if(a!==!1&&(h<0||h>1)){const e=`Invalid toOffset: ${h} (must be 0-1 for percentage)`;return t(e),{success:!1,error:e}}if(a===!1&&h<0){const e=`Invalid toOffset: ${h} (must be >= 0 for absolute distance)`;return t(e),{success:!1,error:e}}}if(V===!1&&E===void 0){const e="fromOffset is required when fromIsPercentage is false";return t(e),{success:!1,error:e}}if(a===!1&&h===void 0){const e="toOffset is required when toIsPercentage is false";return t(e),{success:!1,error:e}}const x={from:n,to:P,fromPosition:E,fromIsPercentage:V,toPosition:h,toIsPercentage:a};return r(e=>e.map((u,l)=>l===d?j(x):u)),t(null),{success:!0}},[I]),v=o.useCallback((n,P)=>{if(!I.some(d=>d.fromLineId===n&&d.toLineId===P)){const d=`Connection from '${n}' to '${P}' not found`;return t(d),{success:!1,error:d}}return r(d=>d.filter(C=>!(C.fromLineId===n&&C.toLineId===P))),t(null),{success:!0}},[I]),p=o.useCallback(()=>{c([]),r([]),t(null)},[]);return{lines:s,curves:I,setScene:w,addLine:$,updateLine:b,removeLine:S,addConnection:L,updateConnection:g,removeConnection:v,clear:p,error:m,_loadScene:f}}function B({lines:s,wheelbase:c}){const[I,r]=o.useState([]),[m,t]=o.useState(null),f=o.useRef([]),w=o.useCallback(g=>{f.current=g,r(g),t(null)},[]),$=o.useCallback(g=>{const v=Array.isArray(g)?g:[g],p=[];for(const d of v)f.current.some(V=>V.id===d.id)&&p.push(`Vehicle with ID '${d.id}' already exists`);if(p.length>0)return t(p.join("; ")),{success:!1,errors:p};const n=v.map(N),{vehicles:P,errors:i}=O.validateAndCreateVehicles(n,s,c);return i.length>0?(t(i.join("; ")),{success:!1,errors:i}):(f.current=[...f.current,...P],r(f.current),t(null),{success:!0})},[s,c]),b=o.useCallback((g,v)=>{const p=f.current.findIndex(h=>h.id===g);if(p===-1){const h=`Vehicle with ID '${g}' not found`;return t(h),{success:!1,error:h}}const n=f.current[p];if(n.state!=="idle"){const h=`Cannot update vehicle '${g}' while it is ${n.state}. Vehicle must be idle.`;return t(h),{success:!1,error:h}}const P=v.lineId??n.lineId;if(!s.find(h=>h.id===P)){const h=`Line '${P}' not found`;return t(h),{success:!1,error:h}}let d,C;v.lineId!==void 0&&v.position===void 0?(d=0,C=!0):v.position!==void 0?(d=v.position,C=v.isPercentage??!0):(d=n.offset,C=n.isPercentage);const V={vehicleId:g,lineId:P,offset:C?d*100:d,isPercentage:C},{vehicles:a,errors:E}=O.validateAndCreateVehicles([V],s,c);return E.length>0?(t(E.join("; ")),{success:!1,error:E.join("; ")}):(f.current=f.current.map((h,x)=>x===p?a[0]:h),r(f.current),t(null),{success:!0})},[s,c]),S=o.useCallback(g=>{if(!f.current.some(p=>p.id===g)){const p=`Vehicle with ID '${g}' not found`;return t(p),{success:!1,error:p}}return f.current=f.current.filter(p=>p.id!==g),r(f.current),t(null),{success:!0}},[]),L=o.useCallback(()=>{f.current=[],r([]),t(null)},[]);return{vehicles:I,addVehicles:$,updateVehicle:b,removeVehicle:S,clear:L,error:m,_loadVehicles:w}}function W({vehicles:s,lines:c}){const[I,r]=o.useState(new Map),[m,t]=o.useState(null),f=o.useCallback(b=>{r(b),t(null)},[]),w=o.useCallback((b,S)=>{if(!s.some(i=>i.id===b)){const i=`Vehicle '${b}' not found`;return t(i),{success:!1,error:i}}const g=c.find(i=>i.id===S.targetLineId);if(!g){const i=`Line '${S.targetLineId}' not found`;return t(i),{success:!1,error:i}}const v=S.isPercentage!==!1,p=q.distance(g.start,g.end);if(!v&&S.targetPosition===void 0){const i="targetPosition is required when isPercentage is false";return t(i),{success:!1,error:i}}const n=S.targetPosition??1;if(v){if(n<0||n>1){const i=`Invalid targetPosition: ${n} (must be 0-1 for percentage)`;return t(i),{success:!1,error:i}}}else{if(n<0){const i=`Invalid targetPosition: ${n} (must be >= 0 for absolute distance)`;return t(i),{success:!1,error:i}}if(n>p){const i=`Position ${n} exceeds line length ${p}`;return t(i),{success:!1,error:i}}}const P=H({vehicleId:b,...S});return r(i=>{const d=new Map(i),C=d.get(b)||[];return d.set(b,[...C,P]),d}),t(null),{success:!0}},[s,c]),$=o.useCallback(b=>{if(b!==void 0){if(!s.some(L=>L.id===b)){const L=`Vehicle '${b}' not found`;return t(L),{success:!1,error:L}}r(L=>{const g=new Map(L);return g.delete(b),g})}else r(new Map);return t(null),{success:!0}},[s]);return{vehicleQueues:I,queueMovement:w,clearQueue:$,error:m,_loadQueues:f}}function Z({vehicles:s,lines:c,vehicleQueues:I,wheelbase:r,tangentMode:m,curves:t,eventEmitter:f}){const[w,$]=o.useState([]),b=o.useMemo(()=>({wheelbase:r,tangentMode:m}),[r,m]),S=o.useMemo(()=>new Map(c.map(V=>[V.id,V])),[c]),L=o.useRef(new Map);o.useEffect(()=>{const{movingVehicles:V,stateMap:a}=q.initializeAllVehicles(s,S);L.current=a;const E=setTimeout(()=>{$(V)},0);return()=>clearTimeout(E)},[s,S]);const g=o.useRef(null);o.useEffect(()=>{c.length>0&&(g.current=q.buildGraph(c,t,b))},[c,t,b]);const v=o.useRef(0),p=o.useRef(!1),n=o.useCallback(V=>{if(!p.current)return!1;let a=!1;for(const[,h]of L.current)if(h.vehicle.state==="moving"){a=!0;break}if(!a)return!1;const E=[];for(const[h,x]of L.current){if(x.vehicle.state!=="moving"||!x.execution)continue;const e=x.execution;let u;if(e.front.currentSegmentIndex<e.path.segments.length){const y=e.path.segments[e.front.currentSegmentIndex];if(y.type==="line"){const M=S.get(y.lineId);M&&(u=Math.sqrt(Math.pow(M.end.x-M.start.x,2)+Math.pow(M.end.y-M.start.y,2)))}}const l=q.updateAxlePosition(x.vehicle.rear,e.rear,e.path,V,S,e.curveDataMap),k=q.updateAxlePosition(x.vehicle.front,e.front,e.path,V,S,e.curveDataMap,u);if(x.vehicle={...x.vehicle,rear:l.axleState,front:k.axleState},x.execution.rear=l.execution,x.execution.front=k.execution,l.completed){const y={linesMap:S,config:b,vehicleQueues:I,curves:t,graphRef:g,prepareCommandPath:q.prepareCommandPath,onCommandComplete:Q=>E.push({type:"commandComplete",data:Q}),onCommandStart:Q=>E.push({type:"commandStart",data:Q})},M=q.handleArrival(x,y);x.vehicle=M.vehicle,M.newExecution!==void 0&&(x.execution=M.newExecution),M.vehicle.state!=="moving"&&E.push({type:"stateChange",data:{vehicleId:h,from:"moving",to:M.vehicle.state}});const D=M.vehicle.rear.position,T=M.vehicle.front.position;E.push({type:"positionUpdate",data:{vehicleId:h,rear:D,front:T,center:{x:(D.x+T.x)/2,y:(D.y+T.y)/2},angle:Math.atan2(T.y-D.y,T.x-D.x)}})}}if($(h=>h.map(x=>{const e=L.current.get(x.id);return e?e.vehicle:x})),f&&E.length>0){const h=v.current;setTimeout(()=>{v.current===h&&E.forEach(({type:x,data:e})=>{f.emit(x,e)})},0)}for(const[,h]of L.current)if(h.vehicle.state==="moving")return!0;return!1},[S,t,b,I,f]),P=o.useCallback(()=>{if(p.current)return!0;const V=g.current;if(!V)return!1;const a=[];let E=!1;for(const[h,x]of L.current){const e=x.vehicle,u=I.get(h);if(!u||u.length===0)continue;const l=u[0],k={graph:V,linesMap:S,curves:t,config:b},y=q.prepareCommandPath(e,l,k);if(!y){console.warn(`No path found for vehicle ${h}`);continue}const M=q.calculateFrontAxlePosition(y.path,0,0,r);L.current.set(h,{...x,execution:{path:y.path,curveDataMap:y.curveDataMap,currentCommandIndex:0,rear:{currentSegmentIndex:0,segmentDistance:0},front:M?{currentSegmentIndex:M.segmentIndex,segmentDistance:M.segmentDistance}:{currentSegmentIndex:0,segmentDistance:0}},vehicle:{...e,state:"moving"}}),E=!0,e.state!=="moving"&&a.push({id:h,fromState:e.state,command:l,startPosition:{lineId:e.rear.lineId,absoluteOffset:e.rear.absoluteOffset,position:e.rear.position}})}if(!E)return!1;if(p.current=!0,$(h=>h.map(x=>{const e=L.current.get(x.id);return e?e.vehicle:x})),f&&a.length>0){const h=v.current;setTimeout(()=>{v.current===h&&a.forEach(({id:x,fromState:e,command:u,startPosition:l})=>{f.emit("commandStart",{vehicleId:x,command:u,commandIndex:0,startPosition:l}),f.emit("stateChange",{vehicleId:x,from:e,to:"moving"})})},0)}return!0},[S,t,I,b,r,f]),i=o.useCallback(()=>{v.current++,p.current=!1;const{movingVehicles:V,stateMap:a}=q.initializeAllVehicles(s,S);L.current=a,$(V)},[s,S]),d=o.useCallback(V=>{const a=L.current.get(V);if(!a||a.vehicle.state!=="waiting")return!1;const E=I.get(V),h=a.execution;if(!h)return!1;const x=h.currentCommandIndex+1;if(E&&x<E.length){const e=g.current;if(e){const u=E[x],l={graph:e,linesMap:S,curves:t,config:b},k=q.prepareCommandPath(a.vehicle,u,l);if(k){const y=q.calculateFrontAxlePosition(k.path,0,0,r);if(a.execution={path:k.path,curveDataMap:k.curveDataMap,currentCommandIndex:x,rear:{currentSegmentIndex:0,segmentDistance:0},front:y?{currentSegmentIndex:y.segmentIndex,segmentDistance:y.segmentDistance}:{currentSegmentIndex:0,segmentDistance:0}},a.vehicle={...a.vehicle,state:"moving"},$(M=>M.map(D=>D.id===V?a.vehicle:D)),f){const M=v.current;setTimeout(()=>{v.current===M&&f.emit("stateChange",{vehicleId:V,from:"waiting",to:"moving"})},0)}return!0}}}if(a.vehicle={...a.vehicle,state:"idle"},a.execution=null,$(e=>e.map(u=>u.id===V?a.vehicle:u)),f){const e=v.current;setTimeout(()=>{v.current===e&&f.emit("stateChange",{vehicleId:V,from:"waiting",to:"idle"})},0)}return!0},[I,S,t,b,r,f]),C=o.useCallback(()=>{for(const[,V]of L.current)if(V.vehicle.state==="moving")return!0;return!1},[]);return{movingVehicles:w,prepare:P,tick:n,reset:i,continueVehicle:d,isMoving:C,isPrepared:p.current}}function re({wheelbase:s,tangentMode:c="proportional-40",eventEmitter:I}){const r=J(),m=B({lines:r.lines,wheelbase:s}),t=W({vehicles:m.vehicles,lines:r.lines,curves:r.curves}),f=Z({vehicles:m.vehicles,lines:r.lines,vehicleQueues:t.vehicleQueues,wheelbase:s,tangentMode:c,curves:r.curves,eventEmitter:I}),w=o.useCallback(e=>m.vehicles.filter(u=>u.lineId===e||u.rear.lineId===e),[m.vehicles]),$=o.useCallback(e=>w(e).length>0,[w]),b=o.useCallback(e=>{const u=r.addLine(e);return u.success?{success:!0}:{success:!1,error:u.error}},[r]),S=o.useCallback((e,u)=>{const l=r.updateLine(e,u);return l.success?{success:!0}:{success:!1,error:l.error}},[r]),L=o.useCallback(e=>{const u=[],l=w(e);l.length>0&&(u.push({type:"vehicle_on_removed_line",message:`${l.length} vehicle(s) are on line '${e}'`,details:{lineId:e,vehicleIds:l.map(M=>M.id)}}),l.forEach(M=>{m.removeVehicle(M.id),t.clearQueue(M.id)}));const k=r.curves.filter(M=>M.fromLineId===e||M.toLineId===e);k.length>0&&u.push({type:"orphaned_connection",message:`${k.length} connection(s) will be removed`,details:{lineId:e,connectionCount:k.length}});const y=r.removeLine(e);return y.success?{success:!0,warnings:u.length>0?u:void 0}:{success:!1,error:y.error}},[r,w,m,t]),g=o.useCallback(()=>{r.clear(),m.clear(),t.clearQueue()},[r,m,t]),v=o.useCallback((e,u,l)=>{const k=r.addConnection({from:e,to:u,fromPosition:l?.fromOffset,fromIsPercentage:l?.fromIsPercentage,toPosition:l?.toOffset,toIsPercentage:l?.toIsPercentage});return k.success?{success:!0}:{success:!1,error:k.error}},[r]),p=o.useCallback((e,u,l)=>{const k=r.updateConnection(e,u,l);return k.success?{success:!0}:{success:!1,error:k.error}},[r]),n=o.useCallback((e,u)=>{const l=r.removeConnection(e,u);return l.success?{success:!0}:{success:!1,error:l.error}},[r]),P=o.useCallback(e=>{const u=m.addVehicles(e);return u.success?{success:!0}:{success:!1,error:u.errors?.join("; ")}},[m]),i=o.useCallback((e,u)=>{const l=m.updateVehicle(e,u);return l.success?{success:!0}:{success:!1,error:l.error}},[m]),d=o.useCallback(e=>{const u=[],l=t.vehicleQueues.get(e);l&&l.length>0&&(u.push({type:"movement_queue_cleared",message:`${l.length} queued movement(s) will be cleared for vehicle '${e}'`,details:{vehicleId:e}}),t.clearQueue(e));const k=m.removeVehicle(e);return k.success?{success:!0,warnings:u.length>0?u:void 0}:{success:!1,error:k.error}},[m,t]),C=o.useCallback(()=>{m.clear(),t.clearQueue()},[m,t]),V=o.useCallback(e=>{const u={targetLineId:e.lineId,targetPosition:e.position??1,isPercentage:e.isPercentage,wait:e.wait,payload:e.payload},l=t.queueMovement(e.id,u);return l.success?{success:!0}:{success:!1,error:l.error}},[t]),a=o.useCallback(e=>{const u=t.clearQueue(e);return u.success?{success:!0}:{success:!1,error:u.error}},[t]),E=o.useCallback(e=>{const u=[],l=[],{scene:k,vehicles:y,movements:M}=O.parseAllDSL(e);k.errors.length>0&&l.push(...k.errors),y.errors.length>0&&l.push(...y.errors),M.errors.length>0&&l.push(...M.errors);const D=k.data.lines.map(z),T=(k.data.connections||[]).map(j),Q=y.data.map(N),{vehicles:A,errors:_}=O.validateAndCreateVehicles(Q,D,s);_.length>0&&l.push(..._);const U=new Map;for(const G of M.data){const Y=U.get(G.vehicleId)||[];Y.push(H(G)),U.set(G.vehicleId,Y)}return r._loadScene(D,T),m._loadVehicles(A),t._loadQueues(U),l.length>0&&u.push({type:"dsl_parse_error",message:`DSL loading had ${l.length} error(s)`,details:{errors:l}}),{success:!0,warnings:u.length>0?u:void 0}},[r,m,t,s]),h=o.useCallback(e=>{const u=[],l=[],k=e.lines.map(z),y=(e.connections||[]).map(j),M=(e.vehicles||[]).map(N),{vehicles:D,errors:T}=O.validateAndCreateVehicles(M,k,s);T.length>0&&l.push(...T);const Q=new Map;for(const A of e.movements||[]){const _=Q.get(A.vehicleId)||[];_.push(H({vehicleId:A.vehicleId,targetLineId:A.targetLineId,targetPosition:A.targetPosition,isPercentage:A.isPercentage,wait:A.wait,payload:A.payload})),Q.set(A.vehicleId,_)}return r._loadScene(k,y),m._loadVehicles(D),t._loadQueues(Q),l.length>0&&u.push({type:"dsl_parse_error",message:`JSON loading had ${l.length} error(s)`,details:{errors:l}}),{success:!0,warnings:u.length>0?u:void 0}},[r,m,t,s]),x=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,vehicleQueues:t.vehicleQueues,error:x,addLine:b,updateLine:S,removeLine:L,clearScene:g,connect:v,updateConnection:p,disconnect:n,addVehicles:P,updateVehicle:i,removeVehicle:d,clearVehicles:C,goto:V,clearQueue:a,prepare:f.prepare,tick:f.tick,reset:f.reset,continueVehicle:f.continueVehicle,isMoving:f.isMoving,loadFromDSL:E,loadFromJSON:h,getVehiclesOnLine:w,hasVehiclesOnLine:$}}function R(s){return s.map(c=>({id:c.id,start:c.start,end:c.end}))}function K(s){return s.map(c=>({from:c.fromLineId,to:c.toLineId,fromPosition:c.fromOffset!==void 0?c.fromIsPercentage?c.fromOffset/100:c.fromOffset:void 0,fromIsPercentage:c.fromIsPercentage,toPosition:c.toOffset!==void 0?c.toIsPercentage?c.toOffset/100:c.toOffset:void 0,toIsPercentage:c.toIsPercentage}))}function ne(){const[s,c]=o.useState(""),[I,r]=o.useState(null),{lines:m,curves:t,setScene:f}=J(),w=o.useRef(!1),$=o.useRef("");o.useEffect(()=>{$.current=s},[s]),o.useEffect(()=>{if(w.current)return;const g={lines:R(m),connections:t.length>0?K(t):void 0},v=O.generateSceneDSL(g);v!==$.current&&(w.current=!0,c(v),setTimeout(()=>{w.current=!1},50))},[m,t]);const b=o.useCallback(g=>{w.current=!0,c(g);try{const{data:v,errors:p}=O.parseSceneDSL(g);p.length>0&&r(p.join("; "));const n=f(v);!n.success&&n.errors?r(P=>P?`${P}; ${n.errors.join("; ")}`:n.errors.join("; ")):p.length===0&&r(null)}catch(v){r(v instanceof Error?v.message:"Invalid scene definition")}setTimeout(()=>{w.current=!1},50)},[f]),S=o.useCallback(g=>{const v=typeof g=="function"?g(m):g,p=K(t);f({lines:R(v),connections:p.length>0?p:void 0});const n={lines:R(v),connections:p.length>0?p:void 0},P=O.generateSceneDSL(n);w.current=!0,c(P),setTimeout(()=>{w.current=!1},50)},[m,t,f]),L=o.useCallback(g=>{const v=typeof g=="function"?g(t):g,p=K(v);f({lines:R(m),connections:p.length>0?p:void 0});const n={lines:R(m),connections:p.length>0?p:void 0},P=O.generateSceneDSL(n);w.current=!0,c(P),setTimeout(()=>{w.current=!1},50)},[m,t,f]);return{lines:m,curves:t,sceneDefinitionText:s,sceneError:I,isDebouncing:!1,debounceKey:0,setLines:S,setCurves:L,setSceneDefinitionText:b}}function oe({lines:s,wheelbase:c}){const[I,r]=o.useState(""),[m,t]=o.useState(null),{vehicles:f,addVehicles:w,clear:$,error:b}=B({lines:s,wheelbase:c}),S=o.useRef(!1),L=o.useCallback(g=>{S.current=!0,r(g);try{const{data:v,errors:p}=O.parseVehiclesDSL(g),n=[...p];$();for(const P of v){const i=w(P);!i.success&&i.errors&&n.push(...i.errors)}n.length>0?t(n.join(`
|
|
2
|
-
`)):t(null)}catch(v){t(v instanceof Error?v.message:"Invalid initial movement")}setTimeout(()=>{S.current=!1},50)},[w,$]);return{vehicles:f,initialMovementText:I,movementError:m||b,isDebouncing:!1,debounceKey:0,setInitialMovementText:L}}function ce({lines:s,vehicles:c}){const[I,r]=o.useState(""),[m,t]=o.useState([]),[f,w]=o.useState(null),{vehicleQueues:$,queueMovement:b,clearQueue:S,error:L}=W({vehicles:c,lines:s}),g=o.useRef(!1),v=o.useCallback(p=>{g.current=!0,r(p);try{const{data:n,errors:P}=O.parseMovementDSL(p),i=[...P];S();for(const d of n){const C=b(d.vehicleId,{targetLineId:d.targetLineId,targetPosition:d.targetPosition,isPercentage:d.isPercentage,wait:d.wait,payload:d.payload});!C.success&&C.error&&i.push(C.error)}t(n),i.length>0?w(i.join(`
|
|
3
|
-
`)):w(null)}catch(n){w(n instanceof Error?n.message:"Invalid movement sequence"),t([])}setTimeout(()=>{g.current=!1},50)},[b,S]);return{movementSequenceText:I,gotoCommands:m,vehicleQueues:$,sequenceError:f||L,isDebouncing:!1,debounceKey:0,setMovementSequenceText:v}}const X=o.createContext(null);function ee(){const s=o.useContext(X);if(!s)throw new Error("useVehicleEventEmitter must be used within a VehicleEventProvider");return s}function ie(){return o.useMemo(()=>new O.VehicleEventEmitter,[])}function ae(s,c,I=[]){const r=ee();o.useEffect(()=>r.on(s,c),[r,s,...I])}function ue({children:s}){const c=o.useMemo(()=>new O.VehicleEventEmitter,[]);return te.jsx(X.Provider,{value:c,children:s})}exports.VehicleEventContext=X;exports.VehicleEventProvider=ue;exports.useAnimation=Z;exports.useCreateVehicleEventEmitter=ie;exports.useInitialMovement=oe;exports.useMovementQueue=W;exports.useMovementSequence=ce;exports.useScene=J;exports.useSceneDefinition=ne;exports.useVehicleEvent=ae;exports.useVehicleEventEmitter=ee;exports.useVehicleSimulation=re;exports.useVehicles=B;
|