diff --git a/src/js/game/items/boolean_item.js b/src/js/game/items/boolean_item.js index 38422398..2ff7b0e2 100644 --- a/src/js/game/items/boolean_item.js +++ b/src/js/game/items/boolean_item.js @@ -4,6 +4,8 @@ import { types } from "../../savegame/serialization"; import { BaseItem } from "../base_item"; import { globalConfig } from "../../core/config"; +/** @typedef {0 | 1} Bit **/ + export class BooleanItem extends BaseItem { static getId() { return "boolean_item"; @@ -27,18 +29,18 @@ export class BooleanItem extends BaseItem { } /** - * @param {number} value + * @param {Bit} value */ constructor(value) { super(); - this.value = value ? 1 : 0; + this.value = value; } /** - * @param {BaseItem} other + * @param {BooleanItem} other */ equalsImpl(other) { - return this.value === /** @type {BooleanItem} */ (other).value; + return this.value === other.value; } /** @@ -48,15 +50,19 @@ export class BooleanItem extends BaseItem { * @param {DrawParameters} parameters */ drawItemCenteredImpl(x, y, parameters, diameter = globalConfig.defaultItemDiameter) { - let sprite; - if (this.value) { - sprite = Loader.getSprite("sprites/wires/boolean_true.png"); - } else { - sprite = Loader.getSprite("sprites/wires/boolean_false.png"); - } + const value = Boolean(this.value).toString(); + const sprite = Loader.getSprite(`sprites/wires/boolean_${value}.png`); sprite.drawCachedCentered(parameters, x, y, diameter); } } export const BOOL_FALSE_SINGLETON = new BooleanItem(0); export const BOOL_TRUE_SINGLETON = new BooleanItem(1); + +/** + * @param {unknown} item + * @returns {item is BooleanItem} + **/ +export const isBooleanItem = item => { + return item instanceof BooleanItem; +}; diff --git a/src/js/game/items/color_item.js b/src/js/game/items/color_item.js index 19d26286..7f5946e0 100644 --- a/src/js/game/items/color_item.js +++ b/src/js/game/items/color_item.js @@ -30,10 +30,10 @@ export class ColorItem extends BaseItem { } /** - * @param {BaseItem} other + * @param {ColorItem} other */ equalsImpl(other) { - return this.color === /** @type {ColorItem} */ (other).color; + return this.color === other.color; } /** diff --git a/src/js/game/items/shape_item.js b/src/js/game/items/shape_item.js index d99a7251..58d59c8b 100644 --- a/src/js/game/items/shape_item.js +++ b/src/js/game/items/shape_item.js @@ -28,10 +28,10 @@ export class ShapeItem extends BaseItem { } /** - * @param {BaseItem} other + * @param {ShapeItem} other */ equalsImpl(other) { - return this.definition.getHash() === /** @type {ShapeItem} */ (other).definition.getHash(); + return this.definition.getHash() === other.definition.getHash(); } /** diff --git a/src/js/game/systems/logic_gate.js b/src/js/game/systems/logic_gate.js index 9fe41250..5161aa67 100644 --- a/src/js/game/systems/logic_gate.js +++ b/src/js/game/systems/logic_gate.js @@ -2,8 +2,7 @@ import { LogicGateComponent, enumLogicGateType } from "../components/logic_gate" import { GameSystemWithFilter } from "../game_system_with_filter"; import { BaseItem } from "../base_item"; import { enumPinSlotType } from "../components/wired_pins"; -import { BOOL_TRUE_SINGLETON, BOOL_FALSE_SINGLETON, BooleanItem } from "../items/boolean_item"; -import { enumItemProcessorTypes } from "../components/item_processor"; +import { BOOL_TRUE_SINGLETON, BOOL_FALSE_SINGLETON, BooleanItem, isBooleanItem } from "../items/boolean_item"; export class LogicGateSystem extends GameSystemWithFilter { constructor(root) { @@ -19,8 +18,7 @@ export class LogicGateSystem extends GameSystemWithFilter { } update() { - for (let i = 0; i < this.allEntities.length; ++i) { - const entity = this.allEntities[i]; + this.allEntities.forEach(entity => { const logicComp = entity.components.LogicGate; const slotComp = entity.components.WiredPins; @@ -48,133 +46,84 @@ export class LogicGateSystem extends GameSystemWithFilter { assert(slotComp.slots[0].type === enumPinSlotType.logicalEjector, "Slot 0 should be ejector"); slotComp.slots[0].value = result; - } + }); } /** * @param {Array} parameters - * @returns {BaseItem} + * @returns {BooleanItem} */ compute_AND(parameters) { assert(parameters.length === 2, "bad parameter count for AND"); - const param1 = parameters[0]; - const param2 = parameters[1]; - if (!param1 || !param2) { - // Not enough params + const [param1, param2] = parameters; + + if (!isBooleanItem(param1) || !isBooleanItem(param2)) { return BOOL_FALSE_SINGLETON; } - const itemType = param1.getItemType(); - - if (itemType !== param2.getItemType()) { - // Differing type - return BOOL_FALSE_SINGLETON; - } - - if (itemType === "boolean") { - return /** @type {BooleanItem} */ (param1).value && /** @type {BooleanItem} */ (param2).value - ? BOOL_TRUE_SINGLETON - : BOOL_FALSE_SINGLETON; - } - - return BOOL_FALSE_SINGLETON; + return param1.value && param2.value ? BOOL_TRUE_SINGLETON : BOOL_FALSE_SINGLETON; } /** * @param {Array} parameters - * @returns {BaseItem} + * @returns {BooleanItem} */ compute_NOT(parameters) { - const item = parameters[0]; + const [item] = parameters; + if (!item) { return BOOL_TRUE_SINGLETON; } - if (item.getItemType() !== "boolean") { - // Not a boolean actually + if (!isBooleanItem(item)) { return BOOL_FALSE_SINGLETON; } - const value = /** @type {BooleanItem} */ (item).value; - return value ? BOOL_FALSE_SINGLETON : BOOL_TRUE_SINGLETON; + return item.value ? BOOL_FALSE_SINGLETON : BOOL_TRUE_SINGLETON; } /** * @param {Array} parameters - * @returns {BaseItem} + * @returns {BooleanItem} */ compute_XOR(parameters) { assert(parameters.length === 2, "bad parameter count for XOR"); - const param1 = parameters[0]; - const param2 = parameters[1]; - if (!param1 && !param2) { - // Not enough params + const [param1, param2] = parameters; + + if (!isBooleanItem(param1) || !isBooleanItem(param2)) { return BOOL_FALSE_SINGLETON; } - // Check for the right types - if (param1 && param1.getItemType() !== "boolean") { - return BOOL_FALSE_SINGLETON; - } - - if (param2 && param2.getItemType() !== "boolean") { - return BOOL_FALSE_SINGLETON; - } - - const valueParam1 = param1 ? /** @type {BooleanItem} */ (param1).value : 0; - const valueParam2 = param2 ? /** @type {BooleanItem} */ (param2).value : 0; - - return valueParam1 ^ valueParam2 ? BOOL_TRUE_SINGLETON : BOOL_FALSE_SINGLETON; + return param1.value ^ param2.value ? BOOL_TRUE_SINGLETON : BOOL_FALSE_SINGLETON; } /** * @param {Array} parameters - * @returns {BaseItem} + * @returns {BooleanItem} */ compute_OR(parameters) { assert(parameters.length === 2, "bad parameter count for OR"); - const param1 = parameters[0]; - const param2 = parameters[1]; - if (!param1 && !param2) { - // Not enough params + const [param1, param2] = parameters; + + if (!isBooleanItem(param1) || !isBooleanItem(param2)) { return BOOL_FALSE_SINGLETON; } - const valueParam1 = - param1 && param1.getItemType() === "boolean" ? /** @type {BooleanItem} */ (param1).value : 0; - const valueParam2 = - param2 && param2.getItemType() === "boolean" ? /** @type {BooleanItem} */ (param2).value : 0; - - return valueParam1 || valueParam2 ? BOOL_TRUE_SINGLETON : BOOL_FALSE_SINGLETON; + return param1.value || param2.value ? BOOL_TRUE_SINGLETON : BOOL_FALSE_SINGLETON; } /** * @param {Array} parameters - * @returns {BaseItem} + * @returns {BaseItem|null} */ compute_IF(parameters) { assert(parameters.length === 2, "bad parameter count for IF"); - const flag = parameters[0]; - const value = parameters[1]; - if (!flag || !value) { - // Not enough params - return null; - } + const [flag, item] = parameters; - if (flag.getItemType() !== "boolean") { - // Flag is not a boolean - return null; - } - - // pass through item - if (/** @type {BooleanItem} */ (flag).value) { - return value; - } - - return null; + return isBooleanItem(flag) && flag.value ? item : null; } }