Luis Figueiredo 8 년 전
커밋
cd1a4a1886
2개의 변경된 파일193개의 추가작업 그리고 0개의 파일을 삭제
  1. 45 0
      main.go
  2. 148 0
      seq/sequencer.go

+ 45 - 0
main.go

@@ -0,0 +1,45 @@
+package main
+
+import (
+	"errors"
+	"fmt"
+	"hexasoftware/x/sequencer/seq"
+	"log"
+)
+
+type Xpto struct {
+	ID string
+}
+
+func GenXpto(i int) (*Xpto, error) {
+	log.Println("Generating xpto")
+	return &Xpto{fmt.Sprintf("ID:%d", i)}, nil
+}
+
+func AnotherRandomFunc() error {
+	return errors.New("I have a error")
+}
+func NextXpto(id string) error {
+	log.Println("The id was:", id)
+	return nil
+}
+
+func main() {
+
+	s := seq.New()
+
+	log.Println("Adding GenXPto")
+
+	val := &Xpto{}
+	s.Add("Generate Xpto", GenXpto, 10).Grab(&val)
+	s.Add("Consume xpto", func() error {
+		return NextXpto(val.ID)
+	})
+	s.Add(NextXpto, seq.EP(0))
+	err := s.Exec("abc")
+	log.Println("Val:", val)
+	if err != nil {
+		log.Println("Error on sequence", err)
+	}
+
+}

+ 148 - 0
seq/sequencer.go

@@ -0,0 +1,148 @@
+package seq
+
+import (
+	"fmt"
+	"log"
+	"reflect"
+)
+
+type SeqFunc func(s *Seq) error
+
+type Entry struct {
+	desc  string
+	fn    reflect.Value
+	seqFn SeqFunc
+	param []SeqParam
+	ret   []reflect.Value
+	grab  []reflect.Value
+}
+type SeqParam struct {
+	typ  byte
+	nres int
+	ires int
+	// Or
+	param reflect.Value
+}
+
+func P(n, i int) SeqParam {
+	return SeqParam{1, n, i, reflect.Value{}}
+}
+func EP(n int) SeqParam {
+	return SeqParam{2, n, 0, reflect.Value{}}
+}
+
+type Seq struct {
+	seq  []*Entry
+	last *Entry
+	vars map[string]interface{}
+
+	rep []string
+}
+
+func New() *Seq {
+	return &Seq{[]*Entry{}, nil, map[string]interface{}{}, nil}
+}
+
+func (s *Seq) Add(params ...interface{}) *Seq {
+	entry := &Entry{}
+	fni := 0
+	if v, ok := params[0].(string); ok {
+		entry.desc = v
+		fni = 1
+	}
+	fn := params[fni]
+
+	if v, ok := fn.(SeqFunc); ok {
+		entry.seqFn = v
+	} else {
+		entry.fn = reflect.ValueOf(fn)
+		fnTyp := reflect.TypeOf(fn)
+
+		if fnTyp.Kind() != reflect.Func {
+			log.Fatal("First param must be a function")
+		}
+		vparam := []SeqParam{}
+
+		for _, p := range params[fni+1:] {
+			sp := SeqParam{}
+			switch v := p.(type) {
+			case SeqParam:
+				sp = v
+			default:
+				sp.typ = 0
+				sp.param = reflect.ValueOf(p)
+			}
+			vparam = append(vparam, sp)
+		}
+		entry.param = vparam
+	}
+
+	s.seq = append(s.seq, entry)
+	s.last = entry
+	return s
+}
+
+func (s *Seq) Grab(grab ...interface{}) {
+	if s.last == nil {
+		return
+	}
+	for _, g := range grab {
+		gv := reflect.ValueOf(g)
+		if gv.Kind() != reflect.Ptr {
+			panic("Grab should be pointer")
+		}
+		s.last.grab = append(s.last.grab, gv)
+	}
+}
+
+func (s *Seq) Log(param...interface{){
+
+}
+
+func (s *Seq) Exec(eparam ...interface{}) error {
+	s.rep = []string{}
+	for _, e := range s.seq {
+
+		if e.seqFn != nil {
+			err := e.seqFn(s)
+			if err != nil {
+				return err
+			}
+		}
+		param := []reflect.Value{}
+		for _, p := range e.param {
+			var val reflect.Value
+			switch p.typ {
+			case 0:
+				val = p.param
+			case 1:
+				val = s.seq[p.nres].ret[p.ires]
+			case 2:
+				val = reflect.Indirect(reflect.ValueOf(eparam[p.nres]))
+			}
+			param = append(param, val)
+		}
+		e.ret = e.fn.Call(param)
+		for i, r := range e.ret { // Populate grabs
+			if i < len(e.grab) {
+				e.grab[i].Elem().Set(r)
+			}
+			if err, ok := r.Interface().(error); ok {
+				return err
+			}
+		}
+		if e.desc != "" { // Only if we have a description
+			iret := []interface{}{}
+			for _, r := range e.ret {
+				iret = append(iret, reflect.Indirect(r).Interface())
+			}
+			s.rep = append(s.rep, fmt.Sprintf("E: %s => %s", e.desc, iret))
+		}
+	}
+	log.Println("Report:")
+	for _, r := range s.rep {
+		log.Println(r)
+	}
+
+	return nil
+}