From 731ceb6cd2d7b2a69bbd40679cb54938d23d04be Mon Sep 17 00:00:00 2001
From: Matei Adriel <rafaeladriel11@gmail.com>
Date: Tue, 4 Jun 2019 13:04:25 +0000
Subject: [PATCH] =?UTF-8?q?=20=F0=9F=8D=B3=20=20refactored=20some=20parts?=
 =?UTF-8?q?=20of=20the=20code=20and=20fixd=20the=20wire=20removing=20bug?=
 =?UTF-8?q?=20=F0=9F=93=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/ts/common/component/component.ts          | 39 ++++++---
 src/ts/common/component/material.ts           | 31 +++-----
 .../componentManager/componentManager.ts      | 79 ++++++++++---------
 src/ts/common/pin/pin.ts                      | 29 ++++---
 src/ts/common/wires/wire.ts                   |  5 +-
 src/ts/common/wires/wireManager.ts            | 11 ++-
 src/ts/main.ts                                | 11 ++-
 tsconfig.json                                 |  3 +-
 8 files changed, 113 insertions(+), 95 deletions(-)

diff --git a/src/ts/common/component/component.ts b/src/ts/common/component/component.ts
index a3a8f97..477de85 100644
--- a/src/ts/common/component/component.ts
+++ b/src/ts/common/component/component.ts
@@ -78,7 +78,6 @@ export class Component {
         })
 
         this.material = new Material(data.material.mode, data.material.data)
-
         this.activate()
     }
 
@@ -86,7 +85,7 @@ export class Component {
         this.subscriptions.forEach(val => val.unsubscribe())
     }
 
