From 6e93a23ec275c2c0ab09c627068255d3d9443e0e Mon Sep 17 00:00:00 2001
From: Matei Adriel <rafaeladriel11@gmail.com>
Date: Mon, 3 Jun 2019 22:32:08 +0000
Subject: [PATCH] =?UTF-8?q?=20=F0=9F=9A=8D=20=20buttons=20and=20lights=20?=
 =?UTF-8?q?=F0=9F=8D=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/ts/common/component/component.ts          | 37 ++++++++------
 src/ts/common/component/interfaces.ts         |  1 +
 src/ts/common/component/material.ts           |  5 +-
 .../componentTemplateStore.ts                 | 48 ++++++++++++++++---
 src/ts/common/componentManager/interfaces.ts  |  1 +
 5 files changed, 70 insertions(+), 22 deletions(-)

diff --git a/src/ts/common/component/component.ts b/src/ts/common/component/component.ts
index f1332aa..30cc096 100644
--- a/src/ts/common/component/component.ts
+++ b/src/ts/common/component/component.ts
@@ -28,7 +28,7 @@ export class Component {
     private strokeColor = "#888888"
     private inputs: number
     private outputs: number
-    private activation: (ctx: activationContext) => any
+    private activation: ((ctx: activationContext) => any)[] = []
     private subscriptions: Subscription[] = []
 
     public inputPins: Pin[] = []
@@ -58,14 +58,17 @@ export class Component {
         this.inputPins = [...Array(this.inputs)].fill(true).map(() => new Pin(false, this))
         this.outputPins = [...Array(this.outputs)].fill(true).map(() => new Pin(true, this))
 
-        this.activation = new Function(`return (ctx) => {
-            try{
-                ${data.activation}
-            }
-            catch(err){
-                ctx.error(err,"",ctx.alertOptions)
-            }
-        }`)()
+        this.activation = [data.activation, data.onclick ? data.onclick : ""]
+            .map(val => {
+                return new Function(`return (ctx) => {
+                    try{
+                        ${val}
+                    }
+                    catch(err){
+                        ctx.error(err,"",ctx.alertOptions)
+                    }
+                }`)()
+            })
 
         this.inputPins.forEach(val => {
             const subscription = val.valueChanges.pipe(debounce(() => timer(1000 / 60)))
@@ -87,12 +90,15 @@ export class Component {
         this.clickedChanges.next(this.clicked)
     }
 
-    private activate() {
-        this.activation({
+    private activate(index: number = 0) {
+        this.activation[index]({
             outputs: this.outputPins,
             inputs: this.inputPins,
             succes: (mes: string) => { success(mes, "", alertOptions) },
-            error: (mes: string) => { error(mes, "", alertOptions) }
+            error: (mes: string) => { error(mes, "", alertOptions) },
+            color: (color: string) => {
+                this.material.color.next(color)
+            }
         } as activationContext)
     }
 
@@ -111,6 +117,9 @@ export class Component {
         )
         this.clicked = true
         this.clickedChanges.next(this.clicked)
+
+        this.activate(1)
+        this.activate(0)
     }
 
     handlePinClick(e: MouseEvent, pin: Pin) {
@@ -163,7 +172,7 @@ export class Component {
 
                 const middleX = subscribe(this.x.pipe(map(val => {
                     const scale = this.scale.value[0]
-                    return val + ((mode === "input") ? scale / 10 : 9 * scale / 10 )
+                    return val + ((mode === "input") ? scale / 10 : 9 * scale / 10)
                 })))
 
                 return svg`
@@ -203,7 +212,7 @@ export class Component {
         return new Component(state.template, state.position, state.scale, state.id)
     }
 
-    public static getId(){
+    public static getId() {
         const data = runCounter.get()
         runCounter.increase()
         return data
diff --git a/src/ts/common/component/interfaces.ts b/src/ts/common/component/interfaces.ts
index ba44851..fd8e63d 100644
--- a/src/ts/common/component/interfaces.ts
+++ b/src/ts/common/component/interfaces.ts
@@ -12,6 +12,7 @@ export interface activationContext {
     outputs: Pin[]
     succes: (mes: string) => any
     error: (mes:string) => any
+    color: (color:string) => void
 }
 
 export type materialMode = "standard_image" | "color"
\ No newline at end of file
diff --git a/src/ts/common/component/material.ts b/src/ts/common/component/material.ts
index 7af6633..8d5ce70 100644
--- a/src/ts/common/component/material.ts
+++ b/src/ts/common/component/material.ts
@@ -7,6 +7,7 @@ declare function require<T>(path:string):T
 type partFactory = (part:Part) => void
 
 export class Material {
+    private static cache = false
     private static images: {
         [key: string]: string
     } = {
@@ -19,8 +20,8 @@ export class Material {
 
     constructor (public mode: materialMode,public name:string) {
         const saved = Material.cached.get(mode + name)
-        
-        if (saved)
+
+        if (saved && Material.cache)
             return saved
 
         else Material.cached.set(mode + name,this)
diff --git a/src/ts/common/componentManager/componentTemplateStore.ts b/src/ts/common/componentManager/componentTemplateStore.ts
index 1e2c118..4cba829 100644
--- a/src/ts/common/componentManager/componentTemplateStore.ts
+++ b/src/ts/common/componentManager/componentTemplateStore.ts
@@ -112,9 +112,9 @@ export class ComponentTemplateStore {
             activation: `
                 ctx.outputs[0].value = true
             `.trim(),
-            material:{
-                mode:"color",
-                data:"green"
+            material: {
+                mode: "color",
+                data: "green"
             }
         })
         this.store.set("false", {
@@ -125,10 +125,46 @@ export class ComponentTemplateStore {
             activation: `
                 ctx.outputs[0].value = false
             `.trim(),
-            material:{
-                mode:"color",
-                data:"yellow"
+            material: {
+                mode: "color",
+                data: "yellow"
             }
         })
+        this.store.set("light", {
+            inputs: 1,
+            outputs: 0,
+            name: "light",
+            version: "1.0.0",
+            activation: `
+                if (ctx.inputs[0].value)
+                    ctx.color("yellow")
+                else
+                    ctx.color("white")
+            `.trim(),
+            material: {
+                mode: "color",
+                data: "white"
+            }
+        })
+        this.store.set("button", {
+            inputs: 0,
+            outputs: 1,
+            name: "button",
+            version: "1.0.0",
+            activation: `
+                ctx.outputs[0].value = ctx.outputs[0].memory.value
+            `.trim(),
+            material: {
+                mode: "color",
+                data: "red"
+            },
+            onclick: `
+                ctx.outputs[0].memory.value = !ctx.outputs[0].memory.value
+                if (ctx.outputs[0].memory.value)
+                    ctx.color("#880000")
+                else
+                    ctx.color("red")
+            `
+        })
     }
 }
\ No newline at end of file
diff --git a/src/ts/common/componentManager/interfaces.ts b/src/ts/common/componentManager/interfaces.ts
index 1f86304..990e9c5 100644
--- a/src/ts/common/componentManager/interfaces.ts
+++ b/src/ts/common/componentManager/interfaces.ts
@@ -12,6 +12,7 @@ export interface ComponentTemplate {
     name: string
     version: string
     activation: string
+    onclick?: string
     inputs: number
     outputs: number
     material: {