From 1492884a871b5d5e38bd968d6571f183b7340358 Mon Sep 17 00:00:00 2001 From: cha0s Date: Sat, 22 Jun 2024 22:04:24 -0500 Subject: [PATCH] refactor: efficient slot change diff --- app/ecs-components/inventory.js | 46 ++++++++++++++++++++++++++++----- app/react-components/ui.jsx | 21 +++++++++++---- 2 files changed, 56 insertions(+), 11 deletions(-) diff --git a/app/ecs-components/inventory.js b/app/ecs-components/inventory.js index c639244..59311f3 100644 --- a/app/ecs-components/inventory.js +++ b/app/ecs-components/inventory.js @@ -2,8 +2,45 @@ import Schema from '@/ecs/schema.js'; export default function(Component) { return class Inventory extends Component { + insertMany(entities) { + for (const [id, {slotChanged}] of entities) { + if (slotChanged) { + for (const slotIndex in slotChanged) { + this.get(id).slots[slotIndex] = { + ...this.get(id).slots[slotIndex], + ...slotChanged[slotIndex], + }; + } + } + } + return super.insertMany(entities); + } + markChange(entityId, key, value) { + if ('slotChange' === key) { + const {index, change} = value; + return super.markChange(entityId, key, {[index]: change}); + } + return super.markChange(entityId, key, value); + } + mergeDiff(original, update) { + if (update.slotChange) { + if (!original.slotChange) { + original.slotChange = {}; + } + const merged = {}; + for (const index in update.slotChange) { + merged[index] = { + ...original.slotChange[index], + ...update.slotChange[index], + }; + } + return {slotChanged: merged}; + } + return super.mergeDiff(original, update); + } instanceFromSchema() { const Instance = super.instanceFromSchema(); + const Component = this; Instance.prototype.item = function (slot) { const {slots} = this; const instance = this; @@ -12,12 +49,9 @@ export default function(Component) { if (slot === item.slotIndex) { const proxy = new Proxy(item, { set(target, property, value) { - const newSlots = [...slots]; - newSlots[index] = { - ...target, - [property]: value, - }; - instance.slots = newSlots; + target[property] = value; + const change = {[property]: value}; + Component.markChange(instance.entity, 'slotChange', {index, change}); return true; }, }); diff --git a/app/react-components/ui.jsx b/app/react-components/ui.jsx index eaa44f8..a8014a3 100644 --- a/app/react-components/ui.jsx +++ b/app/react-components/ui.jsx @@ -144,13 +144,24 @@ export default function Ui({disconnected}) { if (localMainEntity === id) { if (payload.ecs[id].Inventory) { const newHotbarSlots = [...hotbarSlots]; - payload.ecs[id].Inventory.slots - .forEach(({qty, slotIndex, source}) => { + const {slots, slotChanged} = payload.ecs[id].Inventory; + if (slotChanged) { + for (const slotIndex in slotChanged) { newHotbarSlots[slotIndex] = { - image: source + '/icon.png', - qty, + ...newHotbarSlots[slotIndex], + ...slotChanged[slotIndex], }; - }); + } + } + if (slots) { + slots + .forEach(({qty, slotIndex, source}) => { + newHotbarSlots[slotIndex] = { + image: source + '/icon.png', + qty, + }; + }); + } setHotbarSlots(newHotbarSlots); } if (payload.ecs[id].Wielder && 'activeSlot' in payload.ecs[id].Wielder) {