Skip to content

Commit b9617fe

Browse files
author
hai.lin
committed
add timer
1 parent 9690d91 commit b9617fe

File tree

8 files changed

+193
-3
lines changed

8 files changed

+193
-3
lines changed

event.go

+32
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ func (p *eventSink) call(wait bool, data interface{}, doSth func(*eventSink)) {
9191

9292
type eventSinkMgr struct {
9393
allWhenStart *eventSink
94+
allWhenTimer *eventSink
9495
allWhenKeyPressed *eventSink
9596
allWhenIReceive *eventSink
9697
allWhenBackdropChanged *eventSink
@@ -102,10 +103,12 @@ type eventSinkMgr struct {
102103
allWhenMoving *eventSink
103104
allWhenTurning *eventSink
104105
calledStart bool
106+
calledTimer bool
105107
}
106108

107109
func (p *eventSinkMgr) reset() {
108110
p.allWhenStart = nil
111+
p.allWhenTimer = nil
109112
p.allWhenKeyPressed = nil
110113
p.allWhenIReceive = nil
111114
p.allWhenBackdropChanged = nil
@@ -121,6 +124,7 @@ func (p *eventSinkMgr) reset() {
121124

122125
func (p *eventSinkMgr) doDeleteClone(this interface{}) {
123126
p.allWhenStart = p.allWhenStart.doDeleteClone(this)
127+
p.allWhenTimer = p.allWhenTimer.doDeleteClone(this)
124128
p.allWhenKeyPressed = p.allWhenKeyPressed.doDeleteClone(this)
125129
p.allWhenIReceive = p.allWhenIReceive.doDeleteClone(this)
126130
p.allWhenBackdropChanged = p.allWhenBackdropChanged.doDeleteClone(this)
@@ -145,6 +149,17 @@ func (p *eventSinkMgr) doWhenStart() {
145149
}
146150
}
147151

152+
func (p *eventSinkMgr) doWhenTimer(time float64) {
153+
if !p.calledTimer {
154+
p.allWhenTimer.asyncCall(false, time, func(ev *eventSink) {
155+
if ev.cond != nil && ev.cond(time) {
156+
ev.sink.(func(float64))(time)
157+
p.calledTimer = true
158+
}
159+
})
160+
}
161+
}
162+
148163
func (p *eventSinkMgr) doWhenKeyPressed(key Key) {
149164
p.allWhenKeyPressed.asyncCall(false, key, func(ev *eventSink) {
150165
ev.sink.(func(Key))(key)
@@ -232,6 +247,7 @@ type IEventSinks interface {
232247
OnMsg__0(onMsg func(msg string, data interface{}))
233248
OnMsg__1(msg string, onMsg func())
234249
OnStart(onStart func())
250+
OnTimer(time float64, onTimer func())
235251
Stop(kind StopKind)
236252
}
237253

@@ -274,6 +290,22 @@ func (p *eventSinks) OnStart(onStart func()) {
274290
}
275291
}
276292

293+
func (p *eventSinks) OnTimer(time float64, onTimer func()) {
294+
p.allWhenTimer = &eventSink{
295+
prev: p.allWhenTimer,
296+
pthis: p.pthis,
297+
sink: func(float64) {
298+
if debugEvent {
299+
log.Println("==> OnTimer", time, nameOf(p.pthis))
300+
}
301+
onTimer()
302+
},
303+
cond: func(data interface{}) bool {
304+
return data.(float64) >= time
305+
},
306+
}
307+
}
308+
277309
func (p *eventSinks) OnClick(onClick func()) {
278310
pthis := p.pthis
279311
p.allWhenClick = &eventSink{

game.go

+13-2
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,8 @@ func (p *Game) addSpecialShape(g reflect.Value, v specsp, inits []Sprite) []Spri
578578
sm.game = p
579579
p.addShape(sm)
580580
}
581+
case "timer":
582+
p.addShape(newTimer(v))
581583
case "measure":
582584
p.addShape(newMeasure(v))
583585
case "sprites":
@@ -717,6 +719,8 @@ func (p *Game) handleEvent(event event) {
717719
p.sinkMgr.doWhenKeyPressed(ev.Key)
718720
case *eventStart:
719721
p.sinkMgr.doWhenStart()
722+
case *eventTimer:
723+
p.sinkMgr.doWhenTimer(ev.time)
720724
}
721725
}
722726

@@ -738,6 +742,8 @@ func (p *Game) eventLoop(me coroutine.Thread) int {
738742
}
739743
func (p *Game) logicLoop(me coroutine.Thread) int {
740744
for {
745+
gtime.Tick(gtime.DeltaTime())
746+
741747
tempItems := p.getTempShapes()
742748
for _, item := range tempItems {
743749
if result, ok := item.(interface{ onUpdate(float64) }); ok {
@@ -1197,11 +1203,16 @@ func (p *Game) Wait(secs float64) {
11971203
}
11981204

11991205
func (p *Game) Timer() float64 {
1200-
panic("todo")
1206+
return gtime.Timer()
12011207
}
12021208

12031209
func (p *Game) ResetTimer() {
1204-
panic("todo")
1210+
gtime.ResetTimer()
1211+
}
1212+
1213+
func (p *Game) OnTimerGreaterThan(secs float64, call func()) {
1214+
engine.Wait(secs)
1215+
gco.WaitMainThread(call)
12051216
}
12061217

12071218
// -----------------------------------------------------------------------------

gdspx.go

+1
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ func (p *Game) syncUpdateLogic() error {
8585
p.startFlag.Do(func() {
8686
p.fireEvent(&eventStart{})
8787
})
88+
p.fireEvent(&eventTimer{time: p.Timer()})
8889

8990
return nil
9091
}

input.go

+4
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,10 @@ type event interface{}
246246

247247
type eventStart struct{}
248248

249+
type eventTimer struct {
250+
time float64
251+
}
252+
249253
type eventKeyDown struct {
250254
Key Key
251255
}

internal/time/timer.go

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package time
2+
3+
var (
4+
gameTimer float64
5+
)
6+
7+
func Tick(deltaTime float64) {
8+
gameTimer += deltaTime
9+
}
10+
11+
func Timer() float64 {
12+
return gameTimer
13+
}
14+
15+
func ResetTimer() {
16+
gameTimer = 0
17+
}

internal/ui/ui_timer.go

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package ui
2+
3+
import (
4+
"github.com/goplus/spx/internal/engine"
5+
"github.com/realdream-ai/mathf"
6+
)
7+
8+
type UiTimer struct {
9+
UiNode
10+
bg *UiNode
11+
label *UiNode
12+
}
13+
14+
func NewUiTimer() *UiTimer {
15+
panel := engine.NewUiNode[UiTimer]()
16+
return panel
17+
}
18+
19+
// !!Warning: this method was called in main thread
20+
func (pself *UiTimer) OnStart() {
21+
pself.bg = SyncBindUI[UiNode](pself.GetId(), "BG")
22+
pself.label = SyncBindUI[UiNode](pself.GetId(), "BG/Label")
23+
}
24+
25+
func (pself *UiTimer) UpdatePos(pos mathf.Vec2) {
26+
uiMgr.SetGlobalPosition(pself.bg.GetId(), pos)
27+
}
28+
29+
func (pself *UiTimer) UpdateText(value string) {
30+
uiMgr.SetText(pself.label.GetId(), value)
31+
}

monitor.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@ import (
2020
"fmt"
2121
"log"
2222
"reflect"
23+
"strconv"
2324
"strings"
2425
"syscall"
2526

27+
gtime "github.com/goplus/spx/internal/time"
2628
"github.com/goplus/spx/internal/tools"
2729
"github.com/goplus/spx/internal/ui"
2830
"github.com/realdream-ai/mathf"
@@ -124,7 +126,8 @@ func getValueRef(target reflect.Value, name string, from int) reflect.Value {
124126
}
125127

126128
const (
127-
getVarPrefix = "getVar:"
129+
getVarPrefix = "getVar:"
130+
getTimerPrefix = "getProp:"
128131
)
129132

130133
func buildMonitorEval(g reflect.Value, t, val string) func() string {
@@ -142,6 +145,10 @@ func buildMonitorEval(g reflect.Value, t, val string) func() string {
142145
}
143146
}
144147
log.Println("[WARN] Monitor: var not found -", name, target)
148+
case strings.HasPrefix(val, getTimerPrefix):
149+
return func() string {
150+
return strconv.FormatFloat(gtime.Timer(), 'f', 3, 64)
151+
}
145152
default:
146153
log.Println("[WARN] Monitor: unknown command -", val)
147154
}

timer.go

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Copyright (c) 2021 The GoPlus Authors (goplus.org). All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package spx
18+
19+
import (
20+
"strconv"
21+
22+
gtime "github.com/goplus/spx/internal/time"
23+
"github.com/goplus/spx/internal/ui"
24+
"github.com/realdream-ai/mathf"
25+
)
26+
27+
type timer struct {
28+
visible bool
29+
pos mathf.Vec2
30+
panel *ui.UiTimer
31+
}
32+
33+
func newTimer(v specsp) *timer {
34+
visible := v["visible"].(bool)
35+
pos := mathf.NewVec2(v["x"].(float64), v["y"].(float64))
36+
panel := ui.NewUiTimer()
37+
timerObj := &timer{
38+
visible: visible,
39+
pos: pos,
40+
panel: panel,
41+
}
42+
panel.UpdatePos(pos)
43+
return timerObj
44+
}
45+
46+
func (pself *timer) onUpdate(delta float64) {
47+
// pself.panel.SetVisible(pself.visible)
48+
if !pself.visible {
49+
return
50+
}
51+
52+
pself.panel.UpdateText(strconv.FormatFloat(gtime.Timer(), 'f', 3, 64))
53+
}
54+
55+
func (pself *timer) Visible() bool {
56+
return pself.visible
57+
}
58+
func (pself *timer) Show() {
59+
pself.visible = true
60+
}
61+
func (pself *timer) Hide() {
62+
pself.visible = false
63+
}
64+
func (pself *timer) Xpos() float64 {
65+
return pself.pos.X
66+
}
67+
func (pself *timer) Ypos() float64 {
68+
return pself.pos.Y
69+
}
70+
func (pself *timer) SetXpos(x float64) {
71+
pself.pos.X = x
72+
}
73+
func (pself *timer) SetYpos(y float64) {
74+
pself.pos.Y = y
75+
}
76+
func (pself *timer) SetXYpos(x float64, y float64) {
77+
pself.pos = mathf.NewVec2(x, y)
78+
}
79+
func (pself *timer) ChangeXpos(dx float64) {
80+
pself.pos.X += dx
81+
}
82+
func (pself *timer) ChangeYpos(dy float64) {
83+
pself.pos.Y += dy
84+
}
85+
func (pself *timer) ChangeXYpos(dx float64, dy float64) {
86+
pself.pos = pself.pos.Add(mathf.NewVec2(dx, dy))
87+
}

0 commit comments

Comments
 (0)