simple-circuit-engine 0.0.12 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +2 -1
- package/CLAUDE.md +2 -0
- package/dist/core/index.js +83 -73
- package/dist/core/setup.d.ts +8 -0
- package/dist/core/simulation/behaviors/arithmetic/AdderBehavior.d.ts +28 -0
- package/dist/core/simulation/behaviors/arithmetic/ArithmeticBehaviorMixin.d.ts +63 -0
- package/dist/core/simulation/behaviors/arithmetic/EightBitAdderBehavior.d.ts +51 -0
- package/dist/core/simulation/behaviors/arithmetic/EightBitOnesComplementBehavior.d.ts +29 -0
- package/dist/core/simulation/behaviors/arithmetic/HalfAdderBehavior.d.ts +22 -0
- package/dist/core/simulation/behaviors/arithmetic/index.d.ts +7 -0
- package/dist/core/simulation/behaviors/index.d.ts +4 -0
- package/dist/core/simulation/states/arithmetic/AdderState.d.ts +16 -0
- package/dist/core/simulation/states/arithmetic/ArithmeticState.d.ts +53 -0
- package/dist/core/simulation/states/arithmetic/EightBitAdderState.d.ts +25 -0
- package/dist/core/simulation/states/arithmetic/EightBitOnesComplementState.d.ts +18 -0
- package/dist/core/simulation/states/arithmetic/HalfAdderState.d.ts +16 -0
- package/dist/core/simulation/states/arithmetic/index.d.ts +7 -0
- package/dist/core/simulation/states/index.d.ts +5 -0
- package/dist/core/simulation/types.d.ts +1 -1
- package/dist/core/topology/Component.d.ts +2 -1
- package/dist/core/topology/types.d.ts +19 -5
- package/dist/{core-Bjta9Y7_.js → core-b6Q8w2sn.js} +1505 -652
- package/dist/core-b6Q8w2sn.js.map +1 -0
- package/dist/i18n/index.d.ts +882 -0
- package/dist/i18n/locales/en.json.d.ts +268 -0
- package/dist/i18n/locales/fr.json.d.ts +268 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +137 -120
- package/dist/scene/CircuitEngine.d.ts +13 -0
- package/dist/scene/index.d.ts +1 -1
- package/dist/scene/index.js +50 -45
- package/dist/scene/setup.d.ts +8 -0
- package/dist/scene/shared/AbstractCircuitController.d.ts +6 -0
- package/dist/scene/shared/components/arithmetic/AdderVisualFactory.d.ts +54 -0
- package/dist/scene/shared/components/arithmetic/EightBitAdderVisualFactory.d.ts +45 -0
- package/dist/scene/shared/components/arithmetic/EightBitOnesComplementVisualFactory.d.ts +63 -0
- package/dist/scene/shared/components/arithmetic/HalfAdderVisualFactory.d.ts +55 -0
- package/dist/scene/shared/components/arithmetic/index.d.ts +4 -0
- package/dist/scene/shared/components/index.d.ts +4 -0
- package/dist/scene/shared/types.d.ts +0 -2
- package/dist/scene/shared/utils/GeometryUtils.d.ts +76 -0
- package/dist/scene/static/CircuitController.d.ts +1 -0
- package/dist/scene/static/PinTooltipWidget.d.ts +5 -0
- package/dist/scene/static/tools/BuildTool.d.ts +4 -0
- package/dist/scene/static/tools/ComponentPickerWidget.d.ts +7 -0
- package/dist/scene/static/tools/ConfigPanelWidget.d.ts +14 -0
- package/dist/{scene-CVsDdySt.js → scene-D4QcWeiq.js} +2487 -1099
- package/dist/scene-D4QcWeiq.js.map +1 -0
- package/package.json +14 -9
- package/dist/core-Bjta9Y7_.js.map +0 -1
- package/dist/scene-CVsDdySt.js.map +0 -1
package/AGENTS.md
CHANGED
package/CLAUDE.md
CHANGED
|
@@ -18,6 +18,7 @@ However, it aims to teach real-world electronic design principles so modeling of
|
|
|
18
18
|
- TypeScript 6.0+ (strict mode), targeting ES2022
|
|
19
19
|
- Three.js 0.183+ (scene, camera, controls, 3D objects, Line2)
|
|
20
20
|
- lil-gui as helper for small interactive modal forms
|
|
21
|
+
- i18next for internationalization (see `src/i18n/CLAUDE.md` for conventions)
|
|
21
22
|
- in-memory circuit model, optional loading/saving from/to a JSON file
|
|
22
23
|
|
|
23
24
|
## Project Structure
|
|
@@ -26,6 +27,7 @@ Simple Circuit Engine follows a **Model-Controller** architecture with clear sep
|
|
|
26
27
|
|
|
27
28
|
- **Core module** (`src/core/`): Pure TypeScript domain **Model** and simulation engine (no dependencies).
|
|
28
29
|
- **Scene module** (`src/scene/`): Three.js visualization layer with editing **Controller** and its tools and the simulation animated **Controller**.
|
|
30
|
+
- **i18next Internationalization** (`src/i18n/`) : localization setup and locales
|
|
29
31
|
|
|
30
32
|
### Core Module (`src/core/`)
|
|
31
33
|
|
package/dist/core/index.js
CHANGED
|
@@ -1,77 +1,87 @@
|
|
|
1
|
-
import { $ as t, A as e,
|
|
1
|
+
import { $ as t, A as e, At as s, B as i, C as o, Ct as r, D as n, Dt as S, E as h, Et as B, F as v, G as d, H as l, I as E, J as m, K as c, L as G, M as p, N as C, O as N, Ot as A, P as T, Q as g, R as u, S as I, St as L, T as D, Tt as y, U as O, V as _, W as R, X as M, Y as b, Z as f, _ as w, _t as P, a as U, at as X, b as F, bt as k, c as x, ct as z, d as H, dt as Y, et as Q, f as V, ft as W, g as j, gt as q, h as J, ht as K, i as Z, it as $, j as aa, k as ta, kt as ea, l as sa, lt as ia, m as oa, mt as ra, n as na, nt as Sa, o as ha, ot as Ba, p as va, pt as da, q as la, r as Ea, rt as ma, s as ca, st as Ga, t as pa, tt as Ca, u as Na, ut as Aa, v as Ta, vt as ga, w as ua, wt as Ia, x as La, xt as Da, y as ya, yt as Oa, z as _a } from "../core-b6Q8w2sn.js";
|
|
2
2
|
export {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
3
|
+
K as ALL_LOGIC_FAMILIES,
|
|
4
|
+
Na as AdderBehavior,
|
|
5
|
+
T as AdderState,
|
|
6
|
+
E as ArithmeticState,
|
|
7
|
+
ta as BatteryBehavior,
|
|
8
|
+
Q as BatteryState,
|
|
9
|
+
aa as BehaviorRegistry,
|
|
10
|
+
q as CIRCUIT_FILE_VERSION,
|
|
11
|
+
P as COMPONENT_TYPE_METADATA,
|
|
12
|
+
S as CameraOptions,
|
|
13
|
+
Ba as Circuit,
|
|
14
|
+
Aa as CircuitMetadata,
|
|
15
|
+
Y as CircuitOptions,
|
|
16
|
+
Z as CircuitRunner,
|
|
17
|
+
I as ClockBehavior,
|
|
18
|
+
la as ClockState,
|
|
19
|
+
W as Component,
|
|
20
|
+
Ca as ComponentState,
|
|
21
|
+
ga as ComponentType,
|
|
22
|
+
Oa as DEFAULT_LOGIC_FAMILY,
|
|
23
|
+
ha as DirtyTracker,
|
|
24
|
+
o as DoubleThrowSwitchBehavior,
|
|
22
25
|
m as DoubleThrowSwitchState,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
F as
|
|
26
|
+
ra as ENode,
|
|
27
|
+
k as ENodeSourceType,
|
|
28
|
+
Da as ENodeType,
|
|
29
|
+
sa as EightBitAdderBehavior,
|
|
30
|
+
C as EightBitAdderState,
|
|
31
|
+
x as EightBitOnesComplementBehavior,
|
|
32
|
+
p as EightBitOnesComplementState,
|
|
33
|
+
ca as EventQueue,
|
|
34
|
+
H as HalfAdderBehavior,
|
|
35
|
+
v as HalfAdderState,
|
|
36
|
+
La as InverterBehavior,
|
|
37
|
+
c as InverterState,
|
|
38
|
+
N as LightbulbBehavior,
|
|
39
|
+
t as LightbulbState,
|
|
40
|
+
ea as Memoize,
|
|
41
|
+
s as MemoizeExpiring,
|
|
42
|
+
ya as Nand4GateBehavior,
|
|
43
|
+
R as Nand4GateState,
|
|
44
|
+
Ta as Nand8GateBehavior,
|
|
45
|
+
O as Nand8GateState,
|
|
46
|
+
F as NandGateBehavior,
|
|
47
|
+
d as NandGateState,
|
|
48
|
+
j as Nor4GateBehavior,
|
|
49
|
+
_ as Nor4GateState,
|
|
50
|
+
J as Nor8GateBehavior,
|
|
51
|
+
i as Nor8GateState,
|
|
52
|
+
w as NorGateBehavior,
|
|
44
53
|
l as NorGateState,
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
54
|
+
Ia as Position,
|
|
55
|
+
A as Position3D,
|
|
56
|
+
n as RectangleLEDBehavior,
|
|
57
|
+
f as RectangleLEDState,
|
|
58
|
+
h as RelayBehavior,
|
|
59
|
+
M as RelayState,
|
|
60
|
+
r as Rotation,
|
|
61
|
+
$ as SIMULATION_SPEED,
|
|
62
|
+
Sa as SimulationState,
|
|
63
|
+
D as SmallLEDBehavior,
|
|
64
|
+
g as SmallLEDState,
|
|
65
|
+
U as StateManager,
|
|
66
|
+
ua as SwitchBehavior,
|
|
67
|
+
b as SwitchState,
|
|
68
|
+
X as TRANSITION_DEFAULTS,
|
|
69
|
+
da as Wire,
|
|
70
|
+
va as Xor4GateBehavior,
|
|
71
|
+
u as Xor4GateState,
|
|
72
|
+
V as Xor8GateBehavior,
|
|
73
|
+
G as Xor8GateState,
|
|
74
|
+
oa as XorGateBehavior,
|
|
75
|
+
_a as XorGateState,
|
|
76
|
+
Ga as classifyGate,
|
|
77
|
+
z as computeGateDelay,
|
|
78
|
+
ia as computeTransitionSpan,
|
|
79
|
+
y as findPositionBestIndex,
|
|
80
|
+
L as generateUUID,
|
|
81
|
+
e as getTransitionSpan,
|
|
82
|
+
pa as registerArithmeticComponentsBehaviors,
|
|
83
|
+
na as registerBasicComponentsBehaviors,
|
|
84
|
+
Ea as registerGatesComponentsBehaviors,
|
|
85
|
+
B as simplifyPositions,
|
|
86
|
+
ma as unionElectricalStates
|
|
77
87
|
};
|
package/dist/core/setup.d.ts
CHANGED
|
@@ -15,3 +15,11 @@ export declare function registerBasicComponentsBehaviors(registry: BehaviorRegis
|
|
|
15
15
|
* @return the input behavior registry for chaining
|
|
16
16
|
*/
|
|
17
17
|
export declare function registerGatesComponentsBehaviors(registry: BehaviorRegistry): BehaviorRegistry;
|
|
18
|
+
/**
|
|
19
|
+
* Register all arithmetic component behaviors in the given registry
|
|
20
|
+
* Arithmetic components are : HalfAdder, Adder, 8bit adder, 8bit one's complement
|
|
21
|
+
* @public
|
|
22
|
+
* @param registry
|
|
23
|
+
* @return the input behavior registry for chaining
|
|
24
|
+
*/
|
|
25
|
+
export declare function registerArithmeticComponentsBehaviors(registry: BehaviorRegistry): BehaviorRegistry;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Component } from '../../../topology/Component';
|
|
2
|
+
import { ComponentState } from '../../states/ComponentState';
|
|
3
|
+
import { INodeElectricalState } from '../../states/types';
|
|
4
|
+
import { IComponentBehavior } from '../types';
|
|
5
|
+
import { ArithmeticBehaviorMixin } from './ArithmeticBehaviorMixin';
|
|
6
|
+
/**
|
|
7
|
+
* Behavior for the Full Adder component (two half adders + OR on carries).
|
|
8
|
+
*
|
|
9
|
+
* Three logic inputs (`inputA`, `inputB`, `carryIn`) and two logic outputs
|
|
10
|
+
* (`sum`, `carryOut`):
|
|
11
|
+
*
|
|
12
|
+
* - `sum = A XOR B XOR carryIn` (parity of the three inputs)
|
|
13
|
+
* - `carryOut = majority(A, B, carryIn)` (two or more inputs high)
|
|
14
|
+
*
|
|
15
|
+
* State encoding follows `${sumBit}${carryBit}` — see {@link AdderState}. All
|
|
16
|
+
* four stable states are reachable; `A = B = carryIn = 1` yields `'11'`.
|
|
17
|
+
*
|
|
18
|
+
* A single medium `transitionSpan` from config is used for every transition,
|
|
19
|
+
* since modeling the cumulative XOR/AND/OR delays per input-output pair would
|
|
20
|
+
* be more complexity than this library's teaching scope warrants.
|
|
21
|
+
*
|
|
22
|
+
* @public
|
|
23
|
+
*/
|
|
24
|
+
export declare class AdderBehavior extends ArithmeticBehaviorMixin implements IComponentBehavior {
|
|
25
|
+
constructor();
|
|
26
|
+
createInitialState(component: Component): ComponentState;
|
|
27
|
+
protected computeTargetStableState(pinStates: Map<string, INodeElectricalState>): string;
|
|
28
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Component } from '../../../topology/Component';
|
|
2
|
+
import { ComponentState } from '../../states/ComponentState';
|
|
3
|
+
import { INodeElectricalState } from '../../states/types';
|
|
4
|
+
import { UUID } from '../../../utils/types';
|
|
5
|
+
import { ENodeSourceType } from '../../../topology/types';
|
|
6
|
+
import { IBehaviorResult } from '../types';
|
|
7
|
+
import { IScheduledEvent } from '../../types';
|
|
8
|
+
import { ComponentBehaviorMixin } from '../ComponentBehavior';
|
|
9
|
+
import { ArithmeticState } from '../../states/arithmetic/ArithmeticState';
|
|
10
|
+
/**
|
|
11
|
+
* Factorises the common plumbing of arithmetic component behaviors:
|
|
12
|
+
*
|
|
13
|
+
* - `vccGuardBehavior` — on vcc loss, drop all outputs low immediately.
|
|
14
|
+
* - `nonLogicInputGuardBehavior` — on any ill-defined logic input, go to
|
|
15
|
+
* `'indeterminate'` immediately.
|
|
16
|
+
* - `onPinsChange` is a **template method** that runs the guards then calls
|
|
17
|
+
* `computeTargetStableState` (subclass-provided) and schedules the
|
|
18
|
+
* transition via `scheduleTransition`.
|
|
19
|
+
* - `scheduleTransition` — encode the `to${target}` transient state, schedule
|
|
20
|
+
* the completion event and preserve the previous stable state in
|
|
21
|
+
* `parameters.prevState` so `allowConductivity` keeps the old outputs
|
|
22
|
+
* energized until the transition fires.
|
|
23
|
+
* - `onEventFiring` — land on the target stable state when the scheduled
|
|
24
|
+
* transition completes.
|
|
25
|
+
* - `allowConductivity` — generic per-output lookup driven by
|
|
26
|
+
*
|
|
27
|
+
* Subclasses must declare `outputPinLabels` in the **same order** as the
|
|
28
|
+
* state encoding used by their {@link ArithmeticState} subclass and
|
|
29
|
+
* implement `computeTargetStableState` to turn the current input pins into
|
|
30
|
+
* that encoding.
|
|
31
|
+
*/
|
|
32
|
+
export declare abstract class ArithmeticBehaviorMixin extends ComponentBehaviorMixin {
|
|
33
|
+
/**
|
|
34
|
+
* Compute the target stable-state encoding from the current pin states.
|
|
35
|
+
* Called only after vcc / non-logic guards have passed.
|
|
36
|
+
*/
|
|
37
|
+
protected abstract computeTargetStableState(pinStates: Map<string, INodeElectricalState>): string;
|
|
38
|
+
onPinsChange(component: Component, state: ComponentState, nodeStates: ReadonlyMap<UUID, INodeElectricalState>, targetTick: number): IBehaviorResult;
|
|
39
|
+
onEventFiring(_component: Component, state: ComponentState, event: IScheduledEvent): IBehaviorResult;
|
|
40
|
+
allowConductivity(component: Component, state: ComponentState, _conductivityType: ENodeSourceType, pinId: string, otherPinId: string): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* On vcc loss: all outputs go low immediately.
|
|
43
|
+
* Returns `null` when vcc is present so callers can proceed.
|
|
44
|
+
*/
|
|
45
|
+
protected vccGuardBehavior(state: ArithmeticState, pinStates: Map<string, INodeElectricalState>, targetTick: number): IBehaviorResult | null;
|
|
46
|
+
/**
|
|
47
|
+
* Scan all logic inputs; if any is ill-defined (both voltage and ground,
|
|
48
|
+
* or neither), switch to `'indeterminate'` immediately. Otherwise returns
|
|
49
|
+
* `null` so the caller can proceed.
|
|
50
|
+
*/
|
|
51
|
+
protected nonLogicInputGuardBehavior(state: ArithmeticState, pinStates: Map<string, INodeElectricalState>, targetTick: number): IBehaviorResult | null;
|
|
52
|
+
/**
|
|
53
|
+
* Schedule a transition toward the given stable target state. If already
|
|
54
|
+
* there (or already heading there) returns a no-change result.
|
|
55
|
+
*
|
|
56
|
+
* Preserves the currently-driving stable state in `parameters.prevState` so
|
|
57
|
+
* `allowConductivity` keeps the old outputs energized until the scheduled
|
|
58
|
+
* event fires. When the previous effective state is `'indeterminate'` the
|
|
59
|
+
* fallback is all-zeros.
|
|
60
|
+
*/
|
|
61
|
+
protected scheduleTransition(component: Component, state: ArithmeticState, targetState: string, targetTick: number): IBehaviorResult;
|
|
62
|
+
protected noChange(state: ComponentState): IBehaviorResult;
|
|
63
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Component } from '../../../topology/Component';
|
|
2
|
+
import { ComponentState } from '../../states/ComponentState';
|
|
3
|
+
import { INodeElectricalState } from '../../states/types';
|
|
4
|
+
import { IComponentBehavior, IBehaviorResult } from '../types';
|
|
5
|
+
import { IScheduledEvent } from '../../types';
|
|
6
|
+
import { UUID } from '../../../utils/types';
|
|
7
|
+
import { ArithmeticBehaviorMixin } from './ArithmeticBehaviorMixin';
|
|
8
|
+
/**
|
|
9
|
+
* Behavior for the 8-bit ripple carry adder (8 full adders in series).
|
|
10
|
+
*
|
|
11
|
+
* Unlike the single full adder whose output settles in one transition, the
|
|
12
|
+
* 8-bit adder models **carry propagation**: when inputs change, only stage 0
|
|
13
|
+
* recomputes immediately (with its own propagation delay); the carry then
|
|
14
|
+
* ripples through stages 1–7, one `transitionSpan` per stage.
|
|
15
|
+
*
|
|
16
|
+
* ### State encoding
|
|
17
|
+
*
|
|
18
|
+
* 16 interleaved bits `C7S7 C6S6 … C1S1 C0S0` stored as a 4-digit hex
|
|
19
|
+
* string. Sum at bit `2*i`, carry at bit `2*i+1`.
|
|
20
|
+
* See {@link EightBitAdderState}.
|
|
21
|
+
*
|
|
22
|
+
* ### Ripple algorithm
|
|
23
|
+
*
|
|
24
|
+
* - **`onPinsChange`**: computes ALL 8 stages with new inputs but **old
|
|
25
|
+
* carries** from the current effective state, producing an intermediate
|
|
26
|
+
* state. Schedules one event for carry propagation starting at stage 1.
|
|
27
|
+
* Uses `shouldCancelPending: true` to restart the ripple cleanly when
|
|
28
|
+
* inputs change mid-propagation.
|
|
29
|
+
*
|
|
30
|
+
* - **`onEventFiring`**: lands on the intermediate, then checks whether the
|
|
31
|
+
* next stage's carry-in changed. If so, recomputes that stage, builds the
|
|
32
|
+
* next intermediate, and schedules the following stage. If not, the carry
|
|
33
|
+
* has stopped and the state is stable. Uses `shouldCancelPending: false`.
|
|
34
|
+
*
|
|
35
|
+
* - **Initialization shortcut**: at `targetTick === 0` the full stable state
|
|
36
|
+
* is computed directly via {@link computeTargetStableState} to avoid the
|
|
37
|
+
* init-loop limitation where chained events are dropped.
|
|
38
|
+
*
|
|
39
|
+
* @public
|
|
40
|
+
*/
|
|
41
|
+
export declare class EightBitAdderBehavior extends ArithmeticBehaviorMixin implements IComponentBehavior {
|
|
42
|
+
constructor();
|
|
43
|
+
createInitialState(component: Component): ComponentState;
|
|
44
|
+
onPinsChange(component: Component, state: ComponentState, nodeStates: ReadonlyMap<UUID, INodeElectricalState>, targetTick: number): IBehaviorResult;
|
|
45
|
+
onEventFiring(component: Component, state: ComponentState, event: IScheduledEvent): IBehaviorResult;
|
|
46
|
+
/**
|
|
47
|
+
* Compute the fully-settled stable state by propagating the carry chain
|
|
48
|
+
* through all 8 stages. Used at initialization and for test verification.
|
|
49
|
+
*/
|
|
50
|
+
protected computeTargetStableState(pinStates: Map<string, INodeElectricalState>): string;
|
|
51
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Component } from '../../../topology/Component';
|
|
2
|
+
import { ComponentState } from '../../states/ComponentState';
|
|
3
|
+
import { INodeElectricalState } from '../../states/types';
|
|
4
|
+
import { IComponentBehavior } from '../types';
|
|
5
|
+
import { ENodeSourceType } from '../../../topology/types';
|
|
6
|
+
import { ArithmeticBehaviorMixin } from './ArithmeticBehaviorMixin';
|
|
7
|
+
/**
|
|
8
|
+
* Behavior for the 8-bit one's complement (8 parallel XOR gates with shared
|
|
9
|
+
* `invert` input).
|
|
10
|
+
*
|
|
11
|
+
* When `invert` is high every output is the bitwise NOT of its input; when low
|
|
12
|
+
* outputs pass through unchanged. All 8 gates fire in parallel — a single
|
|
13
|
+
* `transitionSpan` covers the whole transition (no ripple).
|
|
14
|
+
*
|
|
15
|
+
* State encoding: 9 bits as a 3-hex-char string. Bits 0–7 are outputs,
|
|
16
|
+
* bit 8 is the invert flag. See {@link EightBitOnesComplementState}.
|
|
17
|
+
*
|
|
18
|
+
* The mixin's default `onPinsChange` / `onEventFiring` / `scheduleTransition`
|
|
19
|
+
* handle everything — only `computeTargetStableState` and
|
|
20
|
+
* `allowConductivity` need implementation.
|
|
21
|
+
*
|
|
22
|
+
* @public
|
|
23
|
+
*/
|
|
24
|
+
export declare class EightBitOnesComplementBehavior extends ArithmeticBehaviorMixin implements IComponentBehavior {
|
|
25
|
+
constructor();
|
|
26
|
+
createInitialState(component: Component): ComponentState;
|
|
27
|
+
allowConductivity(component: Component, state: ComponentState, _conductivityType: ENodeSourceType, pinId: string, otherPinId: string): boolean;
|
|
28
|
+
protected computeTargetStableState(pinStates: Map<string, INodeElectricalState>): string;
|
|
29
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Component } from '../../../topology/Component';
|
|
2
|
+
import { ComponentState } from '../../states/ComponentState';
|
|
3
|
+
import { INodeElectricalState } from '../../states/types';
|
|
4
|
+
import { IComponentBehavior } from '../types';
|
|
5
|
+
import { ArithmeticBehaviorMixin } from './ArithmeticBehaviorMixin';
|
|
6
|
+
/**
|
|
7
|
+
* Behavior for the Half Adder component (XOR + AND in one block).
|
|
8
|
+
*
|
|
9
|
+
* - `sum = A XOR B`
|
|
10
|
+
* - `carry = A AND B`
|
|
11
|
+
*
|
|
12
|
+
* State encoding follows `${sumBit}${carryBit}` — see {@link HalfAdderState}.
|
|
13
|
+
* Because `sum` and `carry` can never both be high, only three stable states
|
|
14
|
+
* are reachable: `'00' | '10' | '01'`.
|
|
15
|
+
*
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
export declare class HalfAdderBehavior extends ArithmeticBehaviorMixin implements IComponentBehavior {
|
|
19
|
+
constructor();
|
|
20
|
+
createInitialState(component: Component): ComponentState;
|
|
21
|
+
protected computeTargetStableState(pinStates: Map<string, INodeElectricalState>): string;
|
|
22
|
+
}
|
|
@@ -22,3 +22,7 @@ export { Nor8GateBehavior } from './gates/Nor8GateBehavior';
|
|
|
22
22
|
export { XorGateBehavior } from './gates/XorGateBehavior';
|
|
23
23
|
export { Xor4GateBehavior } from './gates/Xor4GateBehavior';
|
|
24
24
|
export { Xor8GateBehavior } from './gates/Xor8GateBehavior';
|
|
25
|
+
export { HalfAdderBehavior } from './arithmetic/HalfAdderBehavior';
|
|
26
|
+
export { AdderBehavior } from './arithmetic/AdderBehavior';
|
|
27
|
+
export { EightBitAdderBehavior } from './arithmetic/EightBitAdderBehavior';
|
|
28
|
+
export { EightBitOnesComplementBehavior } from './arithmetic/EightBitOnesComplementBehavior';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { UUID } from '../../../utils/types';
|
|
2
|
+
import { ArithmeticState } from './ArithmeticState';
|
|
3
|
+
/**
|
|
4
|
+
* Simulation state for Full Adder components.
|
|
5
|
+
*
|
|
6
|
+
* Hex-encoded stable states: `'0'` (both low), `'1'` (sum high),
|
|
7
|
+
* `'2'` (carry high), `'3'` (both high). All four are reachable;
|
|
8
|
+
* in particular `A = B = carryIn = 1` yields `'3'`.
|
|
9
|
+
*
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
export declare class AdderState extends ArithmeticState {
|
|
13
|
+
constructor(componentId: UUID, initialState?: string);
|
|
14
|
+
get sumHigh(): boolean;
|
|
15
|
+
get carryOutHigh(): boolean;
|
|
16
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { UUID } from '../../../utils/types';
|
|
2
|
+
import { ComponentState } from '../ComponentState';
|
|
3
|
+
/**
|
|
4
|
+
* Base simulation state for arithmetic components (half adder, full adder and
|
|
5
|
+
* future multi-bit adders, multiplexers, ...).
|
|
6
|
+
*
|
|
7
|
+
* Stable states are encoded as a zero-padded hexadecimal string where each
|
|
8
|
+
* bit position maps to one logic output. Simple components use one bit per
|
|
9
|
+
* output in declaration order (bit 0 = first logicOutput). For example a
|
|
10
|
+
* half-adder with sum (bit 0) and carry (bit 1) uses `'0'`..`'3'`.
|
|
11
|
+
*
|
|
12
|
+
* Components with internal carry chains (e.g. 8-bit ripple adder) use an
|
|
13
|
+
* **interleaved** encoding `CiSi` where sum occupies even bits (`2*i`) and
|
|
14
|
+
* carry occupies odd bits (`2*i + 1`). This stores intermediate carries for
|
|
15
|
+
* ripple animation, giving `outputCount = 2 * stageCount` (e.g. 16 bits /
|
|
16
|
+
* 4 hex digits for 8 stages, states `'0000'`..`'ffff'`).
|
|
17
|
+
*
|
|
18
|
+
* Transient (in-flight) states follow the `to${nextState}` convention so
|
|
19
|
+
* animations can be driven generically from `state`/`nextState`. The
|
|
20
|
+
* previously-held stable state is preserved in `parameters.prevState` so the
|
|
21
|
+
* behavior's `allowConductivity` keeps the old outputs energized until the
|
|
22
|
+
* transition fires.
|
|
23
|
+
*
|
|
24
|
+
* A special `'indeterminate'` state is used when any logic input is ill-defined.
|
|
25
|
+
*
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
export declare abstract class ArithmeticState extends ComponentState {
|
|
29
|
+
/**
|
|
30
|
+
* Number of logic outputs for this state
|
|
31
|
+
* (e.g. 2 for half/full adder, 9 for an 8-bit adder: 8 sum bits + carry out).
|
|
32
|
+
*/
|
|
33
|
+
readonly outputCount: number;
|
|
34
|
+
/** Number of hex digits needed to encode all outputs. */
|
|
35
|
+
readonly hexDigitCount: number;
|
|
36
|
+
/** All-outputs-low state string (e.g. `'0'` for 2 outputs, `'000'` for 9). */
|
|
37
|
+
readonly allLowState: string;
|
|
38
|
+
protected constructor(componentId: UUID, outputCount: number, initialState: string);
|
|
39
|
+
/** True when the current state is a transient `to${stable}` transition. */
|
|
40
|
+
get isInTransition(): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Stable state that effectively drives the outputs right now:
|
|
43
|
+
* - stable state → returns that state
|
|
44
|
+
* - transient `to<hex>` → returns the previous stable kept in parameters
|
|
45
|
+
* - `'indeterminate'` → returns `'indeterminate'`
|
|
46
|
+
*/
|
|
47
|
+
get effectiveState(): string;
|
|
48
|
+
/**
|
|
49
|
+
* Whether the `index`-th output is high in the current effective state.
|
|
50
|
+
* Returns `false` when effective state is `'indeterminate'`.
|
|
51
|
+
*/
|
|
52
|
+
isOutputHigh(index: number): boolean;
|
|
53
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { UUID } from '../../../utils/types';
|
|
2
|
+
import { ArithmeticState } from './ArithmeticState';
|
|
3
|
+
/**
|
|
4
|
+
* Simulation state for the 8-bit ripple carry adder.
|
|
5
|
+
*
|
|
6
|
+
* Uses an interleaved 16-bit encoding `C7S7 C6S6 … C1S1 C0S0` where each
|
|
7
|
+
* stage occupies two bits: sum at even position (`2*i`) and carry at odd
|
|
8
|
+
* position (`2*i + 1`). This stores intermediate carries so the ripple
|
|
9
|
+
* animation can show carry propagation stage by stage.
|
|
10
|
+
*
|
|
11
|
+
* Stable states range from `'0000'` (all low) to `'ffff'` (all high).
|
|
12
|
+
* The external outputs are `sum-0`..`sum-7` (bits 0,2,4,…,14) and
|
|
13
|
+
* `carryOut` (bit 15 = C7).
|
|
14
|
+
*
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
export declare class EightBitAdderState extends ArithmeticState {
|
|
18
|
+
constructor(componentId: UUID, initialState?: string);
|
|
19
|
+
/** Whether stage `i`'s sum output is high in the current effective state. */
|
|
20
|
+
isSumHigh(stageIndex: number): boolean;
|
|
21
|
+
/** Whether stage `i`'s internal carry is high in the current effective state. */
|
|
22
|
+
isStageCarryHigh(stageIndex: number): boolean;
|
|
23
|
+
/** Whether the final carry out (C7) is high — drives the `carryOut` pin. */
|
|
24
|
+
isCarryOutHigh(): boolean;
|
|
25
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { UUID } from '../../../utils/types';
|
|
2
|
+
import { ArithmeticState } from './ArithmeticState';
|
|
3
|
+
/**
|
|
4
|
+
* Simulation state for the 8-bit one's complement (8 parallel XOR gates).
|
|
5
|
+
*
|
|
6
|
+
* Uses a 9-bit encoding stored as a 3-digit hex string (`'000'`..`'1ff'`):
|
|
7
|
+
* - Bits 0–7: output values (`output-i = input-i XOR invert`)
|
|
8
|
+
* - Bit 8: current invert input value (stored for animation)
|
|
9
|
+
*
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
export declare class EightBitOnesComplementState extends ArithmeticState {
|
|
13
|
+
constructor(componentId: UUID, initialState?: string);
|
|
14
|
+
/** Whether output bit `index` (0–7) is high in the current effective state. */
|
|
15
|
+
isOutputBitHigh(index: number): boolean;
|
|
16
|
+
/** Whether the invert flag (bit 8) is high in the current effective state. */
|
|
17
|
+
isInvertHigh(): boolean;
|
|
18
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { UUID } from '../../../utils/types';
|
|
2
|
+
import { ArithmeticState } from './ArithmeticState';
|
|
3
|
+
/**
|
|
4
|
+
* Simulation state for Half Adder components.
|
|
5
|
+
*
|
|
6
|
+
* Hex-encoded stable states: `'0'` (both low), `'1'` (sum high),
|
|
7
|
+
* `'2'` (carry high). `'3'` is unreachable because `sum = A XOR B`
|
|
8
|
+
* and `carry = A AND B` can never both be true.
|
|
9
|
+
*
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
export declare class HalfAdderState extends ArithmeticState {
|
|
13
|
+
constructor(componentId: UUID, initialState?: string);
|
|
14
|
+
get sumHigh(): boolean;
|
|
15
|
+
get carryHigh(): boolean;
|
|
16
|
+
}
|
|
@@ -24,3 +24,8 @@ export { Nor8GateState } from './gates/Nor8GateState';
|
|
|
24
24
|
export { XorGateState } from './gates/XorGateState';
|
|
25
25
|
export { Xor4GateState } from './gates/Xor4GateState';
|
|
26
26
|
export { Xor8GateState } from './gates/Xor8GateState';
|
|
27
|
+
export { ArithmeticState } from './arithmetic/ArithmeticState';
|
|
28
|
+
export { HalfAdderState } from './arithmetic/HalfAdderState';
|
|
29
|
+
export { AdderState } from './arithmetic/AdderState';
|
|
30
|
+
export { EightBitAdderState } from './arithmetic/EightBitAdderState';
|
|
31
|
+
export { EightBitOnesComplementState } from './arithmetic/EightBitOnesComplementState';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { UUID, Position, Rotation } from '../utils';
|
|
2
|
-
import { ComponentType, IComponent } from './types';
|
|
2
|
+
import { ComponentType, IComponent, IPinMetadata } from './types';
|
|
3
3
|
/**
|
|
4
4
|
* Electrical component placed on the circuit grid.
|
|
5
5
|
*
|
|
@@ -96,6 +96,7 @@ export declare class Component {
|
|
|
96
96
|
*/
|
|
97
97
|
constructor(type: ComponentType, position: Position, rotation: Rotation, pins: ReadonlyArray<UUID>, editable?: boolean);
|
|
98
98
|
getPinLabel(pinId: UUID): string | undefined;
|
|
99
|
+
getPinMetadata(pinId: UUID): IPinMetadata | undefined;
|
|
99
100
|
setAllParameters(config: Map<string, string>): void;
|
|
100
101
|
setParameter(key: string, value: string): void;
|
|
101
102
|
/**
|