Skip to content

Commit

Permalink
refactor: prefer typed params for API funcs (#463)
Browse files Browse the repository at this point in the history
- Introduce `SpriteName`, `SpriteCostumeName`, `SpriteAnimationName`,
  `SoundName`, `BackdropName`, `WidgetName`.
- Prefer func overloading over using `interface{}` or variadic params as
  optional params.

Signed-off-by: Aofei Sheng <[email protected]>
  • Loading branch information
aofei authored Dec 4, 2024
1 parent 845f2c0 commit 971e4a0
Show file tree
Hide file tree
Showing 7 changed files with 305 additions and 101 deletions.
20 changes: 18 additions & 2 deletions camera.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ func (c *Camera) worldToScreen(point *math32.Vector2) *math32.Vector2 {
}
*/

func (c *Camera) On(obj interface{}) {
func (c *Camera) on(obj interface{}) {
switch v := obj.(type) {
case string:
case SpriteName:
sp := c.g.findSprite(v)
if sp == nil {
log.Println("Camera.On: sprite not found -", v)
Expand All @@ -83,6 +83,22 @@ func (c *Camera) On(obj interface{}) {
c.on_ = obj
}

func (c *Camera) On__0(sprite Sprite) {
c.on(sprite)
}

func (c *Camera) On__1(sprite *SpriteImpl) {
c.on(sprite)
}

func (c *Camera) On__2(sprite SpriteName) {
c.on(sprite)
}

func (c *Camera) On__3(obj specialObj) {
c.on(obj)
}

func (c *Camera) updateOnObj() {
switch v := c.on_.(type) {
case *SpriteImpl:
Expand Down
16 changes: 8 additions & 8 deletions event.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,17 +213,17 @@ func (p *eventSinkMgr) doWhenIReceive(msg string, data interface{}, wait bool) {
})
}

func (p *eventSinkMgr) doWhenBackdropChanged(name string, wait bool) {
func (p *eventSinkMgr) doWhenBackdropChanged(name BackdropName, wait bool) {
p.allWhenBackdropChanged.call(wait, name, func(ev *eventSink) {
ev.sink.(func(string))(name)
ev.sink.(func(BackdropName))(name)
})
}

// -------------------------------------------------------------------------------------
type IEventSinks interface {
OnAnyKey(onKey func(key Key))
OnBackdrop__0(onBackdrop func(name string))
OnBackdrop__1(name string, onBackdrop func())
OnBackdrop__0(onBackdrop func(name BackdropName))
OnBackdrop__1(name BackdropName, onBackdrop func())
OnClick(onClick func())
OnKey__0(key Key, onKey func())
OnKey__1(keys []Key, onKey func(Key))
Expand Down Expand Up @@ -361,26 +361,26 @@ func (p *eventSinks) OnMsg__1(msg string, onMsg func()) {
}
}

func (p *eventSinks) OnBackdrop__0(onBackdrop func(name string)) {
func (p *eventSinks) OnBackdrop__0(onBackdrop func(name BackdropName)) {
p.allWhenBackdropChanged = &eventSink{
prev: p.allWhenBackdropChanged,
pthis: p.pthis,
sink: onBackdrop,
}
}

func (p *eventSinks) OnBackdrop__1(name string, onBackdrop func()) {
func (p *eventSinks) OnBackdrop__1(name BackdropName, onBackdrop func()) {
p.allWhenBackdropChanged = &eventSink{
prev: p.allWhenBackdropChanged,
pthis: p.pthis,
sink: func(name string) {
sink: func(name BackdropName) {
if debugEvent {
log.Println("==> onBackdrop", name, nameOf(p.pthis))
}
onBackdrop()
},
cond: func(data interface{}) bool {
return data.(string) == name
return data.(BackdropName) == name
},
}
}
Expand Down
93 changes: 67 additions & 26 deletions game.go
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ func (p *Game) loadIndex(g reflect.Value, proj *projConfig) (err error) {

ebiten.SetWindowResizingMode(ebiten.WindowResizingModeOnlyFullscreenEnabled)
if proj.Camera != nil && proj.Camera.On != "" {
p.Camera.On(proj.Camera.On)
p.Camera.On__2(proj.Camera.On)
}
if loader, ok := g.Addr().Interface().(interface{ OnLoaded() }); ok {
loader.OnLoaded()
Expand Down Expand Up @@ -860,7 +860,7 @@ func (p *Game) touchingSpriteBy(dst *SpriteImpl, name string) *SpriteImpl {

func (p *Game) objectPos(obj interface{}) (float64, float64) {
switch v := obj.(type) {
case string:
case SpriteName:
if sp := p.findSprite(v); sp != nil {
return sp.getXY()
}
Expand Down Expand Up @@ -1033,7 +1033,7 @@ func (p *Game) doFindSprite(src Shape) int {
return -1
}

func (p *Game) findSprite(name string) *SpriteImpl {
func (p *Game) findSprite(name SpriteName) *SpriteImpl {
for _, item := range p.items {
if sp, ok := item.(*SpriteImpl); ok {
if !sp.isCloned_ && sp.name == name {
Expand All @@ -1045,7 +1045,6 @@ func (p *Game) findSprite(name string) *SpriteImpl {
}

// -----------------------------------------------------------------------------

func (p *Game) drawBackground(dc drawContext) {
c := p.costumes[p.costumeIndex_]
img, _, _ := c.needImage(p.fs)
Expand Down Expand Up @@ -1156,7 +1155,9 @@ func (p *Game) onHit(hc hitContext) (hr hitResult, ok bool) {

// -----------------------------------------------------------------------------

func (p *Game) BackdropName() string {
type BackdropName = string

func (p *Game) BackdropName() BackdropName {
return p.getCostumeName()
}

Expand All @@ -1166,24 +1167,64 @@ func (p *Game) BackdropIndex() int {

// StartBackdrop func:
//
// StartBackdrop(backdropName) or
// StartBackdrop(backdropIndex) or
// StartBackdrop(backdrop) or
// StartBackdrop(index) or
// StartBackdrop(spx.Next)
// StartBackdrop(spx.Prev)
func (p *Game) StartBackdrop(backdrop interface{}, wait ...bool) {
func (p *Game) startBackdrop(backdrop interface{}, wait bool) {
if p.goSetCostume(backdrop) {
p.windowWidth_ = 0
p.doWindowSize()
p.doWhenBackdropChanged(p.getCostumeName(), wait != nil && wait[0])
p.doWhenBackdropChanged(p.getCostumeName(), wait)
}
}

func (p *Game) NextBackdrop(wait ...bool) {
p.StartBackdrop(Next, wait...)
func (p *Game) StartBackdrop__0(backdrop BackdropName) {
p.startBackdrop(backdrop, false)
}

func (p *Game) StartBackdrop__1(backdrop BackdropName, wait bool) {
p.startBackdrop(backdrop, wait)
}

func (p *Game) StartBackdrop__2(index int) {
p.startBackdrop(index, false)
}

func (p *Game) StartBackdrop__3(index int, wait bool) {
p.startBackdrop(index, wait)
}

func (p *Game) StartBackdrop__4(index float64) {
p.startBackdrop(index, false)
}

func (p *Game) StartBackdrop__5(index float64, wait bool) {
p.startBackdrop(index, wait)
}

func (p *Game) PrevBackdrop(wait ...bool) {
p.StartBackdrop(Prev, wait...)
func (p *Game) StartBackdrop__6(action switchAction) {
p.startBackdrop(action, false)
}

func (p *Game) StartBackdrop__7(action switchAction, wait bool) {
p.startBackdrop(action, wait)
}

func (p *Game) NextBackdrop__0() {
p.StartBackdrop__6(Next)
}

func (p *Game) NextBackdrop__1(wait bool) {
p.StartBackdrop__7(Next, wait)
}

func (p *Game) PrevBackdrop__0() {
p.StartBackdrop__6(Prev)
}

func (p *Game) PrevBackdrop__1(wait bool) {
p.StartBackdrop__7(Prev, wait)
}

// -----------------------------------------------------------------------------
Expand Down Expand Up @@ -1282,6 +1323,8 @@ func (p *Game) ClearSoundEffects() {

type Sound *soundConfig

type SoundName = string

func (p *Game) canBindSound(name string) bool {
// auto bind the sound, if assets/sounds/{name}/index.json exists.
prefix := "sounds/" + name
Expand All @@ -1293,7 +1336,7 @@ func (p *Game) canBindSound(name string) bool {
return true
}

func (p *Game) loadSound(name string) (media Sound, err error) {
func (p *Game) loadSound(name SoundName) (media Sound, err error) {
if media, ok := p.sounds.audios[name]; ok {
return media, nil
}
Expand All @@ -1317,9 +1360,6 @@ func (p *Game) loadSound(name string) (media Sound, err error) {
// Play(video) -- maybe
// Play(media, wait) -- sync
// Play(media, opts)
// Play(mediaName)
// Play(mediaName, wait) -- sync
// Play(mediaName, opts)
func (p *Game) Play__0(media Sound) {
p.Play__2(media, &PlayOptions{})
}
Expand All @@ -1338,21 +1378,22 @@ func (p *Game) Play__2(media Sound, action *PlayOptions) {
panic(err)
}
}
func (p *Game) Play__3(mediaName string) {
p.Play__5(mediaName, &PlayOptions{})

func (p *Game) Play__3(media SoundName) {
p.Play__5(media, &PlayOptions{})
}

func (p *Game) Play__4(mediaName string, wait bool) {
p.Play__5(mediaName, &PlayOptions{Wait: wait})
func (p *Game) Play__4(media SoundName, wait bool) {
p.Play__5(media, &PlayOptions{Wait: wait})
}

func (p *Game) Play__5(mediaName string, action *PlayOptions) {
media, err := p.loadSound(mediaName)
func (p *Game) Play__5(media SoundName, action *PlayOptions) {
m, err := p.loadSound(media)
if err != nil {
log.Println(err)
return
}
p.Play__2(media, action)
p.Play__2(m, action)
}

func (p *Game) StopAllSounds() {
Expand Down Expand Up @@ -1433,7 +1474,7 @@ type ShapeGetter interface {
// Instead of being used directly, it is meant to be called by `Gopt_Game_Gopx_GetWidget` only.
// We extract `GetWidget_` to keep `Gopt_Game_Gopx_GetWidget` simple, which simplifies work in ispx,
// see details in https://github.com/goplus/builder/issues/765#issuecomment-2313915805.
func GetWidget_(sg ShapeGetter, name string) Widget {
func GetWidget_(sg ShapeGetter, name WidgetName) Widget {
items := sg.getAllShapes()
for _, item := range items {
widget, ok := item.(Widget)
Expand All @@ -1445,7 +1486,7 @@ func GetWidget_(sg ShapeGetter, name string) Widget {
}

// GetWidget returns the widget instance (in given type) with given name. It panics if not found.
func Gopt_Game_Gopx_GetWidget[T any](sg ShapeGetter, name string) *T {
func Gopt_Game_Gopx_GetWidget[T any](sg ShapeGetter, name WidgetName) *T {
widget := GetWidget_(sg, name)
if result, ok := widget.(interface{}).(*T); ok {
return result
Expand Down
4 changes: 2 additions & 2 deletions monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import (
// Monitor class.
type Monitor struct {
game *Game
name string
name WidgetName
size float64
target string
val string
Expand Down Expand Up @@ -304,7 +304,7 @@ func (p *Monitor) hit(hc hitContext) (hr hitResult, ok bool) {

// -------------------------------------------------------------------------------------
// IWidget
func (pself *Monitor) GetName() string {
func (pself *Monitor) GetName() WidgetName {
return pself.name
}

Expand Down
13 changes: 6 additions & 7 deletions spbase.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ func (p *imageLoaderByCostumeSet) load(fs spxfs.Dir, pt *imagePoint) (gdi.Image,
// -------------------------------------------------------------------------------------

type costume struct {
name string
name SpriteCostumeName
img delayloadImage
faceRight float64
bitmapResolution int
Expand Down Expand Up @@ -296,7 +296,7 @@ func initCSPart(p *baseObj, img *costumeSetImage, faceRight float64, bitmapResol
}
}

func addCostumeWith(p *baseObj, name string, img *costumeSetImage, faceRight float64, i, bitmapResolution int) {
func addCostumeWith(p *baseObj, name SpriteCostumeName, img *costumeSetImage, faceRight float64, i, bitmapResolution int) {
c := newCostumeWith(name, img, faceRight, i, bitmapResolution)
p.costumes = append(p.costumes, c)
}
Expand Down Expand Up @@ -334,7 +334,7 @@ func (p *baseObj) initFrom(src *baseObj) {
p.costumeIndex_ = src.costumeIndex_
}

func (p *baseObj) findCostume(name string) int {
func (p *baseObj) findCostume(name SpriteCostumeName) int {
for i, c := range p.costumes {
if c.name == name {
return i
Expand All @@ -345,7 +345,7 @@ func (p *baseObj) findCostume(name string) int {

func (p *baseObj) goSetCostume(val interface{}) bool {
switch v := val.(type) {
case string:
case SpriteCostumeName:
return p.setCostumeByName(v)
case int:
return p.setCostumeByIndex(v)
Expand Down Expand Up @@ -373,8 +373,7 @@ func (p *baseObj) setCostumeByIndex(idx int) bool {
}
return false
}

func (p *baseObj) setCostumeByName(name string) bool {
func (p *baseObj) setCostumeByName(name SpriteCostumeName) bool {
if idx := p.findCostume(name); idx >= 0 {
return p.setCostumeByIndex(idx)
}
Expand All @@ -393,7 +392,7 @@ func (p *baseObj) getCostumeIndex() int {
return p.costumeIndex_
}

func (p *baseObj) getCostumeName() string {
func (p *baseObj) getCostumeName() SpriteCostumeName {
return p.costumes[p.costumeIndex_].name
}

Expand Down
Loading

0 comments on commit 971e4a0

Please sign in to comment.