-    public handleMouseUp(e: MouseEvent) {
+    public handleMouseUp() {
         this.clicked = false
         this.clickedChanges.next(this.clicked)
     }
@@ -126,17 +125,35 @@ export class Component {
             this.activate(0)
         }
 
-        else if (e.button === 2){
-            manager.components = manager.components.filter(val => val !== this)
-            manager.wireManager.wires
-                .filter(val => val.input.of === this || val.output.of === this)
-                .forEach(val => val.dispose())
-            manager.wireManager.update.next(true)
-            manager.update()
+        else if (e.button === 2) {
+            // setTimeout(() => {
+                console.log("removed")
+                manager.components = manager.components.filter(({ id }) => id !== this.id)
+                manager.update()
+
+                manager.wireManager.wires
+                    .filter(val => val.input.of.id == this.id || val.output.of.id == this.id)
+                    .forEach(val => {
+                        manager.wireManager.remove(val)
+                    })
+                // manager.to
+
+                console.log("removed 1")
+
+                manager.wireManager.update.next(true)
+
+                console.log("removed 2")
+
+                manager.update()
+
+                console.log("removed 3")
+                console.log(manager.components)
+                console.log(manager.wireManager)
+            // }, 0)
         }
     }
 
-    handlePinClick(e: MouseEvent, pin: Pin) {
+    handlePinClick(pin: Pin) {
         Component.wireManager.add(pin)
     }
 
@@ -200,7 +217,7 @@ export class Component {
                     r=${pinScale}
                     cx=${x}
                     cy=${y} stroke-width=${stroke}
-                    @click=${(e: MouseEvent) => this.handlePinClick(e, val)}
+                    @click=${() => this.handlePinClick(val)}
                     ></circle>
                 `})
     }
diff --git a/src/ts/common/component/material.ts b/src/ts/common/component/material.ts
index ac7ad1e..5ab40de 100644
--- a/src/ts/common/component/material.ts
+++ b/src/ts/common/component/material.ts
@@ -1,42 +1,33 @@
-import { TemplateResult, svg, SVGTemplateResult, Part } from "lit-html";
-import { Subject, BehaviorSubject } from "rxjs";
+import { svg, Part } from "lit-html";
+import { BehaviorSubject } from "rxjs";
 import { materialMode } from "./interfaces";
 
-declare function require<T>(path:string):T
+declare function require<T>(path: string): T
 
-type partFactory = (part:Part) => void
+type partFactory = (part: Part) => void
 
 export class Material {
-    private static cache = false
     private static images: {
         [key: string]: string
     } = {
-        and: require("../../../assets/and_gate.jpg"),
-        or: require("../../../assets/or_gate.png"),
-        xor: require("../../../assets/xor_gate.png")
-    }
+            and: require("../../../assets/and_gate.jpg"),
+            or: require("../../../assets/or_gate.png"),
+            xor: require("../../../assets/xor_gate.png")
+        }
 
-    private static cached = new Map()
 
     public color = new BehaviorSubject<string>("rgba(0,0,0,0)")
 
-    constructor (public mode: materialMode,public name:string) {
-        const saved = Material.cached.get(mode + name)
-
-        if (saved && Material.cache)
-            return saved
-
-        else Material.cached.set(mode + name,this)
-
+    constructor(public mode: string, public name: materialMode | string) {
         if (this.mode === "color")
             this.color.next(name)
     }
 
-    innerHTML (x: partFactory, y: partFactory, w: partFactory, h: partFactory) {
+    innerHTML(x: partFactory, y: partFactory, w: partFactory, h: partFactory) {
         return svg`<foreignobject x=${x} y=${y} width=${w} height=${h}>
             <div class="component-container">
                 <img src=${Material.images[this.name]} height="97%" width="97%" draggable=false class="component">
-            </div>
+           </div>
         </foreignobject>`
     }
 }
\ No newline at end of file
diff --git a/src/ts/common/componentManager/componentManager.ts b/src/ts/common/componentManager/componentManager.ts
index 0e4371f..4e4579c 100644
--- a/src/ts/common/componentManager/componentManager.ts
+++ b/src/ts/common/componentManager/componentManager.ts
@@ -102,13 +102,13 @@ export class ComponentManager {
     public file: {
         [key: string]: () => void
     } = {
-        clear: () => this.clear(),
-        clean: () => this.smartClear(),
-        save: () => this.save(),
-        refresh: () => this.refresh(),
-        download: () => download(this,[],[]),
-        delete: () => this.delete(this.name)
-    }
+            clear: () => this.clear(),
+            clean: () => this.smartClear(),
+            save: () => this.save(),
+            refresh: () => this.refresh(),
+            download: () => download(this, [], []),
+            delete: () => this.delete(this.name)
+        }
 
     constructor() {
         runCounter.increase()
@@ -185,7 +185,11 @@ export class ComponentManager {
             }
         })
 
-        this.wireManager.update.subscribe(val => this.update())
+        this.wireManager.update.subscribe(() => {
+            // this.save()
+            this.update()
+            // this.save()
+        })
         if (this.saves.value.length === 0)
             this.save()
 
@@ -270,7 +274,7 @@ All you work will be lost!`
             this.refresh()
         }
 
-        return new Promise(async (res, rej) => {//get wheater theres already a simulation with that name
+        return new Promise(async (res) => {//get wheater theres already a simulation with that name
             if (this.store.get(name) && await this.handleDuplicateModal(name) ||
                 !this.store.get(name)) {
                 create()
@@ -341,51 +345,52 @@ All you work will be lost!`
         this.svgs.next(this.render())
     }
 
-    handleMouseDown(e: MouseEvent) {
+    handleMouseDown() {
         this.clicked = true
     }
 
-    handleMouseUp(e: MouseEvent) {
+    handleMouseUp() {
         this.clicked = false
     }
 
     handleMouseMove(e: MouseEvent) {
-        let toAddOnTop: number
-        let outsideComponents = true
+        if (e.button === 0) {
+            let toAddOnTop: number
+            let outsideComponents = true
 
-        for (let i = 0; i < this.components.length; i++) {
-            const component = this.components[i]
-            if (component.clicked) {
-                outsideComponents = false
-                component.move(e)
-                if (this.onTop != component) {
-                    toAddOnTop = i
+            for (let i = 0; i < this.components.length; i++) {
+                const component = this.components[i]
+                if (component.clicked) {
+                    outsideComponents = false
+                    component.move(e)
+                    if (this.onTop != component) {
+                        toAddOnTop = i
+                    }
                 }
             }
-        }
 
-        if (toAddOnTop >= 0) {
-            this.onTop = this.components[toAddOnTop]
-            this.components.push(this.onTop)
-            this.update()
-        }
+            if (toAddOnTop >= 0) {
+                this.onTop = this.components[toAddOnTop]
+                this.components.push(this.onTop)
+                this.update()
+            }
 
-        else if (outsideComponents && this.clicked) {
-            const mousePosition = [e.clientX, e.clientY]
-            const delta = mousePosition.map((value, index) =>
-                this.screen.mousePosition[index] - value
-            ) as [number, number]
-            this.screen.move(...delta)
+            else if (outsideComponents && this.clicked) {
+                const mousePosition = [e.clientX, e.clientY]
+                const delta = mousePosition.map((value, index) =>
+                    this.screen.mousePosition[index] - value
+                ) as [number, number]
+                this.screen.move(...delta)
+            }
         }
     }
 
     render() {
         let toRemoveDuplicatesFor: Component
 
-        const size = 10
         const result = this.components.map(component => {
-            const mouseupHandler = (e: MouseEvent) => {
-                component.handleMouseUp(e)
+            const mouseupHandler = () => {
+                component.handleMouseUp()
                 toRemoveDuplicatesFor = component
             }
 
@@ -433,7 +438,7 @@ All you work will be lost!`
         instances.pop()
 
         this.components = this.components
-            .filter((val, index) => instances.indexOf(index) != -1)
+            .filter((_, index) => instances.indexOf(index) != -1)
     }
 
     get state(): ManagerState {
@@ -472,7 +477,7 @@ All you work will be lost!`
         this.update()
     }
 
-    save(name?: string) {
+    save() {
         for (let i = 0; i < this.commandHistory.length; i++) {
             const element = this.commandHistory[i];
             this.commandHistoryStore.set(i.toString(), element)
diff --git a/src/ts/common/pin/pin.ts b/src/ts/common/pin/pin.ts
index d7ac859..b62da36 100644
--- a/src/ts/common/pin/pin.ts
+++ b/src/ts/common/pin/pin.ts
@@ -6,12 +6,15 @@ import { Component } from "../component";
 export class Pin {
     private static lastId = 0
 
-    public pair: Pin
-    private subscriptions: Subscription[] = []
+    public pairs: Pin[] = []
+    private subscriptions: {
+        subscription: Subscription
+        key: Pin
+    }[] = []
 
     public id: number
     public _value = 0
-    public color = new BehaviorSubject<[number, number, number, number]>([0, 0, 0,0])
+    public color = new BehaviorSubject<[number, number, number, number]>([0, 0, 0, 0])
     public memory: any = {}
     public valueChanges = new Subject<number>()
 
@@ -31,7 +34,6 @@ export class Pin {
     set value(value: number) {
         if (!this.allowWrite) return
         this.setValue(value)
-
     }
 
     public setValue(value: number) {
@@ -42,24 +44,27 @@ export class Pin {
             [255, 216, 20, 1] :
             [90, 90, 90, 1]
 
-            this.color.next((this.pair) ? color : [0,0,0,0])
+        this.color.next((this.pairs.length) ? color : [0, 0, 0, 0])
     }
 
-    public bindTo(pin: Pin){
-        this.pair = pin
+    public bindTo(pin: Pin) {
+        this.pairs.push(pin)
         const subscription = pin.valueChanges.subscribe(val => this.setValue(val))
 
-        this.subscriptions.push(subscription)
+        this.subscriptions.push({
+            subscription,
+            key: pin
+        })
     }
 
     public unbind(pin: Pin) {
-        if (this.pair == pin){
-            this.pair = null
-            this.subscriptions.forEach(val => val.unsubscribe())
+        if (this.pairs.includes(pin)) {
+            this.pairs = this.pairs.filter(val => val !== pin)
+            this.subscriptions.filter(val => val.key === pin).forEach(({ subscription }) => subscription.unsubscribe())
         }
     }
 
-    public update(){
+    public update() {
         this.setValue(this._value)
     }
 }
\ No newline at end of file
diff --git a/src/ts/common/wires/wire.ts b/src/ts/common/wires/wire.ts
index dd585f7..150a92d 100644
--- a/src/ts/common/wires/wire.ts
+++ b/src/ts/common/wires/wire.ts
@@ -3,14 +3,15 @@ import { Pin } from "../pin";
 export class Wire {
     constructor (public input:Pin,public output:Pin){
         this.output.bindTo(this.input)
-        this.input.pair = this.output
+        this.input.pairs.push(this.output)
         this.input.update()
         this.output.update()
     }
 
     public dispose(){
+        this.output.setValue(0)
         this.output.unbind(this.input)
-        this.input.pair = null
+        this.input.unbind(this.output)
         this.input.update()
         this.output.update()
     }
diff --git a/src/ts/common/wires/wireManager.ts b/src/ts/common/wires/wireManager.ts
index 4b6ded8..dc8e7a6 100644
--- a/src/ts/common/wires/wireManager.ts
+++ b/src/ts/common/wires/wireManager.ts
@@ -3,9 +3,8 @@ import { Pin } from "../pin";
 import { Wire } from "./wire";
 import { svg } from "lit-html";
 import { subscribe } from "lit-rx";
-import { ComponentManager } from "../componentManager";
-import { Observable, Subject } from "rxjs";
-import { WireState, WireStateVal } from "./interface";
+import { Subject } from "rxjs";
+import { WireStateVal } from "./interface";
 
 @Singleton
 export class WireManager {
@@ -36,7 +35,7 @@ export class WireManager {
 
     public tryResolving() {
         if (this.start && this.end && this.start != this.end) {
-            if (this.canBind(this.start, this.end)) {
+            if (this.canBind(this.end)) {
                 this.wires.push(new Wire(this.start, this.end))
                 this.start = null
                 this.end = null
@@ -45,13 +44,13 @@ export class WireManager {
         }
     }
 
-    private canBind(start: Pin, end: Pin) {
+    private canBind(end: Pin) {
         if (this.wires.find(val => val.output === end))
             return false
         return true
     }
 
-    private remove(target: Wire) {
+    public remove(target: Wire) {
         target.dispose()
         this.wires = this.wires.filter(val => val !== target)
         this.update.next(true)
diff --git a/src/ts/main.ts b/src/ts/main.ts
index 74e1a78..491eca0 100644
--- a/src/ts/main.ts
+++ b/src/ts/main.ts
@@ -1,7 +1,6 @@
-import { render, html, svg } from "lit-html"
+import { render, html } from "lit-html"
 import { subscribe } from "lit-rx"
 import { Screen } from "./common/screen.ts";
-import { Component } from "./common/component";
 import { ComponentManager } from "./common/componentManager";
 import { map } from "rxjs/operators";
 import { MDCMenu } from '@material/menu';
@@ -57,11 +56,11 @@ render(html`
     manager.handleMouseMove(e)
     screen.updateMouse(e)
 })}
-        @mousedown=${(e: MouseEvent) => handleEvent(e, (e: MouseEvent) =>
-    manager.handleMouseDown(e)
+        @mousedown=${(e: MouseEvent) => handleEvent(e, () =>
+    manager.handleMouseDown()
 )}
-        @mouseup=${(e: MouseEvent) => handleEvent(e, (e: MouseEvent) =>
-    manager.handleMouseUp(e)
+        @mouseup=${(e: MouseEvent) => handleEvent(e, () =>
+    manager.handleMouseUp()
 )}
         @wheel=${(e: MouseEvent) => handleEvent(e, (e: WheelEvent) =>
     screen.handleScroll(e)
diff --git a/tsconfig.json b/tsconfig.json
index 1b23f77..a5ff8b7 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -26,6 +26,7 @@
         "deploy.ts"
     ],
     "exclude": [
-        "node_modules"
+        "node_modules",
+        "dist"
     ]
 }
\ No newline at end of file