html-tower/static/engine.js

121 lines
3.2 KiB
JavaScript

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");