| import {onMount, onDestroy} from 'svelte'; | import {onMount, onDestroy} from 'svelte'; | ||||
| export let components; | export let components; | ||||
| export let nodes = []; | |||||
| class LogicSim { | class LogicSim { | ||||
| constructor(can) { | constructor(can) { | ||||
| onMount(() => { | onMount(() => { | ||||
| sim = new LogicSim(canvas); | sim = new LogicSim(canvas); | ||||
| for (let node of nodes) { | |||||
| sim.nodes.push(node); | |||||
| } | |||||
| interval = setInterval(sim.update.bind(sim), 100); | interval = setInterval(sim.update.bind(sim), 100); | ||||
| }); | }); | ||||
| if (path[0] != "/") { | if (path[0] != "/") { | ||||
| console.error("Illegal path:", path); | console.error("Illegal path:", path); | ||||
| path = "/"; | path = "/"; | ||||
| } else if (path == "") { | |||||
| path = "/"; | |||||
| } | } | ||||
| let parts = path.split("/").filter(el => el != ""); | let parts = path.split("/").filter(el => el != ""); |
| import * as comps from './circuit-components.js'; | import * as comps from './circuit-components.js'; | ||||
| let components = [ | let components = [ | ||||
| {name: "Input", ctor: comps.Input}, | |||||
| {name: "Switch", ctor: comps.Switch}, | |||||
| {name: "NotGate", ctor: comps.NotGate}, | {name: "NotGate", ctor: comps.NotGate}, | ||||
| {name: "Diode", ctor: comps.Diode}, | {name: "Diode", ctor: comps.Diode}, | ||||
| {name: "Lamp", ctor: comps.Lamp}, | {name: "Lamp", ctor: comps.Lamp}, |
| {:else} | {:else} | ||||
| <button on:click={begin}>Begin</button> | <button on:click={begin}>Begin</button> | ||||
| {/if} | {/if} | ||||
| <button on:click={begin}>Skip</button> | |||||
| <button on:click={begin} disabled={page == level.pages.length - 1}>Skip</button> | |||||
| </div> | </div> | ||||
| {:else} | {:else} | ||||
| <CircuitSim components={components} /> | |||||
| <CircuitSim components={components} nodes={nodes} /> | |||||
| {/if} | {/if} | ||||
| </main> | </main> | ||||
| return {name, ctor: availableComponents[name]}; | return {name, ctor: availableComponents[name]}; | ||||
| }); | }); | ||||
| let nodes = []; | |||||
| let y = 0; | |||||
| for (let name of level.inputs) { | |||||
| nodes.push(new availableComponents.Input(-4, y, name)); | |||||
| y += 2; | |||||
| } | |||||
| y = 0; | |||||
| for (let name of level.outputs) { | |||||
| nodes.push(new availableComponents.Output(4, y, name)); | |||||
| y += 2; | |||||
| } | |||||
| let page = 0; | let page = 0; | ||||
| let showIntro = true; | let showIntro = true; | ||||
| } | } | ||||
| export class Input { | export class Input { | ||||
| constructor(x, y, name) { | |||||
| this.name = name || "Input"; | |||||
| this.x = x; | |||||
| this.y = y; | |||||
| this.inputs = []; | |||||
| this.outputs = [{name: "Input", link: new Link(this, 0)}]; | |||||
| this.width = 4; | |||||
| this.height = 1; | |||||
| this.lit = false; | |||||
| } | |||||
| activate() { | |||||
| this.lit = !this.lit; | |||||
| } | |||||
| tick() { | |||||
| if (this.lit) { | |||||
| this.outputs[0].link.next = true; | |||||
| } else { | |||||
| this.outputs[0].link.next = false; | |||||
| } | |||||
| } | |||||
| commit() { | |||||
| this.outputs[0].link.commit(); | |||||
| } | |||||
| } | |||||
| export class Output { | |||||
| constructor(x, y, name) { | |||||
| this.name = name || "Output"; | |||||
| this.x = x; | |||||
| this.y = y; | |||||
| this.inputs = [{name: "Output", links: []}]; | |||||
| this.outputs = []; | |||||
| this.width = 4; | |||||
| this.height = 1; | |||||
| this.lit = false; | |||||
| this.nextLit = false; | |||||
| } | |||||
| tick() { | |||||
| this.nextLit = false; | |||||
| for (let link of this.inputs[0].links) { | |||||
| if (link.current) { | |||||
| this.nextLit = true; | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| commit() { | |||||
| this.lit = this.nextLit; | |||||
| } | |||||
| } | |||||
| export class Switch { | |||||
| constructor(x, y) { | constructor(x, y) { | ||||
| this.name = "IN"; | |||||
| this.name = "OFF"; | |||||
| this.x = x; | this.x = x; | ||||
| this.y = y; | this.y = y; | ||||
| this.inputs = []; | this.inputs = []; | ||||
| activate() { | activate() { | ||||
| this.lit = !this.lit; | this.lit = !this.lit; | ||||
| this.name = this.lit ? "ON" : "OFF"; | |||||
| } | } | ||||
| tick() { | tick() { |
| "LED", | "LED", | ||||
| ], | ], | ||||
| components: [ | components: [ | ||||
| "Input", | |||||
| "Switch", | |||||
| "NotGate", | "NotGate", | ||||
| ], | ], | ||||