mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-26 02:42:02 +01:00
parent
70a225fd7e
commit
2bea7d4e1a
@ -33,7 +33,6 @@ package audio
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"runtime"
|
"runtime"
|
||||||
@ -149,7 +148,9 @@ func (c *Context) loop() {
|
|||||||
<-resumeCh
|
<-resumeCh
|
||||||
default:
|
default:
|
||||||
if _, err := io.CopyN(p, c.mux, 2048); err != nil {
|
if _, err := io.CopyN(p, c.mux, 2048); err != nil {
|
||||||
|
c.m.Lock()
|
||||||
c.err = err
|
c.err = err
|
||||||
|
c.m.Unlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.m.Lock()
|
c.m.Lock()
|
||||||
@ -270,9 +271,9 @@ type proceededValues struct {
|
|||||||
//
|
//
|
||||||
// NewPlayer takes the ownership of src. Player's Close calls src's Close.
|
// NewPlayer takes the ownership of src. Player's Close calls src's Close.
|
||||||
func NewPlayer(context *Context, src io.ReadCloser) (*Player, error) {
|
func NewPlayer(context *Context, src io.ReadCloser) (*Player, error) {
|
||||||
if context.mux.hasSource(src) {
|
//if context.mux.hasSource(src) {
|
||||||
return nil, errors.New("audio: src cannot be shared with another Player")
|
// return nil, errors.New("audio: src cannot be shared with another Player")
|
||||||
}
|
//}
|
||||||
p := &Player{
|
p := &Player{
|
||||||
&playerImpl{
|
&playerImpl{
|
||||||
mux: context.mux,
|
mux: context.mux,
|
||||||
|
@ -64,3 +64,31 @@ func TestGC(t *testing.T) {
|
|||||||
}
|
}
|
||||||
t.Errorf("time out")
|
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
|
package audio
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
@ -43,6 +44,15 @@ func (m *mux) Read(b []byte) (int, error) {
|
|||||||
m.m.Lock()
|
m.m.Lock()
|
||||||
defer m.m.Unlock()
|
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 {
|
if len(m.ps) == 0 {
|
||||||
l := len(b)
|
l := len(b)
|
||||||
l &= mask
|
l &= mask
|
||||||
@ -137,14 +147,3 @@ func (m *mux) hasPlayer(player *playerImpl) bool {
|
|||||||
m.m.RUnlock()
|
m.m.RUnlock()
|
||||||
return ok
|
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