console.log("loading engine"); const initEvent = () => { let subscribers = {}; return (message, ...messageArgs) => { switch (message) { case "addSubscriber": let subscriberName = messageArgs[0]; let subscriberFunc = messageArgs[1]; subscribers[subscriberName] = subscriberFunc; break; case "raise": let delta = messageArgs[0]; let eventData = messageArgs[1]; Object.entries(subscribers).forEach(([id, subscriber]) => { subscriber(delta, eventData); }); break; } }; }; const engine = (() => { let queue = []; let timer; let state; let time = Date.now(); let entities = {}; let components = {}; let events = {}; const engineTick = 1000 / 60; const tick = () => { let now = Date.now(); let delta = now - time; time = now; while (queue.length > 0) { let eventName = queue.shift(); events[eventName]("raise", delta); } timer = setTimeout(tick, engineTick); }; const halt = () => { console.log("halted"); state="halted"; clearTimeout(timer); }; return (message, ...messageArgs) => { switch (message) { case "queueEvent": { queue.push(messageArgs[0]); break; } case "events": { return events; } case "entities": { return entities; } case "components": { return components; } case "world": { return { entities, components, events, }; } case "registerEntity": { let node = messageArgs[0]; entities[node.id] = []; break; } case "removeEntity": { let node = messageArgs[0]; entities[node.id].forEach(([componentType, component]) => { delete components[componentType].instances[component]; }); delete entities[node.id]; queue.push((_) => node.remove()); break; } case "registerComponentType": { let [componentType, constructor] = messageArgs; components[componentType] = { constructor, instances: {} }; break; } case "getComponentConstructor": { let [componentType] = messageArgs; return components [componentType].constructor(engine); } case "addComponent": { let [entity, componentType, component] = messageArgs; entities[entity.id].push([componentType, component]); components[componentType].instances[entity.id] = component; break; } case "registerEvent": { let eventName = messageArgs[0]; let newEvent = initEvent(); events[eventName] = newEvent; break; } case "subscribeToEvent": { let [eventName, subscriberName, newSubscriber] = messageArgs; events[eventName]("addSubscriber", subscriberName, newSubscriber); break; } case 'start': { state="running"; tick(); break; } case 'state': { return state; } case 'halt': { halt(); break; } }; }; })(); initCollisionSystem (engine); initTransformSystem(engine); inputSystem(engine); playerSystem(engine); initEnvironmentSystem (engine); engine("start");