🍳 refactored some parts of the code and fixd the wire removing bug 📙

This commit is contained in:
Matei Adriel 2019-06-04 13:04:25 +00:00
parent d7d20b2360
commit 731ceb6cd2
8 changed files with 113 additions and 95 deletions

View file

@ -78,7 +78,6 @@ export class Component {
}) })
this.material = new Material(data.material.mode, data.material.data) this.material = new Material(data.material.mode, data.material.data)
this.activate() this.activate()
} }
@ -86,7 +85,7 @@ export class Component {
this.subscriptions.forEach(val => val.unsubscribe()) this.subscriptions.forEach(val => val.unsubscribe())
} }
public handleMouseUp(e: MouseEvent) { public handleMouseUp() {
this.clicked = false this.clicked = false
this.clickedChanges.next(this.clicked) this.clickedChanges.next(this.clicked)
} }
@ -126,17 +125,35 @@ export class Component {
this.activate(0) this.activate(0)
} }
else if (e.button === 2){ else if (e.button === 2) {
manager.components = manager.components.filter(val => val !== this) // setTimeout(() => {
manager.wireManager.wires console.log("removed")
.filter(val => val.input.of === this || val.output.of === this) manager.components = manager.components.filter(({ id }) => id !== this.id)
.forEach(val => val.dispose()) manager.update()
manager.wireManager.update.next(true)
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) Component.wireManager.add(pin)
} }
@ -200,7 +217,7 @@ export class Component {
r=${pinScale} r=${pinScale}
cx=${x} cx=${x}
cy=${y} stroke-width=${stroke} cy=${y} stroke-width=${stroke}
@click=${(e: MouseEvent) => this.handlePinClick(e, val)} @click=${() => this.handlePinClick(val)}
></circle> ></circle>
`}) `})
} }

View file

