瀏覽代碼

facilitate registry descriptions

luis 7 年之前
父節點
當前提交
13a692d554

+ 5 - 5
browser/vue-flow/src/components/defregistry.js

@@ -1,26 +1,26 @@
 export default{
   'Input': {
     categories: ['core'],
-    output: 'interface {}',
+    output: {type: 'interface {}'},
     style: { color: '#686', shape: 'circle' },
     props: {} // should be sent in the node
   },
   'Variable': {
     categories: ['core'],
-    output: 'interface {}',
+    output: {type: 'interface {}'},
     style: { color: '#88a', shape: 'circle' },
     props: {init: ''}
   },
   'Const': {
     categories: ['core'],
-    output: 'interface {}',
+    output: {type: 'interface {}'},
     style: { color: '#555' }
     // , props: {value: ''}
   },
   'Log': {
     categories: ['core'],
-    inputs: ['interface {}'],
-    output: 'interface {}',
+    inputs: [{type: 'interface {}'}],
+    output: {type: 'interface {}'},
     style: { color: '#665', shape: 'circle' }
   }
 

+ 5 - 5
browser/vue-flow/src/components/flow/manager.vue

@@ -275,9 +275,9 @@ export default {
 
       this.pointerLink.active = true
       if (isInput) {
-        this.pointerLink.src = {nodeId: nodeId, type: this.registry[node.src].inputs[socket.in], in: socket.in}
+        this.pointerLink.src = {nodeId: nodeId, type: this.registry[node.src].inputs[socket.in].type, in: socket.in}
       } else {
-        this.pointerLink.src = {nodeId: nodeId, type: this.registry[node.src].output, out: 0}
+        this.pointerLink.src = {nodeId: nodeId, type: this.registry[node.src].output.type, out: 0}
       }
       utils.createDrag({
         drag: (ev) => {
@@ -296,7 +296,7 @@ export default {
           // find Parent
 
           var curTarget = ev.target
-          for (;curTarget = curTarget.parentNode; curTarget != document.body) {
+          for (;curTarget = curTarget.parentNode; curTarget !== document.body) {
             if (curTarget.hasAttribute('data-nodeid')) {
               break
             }
@@ -333,8 +333,8 @@ export default {
           const nodeFrom = this.nodeData.nodes.find(n => n.id === link.from)
           const nodeTo = this.nodeData.nodes.find(n => n.id === link.to)
 
-          const output = this.registry[nodeFrom.src].output
-          const input = this.registry[nodeTo.src].inputs[link.in]
+          const output = this.registry[nodeFrom.src].output.type
+          const input = this.registry[nodeTo.src].inputs[link.in].type
           // Type checking
           if (!(output === 'interface {}' || output === input || input === 'interface {}')) {
             console.error('LINK: Invalid type')

+ 27 - 5
browser/vue-flow/src/components/flow/node.vue

@@ -74,7 +74,7 @@
       v-bind="inputProps(i)"
       @mousedown.stop.prevent="socketPointerDown($event, {in:i})"
       class="flow-node__socket flow-node__socket--inputs"
-      :class="{'flow-node__socket--match': match.in && (inp == match.in || match.in == 'interface {}' || inp=='interface {}')}"
+      :class="{'flow-node__socket--match': match.in && (inp.type == match.in || match.in == 'interface {}' || inp.type=='interface {}')}"
     >
       <circle r="5" />
       <text
@@ -82,7 +82,7 @@
         :x="-18"
         :y="4"
         class="flow-node__socket-detail"
-      >{{ inp }}</text>
+      >{{ inputLabel(i) }}</text>
 
     </g>
     <!-- output -->
@@ -94,14 +94,14 @@
       :key="'out'+0"
       @mousedown.stop.prevent="socketPointerDown($event, {out:0})"
       class="flow-node__socket flow-node__socket--outputs"
-      :class="{ 'flow-node__socket--match': match.out && (output == match.out || match.out == 'interface {}' || output == 'interface {}'), }"
+      :class="{ 'flow-node__socket--match': match.out && (output.type == match.out || match.out == 'interface {}' || output.type == 'interface {}'), }"
     >
       <circle r="5" />
       <text
         class="flow-node__socket-detail"
         :x="18"
         :y="4">
-        {{ output }}
+        {{ outputLabel(0) }}
       </text>
     </g>
 
@@ -133,7 +133,7 @@ export default {
     'id': {type: String, required: true},
     'label': {type: String, default: ''},
     'inputs': {type: Array, default: () => []},
-    'output': {type: String, default: ''},
+    'output': {type: Object, default: ''},
     'match': {type: Object, default: () => {}},
     'dragging': {type: Boolean, default: false},
     'selected': {type: Boolean, default: false},
@@ -205,6 +205,27 @@ export default {
           r: 5
         }
       }
+    },
+    inputLabel () {
+      return (i) => {
+        let input = ''
+        if (this.inputs[i].name) {
+          input += this.inputs[i].name + ':'
+        }
+        input += this.inputs[i].type
+        return input
+      }
+    },
+    outputLabel () {
+      return (i) => {
+        var output = ''
+        if (this.output.name) {
+          output += this.output.name + ':'
+        }
+        output += this.output.type
+
+        return output
+      }
     }
   },
   watch: {
@@ -233,6 +254,7 @@ export default {
         y: this.bodyProps.y + d + (i * 2 * d)
       }
     },
+
     outputPos (i) {
       const rect = this.bodyProps
       return {

+ 1 - 0
go/src/flow/hook.go

@@ -5,6 +5,7 @@ import (
 	"time"
 )
 
+// Hooks for node life cycle
 type Hooks struct {
 	sync.Mutex
 	hooks []Hook

+ 51 - 0
go/src/flow/registry/batch.go

@@ -0,0 +1,51 @@
+package registry
+
+//Batch helper to batch set properties
+type Batch []*Entry
+
+// MakeBatch creates a batch
+func MakeBatch(params ...interface{}) Batch {
+	ret := Batch{}
+	for _, el := range params {
+		switch v := el.(type) {
+		case Batch:
+			ret = append(ret, v...)
+		case *Entry:
+			ret = append(ret, v)
+		}
+	}
+	return ret
+}
+
+//Tags set categories of the group
+func (eg Batch) Tags(cat ...string) Batch {
+	for _, e := range eg {
+		e.Tags(cat...)
+	}
+	return eg
+}
+
+// DescInputs describe inputs
+func (eg Batch) DescInputs(input ...string) Batch {
+	for _, e := range eg {
+		e.DescInputs(input...)
+	}
+	return eg
+
+}
+
+// DescOutput describe inputs
+func (eg Batch) DescOutput(v string) Batch {
+	for _, e := range eg {
+		e.DescOutput(v)
+	}
+	return eg
+}
+
+// Extra set extras of the group
+func (eg Batch) Extra(name string, value interface{}) Batch {
+	for _, e := range eg {
+		e.Extra(name, value)
+	}
+	return eg
+}

+ 29 - 0
go/src/flow/registry/batch_test.go

@@ -0,0 +1,29 @@
+package registry_test
+
+import (
+	"flow/internal/assert"
+	"flow/registry"
+	"strings"
+	"testing"
+)
+
+func TestMakeBatch(t *testing.T) {
+	a := assert.A(t)
+	r := registry.New()
+
+	b := registry.MakeBatch(
+		r.Add(strings.Split, strings.Join),
+		r.Add(strings.Compare),
+		r.Register("named", strings.Compare),
+	)
+	a.Eq(len(b), 4, "should have 3 entries in batch")
+
+	b.DescInputs("str")
+	b.DescOutput("result")
+
+	for _, en := range b {
+		a.Eq(en.Description.Inputs[0].Name, "str", "first input should be string")
+		a.Eq(en.Description.Output.Name, "result", "output should be equal")
+	}
+
+}

+ 35 - 37
go/src/flow/registry/entry.go

@@ -5,15 +5,20 @@ import (
 	"reflect"
 )
 
+//DescType type Description
+type DescType struct {
+	Type string `json:"type"`
+	Name string `json:"name"`
+}
+
 // Description of an entry
 type Description struct {
 	Name string   `json:"name"`
 	Tags []string `json:"categories"`
 
-	Inputs     []string       `json:"inputs"`
-	InputDesc  map[int]string `json:"inputsDesc"`
-	Output     string         `json:"output"`
-	OutputDesc string         `json:"outputDesc"`
+	//InputType
+	Inputs []DescType `json:"inputs"`
+	Output DescType   `json:"output"`
 
 	Extra map[string]interface{} `json:"extra"`
 }
@@ -43,21 +48,20 @@ func NewEntry(r *R, fn interface{}) *Entry {
 	}
 
 	fnTyp := reflect.TypeOf(e.fn)
-	Inputs := []string{}
 	nInputs := fnTyp.NumIn()
+	Inputs := make([]DescType, nInputs)
 	for i := 0; i < nInputs; i++ {
-		e.Inputs = append(e.Inputs, fnTyp.In(i))
-		Inputs = append(Inputs, fmt.Sprint(fnTyp.In(i)))
+		Inputs[i] = DescType{fmt.Sprint(fnTyp.In(i)), ""}
+		e.Inputs = append(e.Inputs, fnTyp.In(i)) // ?
 	}
-	Output := fmt.Sprint(fnTyp.Out(0))
-	e.Output = fnTyp.Out(0)
+	Output := DescType{fmt.Sprint(fnTyp.Out(0)), ""}
+	e.Output = fnTyp.Out(0) // ?
 
 	e.Description = &Description{
-		Tags:      []string{"generic"},
-		Inputs:    Inputs,
-		Output:    Output,
-		InputDesc: map[int]string{},
-		Extra:     map[string]interface{}{},
+		Tags:   []string{"generic"},
+		Inputs: Inputs,
+		Output: Output,
+		Extra:  map[string]interface{}{},
 	}
 	return e
 }
@@ -67,6 +71,10 @@ func (e *Entry) Err() error {
 	return e.err
 }
 
+/////////////
+// Descriptions
+/////
+
 //Tags of the entry
 func (e *Entry) Tags(cat ...string) *Entry {
 	if e.err != nil {
@@ -76,12 +84,18 @@ func (e *Entry) Tags(cat ...string) *Entry {
 	return e
 }
 
-// DescInput description for Input
-func (e *Entry) DescInput(i int, desc string) *Entry {
+// DescInputs description for Inputs
+func (e *Entry) DescInputs(desc ...string) *Entry {
 	if e.err != nil {
 		return e
 	}
-	e.Description.InputDesc[i] = desc
+	for i, d := range desc {
+		if i >= len(e.Description.Inputs) { // do nothing
+			return e
+		}
+		curDesc := e.Description.Inputs[i]
+		e.Description.Inputs[i] = DescType{curDesc.Type, d}
+	}
 	return e
 }
 
@@ -90,7 +104,10 @@ func (e *Entry) DescOutput(desc string) *Entry {
 	if e.err != nil {
 		return e
 	}
-	e.Description.OutputDesc = desc
+	e.Description.Output = DescType{
+		e.Description.Output.Type,
+		desc,
+	}
 	return e
 }
 
@@ -102,22 +119,3 @@ func (e *Entry) Extra(name string, extra interface{}) *Entry {
 	e.Description.Extra[name] = extra
 	return e
 }
-
-//Batch helper to batch set properties
-type Batch []*Entry
-
-//Tags set categories of the group
-func (eg Batch) Tags(cat ...string) Batch {
-	for _, e := range eg {
-		e.Tags(cat...)
-	}
-	return eg
-}
-
-// Extra set extras of the group
-func (eg Batch) Extra(name string, value interface{}) Batch {
-	for _, e := range eg {
-		e.Extra(name, value)
-	}
-	return eg
-}

+ 17 - 10
go/src/flow/registry/entry_test.go

@@ -23,23 +23,31 @@ func TestDescription(t *testing.T) {
 	a := assert.A(t)
 	r := registry.New()
 
-	e := registry.NewEntry(r, func() int { return 0 })
+	e := registry.NewEntry(r, func(a int) int { return 0 })
 	e.Tags("a", "b")
 	a.Eq(e.Err(), nil, "should not fail setting categories")
 	a.Eq(len(e.Description.Tags), 2, "should have 2 categories")
+	a.Eq(len(e.Description.Inputs), 1, "Should have 2 input description")
 
-	e.DescInput(0, "input doc")
-	a.Eq(e.Err(), nil, "should not fail setting input description")
-	a.Eq(len(e.Description.InputDesc), 1, "should have 1 input description")
+	e2 := registry.NewEntry(r, func(a, b int) int { return 0 })
+	a.Eq(len(e2.Description.Inputs), 2, "Should have 2 input description")
+
+	e.DescInputs("input")
+	a.Eq(e.Err(), nil, "should not fail setting input name")
+	a.Eq(e.Description.Inputs[0].Name, "input", "should have the input description")
 
-	e.DescOutput("output desc")
+	e.DescInputs("input", "2", "3")
+	a.Eq(len(e.Description.Inputs), 1, "should have only one input")
+
+	e.DescOutput("output name")
 	a.Eq(e.Err(), nil, "should not fail setting input description")
-	a.Eq(e.Description.OutputDesc, "output desc", "output description should be the same")
+	a.Eq(e.Description.Output.Name, "output name", "output description should be the same")
 
 	e.Extra("test", 123)
 	a.Eq(e.Err(), nil, "should not fail setting extra doc")
 	a.Eq(e.Description.Extra["test"], 123, "extra text should be as expected")
 }
+
 func TestDescriptionError(t *testing.T) {
 	a := assert.A(t)
 	r := registry.New()
@@ -47,9 +55,9 @@ func TestDescriptionError(t *testing.T) {
 	a.Eq(e.Err(), registry.ErrNotAFunc, "entry is not a function")
 	e.Tags("a", "b")
 	a.Eq(e.Err(), registry.ErrNotAFunc, "entry is not a function")
-	e.DescInput(0, "input doc")
+	e.DescInputs("input")
 	a.Eq(e.Err(), registry.ErrNotAFunc, "entry is not a function")
-	e.DescOutput("output desc")
+	e.DescOutput("output")
 	a.Eq(e.Err(), registry.ErrNotAFunc, "entry is not a function")
 	e.Extra("test", 123)
 	a.Eq(e.Err(), registry.ErrNotAFunc, "entry is not a function")
@@ -64,8 +72,7 @@ func TestEntryBatch(t *testing.T) {
 		registry.NewEntry(r, func() int { return 0 }),
 		registry.NewEntry(r, func() int { return 0 }),
 		registry.NewEntry(r, func() int { return 0 }),
-	}.Tags("test").
-		Extra("name", 1)
+	}.Tags("test").Extra("name", 1)
 
 	a.Eq(len(b), 3, "should have 3 items")
 	for _, e := range b {

+ 3 - 3
go/src/flow/registry/registry.go

@@ -42,10 +42,10 @@ func (r *R) Add(fns ...interface{}) Batch {
 
 	b := Batch{}
 	for _, fn := range fns {
-		if e, ok := fn.(*Entry); ok { // Just add to batch
-			b = append(b, e)
-			continue
+		if reflect.TypeOf(fn).Kind() != reflect.Func {
+			return nil
 		}
+		// Automatic naming
 		name := runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name()
 		name = path.Ext(name)[1:]
 		b = append(b, r.Register(name, fn))

+ 3 - 2
go/src/flow/registry/registry_test.go

@@ -18,7 +18,7 @@ func TestRegistry(t *testing.T) {
 	d := e.Description
 
 	a.Eq(len(d.Inputs), 2, "should have 2 outputs")
-	a.Eq(d.Output, "[]float32", "output type")
+	a.Eq(d.Output.Type, "[]float32", "output type")
 
 	t.Log(d)
 
@@ -160,8 +160,9 @@ func TestClone(t *testing.T) {
 func TestAddEntry(t *testing.T) {
 	a := assert.A(t)
 	r := registry.New()
+
 	g := r.Add(r.Register("vecadd", dummy1))
-	a.Eq(len(g), 1, "should contain 1 entry")
+	a.Eq(len(g), 0, "should contain 1 entry")
 
 	r.Add(dummy2)
 

+ 4 - 4
go/src/flowserver/cmd/flowserver/main.go

@@ -18,10 +18,10 @@ func main() {
 	prettylog.Global()
 	log.Println("Running version:", flowserver.Version)
 
-	// String functions
-	registry.Add(
-		strings.Split, strings.Join,
-		strings.Compare, strings.Contains,
+	registry.MakeBatch(
+		registry.Add(strings.Split).DescInputs("string", "separator"),
+		registry.Add(strings.Join).DescInputs("", "sep"),
+		registry.Add(strings.Compare, strings.Contains),
 		registry.Register("Cat", func(a, b string) string { return a + " " + b }),
 		registry.Register("ToString", func(a interface{}) string { return fmt.Sprint(a) }),
 	).Tags("string").Extra("style", registry.M{"color": "#839"})