mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 01:01:56 +00:00
dynamic: add CallStructFieldsMethod for map struct field call
Signed-off-by: c9s <yoanlin93@gmail.com>
This commit is contained in:
parent
527070d13d
commit
e2ab363e64
|
@ -1,10 +1,9 @@
|
|||
package bbgo
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/c9s/bbgo/pkg/dynamic"
|
||||
"github.com/c9s/bbgo/pkg/types"
|
||||
)
|
||||
|
||||
type ExitMethod struct {
|
||||
|
@ -16,34 +15,29 @@ type ExitMethod struct {
|
|||
}
|
||||
|
||||
func (m *ExitMethod) Subscribe(session *ExchangeSession) {
|
||||
// TODO: pull out this implementation as a simple function to reflect.go
|
||||
rv := reflect.ValueOf(m)
|
||||
rt := reflect.TypeOf(m)
|
||||
|
||||
rv = rv.Elem()
|
||||
rt = rt.Elem()
|
||||
infType := reflect.TypeOf((*types.Subscriber)(nil)).Elem()
|
||||
|
||||
argValues := dynamic.ToReflectValues(session)
|
||||
for i := 0; i < rt.NumField(); i++ {
|
||||
fieldType := rt.Field(i)
|
||||
if fieldType.Type.Implements(infType) {
|
||||
method := rv.Field(i).MethodByName("Subscribe")
|
||||
method.Call(argValues)
|
||||
}
|
||||
if err := dynamic.CallStructFieldsMethod(m, "Subscribe", session); err != nil {
|
||||
panic(errors.Wrap(err, "dynamic call failed"))
|
||||
}
|
||||
}
|
||||
|
||||
func (m *ExitMethod) Bind(session *ExchangeSession, orderExecutor *GeneralOrderExecutor) {
|
||||
if m.ProtectiveStopLoss != nil {
|
||||
m.ProtectiveStopLoss.Bind(session, orderExecutor)
|
||||
} else if m.RoiStopLoss != nil {
|
||||
}
|
||||
|
||||
if m.RoiStopLoss != nil {
|
||||
m.RoiStopLoss.Bind(session, orderExecutor)
|
||||
} else if m.RoiTakeProfit != nil {
|
||||
}
|
||||
|
||||
if m.RoiTakeProfit != nil {
|
||||
m.RoiTakeProfit.Bind(session, orderExecutor)
|
||||
} else if m.LowerShadowTakeProfit != nil {
|
||||
}
|
||||
|
||||
if m.LowerShadowTakeProfit != nil {
|
||||
m.LowerShadowTakeProfit.Bind(session, orderExecutor)
|
||||
} else if m.CumulatedVolumeTakeProfit != nil {
|
||||
}
|
||||
|
||||
if m.CumulatedVolumeTakeProfit != nil {
|
||||
m.CumulatedVolumeTakeProfit.Bind(session, orderExecutor)
|
||||
}
|
||||
}
|
||||
|
|
41
pkg/dynamic/call.go
Normal file
41
pkg/dynamic/call.go
Normal file
|
@ -0,0 +1,41 @@
|
|||
package dynamic
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// CallStructFieldsMethod iterates field from the given struct object
|
||||
// check if the field object implements the interface, if it's implemented, then we call a specific method
|
||||
func CallStructFieldsMethod(m interface{}, method string, args ...interface{}) error {
|
||||
rv := reflect.ValueOf(m)
|
||||
rt := reflect.TypeOf(m)
|
||||
|
||||
if rt.Kind() != reflect.Ptr {
|
||||
return errors.New("the given object needs to be a pointer")
|
||||
}
|
||||
|
||||
rv = rv.Elem()
|
||||
rt = rt.Elem()
|
||||
|
||||
if rt.Kind() != reflect.Struct {
|
||||
return errors.New("the given object needs to be struct")
|
||||
}
|
||||
|
||||
argValues := ToReflectValues(args...)
|
||||
for i := 0; i < rt.NumField(); i++ {
|
||||
fieldType := rt.Field(i)
|
||||
|
||||
// skip non-exported fields
|
||||
if !fieldType.IsExported() {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := fieldType.Type.MethodByName(method); ok {
|
||||
refMethod := rv.Field(i).MethodByName(method)
|
||||
refMethod.Call(argValues)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
29
pkg/dynamic/call_test.go
Normal file
29
pkg/dynamic/call_test.go
Normal file
|
@ -0,0 +1,29 @@
|
|||
package dynamic
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type callTest struct {
|
||||
ChildCall1 *childCall1
|
||||
ChildCall2 *childCall2
|
||||
}
|
||||
|
||||
type childCall1 struct{}
|
||||
|
||||
func (c *childCall1) Subscribe(a int) {}
|
||||
|
||||
type childCall2 struct{}
|
||||
|
||||
func (c *childCall2) Subscribe(a int) {}
|
||||
|
||||
func TestCallStructFieldsMethod(t *testing.T) {
|
||||
c := &callTest{
|
||||
ChildCall1: &childCall1{},
|
||||
ChildCall2: &childCall2{},
|
||||
}
|
||||
err := CallStructFieldsMethod(c, "Subscribe", 10)
|
||||
assert.NoError(t, err)
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
package types
|
||||
|
||||
type Subscriber interface {
|
||||
Subscribe()
|
||||
}
|
Loading…
Reference in New Issue
Block a user