@ -1,42 +1,33 @@
import { TemplateResult, svg, SVGTemplateResult, Part } from "lit-html"; import { svg, Part } from "lit-html";
import { Subject, BehaviorSubject } from "rxjs"; import { BehaviorSubject } from "rxjs";
import { materialMode } from "./interfaces"; 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 { export class Material {
private static cache = false
private static images: { private static images: {
[key: string]: string [key: string]: string
} = { } = {
and: require("../../../assets/and_gate.jpg"), and: require("../../../assets/and_gate.jpg"),
or: require("../../../assets/or_gate.png"), or: require("../../../assets/or_gate.png"),
xor: require("../../../assets/xor_gate.png") xor: require("../../../assets/xor_gate.png")
} }
private static cached = new Map()
public color = new BehaviorSubject<string>("rgba(0,0,0,0)") public color = new BehaviorSubject<string>("rgba(0,0,0,0)")
constructor (public mode: materialMode,public name:string) { constructor(public mode: string, public name: materialMode | string) {
const saved = Material.cached.get(mode + name)
if (saved && Material.cache)
return saved
else Material.cached.set(mode + name,this)
if (this.mode === "color") if (this.mode === "color")
this.color.next(name) 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}> return svg`<foreignobject x=${x} y=${y} width=${w} height=${h}>
<div class="component-container"> <div class="component-container">
<img src=${Material.images[this.name]} height="97%" width="97%" draggable=false class="component"> <img src=${Material.images[this.name]} height="97%" width="97%" draggable=false class="component">
</div> </div>
</foreignobject>` </foreignobject>`
} }
} }

View file

@ -102,13 +102,13 @@ export class ComponentManager {
public file: { public file: {
[key: string]: () => void [key: string]: () => void
} = { } = {
clear: () => this.clear(), clear: () => this.clear(),
clean: () => this.smartClear(), clean: () => this.smartClear(),
save: () => this.save(), save: () => this.save(),
refresh: () => this.refresh(), refresh: () => this.refresh(),
download: () => download(this,[],[]), download: () => download(this, [], []),
delete: () => this.delete(this.name) delete: () => this.delete(this.name)
} }
constructor() { constructor() {
runCounter.increase() 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) if (this.saves.value.length === 0)
this.save() this.save()
@ -270,7 +274,7 @@ All you work will be lost!`
this.refresh() 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) || if (this.store.get(name) && await this.handleDuplicateModal(name) ||
!this.store.get(name)) { !this.store.get(name)) {
create() create()
@ -341,51 +345,52 @@ All you work will be lost!`
this.svgs.next(this.render()) this.svgs.next(this.render())
} }
handleMouseDown(e: MouseEvent) { handleMouseDown() {
this.clicked = true this.clicked = true
} }
handleMouseUp(e: MouseEvent) { handleMouseUp() {
this.clicked = false this.clicked = false
} }
handleMouseMove(e: MouseEvent) { handleMouseMove(e: MouseEvent) {
let toAddOnTop: number if (e.button === 0) {
let outsideComponents = true let toAddOnTop: number
let outsideComponents = true
for (let i = 0; i < this.components.length; i++) { for (let i = 0; i < this.components.length; i++) {
const component = this.components[i] const component = this.components[i]
if (component.clicked) { if (component.clicked) {
outsideComponents = false outsideComponents = false
component.move(e) component.move(e)
if (this.onTop != component) { if (this.onTop != component) {
toAddOnTop = i toAddOnTop = i
}
} }
} }
}
if (toAddOnTop >= 0) { if (toAddOnTop >= 0) {
this.onTop = this.components[toAddOnTop] this.onTop = this.components[toAddOnTop]
this.components.push(this.onTop) this.components.push(this.onTop)
this.update() this.update()
} }
else if (outsideComponents && this.clicked) { else if (outsideComponents && this.clicked) {
const mousePosition = [e.clientX, e.clientY] const mousePosition = [e.clientX, e.clientY]
const delta = mousePosition.map((value, index) => const delta = mousePosition.map((value, index) =>
this.screen.mousePosition[index] - value this.screen.mousePosition[index] - value
) as [number, number] ) as [number, number]
this.screen.move(...delta) this.screen.move(...delta)
}
} }
} }
render() { render() {
let toRemoveDuplicatesFor: Component let toRemoveDuplicatesFor: Component
const size = 10
const result = this.components.map(component => { const result = this.components.map(component => {
const mouseupHandler = (e: MouseEvent) => { const mouseupHandler = () => {
component.handleMouseUp(e) component.handleMouseUp()
toRemoveDuplicatesFor = component toRemoveDuplicatesFor = component
} }
@ -433,7 +438,7 @@ All you work will be lost!`
instances.pop() instances.pop()
this.components = this.components this.components = this.components
.filter((val, index) => instances.indexOf(index) != -1) .filter((_, index) => instances.indexOf(index) != -1)
} }
get state(): ManagerState { get state(): ManagerState {
@ -472,7 +477,7 @@ All you work will be lost!`
this.update() this.update()
} }
save(name?: string) { save() {
for (let i = 0; i < this.commandHistory.length; i++) { for (let i = 0; i < this.commandHistory.length; i++) {
const element = this.commandHistory[i]; const element = this.commandHistory[i];
this.commandHistoryStore.set(i.toString(), element) this.commandHistoryStore.set(i.toString(), element)

View file

@ -6,12 +6,15 @@ import { Component } from "../component";
export class Pin { export class Pin {
private static lastId = 0 private static lastId = 0
public pair: Pin public pairs: Pin[] = []
private subscriptions: Subscription[] = [] private subscriptions: {
subscription: Subscription
key: Pin
}[] = []
public id: number public id: number
public _value = 0 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 memory: any = {}
public valueChanges = new Subject<number>() public valueChanges = new Subject<number>()
@ -31,7 +34,6 @@ export class Pin {
set value(value: number) { set value(value: number) {
if (!this.allowWrite) return if (!this.allowWrite) return
this.setValue(value) this.setValue(value)
} }
public setValue(value: number) { public setValue(value: number) {
@ -42,24 +44,27 @@ export class Pin {
[255, 216, 20, 1] : [255, 216, 20, 1] :
[90, 90, 90, 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){ public bindTo(pin: Pin) {
this.pair = pin this.pairs.push(pin)
const subscription = pin.valueChanges.subscribe(val => this.setValue(val)) const subscription = pin.valueChanges.subscribe(val => this.setValue(val))
this.subscriptions.push(subscription) this.subscriptions.push({
subscription,
key: pin
})
} }
public unbind(pin: Pin) { public unbind(pin: Pin) {
if (this.pair == pin){ if (this.pairs.includes(pin)) {
this.pair = null this.pairs = this.pairs.filter(val => val !== pin)
this.subscriptions.forEach(val => val.unsubscribe()) this.subscriptions.filter(val => val.key === pin).forEach(({ subscription }) => subscription.unsubscribe())
} }
} }
public update(){ public update() {
this.setValue(this._value) this.setValue(this._value)
} }
} }

View file

@ -3,14 +3,15 @@ import { Pin } from "../pin";
export class Wire { export class Wire {
constructor (public input:Pin,public output:Pin){ constructor (public input:Pin,public output:Pin){
this.output.bindTo(this.input) this.output.bindTo(this.input)
this.input.pair = this.output this.input.pairs.push(this.output)
this.input.update() this.input.update()
this.output.update() this.output.update()
} }
public dispose(){ public dispose(){
this.output.setValue(0)
this.output.unbind(this.input) this.output.unbind(this.input)
this.input.pair = null this.input.unbind(this.output)
this.input.update() this.input.update()
this.output.update() this.output.update()
} }

View file

@ -3,9 +3,8 @@ import { Pin } from "../pin";
import { Wire } from "./wire"; import { Wire } from "./wire";
import { svg } from "lit-html"; import { svg } from "lit-html";
import { subscribe } from "lit-rx"; import { subscribe } from "lit-rx";
import { ComponentManager } from "../componentManager"; import { Subject } from "rxjs";
import { Observable, Subject } from "rxjs"; import { WireStateVal } from "./interface";
import { WireState, WireStateVal } from "./interface";
@Singleton @Singleton
export class WireManager { export class WireManager {
@ -36,7 +35,7 @@ export class WireManager {
public tryResolving() { public tryResolving() {
if (this.start && this.end && this.start != this.end) { 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.wires.push(new Wire(this.start, this.end))
this.start = null this.start = null
this.end = 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)) if (this.wires.find(val => val.output === end))
return false return false
return true return true
} }
private remove(target: Wire) { public remove(target: Wire) {
target.dispose() target.dispose()
this.wires = this.wires.filter(val => val !== target) this.wires = this.wires.filter(val => val !== target)
this.update.next(true) this.update.next(true)

View file

@ -1,7 +1,6 @@
import { render, html, svg } from "lit-html" import { render, html } from "lit-html"
import { subscribe } from "lit-rx" import { subscribe } from "lit-rx"
import { Screen } from "./common/screen.ts"; import { Screen } from "./common/screen.ts";
import { Component } from "./common/component";
import { ComponentManager } from "./common/componentManager"; import { ComponentManager } from "./common/componentManager";
import { map } from "rxjs/operators"; import { map } from "rxjs/operators";
import { MDCMenu } from '@material/menu'; import { MDCMenu } from '@material/menu';
@ -57,11 +56,11 @@ render(html`
manager.handleMouseMove(e) manager.handleMouseMove(e)
screen.updateMouse(e) screen.updateMouse(e)
})} })}
@mousedown=${(e: MouseEvent) => handleEvent(e, (e: MouseEvent) => @mousedown=${(e: MouseEvent) => handleEvent(e, () =>
manager.handleMouseDown(e) manager.handleMouseDown()
)} )}
@mouseup=${(e: MouseEvent) => handleEvent(e, (e: MouseEvent) => @mouseup=${(e: MouseEvent) => handleEvent(e, () =>
manager.handleMouseUp(e) manager.handleMouseUp()
)} )}
@wheel=${(e: MouseEvent) => handleEvent(e, (e: WheelEvent) => @wheel=${(e: MouseEvent) => handleEvent(e, (e: WheelEvent) =>
screen.handleScroll(e) screen.handleScroll(e)

View file

@ -26,6 +26,7 @@
"deploy.ts" "deploy.ts"
], ],
"exclude": [ "exclude": [
"node_modules" "node_modules",
"dist"
] ]
} }