minor converter rates refactoring

This commit is contained in:
azykov@mail.ru
2026-08-31 22:10:16 +03:00
parent d96a6e2e92
commit 90501176ef
2 changed files with 44 additions and 24 deletions
+31 -19
View File
@@ -16,7 +16,6 @@ export type BehaviourLink = {
} }
export type BehaviourInput = BehaviourResourcePin & { export type BehaviourInput = BehaviourResourcePin & {
rate: number; // per second of tick deltaTime
link: BehaviourLink; link: BehaviourLink;
} }
@@ -25,7 +24,6 @@ export type BehaviourInputs = {
} }
export type BehaviourOutput = BehaviourResourcePin & { export type BehaviourOutput = BehaviourResourcePin & {
rate: number; // per second of tick deltaTime
} }
export type BehaviourOutputs = { export type BehaviourOutputs = {
@@ -51,13 +49,11 @@ export abstract class Behaviour {
this.outputs = { this.outputs = {
pins: source.outputs.pins.map((output) => ({ pins: source.outputs.pins.map((output) => ({
resource: output.resource, resource: output.resource,
rate: output.rate,
})), })),
} }
this.inputs = { this.inputs = {
pins: source.inputs.pins.map((input) => ({ pins: source.inputs.pins.map((input) => ({
resource: input.resource, resource: input.resource,
rate: input.rate,
link: input.link, link: input.link,
})), })),
} }
@@ -71,7 +67,7 @@ export abstract class Behaviour {
abstract getDisplayInfo(): BehaviourDisplayInfo; abstract getDisplayInfo(): BehaviourDisplayInfo;
/** Withdraws up to `amount` of `resource` from this behaviour's storage, returning how much was actually taken. */ /** Withdraws up to `amount` of `resource` from this behaviour's storage, returning how much was actually taken. */
protected take(resource: Resource, amount: number): number { public take(resource: Resource, amount: number): number {
const available = this.storage[resource] ?? 0; const available = this.storage[resource] ?? 0;
const taken = Math.min(available, amount); const taken = Math.min(available, amount);
this.storage[resource] = available - taken; this.storage[resource] = available - taken;
@@ -82,30 +78,46 @@ export abstract class Behaviour {
this.storage[resource] = (this.storage[resource] ?? 0) + amount; this.storage[resource] = (this.storage[resource] ?? 0) + amount;
} }
/** Fills this behaviour's own storage from its outputs' production rates. */ abstract produce(deltaTime: number): void;
public produce(deltaTime: number): void {
for (const output of this.outputs.pins) abstract pull(deltaTime: number, resolve: (id: string) => Behaviour | undefined): void;
this.give(output.resource, output.rate * deltaTime); }
export class Converter extends Behaviour {
public readonly inputRates: Partial<Resources>;
public readonly outputRates: Partial<Resources>;
constructor(source: SerializedNodeBehaviour & SerializedConverter) {
if (source.kind !== 'converter')
throw new Error('Invalid source');
super(source);
this.inputRates = {};
for (const pin of source.inputs.pins)
this.inputRates[pin.resource] = pin.rate;
this.outputRates = {};
for (const pin of source.outputs.pins)
this.outputRates[pin.resource] = pin.rate;
} }
/** Pulls resources into this behaviour's storage from whatever each input pin is linked to. */ /** Fills this converter's own storage from its outputs' production rates. */
public produce(deltaTime: number): void {
for (const output of this.outputs.pins)
this.give(output.resource, (this.outputRates[output.resource] ?? 0) * deltaTime);
}
/** Pulls resources into this converter's storage from whatever each input pin is linked to. */
public pull(deltaTime: number, resolve: (id: string) => Behaviour | undefined): void { public pull(deltaTime: number, resolve: (id: string) => Behaviour | undefined): void {
for (const input of this.inputs.pins) { for (const input of this.inputs.pins) {
const source = resolve(input.link.target); const source = resolve(input.link.target);
if (!source) if (!source)
continue; continue;
const taken = source.take(input.link.resource, input.rate * deltaTime); const rate = this.inputRates[input.resource] ?? 0;
const taken = source.take(input.link.resource, rate * deltaTime);
this.give(input.resource, taken); this.give(input.resource, taken);
} }
} }
}
export class Converter extends Behaviour {
constructor(source: SerializedNodeBehaviour & SerializedConverter) {
if (source.kind !== 'converter')
throw new Error('Invalid source');
super(source);
}
public getDisplayInfo(): BehaviourDisplayInfo { public getDisplayInfo(): BehaviourDisplayInfo {
return { return {
+13 -5
View File
@@ -1,20 +1,28 @@
import { defaultGame } from "../prefabs/game"; import { defaultGame } from "../prefabs/game";
import { Game, SerializedGame, SerializedNodeBehaviour } from "../types"; import { Game, SerializedGame, SerializedNodeBehaviour } from "../types";
import { Behaviour, behaviours } from "./functions"; import { Behaviour, behaviours, Converter } from "./functions";
export function serializeBehaviour(behaviour: Behaviour): SerializedNodeBehaviour { export function serializeBehaviour(behaviour: Behaviour): SerializedNodeBehaviour {
switch (behaviour.kind) { switch (behaviour.kind) {
case 'converter': case 'converter': {
const converter = behaviour as Converter;
return { return {
id: behaviour.id, id: converter.id,
kind: 'converter', kind: 'converter',
inputs: { inputs: {
pins: behaviour.inputs.pins.map((pin) => ({ ...pin })), pins: converter.inputs.pins.map((pin) => ({
...pin,
rate: converter.inputRates[pin.resource] ?? 0,
})),
}, },
outputs: { outputs: {
pins: behaviour.outputs.pins.map((pin) => ({ ...pin })), pins: converter.outputs.pins.map((pin) => ({
...pin,
rate: converter.outputRates[pin.resource] ?? 0,
})),
}, },
}; };
}
default: default:
throw new Error('Unknown behaviour'); throw new Error('Unknown behaviour');
} }