From 931a6c0e81e2bd992575b355cde5223be8f996fa Mon Sep 17 00:00:00 2001 From: cha0s Date: Tue, 25 Jun 2024 05:46:03 -0500 Subject: [PATCH] refactor: item access --- app/ecs-components/engine.js | 1 + app/ecs-components/inventory.js | 12 +++++++++-- app/ecs-components/wielder.js | 24 +++++++++++++++++++--- app/engine.js | 35 +++++++++++++++++++-------------- app/react-components/ecs.jsx | 29 ++++++++++----------------- 5 files changed, 62 insertions(+), 39 deletions(-) create mode 100644 app/ecs-components/engine.js diff --git a/app/ecs-components/engine.js b/app/ecs-components/engine.js new file mode 100644 index 0000000..ff8b4c5 --- /dev/null +++ b/app/ecs-components/engine.js @@ -0,0 +1 @@ +export default {}; diff --git a/app/ecs-components/inventory.js b/app/ecs-components/inventory.js index 1fa7124..bb38d7a 100644 --- a/app/ecs-components/inventory.js +++ b/app/ecs-components/inventory.js @@ -44,13 +44,21 @@ export default function(Component) { instanceFromSchema() { const Instance = super.instanceFromSchema(); const Component = this; - Instance.prototype.item = function (slot) { + Instance.prototype.item = async function (slot) { const {slots} = this; if (!(slot in slots)) { return undefined; } + const json = await ( + fetch([slots[slot].source, 'item.json'].join('/')) + .then((response) => (response.ok ? response.json() : {})) + ); + const item = { + ...slots[slot], + ...json, + }; const instance = this; - const proxy = new Proxy(slots[slot], { + const proxy = new Proxy(item, { set(target, property, value) { target[property] = value; if ('qty' === property && value <= 0) { diff --git a/app/ecs-components/wielder.js b/app/ecs-components/wielder.js index c0d56b7..5e23ea4 100644 --- a/app/ecs-components/wielder.js +++ b/app/ecs-components/wielder.js @@ -1,3 +1,21 @@ -export default { - activeSlot: {type: 'uint16'}, -}; +import Schema from '@/ecs/schema.js'; + +export default function(Component) { + return class Wielder extends Component { + instanceFromSchema() { + const Instance = super.instanceFromSchema(); + const Component = this; + Instance.prototype.activeItem = async function () { + const {Inventory, Wielder} = Component.ecs.get(this.entity); + return Inventory.item(Wielder.activeSlot + 1); + }; + return Instance; + } + static schema = new Schema({ + type: 'object', + properties: { + activeSlot: {type: 'uint16'}, + }, + }); + } +} diff --git a/app/engine.js b/app/engine.js index ae72025..c3b72af 100644 --- a/app/engine.js +++ b/app/engine.js @@ -72,6 +72,7 @@ export default class Engine { const area = {x: 100, y: 60}; ecs.create({ AreaSize: {x: area.x * 16, y: area.y * 16}, + Engine: {}, TileLayers: { layers: [ { @@ -169,6 +170,7 @@ export default class Engine { this.createEcs(), await this.server.readData(path), ); + this.ecses[path].get(1).Engine.engine = this; } async loadPlayer(id) { @@ -246,21 +248,24 @@ export default class Engine { break; } case 'use': { - const item = Inventory.item(Wielder.activeSlot + 1); - if (item) { - this.server.readAsset([ - item.source, - payload.value ? 'start.js' : 'stop.js', - ].join('/')) - .then((response) => response.ok ? response.text() : '') - .then((code) => { - if (code) { - Ticking.addTickingPromise( - Script.tickingPromise(code, {item, wielder: entity}), - ); - } - }); - } + Inventory.item(Wielder.activeSlot + 1).then(async (item) => { + if (item) { + const code = await( + this.server.readAsset([ + item.source, + payload.value ? 'start.js' : 'stop.js', + ].join('/')) + .then((script) => (script.ok ? script.text() : '')) + ); + if (code) { + const context = { + item, + wielder: entity, + }; + Ticking.addTickingPromise(Script.tickingPromise(code, context)); + } + } + }); break; } } diff --git a/app/react-components/ecs.jsx b/app/react-components/ecs.jsx index a8a704f..a056d5b 100644 --- a/app/react-components/ecs.jsx +++ b/app/react-components/ecs.jsx @@ -11,33 +11,20 @@ import TargetingGhost from './targeting-ghost.jsx'; import TargetingGrid from './targeting-grid.jsx'; import TileLayer from './tile-layer.jsx'; -function entityActiveItem(entity) { - const {Inventory, Wielder} = entity; - return Inventory.item(Wielder.activeSlot + 1); -} - export default function EcsComponent() { const [ecs] = useEcs(); const [entities, setEntities] = useState({}); - const [activeItem, setActiveItem] = useState(false); const [activeTool, setActiveTool] = useState(false); const [mainEntity] = useMainEntity(); useEffect(() => { if (mainEntity) { - setActiveItem(entityActiveItem(ecs.get(mainEntity))); + ecs.get(mainEntity) + .Wielder.activeItem() + .then(({tool} = {}) => { + setActiveTool(tool); + }); } }, [ecs, mainEntity]); - useEffect(() => { - if (!activeItem) { - setActiveTool(undefined); - return; - } - fetch([activeItem.source, 'item.json'].join('/')) - .then((response) => (response.ok ? response.json() : {})) - .then(({tool}) => { - setActiveTool(tool); - }); - }, [activeItem]); usePacket('Tick', (payload) => { if (0 === Object.keys(payload.ecs).length) { return; @@ -47,7 +34,11 @@ export default function EcsComponent() { && payload.ecs[mainEntity] && (payload.ecs[mainEntity].Inventory || payload.ecs[mainEntity].Wielder) ) { - setActiveItem(entityActiveItem(ecs.get(mainEntity))); + ecs.get(mainEntity) + .Wielder.activeItem() + .then(({tool} = {}) => { + setActiveTool(tool); + }); } const updatedEntities = {...entities}; for (const id in payload.ecs) {