Browse Source

WIP backend

luis 7 years ago
parent
commit
7e846660b9

+ 8 - 0
browser/vue-flow/src/components/flow/manager.vue

@@ -360,6 +360,14 @@ export default {
         label: src,
         src: src
       }
+      // Setup Props
+      if (this.registry[src].props) {
+        for (let k in this.registry[src].props) {
+          newNode.prop || (newNode.prop = {})
+          newNode.prop[k] = ''
+        }
+      }
+
       this.nodeData.nodes.push(newNode)
       let nu = {}
       this.sendFlowEvent('nodeUpdate', (nu[newNode.id] = newNode, nu))

+ 24 - 3
browser/vue-flow/src/components/main.vue

@@ -91,6 +91,12 @@
               <div class="property">Bogus description</div>
               <label>Help</label>
               <div class="property">Connect to input a thing and goes to output another thing</div>
+              <div class="flow-modal__params" v-if="nodeInspectTarget.prop" @keydown.enter="nodeInspectTarget=null">
+                <div class="flow-modal__param" v-for="(v,k) in nodeInspectTarget.prop">
+                  <label>{{ k }}</label>
+                  <input type="text" v-model="nodeInspectTarget.prop[k]">
+                </div>
+              </div>
             </div>
           </div>
           <label>label</label>
