136 lines
3.6 KiB
JavaScript
136 lines
3.6 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 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");
|