Skip to content

Commit 16eff2f

Browse files
authored
Merge pull request #204 from goplus/main
v1.0.0-rc6
2 parents 88a40c6 + ce3a7f7 commit 16eff2f

10 files changed

Lines changed: 225 additions & 37 deletions

File tree

.github/dependabot.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# To get started with Dependabot version updates, you'll need to specify which
2+
# package ecosystems to update and where the package manifests are located.
3+
# Please see the documentation for all configuration options:
4+
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5+
6+
version: 2
7+
updates:
8+
- package-ecosystem: "gomod" # See documentation for possible values
9+
directory: "/" # Location of package manifests
10+
schedule:
11+
interval: "daily"

.github/workflows/go.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ jobs:
1111
build:
1212
runs-on: ubuntu-latest
1313
steps:
14-
- uses: actions/checkout@v2
14+
- uses: actions/checkout@v3
1515

1616
- name: Set up Go
17-
uses: actions/setup-go@v2
17+
uses: actions/setup-go@v3
1818
with:
1919
go-version: 1.16
2020

audio.go

Lines changed: 138 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ type readSeekCloser struct {
2121
}
2222

2323
type readCloser struct {
24-
io.Reader
24+
io.ReadSeeker
2525
io.Closer
2626
}
2727

@@ -38,9 +38,41 @@ func newReadSeeker(source io.ReadCloser) io.ReadSeeker {
3838

3939
// -------------------------------------------------------------------------------------
4040

41+
type playerState byte
42+
43+
const (
44+
playerPlay playerState = iota
45+
playerClosed
46+
playerPaused
47+
)
48+
49+
type PlayAction int
50+
51+
const (
52+
PlayRewind PlayAction = iota
53+
PlayContinue
54+
PlayPause
55+
PlayResume
56+
PlayStop
57+
)
58+
59+
type PlayOptions struct {
60+
Action PlayAction
61+
Wait bool
62+
Loop bool
63+
}
64+
65+
type soundPlayer struct {
66+
*audio.Player
67+
media Sound
68+
state playerState
69+
loop bool
70+
}
71+
4172
type soundMgr struct {
73+
g *Game
4274
audioContext *audio.Context
43-
players map[*audio.Player]chan bool
75+
players map[*soundPlayer]chan bool
4476
playersM sync.Mutex
4577
}
4678

@@ -49,26 +81,32 @@ const (
4981
defaultRatio = 100.0
5082
)
5183

52-
func (p *soundMgr) addPlayer(sp *audio.Player, done chan bool) {
84+
func (p *soundMgr) addPlayer(sp *soundPlayer, done chan bool) {
5385
p.playersM.Lock()
5486
defer p.playersM.Unlock()
5587

5688
p.players[sp] = done
5789
}
5890

59-
func (p *soundMgr) init() {
91+
func (p *soundMgr) init(g *Game) {
6092
audioContext := audio.NewContext(defaultSampleRate)
6193
p.audioContext = audioContext
62-
p.players = make(map[*audio.Player]chan bool)
94+
p.players = make(map[*soundPlayer]chan bool)
95+
p.g = g
6396
}
6497

6598
func (p *soundMgr) update() {
6699
p.playersM.Lock()
67100
defer p.playersM.Unlock()
68101

69-
var closed []*audio.Player
102+
var closed []*soundPlayer
70103
for sp, done := range p.players {
71-
if !sp.IsPlaying() {
104+
if !sp.IsPlaying() && sp.state != playerPaused {
105+
if sp.loop {
106+
sp.Rewind()
107+
sp.Play()
108+
continue
109+
}
72110
sp.Close()
73111
if done != nil {
74112
done <- true
@@ -85,20 +123,59 @@ func (p *soundMgr) stopAll() {
85123
p.playersM.Lock()
86124
defer p.playersM.Unlock()
87125

88-
closed := make([]*audio.Player, 0, len(p.players))
126+
closed := make([]*soundPlayer, 0, len(p.players))
89127
for sp, done := range p.players {
90128
sp.Close()
91129
if done != nil {
92130
done <- true
93131
}
132+
sp.state = playerClosed
94133
closed = append(closed, sp)
95134
}
96135
for _, sp := range closed {
97136
delete(p.players, sp)
98137
}
99138
}
100139

101-
func (p *soundMgr) play(source io.ReadCloser, wait ...bool) (err error) {
140+
func (p *soundMgr) playAction(media Sound, opts *PlayOptions) (err error) {
141+
switch opts.Action {
142+
case PlayRewind:
143+
err = p.play(media, opts.Wait, opts.Loop)
144+
case PlayContinue:
145+
err = p.playContinue(media, opts.Wait, opts.Loop)
146+
case PlayStop:
147+
p.stop(media)
148+
case PlayResume:
149+
p.resume(media)
150+
case PlayPause:
151+
p.pause(media)
152+
}
153+
return
154+
}
155+
156+
func (p *soundMgr) playContinue(media Sound, wait, loop bool) (err error) {
157+
p.playersM.Lock()
158+
found := false
159+
for sp := range p.players {
160+
if sp.media.Path == media.Path {
161+
sp.loop = loop
162+
found = true
163+
}
164+
}
165+
p.playersM.Unlock()
166+
167+
if !found {
168+
err = p.play(media, wait, loop)
169+
}
170+
return
171+
}
172+
173+
func (p *soundMgr) play(media Sound, wait, loop bool) (err error) {
174+
source, err := p.g.fs.Open(media.Path)
175+
if err != nil {
176+
panic(err)
177+
}
178+
102179
audioContext := p.audioContext
103180
d, _, err := qaudio.Decode(newReadSeeker(source))
104181
if err != nil {
@@ -108,25 +185,73 @@ func (p *soundMgr) play(source io.ReadCloser, wait ...bool) (err error) {
108185

109186
d = convert.ToStereo16(d)
110187
d = convert.Resample(d, audioContext.SampleRate())
111-
sp, err := audioContext.NewPlayer(&readCloser{d, source})
188+
189+
sp := &soundPlayer{media: media, loop: loop}
190+
sp.Player, err = audioContext.NewPlayer(&readCloser{d, source})
112191
if err != nil {
113192
source.Close()
114193
return
115194
}
116195

117-
var waitDone = (wait != nil)
118196
var done chan bool
119-
if waitDone {
197+
if wait {
120198
done = make(chan bool, 1)
121199
}
122200
p.addPlayer(sp, done)
123201
sp.Play()
124-
if waitDone {
202+
if wait {
125203
waitForChan(done)
126204
}
127205
return
128206
}
129207

208+
func (p *soundMgr) stop(media Sound) {
209+
p.playersM.Lock()
210+
defer p.playersM.Unlock()
211+
212+
closed := make([]*soundPlayer, 0, len(p.players))
213+
for sp, done := range p.players {
214+
if sp.media.Path == media.Path {
215+
sp.Close()
216+
if done != nil {
217+
done <- true
218+
}
219+
sp.state = playerClosed
220+
closed = append(closed, sp)
221+
}
222+
}
223+
for _, sp := range closed {
224+
delete(p.players, sp)
225+
}
226+
}
227+
228+
func (p *soundMgr) pause(media Sound) {
229+
p.playersM.Lock()
230+
defer p.playersM.Unlock()
231+
232+
for sp := range p.players {
233+
if sp.media.Path == media.Path {
234+
sp.Pause()
235+
sp.state = playerPaused
236+
237+
}
238+
239+
}
240+
}
241+
242+
func (p *soundMgr) resume(media Sound) {
243+
p.playersM.Lock()
244+
defer p.playersM.Unlock()
245+
for sp := range p.players {
246+
if sp.media.Path == media.Path {
247+
sp.Play()
248+
sp.state = playerPlay
249+
250+
}
251+
252+
}
253+
}
254+
130255
func (p *soundMgr) volume() float64 {
131256
for sp := range p.players {
132257
return sp.Volume() * defaultRatio

game.go

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ func (p *Game) startLoad(resource interface{}, cfg *Config) (err error) {
414414
}
415415
p.initGame()
416416
p.input.init(p, keyDuration)
417-
p.sounds.init()
417+
p.sounds.init(p)
418418
p.shapes = make(map[string]Spriter)
419419
p.events = make(chan event, 16)
420420
p.fs = fs
@@ -1344,15 +1344,22 @@ func (p *Game) loadSound(name string) (media Sound, err error) {
13441344
// Play func:
13451345
// Play(sound)
13461346
// Play(video) -- maybe
1347-
func (p *Game) Play__0(media Sound, wait ...bool) {
1347+
// Play(media, wait) -- sync
1348+
// Play(media, opts)
1349+
func (p *Game) Play__0(media Sound) {
1350+
p.Play__2(media, &PlayOptions{})
1351+
}
1352+
1353+
func (p *Game) Play__1(media Sound, wait bool) {
1354+
p.Play__2(media, &PlayOptions{Wait: wait})
1355+
}
1356+
1357+
func (p *Game) Play__2(media Sound, action *PlayOptions) {
13481358
if debugInstr {
1349-
log.Println("Play", media.Path, wait)
1359+
log.Println("Play", media.Path)
13501360
}
1351-
f, err := p.fs.Open(media.Path)
1352-
if err != nil {
1353-
panic(err)
1354-
}
1355-
err = p.sounds.play(f, wait...)
1361+
1362+
err := p.sounds.playAction(media, action)
13561363
if err != nil {
13571364
panic(err)
13581365
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ require (
66
github.com/ajstarks/svgo v0.0.0-20210927141636-6d70534b1098
77
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
88
github.com/goplus/canvas v0.1.0
9-
github.com/goplus/gop v1.1.0-alpha2
9+
github.com/goplus/gop v1.1.0-rc2
1010
github.com/hajimehoshi/ebiten/v2 v2.2.0
1111
github.com/pkg/errors v0.9.1
1212
github.com/qiniu/audio v0.2.1

go.sum

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,23 @@ github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm
44
github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk=
55
github.com/ajstarks/svgo v0.0.0-20210927141636-6d70534b1098 h1:iiPTCsr/y6MEke5leED5Bi/0zlznD44tlHQvTgLOJcE=
66
github.com/ajstarks/svgo v0.0.0-20210927141636-6d70534b1098/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM=
7+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
8+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
79
github.com/esimov/stackblur-go v1.0.1-0.20190121110005-00e727e3c7a9 h1:TJdKpA5v3Xu24Vv0yQy1MyRJgpt7vk9AT58fGPfiZcs=
810
github.com/esimov/stackblur-go v1.0.1-0.20190121110005-00e727e3c7a9/go.mod h1:a3zzeKuJKUpCcReHmEsuPaEnq42D2b/bHoCI8UjIuMY=
911
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be h1:vEIVIuBApEBQTEJt19GfhoU+zFSV+sNTa9E9FdnRYfk=
1012
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
1113
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
1214
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
15+
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
16+
github.com/goplus/c2go v0.7.2/go.mod h1:Gd/r7JdrxXDoFKXyP6tsKTM0+j50CGxT0QDJ/5k8hYU=
1317
github.com/goplus/canvas v0.1.0 h1:Vx3f2+U8UANvWf5/01YsQYKNbZDm1GZCjhlEBFrQkeU=
1418
github.com/goplus/canvas v0.1.0/go.mod h1:Rhcvo5qkpD9WuXFnvnXtrBSY97l6h7sXQuofrmiLNdM=
15-
github.com/goplus/gop v1.1.0-alpha2 h1:s3wMFJpprmFBmVRqUIoggQ2wJ3Kb3gX+7J0f8f2Oh8Q=
16-
github.com/goplus/gop v1.1.0-alpha2/go.mod h1:FTu64eb9ZYCwnTfSze6asR8kbxXPs6mbI+kRmUikKf0=
17-
github.com/goplus/gox v1.9.4/go.mod h1:PznHkzl2HARBf7+s2reqcwKm1Z1a6Wae6EntQEh0iJI=
19+
github.com/goplus/gop v1.1.0-rc2 h1:a7qKX5NiJHvmwUU2Rm3+9ujgBkmOlmH4UcyjWsRoh98=
20+
github.com/goplus/gop v1.1.0-rc2/go.mod h1:SDRkIwrlplH1dZjEubh1vubA8aJvPtMrkEgFz+MjJsA=
21+
github.com/goplus/gox v1.11.7/go.mod h1:gu7fuQF8RmWPZUjd+tEJGuV3m/vOEv0bHrct0x/KatM=
22+
github.com/goplus/libc v0.3.6/go.mod h1:nyKm7Iir6iI6hQT5WWUG6Jomx2zt/XRAGLLKtLrlICI=
23+
github.com/goplus/mod v0.9.7/go.mod h1:NHU13OjeNV3ez1f+R9FLJIlIun0KNSuZb0jnmP3N3o8=
1824
github.com/hajimehoshi/bitmapfont/v2 v2.1.3/go.mod h1:2BnYrkTQGThpr/CY6LorYtt/zEPNzvE/ND69CRTaHMs=
1925
github.com/hajimehoshi/ebiten/v2 v2.2.0 h1:2mP9HrLLqiH9X3MajElYZEjVZU/CGh22iFkjatxhT4w=
2026
github.com/hajimehoshi/ebiten/v2 v2.2.0/go.mod h1:olKl/qqhMBBAm2oI7Zy292nCtE+nitlmYKNF3UpbFn0=
@@ -30,10 +36,15 @@ github.com/jezek/xgb v0.0.0-20210312150743-0e0f116e1240 h1:dy+DS31tGEGCsZzB45HmJ
3036
github.com/jezek/xgb v0.0.0-20210312150743-0e0f116e1240/go.mod h1:3P4UH/k22rXyHIJD2w4h2XMqPX4Of/eySEZq9L6wqc4=
3137
github.com/jfreymuth/oggvorbis v1.0.3/go.mod h1:1U4pqWmghcoVsCJJ4fRBKv9peUJMBHixthRlBeD6uII=
3238
github.com/jfreymuth/vorbis v1.0.2/go.mod h1:DoftRo4AznKnShRl1GxiTFCseHr4zR9BN3TWXyuzrqQ=
39+
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
3340
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
41+
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
42+
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
43+
github.com/petermattis/goid v0.0.0-20220331194723-8ee3e6ded87a/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
3444
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
3545
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
3646
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
47+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
3748
github.com/qiniu/audio v0.2.1 h1:lAc3dWfr7uAfn7mfee2u0/fl/QSQA9oTOqdBtxyFZAM=
3849
github.com/qiniu/audio v0.2.1/go.mod h1:APMJRPaS4toviejZnDzzZ8wVyr12jqZhd3xfKr/qYnE=
3950
github.com/qiniu/oksvg v0.2.0-no-charset h1:KKQg81v52pd5VyaxrF891igoOO50epKfFWkryYgntnE=
@@ -43,6 +54,8 @@ github.com/qiniu/x v1.11.5/go.mod h1:03Ni9tj+N2h2aKnAz+6N0Xfl8FwMEDRC2PAlxekASDs
4354
github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9/go.mod h1:mvWM0+15UqyrFKqdRjY6LuAVJR0HOVhJlEgZ5JWtSWU=
4455
github.com/srwiley/rasterx v0.0.0-20210519020934-456a8d69b780 h1:oDMiXaTMyBEuZMU53atpxqYsSB3U1CHkeAu2zr6wTeY=
4556
github.com/srwiley/rasterx v0.0.0-20210519020934-456a8d69b780/go.mod h1:mvWM0+15UqyrFKqdRjY6LuAVJR0HOVhJlEgZ5JWtSWU=
57+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
58+
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
4659
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
4760
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
4861
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=

0 commit comments

Comments
 (0)