@@ -127,9 +133,24 @@ export default {
   data () {
     return {
       registry: {
-        'Input': { group: 'Generic', output: 'any', style: { color: '#686', textColor: '#fff', type: 'circle' } },
-        'Variable': { group: 'Generic', output: 'any', style: { color: '#88a', textColor: '#000' } },
-        'Const': { group: 'Generic', output: 'any', style: { color: '#777', textColor: '#333' } },
+        'Input': {
+          group: 'Generic',
+          output: 'any',
+          style: { color: '#686', textColor: '#fff', type: 'circle' },
+          props: {} // should be sent in the node
+        },
+        'Variable': {
+          group: 'Generic',
+          output: 'any',
+          style: { color: '#88a', textColor: '#000' },
+          props: {init: '', size: 0}
+        },
+        'Const': {
+          group: 'Generic',
+          output: 'any',
+          style: { color: '#777', textColor: '#333' },
+          props: {value: ''}
+        },
 
         'MatMul': { group: 'Machine learning', inputs: [ '[]float32', '[]float32' ], output: '[]float32', style: { color: '#a44', textColor: 'white' } },
         // 'Input': { group: 'Machine learning', inputs: [], output: '[]float32', style: { 'color': '#686', 'textColor': '#fff' } },

+ 0 - 8
browser/vue-flow/src/components/nodeinspect.vue

@@ -1,8 +0,0 @@
-<template/>
-<script>
-export default {
-  props: {
-    nodeModal: { type: Boolean, default: false}
-  }
-}
-</script>

+ 18 - 16
go/src/flow/flow.go

@@ -2,7 +2,6 @@ package flow
 
 import (
 	"bytes"
-	"crypto/rand"
 	"encoding/json"
 	"fmt"
 	"io"
@@ -32,6 +31,9 @@ type Flow struct {
 
 	err   error
 	runID int
+
+	// Experimental run Event
+	handlers []func(name string, payLoad map[string]Data)
 }
 
 // New create a new flow
@@ -110,9 +112,6 @@ func (f *Flow) Op(name string, params ...interface{}) Operation {
 		return nil
 	}
 	// generate ID
-
-	//f.operations = append(f.operations, opEntry{name, inputs, executor})
-	//refID := len(f.operations) - 1
 	for {
 		uuid := puuid()
 		if _, ok := f.operations[uuid]; ok {
@@ -210,11 +209,13 @@ func (f *Flow) Analyse(w io.Writer, params ...Data) {
 		fmt.Fprintf(fw, "%v\n", res)
 
 		fmt.Fprintf(w, "%s", fw.String())
-
 	}
-
 }
 
+/////////////////////////////
+// Serializers inspectors
+//////////////////////
+
 func (f *Flow) String() string {
 	ret := bytes.NewBuffer(nil)
 	// consts
@@ -267,16 +268,17 @@ func (f *Flow) MarshalJSON() ([]byte, error) {
 	return json.Marshal(data)
 }
 
-func puuid() (uuid string) {
+//////////////////////////////////////////////
+// Experimental event
+////////////////
 
-	b := make([]byte, 16)
-	_, err := rand.Read(b)
-	if err != nil {
-		fmt.Println("Error: ", err)
-		return
-	}
-
-	uuid = fmt.Sprintf("%X-%X-%X-%X-%X", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
+// Handle attach a handler
+func (f *Flow) Handle(handler func(name string, payLoad map[string]Data)) {
+	f.handlers = append(f.handlers, handler)
+}
 
-	return
+func (f *Flow) trigger(name string, payLoad map[string]Data) {
+	for _, h := range f.handlers {
+		h(name, payLoad)
+	}
 }

+ 8 - 0
go/src/flow/flow_test.go

@@ -115,6 +115,14 @@ func TestReference(t *testing.T) {
 
 	res := op.Process()
 	CheckEq(t, res, desired)
+}
+
+func TestHandler(t *testing.T) {
+	f, op := prepareComplex()
+	f.Handle(func(name string, payLoad map[string]flow.Data) {
+		t.Log("Something happened:", name, payLoad)
+	})
+	op.Process()
 
 }
 

+ 9 - 1
go/src/flow/operation.go

@@ -115,8 +115,16 @@ func opFunc(f *Flow, id string) *operation {
 				callParam[i] = reflect.ValueOf(fr)
 
 			}
+			f.trigger("nodeStart", map[string]Data{
+				"id": id,
+			})
+			ret := reflect.ValueOf(op.executor).Call(callParam)[0].Interface()
+			f.trigger("nodeFinish", map[string]Data{
+				"id":     id,
+				"result": ret,
+			})
 
-			return reflect.ValueOf(op.executor).Call(callParam)[0].Interface()
+			return ret
 		},
 	}
 }

+ 19 - 0
go/src/flow/utils.go

@@ -0,0 +1,19 @@
+package flow
+
+import (
+	"crypto/rand"
+	"fmt"
+)
+
+func puuid() (uuid string) {
+
+	b := make([]byte, 16)
+	_, err := rand.Read(b)
+	if err != nil {
+		fmt.Println("Error: ", err)
+		return
+	}
+	uuid = fmt.Sprintf("%X-%X-%X-%X-%X", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
+
+	return
+}

+ 77 - 0
go/src/flowserver/noderunner.go

@@ -0,0 +1,77 @@
+package flowserver
+
+import (
+	"encoding/json"
+	"flow"
+)
+
+// Node that will contain registry src
+type Node struct {
+	ID   string            `json:"id"`
+	Src  string            `json:"src"`
+	Prop map[string]string `json:"prop"`
+}
+
+// Link that joins two nodes
+type Link struct {
+	From string `json:"from"`
+	To   string `json:"to"`
+	In   int    `json:"in"`
+}
+
+// FlowDocument flow document
+type FlowDocument struct {
+	Nodes []Node `json:"nodes"`
+	Links []Link `json:"links"`
+}
+
+//NodeRun
+func FlowBuild(rawData []byte) *flow.Flow {
+	doc := FlowDocument{[]Node{}, []Link{}}
+	json.Unmarshal(rawData, &doc)
+
+	f := flow.New()
+
+	nodeMap := map[string]Node{}
+	for _, n := range doc.Nodes {
+		nodeMap[n.ID] = n
+	}
+	inputMap := map[string]flow.Operation{}
+
+	ninput := 0
+	for _, n := range doc.Nodes {
+		// Find link refered as To
+		param := make([]interface{}, 10) // 10 is temporary to test out operations
+		lastParamID := -1
+		for _, l := range doc.Links {
+			if l.To != n.ID {
+				continue
+			}
+			if l.In > lastParamID {
+				lastParamID = l.In
+			}
+			// Define operators here
+			from := nodeMap[l.From]
+			switch from.Src {
+			case "Input":
+				inOp, ok := inputMap[n.ID]
+				if !ok {
+					inOp = f.In(ninput)
+					inputMap[n.ID] = inOp
+					ninput++
+				}
+				param[l.In] = inOp // By id perhaps
+			case "Variable":
+				param[l.In] = f.Var(from.ID, "Temporary")
+			default:
+				param[l.In] = f.Res(from.ID)
+			}
+		}
+		param = param[:lastParamID+1]
+		if n.Src == "Input" || n.Src == "Variable" {
+			continue
+		}
+		f.DefOp(n.ID, n.Src, param...)
+	}
+	return f
+}

+ 15 - 6
go/src/flowserver/session.go

@@ -17,7 +17,7 @@ type FlowSession struct {
 	clients []*websocket.Conn
 	Chat    ChatRoom
 
-	RawData []byte // Just share data
+	RawDoc []byte // Just share data
 }
 
 //NewSession creates and initializes a NewSession
@@ -32,9 +32,8 @@ func (f *FlowSession) ClientAdd(c *websocket.Conn) error {
 	defer f.Unlock()
 
 	f.clients = append(f.clients, c)
-
 	dataMap := map[string]interface{}{}
-	json.Unmarshal(f.RawData, &dataMap)
+	json.Unmarshal(f.RawDoc, &dataMap)
 
 	return c.WriteJSON(flowmsg.SendMessage{OP: "document", Data: dataMap})
 
@@ -64,11 +63,11 @@ func (f *FlowSession) DocumentUpdate(c *websocket.Conn, data []byte) error {
 	defer f.Unlock()
 	log.Println("Document updating")
 
-	f.RawData = data // Update
+	f.RawDoc = data // Update
 	dataMap := map[string]interface{}{}
 
 	// contextual lock
-	err := json.Unmarshal(f.RawData, &dataMap)
+	err := json.Unmarshal(f.RawDoc, &dataMap)
 	if err != nil {
 		return err
 	}
@@ -82,10 +81,20 @@ func (f *FlowSession) Document(c *websocket.Conn) error {
 	defer f.Unlock()
 
 	dataMap := map[string]interface{}{}
-	json.Unmarshal(f.RawData, &dataMap)
+	json.Unmarshal(f.RawDoc, &dataMap)
 	return c.WriteJSON(flowmsg.SendMessage{OP: "document", Data: dataMap})
 }
 
+// NodeRun a node triggering results
+// Build a flow and run
+func (f *FlowSession) NodeRun(c *websocket.Conn, data []byte) error {
+	FlowBuild(f.RawDoc)
+
+	//	f := flow.New()
+
+	return nil
+}
+
 // Broadcast broadcast a message in session besides C
 func (f *FlowSession) Broadcast(c *websocket.Conn, v interface{}) error {
 	f.Lock()

+ 7 - 0
go/src/flowserver/sessionmgr.go

@@ -153,6 +153,13 @@ func (fsm *FlowSessionManager) ServeHTTP(w http.ResponseWriter, r *http.Request)
 				}
 				return sess.Broadcast(c, flowmsg.SendMessage{OP: m.OP, Data: m.Data})
 			}()
+		case "nodeRun":
+			err = func() error {
+				if sess == nil {
+					return errors.New("nodeRun: invalid session")
+				}
+				return sess.NodeRun(c, m.Data)
+			}()
 		case "chatJoin":
 			err = func() error {
 				if sess == nil {

+ 5 - 36
go/src/flowx/main.go

@@ -3,6 +3,7 @@ package main
 import (
 	"encoding/json"
 	"flow"
+	"flowserver"
 	"log"
 
 	"github.com/gohxs/prettylog"
@@ -59,39 +60,20 @@ const jsonRaw = `
  ]
 }`
 
-// Node that will contain registry src
-type Node struct {
-	ID  string `json:"id"`
-	Src string `json:"src"`
-}
-
-// Link that joins two nodes
-type Link struct {
-	From string `json:"from"`
-	To   string `json:"to"`
-	In   int    `json:"in"`
-}
-
-type FlowDocument struct {
-	Nodes []Node `json:"nodes"`
-	Links []Link `json:"links"`
-}
-
 func main() {
 	prettylog.Global()
-	doc := FlowDocument{[]Node{}, []Link{}}
+	doc := flowserver.FlowDocument{[]flowserver.Node{}, []flowserver.Link{}}
 	json.Unmarshal([]byte(jsonRaw), &doc)
-
-	log.Println("Doc is:", doc)
 	// Handling flow
 	//
 	reg := flow.NewRegistry()
 	reg.Register("StrCat", StrCat)
 	reg.Register("StrReverse", StrReverse)
+
 	f := flow.New()
 	f.SetRegistry(reg)
 
-	nodeMap := map[string]Node{}
+	nodeMap := map[string]flowserver.Node{}
 	for _, n := range doc.Nodes {
 		nodeMap[n.ID] = n
 	}
@@ -99,7 +81,6 @@ func main() {
 
 	ninput := 0
 	for _, n := range doc.Nodes {
-		log.Println("Processing node:", n.ID)
 		// Find link refered as To
 		param := make([]interface{}, 10) // 10 is temporary to test out operations
 		lastParamID := -1
@@ -110,12 +91,10 @@ func main() {
 			if l.In > lastParamID {
 				lastParamID = l.In
 			}
-			log.Println("Attaching input:", l.In)
 			// Define operators here
 			from := nodeMap[l.From]
 			switch from.Src {
 			case "Input":
-				log.Println("Input is external Input")
 				inOp, ok := inputMap[n.ID]
 				if !ok {
 					inOp = f.In(ninput)
@@ -124,26 +103,16 @@ func main() {
 				}
 				param[l.In] = inOp // By id perhaps
 			case "Variable":
-				log.Println("Input is a variable")
 				param[l.In] = f.Var(from.ID, "Temporary")
 			default:
-				log.Println("Input is another node")
 				param[l.In] = f.Res(from.ID)
 			}
 		}
-		log.Println("Params")
 		param = param[:lastParamID+1]
-		log.Println("Defining operation", n.ID, n.Src)
 		if n.Src == "Input" || n.Src == "Variable" {
-			log.Println("Not a func, moving")
 			continue
 		}
-		if len(param) > 0 {
-			f.DefOp(n.ID, n.Src, param...)
-		} else {
-			f.DefOp(n.ID, n.Src)
-		}
-		log.Println("Operation using", n.Src, "Has", len(param), "Parameters")
+		f.DefOp(n.ID, n.Src, param...)
 	}
 
 	log.Println("Flow:\n", f)