export class Block { /** * @param {string} id * @param {[number, number, number]} pos * @param {Object} state * @param {Array} world */ constructor(id, pos, state, world = []) { this.id = id; this.pos = pos; this.state = state; this.worlds = world; } delete() { for (let world of this.worlds) { world.blocks } } } export class World { constructor() { this.blocks = new Map(); this.listeners = new Set(); } /** * Subscribe to modify events. * @param {function()} callback. Called when this world is modified. * @returns {function()} Unsubscribe function. */ subscribe(callback) { this.listeners.add(callback); return () => this.listeners.delete(callback); } /** * Notify all listeners of a modification. */ notify() { for (const listener of this.listeners) listener(); } /** * Set a block and state at a position. * @param {string} id * @param {number} x * @param {number} y * @param {number} z * @param {Object} state */ set(id, x, y, z, state = {}) { const key = `${x},${y},${z}`; this.blocks.set(key, new Block(id, [x, y, z], state)); this.notify(); } /** * Remove a block at a position. * @param {number} x * @param {number} y * @param {number} z */ del(x, y, z) { if (this.blocks.delete(`${x},${y},${z}`)) { this.notify(); } } /** * Get a block at a position. * @param {number} x * @param {number} y * @param {number} z * @returns {any} */ get(x, y, z) { return this.blocks.get(`${x},${y},${z}`); } }