diff --git a/src/ts/common/componentManager/componentManager.ts b/src/ts/common/componentManager/componentManager.ts index deb13fe..1fc07a3 100644 --- a/src/ts/common/componentManager/componentManager.ts +++ b/src/ts/common/componentManager/componentManager.ts @@ -18,13 +18,14 @@ import { modal } from "../modals"; import { map } from "rxjs/operators"; import { persistent } from "../store/persistent"; +const defaultName = "default" @Singleton export class ComponentManager { public components: Component[] = [] public svgs = new Subject() public placeholder = new BehaviorSubject("Create simulation") - public saves = new BehaviorSubject(["hello world"]) + public barAlpha = new BehaviorSubject("0"); private temporaryCommnad = "" private onTop: Component @@ -34,6 +35,13 @@ export class ComponentManager { private wireManager = new WireManager() private templateStore = new ComponentTemplateStore() private settings = new Settings() + private standard: { + offset: number + scale: [number, number] + } = { + offset: 50, + scale: [100, 100] + } private commandHistoryStore = new Store("commandHistory") private store = new Store("simulationStates") @@ -49,7 +57,7 @@ export class ComponentManager { private upEvent = new KeyboardInput("up") private downEvent = new KeyboardInput("down") - @persistent("current", "main'") + @persistent(defaultName, "main") public name: string public alertOptions = alertOptions @@ -88,7 +96,8 @@ export class ComponentManager { } private inputMode: string - public barAlpha = new BehaviorSubject("0"); + public gates = this.templateStore.store.lsChanges + public saves = this.store.lsChanges constructor() { runCounter.increase() @@ -150,7 +159,10 @@ export class ComponentManager { this.placeholder.next("Command palette") } else if (this.clearEvent.value) { - this.clear() + if (this.shiftEvent.value) + this.clear() + else + this.smartClear() } else if (this.saveEvent.value) { this.save() @@ -163,7 +175,6 @@ export class ComponentManager { }) this.wireManager.update.subscribe(val => this.update()) - this.saves.next(this.store.ls()) if (this.saves.value.length === 0) this.save() @@ -174,13 +185,14 @@ export class ComponentManager { this.inputMode = "create" this.placeholder.next("Create simulation") } - preInput() { + + private preInput() { const elem = document.getElementById("nameInput") elem.value = "" this.barAlpha.next("1") } - async create() { + private async create() { const elem = document.getElementById("nameInput") this.barAlpha.next("0") @@ -204,8 +216,35 @@ All you work will be lost!` return result } + public add(template: string, position?: [number, number]) { + const pos = position ? position : [...Array(2)].fill(this.standard.offset * this.components.length) as [number, number] + + this.components.push(new Component(template, pos, this.standard.scale)) + this.update() + } + + public async delete(name: string) { + const res = await modal({ + title: "Are you sure?", + content: html`Deleting a simulations is ireversible, and all work will be lost!` + }) + + if (res) { + if (this.name === name) { + if (this.saves.value.length > 1) { + this.switchTo(this.saves.value.find(val => val !== name)) + } + else { + let newName = (name === defaultName) ? `${defaultName}(1)` : defaultName + await this.createEmptySimulation(newName) + this.switchTo(newName) + } + } + this.store.delete(name) + } + } + public createEmptySimulation(name: string) { - console.log(name) const create = () => { this.store.set(name, { wires: [], @@ -230,8 +269,6 @@ All you work will be lost!` } public switchTo(name: string) { - console.log(`switching to ${name}`) - const data = this.store.get(name) if (!data) error(`An error occured when trying to load ${name}`, "", this.alertOptions) @@ -260,7 +297,15 @@ All you work will be lost!` "", this.alertOptions) } - clear() { + public smartClear() { + this.components = this.components.filter(({ id }) => + this.wireManager.wires.find(val => val.input.of.id == id || val.output.of.id == id) + ) + this.update() + success("Succesfully cleared all unconnected components", "", this.alertOptions) + } + + public clear() { this.components = [] this.wireManager.dispose() this.update() @@ -269,8 +314,6 @@ All you work will be lost!` } refresh() { - console.log(this.name) - if (this.store.get(this.name)) { this.loadState(this.store.get(this.name)) } @@ -424,7 +467,6 @@ All you work will be lost!` this.commandHistoryStore.set(i.toString(), element) } this.store.set(this.name, this.state) - this.saves.next(this.store.ls()) success(`Saved the simulation ${this.name} succesfully!`, "", this.alertOptions) } } \ No newline at end of file diff --git a/src/ts/common/store/store.ts b/src/ts/common/store/store.ts index 284fe24..32a6f67 100644 --- a/src/ts/common/store/store.ts +++ b/src/ts/common/store/store.ts @@ -1,23 +1,40 @@ +import { BehaviorSubject } from "rxjs"; + export class Store { - constructor(private name: string){ } + public lsChanges = new BehaviorSubject([]) + + constructor(private name: string){ + this.update() + } + + update(){ + this.lsChanges.next(this.ls()) + } get(key:string):T{ const data = localStorage[`${this.name}/${key}`] - + if(data) return JSON.parse(data).value - + return null } + delete(key:string){ + localStorage.removeItem(`${this.name}/${key}`) + this.update() + } + set(key:string,value:T){ localStorage[`${this.name}/${key}`] = JSON.stringify({ value }) + + this.update() return this } ls() { let keys = [] - + for (const i in localStorage){ if (i.indexOf(this.name) == 0) keys.push(i.substr(this.name.length + 1)) diff --git a/src/ts/common/wires/wireManager.ts b/src/ts/common/wires/wireManager.ts index 05ba719..042d6e3 100644 --- a/src/ts/common/wires/wireManager.ts +++ b/src/ts/common/wires/wireManager.ts @@ -11,8 +11,8 @@ import { WireState, WireStateVal } from "./interface"; export class WireManager { public start: Pin public end: Pin - - private wires: Wire[] = [] + + public wires: Wire[] = [] public update = new Subject() diff --git a/src/ts/main.ts b/src/ts/main.ts index 4a404fe..1a5170b 100644 --- a/src/ts/main.ts +++ b/src/ts/main.ts @@ -10,10 +10,6 @@ import { MDCMenu } from '@material/menu'; const screen = new Screen() const manager = new ComponentManager() -manager.components.push(new Component("and", [200, 100], [100, 100])) -// manager.components.push(new Component("not", [200, 500], [100, 100])) -// manager.components.push(new Component("true", [200, 500], [100, 100])) -// manager.components.push(new Component("false", [200, 500], [100, 100])) manager.save() manager.update() @@ -64,32 +60,50 @@ render(html` -
+
+
+ +
+
`, document.body) -const menu = new MDCMenu(document.querySelector('.mdc-menu')); -menu.hoistMenuToBody() -menu.setAnchorElement(document.querySelector(`#openSimulation`)) +const menus = [new MDCMenu(document.querySelector('#saveMenu')), new MDCMenu(document.querySelector('#gateMenu'))] +menus.forEach(menu => menu.hoistMenuToBody()) +menus[0].setAnchorElement(document.querySelector(`#openSimulation`)) +menus[1].setAnchorElement(document.querySelector("#openGates")) manager.update() \ No newline at end of file