Skip to content

Commit

Permalink
Support auto-binding var (Monkey Sprite)
Browse files Browse the repository at this point in the history
  • Loading branch information
qlli committed Oct 13, 2024
1 parent 40d3717 commit 6bde31b
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 3 deletions.
18 changes: 15 additions & 3 deletions game.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ func Gopt_Game_Run(game Gamer, resource interface{}, gameConf ...*Config) {
}
g.startLoad(fs, &conf)
for i, n := 0, v.NumField(); i < n; i++ {
name, val := getFieldPtrOrAlloc(v, i)
name, val := getFieldPtrOrAlloc(g, v, i)
switch fld := val.(type) {
case *Sound:
if g.canBindSound(name) {
Expand Down Expand Up @@ -301,17 +301,24 @@ func instance(gamer reflect.Value) *Game {
return fld.Addr().Interface().(*Game)
}

func getFieldPtrOrAlloc(v reflect.Value, i int) (name string, val interface{}) {
func getFieldPtrOrAlloc(g *Game, v reflect.Value, i int) (name string, val interface{}) {
tFld := v.Type().Field(i)
vFld := v.Field(i)
typ := tFld.Type
word := unsafe.Pointer(vFld.Addr().Pointer())
ret := reflect.NewAt(typ, word).Interface()

if vFld.Kind() == reflect.Ptr && typ.Implements(tySpriter) {
obj := reflect.New(typ.Elem())
reflect.ValueOf(ret).Elem().Set(obj)
ret = obj.Interface()
}

if vFld.Kind() == reflect.Interface && typ.Implements(tySprite) && g.canBindSprite(tFld.Name) {
obj := reflect.New(g.typs[tFld.Name])
reflect.ValueOf(ret).Elem().Set(obj)
ret = obj.Interface()
}
return tFld.Name, ret
}

Expand All @@ -338,6 +345,10 @@ func findObjPtr(v reflect.Value, name string, from int) interface{} {
word := unsafe.Pointer(vFld.Pointer())
return reflect.NewAt(typ.Elem(), word).Interface()
}
if vFld.Kind() == reflect.Interface {
word := unsafe.Pointer(vFld.Addr().Pointer())
return reflect.NewAt(tFld.Type, word).Elem().Interface()
}
word := unsafe.Pointer(vFld.Addr().Pointer())
return reflect.NewAt(typ, word).Interface()
}
Expand Down Expand Up @@ -483,7 +494,7 @@ func Gopt_Game_Reload(game Gamer, index interface{}) (err error) {
g := instance(v)
g.reset()
for i, n := 0, v.NumField(); i < n; i++ {
name, val := getFieldPtrOrAlloc(v, i)
name, val := getFieldPtrOrAlloc(g, v, i)
if fld, ok := val.(Spriter); ok {
if err := g.loadSprite(fld, name, v); err != nil {
panic(err)
Expand Down Expand Up @@ -589,6 +600,7 @@ func (p *Game) addStageSprites(g reflect.Value, v specsp, inits []Spriter) []Spr

var (
tySpriter = reflect.TypeOf((*Spriter)(nil)).Elem()
tySprite = reflect.TypeOf((*Sprite)(nil)).Elem()
)

// -----------------------------------------------------------------------------
Expand Down
3 changes: 3 additions & 0 deletions sprite.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ const (

type Sprite interface {
IEventSinks
Shape
Main()

Animate(name string)
Ask(msg interface{})
BounceOffEdge()
Expand Down

0 comments on commit 6bde31b

Please sign in to comment.