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 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"); 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] = []; break; } case "removeEntity": { let node = messageArgs[0]; entities[node].forEach(([componentType, component]) => { components[componentType].remove(component); }); delete entities[node]; queue.push((_) => node.remove()); break; } case "registerComponentType": { let componentType = messageArgs[0]; components[componentType] = new Set(); break; } case "addComponent": { let [entity, componentType, component] = messageArgs; entities[entity].push([componentType, component]); components[componentType].add(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': { tick(); break; } case 'halt': { halt(); break; } }; }; })(); initTransformSystem(engine); inputSystem(engine); playerSystem(engine); engine("start");