Ejemplo n.º 1
0
Archivo: thread.go Proyecto: gaxxx/funx
func newThread(route []interface{}) *Thread {
	if len(route) == 0 {
		return nil
	}
	first := reflect.NewValue(route[0])
	args := make([]reflect.Value, 0, 8)
	canStop := true
	ok := false
	var fv *reflect.FuncValue
	switch first.(type) {
	case *reflect.PtrValue:
		{
			if len(route) < 2 {
				return nil
			}
			if str, typeok := route[1].(string); typeok {
				fv = getMemFunc(first.(*reflect.PtrValue), str)
				typ := fv.Type().(*reflect.FuncType)
				needArgs := typ.NumIn()
				actualArgs := len(route) - 1
				if needArgs == actualArgs {
					ok = true
					canStop = false
				} else if needArgs == actualArgs+1 {
					canStop = true
					ok = checkLastArg(typ)
				}
				if ok {
					args = append(args, first)
					for _, i := range route[2:] {
						args = append(args, reflect.NewValue(i))
					}
				}
			}
		}
	case *reflect.FuncValue:
		{
			fv = first.(*reflect.FuncValue)
			typ := fv.Type().(*reflect.FuncType)
			needArgs := typ.NumIn()
			actualArgs := len(route) - 1
			if needArgs == actualArgs {
				ok = true
				canStop = false
			} else if needArgs == actualArgs+1 {
				canStop = true
				ok = checkLastArg(typ)
			}
			if ok {
				for _, i := range route[1:] {
					args = append(args, reflect.NewValue(i))
				}
			}
		}
	}

	if ok {
		t := new(Thread)
		t.fv = fv
		t.canStop = canStop
		t.args = args
		return t
	}
	return nil
}