mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
parent
70a225fd7e
commit
2bea7d4e1a
@ -33,7 +33,6 @@ package audio
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"runtime"
|
||||
@ -149,7 +148,9 @@ func (c *Context) loop() {
|
||||
<-resumeCh
|
||||
default:
|
||||
if _, err := io.CopyN(p, c.mux, 2048); err != nil {
|
||||
c.m.Lock()
|
||||
c.err = err
|
||||
c.m.Unlock()
|
||||
return
|
||||
}
|
||||
c.m.Lock()
|
||||
@ -270,9 +271,9 @@ type proceededValues struct {
|
||||
//
|
||||
// NewPlayer takes the ownership of src. Player's Close calls src's Close.
|
||||
func NewPlayer(context *Context, src io.ReadCloser) (*Player, error) {
|
||||
if context.mux.hasSource(src) {
|
||||
return nil, errors.New("audio: src cannot be shared with another Player")
|
||||
}
|
||||
//if context.mux.hasSource(src) {
|
||||
// return nil, errors.New("audio: src cannot be shared with another Player")
|
||||
//}
|
||||
p := &Player{
|
||||
&playerImpl{
|
||||
mux: context.mux,
|
||||
|
@ -64,3 +64,31 @@ func TestGC(t *testing.T) {
|
||||
}
|
||||
t.Errorf("time out")
|
||||
}
|
||||
|
||||
// Issue #853
|
||||
func TestSameSourcePlayers(t *testing.T) {
|
||||
src := BytesReadSeekCloser(make([]byte, 4))
|
||||
p0, err := NewPlayer(context, src)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
p1, err := NewPlayer(context, src)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// As the player does not play yet, error doesn't happen.
|
||||
if err := UpdateForTesting(); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
p0.Play()
|
||||
p1.Play()
|
||||
|
||||
// 200[ms] should be enough all the bytes are consumed.
|
||||
// TODO: This is a darty hack. Would it be possible to use virtual time?
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
if err := UpdateForTesting(); err == nil {
|
||||
t.Errorf("got: nil, want: an error")
|
||||
}
|
||||
}
|
||||
|
21
audio/mux.go
21
audio/mux.go
@ -15,6 +15,7 @@
|
||||
package audio
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"runtime"
|
||||
"sync"
|
||||
@ -43,6 +44,15 @@ func (m *mux) Read(b []byte) (int, error) {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
// Check the source duplication
|
||||
srcs := map[io.ReadCloser]struct{}{}
|
||||
for p := range m.ps {
|
||||
if _, ok := srcs[p.src]; ok {
|
||||
return 0, errors.New("audio: a same source is used by multiple Player")
|
||||
}
|
||||
srcs[p.src] = struct{}{}
|
||||
}
|
||||
|
||||
if len(m.ps) == 0 {
|
||||
l := len(b)
|
||||
l &= mask
|
||||
@ -137,14 +147,3 @@ func (m *mux) hasPlayer(player *playerImpl) bool {
|
||||
m.m.RUnlock()
|
||||
return ok
|
||||
}
|
||||
|
||||
func (m *mux) hasSource(src io.ReadCloser) bool {
|
||||
m.m.RLock()
|
||||
defer m.m.RUnlock()
|
||||
for p := range m.ps {
|
||||
if p.src == src {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user