flowbuilder.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. package flowserver
  2. import (
  3. "encoding/json"
  4. "flow"
  5. "flow/registry"
  6. "log"
  7. "reflect"
  8. )
  9. // Node that will contain registry src
  10. type Node struct {
  11. ID string `json:"id"`
  12. Src string `json:"src"`
  13. Label string `json:"label"`
  14. Prop map[string]string `json:"prop"`
  15. }
  16. // Link that joins two nodes
  17. type Link struct {
  18. From string `json:"from"`
  19. To string `json:"to"`
  20. In int `json:"in"`
  21. }
  22. // FlowDocument flow document
  23. type FlowDocument struct {
  24. Nodes []Node `json:"nodes"`
  25. Links []Link `json:"links"`
  26. }
  27. // FlowBuild build a flowGraph
  28. func FlowBuild(rawData []byte, r *registry.R) (*flow.Flow, error) {
  29. doc := FlowDocument{[]Node{}, []Link{}}
  30. err := json.Unmarshal(rawData, &doc)
  31. if err != nil {
  32. return nil, err
  33. }
  34. f := flow.New()
  35. f.SetRegistry(r)
  36. nodeMap := map[string]Node{}
  37. for _, n := range doc.Nodes {
  38. nodeMap[n.ID] = n
  39. }
  40. inputMap := map[string]flow.Operation{}
  41. ninput := 0
  42. for _, n := range doc.Nodes {
  43. if n.Src == "Input" || n.Src == "Variable" || n.Src == "Const" {
  44. continue
  45. }
  46. // Find link refered as To
  47. entry, err := r.Entry(n.Src)
  48. if err != nil {
  49. return nil, err
  50. }
  51. param := make([]flow.Data, len(entry.Inputs))
  52. // Find links
  53. for _, l := range doc.Links {
  54. if l.To != n.ID {
  55. continue
  56. }
  57. // Define operators here
  58. from := nodeMap[l.From]
  59. switch from.Src {
  60. case "Input":
  61. inOp, ok := inputMap[n.ID]
  62. if !ok {
  63. inOp = f.In(ninput)
  64. inputMap[n.ID] = inOp
  65. ninput++
  66. }
  67. param[l.In] = inOp // By id perhaps
  68. case "Variable":
  69. param[l.In] = f.Var(from.ID, from.Prop["init"])
  70. case "Const":
  71. // XXX: Automate this in a func
  72. newVal := reflect.New(entry.Inputs[l.In])
  73. raw := from.Label
  74. //raw := from.Prop["value"]
  75. if _, ok := newVal.Interface().(*string); ok {
  76. log.Println("Trying to unmarshal a string")
  77. raw = "\"" + raw + "\""
  78. }
  79. log.Println("Will unmarshal raw:", raw)
  80. err := json.Unmarshal([]byte(raw), newVal.Interface())
  81. if err != nil {
  82. // ignore error
  83. log.Println("unmarshalling Error", err)
  84. //param[l.In] = nil
  85. //continue
  86. }
  87. param[l.In] = f.Const(newVal.Elem().Interface())
  88. default:
  89. param[l.In] = f.Res(from.ID)
  90. }
  91. }
  92. f.DefOp(n.ID, n.Src, param...)
  93. }
  94. return f, nil
  95. }