54 lines
1.3 KiB
GDScript
54 lines
1.3 KiB
GDScript
extends Node
|
|
|
|
export (int) var player_count = 5
|
|
|
|
class SoundRequest:
|
|
var stream
|
|
var priority = 0
|
|
|
|
func _init(_stream: AudioStream, _priority: int = 0):
|
|
stream = _stream
|
|
priority = _priority
|
|
|
|
var players := []
|
|
var sound_queue := []
|
|
|
|
func _ready():
|
|
## Singletons don't run process unless explicitly enabled
|
|
set_process(true)
|
|
|
|
for i in range(player_count):
|
|
var player = AudioStreamPlayer.new()
|
|
add_child(player)
|
|
players.append(player)
|
|
|
|
func play_sound(stream: AudioStream, priority: int = 0):
|
|
# Try to find an available player
|
|
for i in range(player_count):
|
|
if not players[i].playing:
|
|
players[i].stream = stream
|
|
players[i].play()
|
|
return
|
|
|
|
##TODO: This may be slow, perhaps just a pop push front is good enough
|
|
# No player is available, add to queue
|
|
sound_queue.append(SoundRequest.new(stream, priority))
|
|
# Sort queue by priority (descending)
|
|
sound_queue.sort_custom(self, "_sort_by_priority")
|
|
|
|
func _process(_delta):
|
|
if sound_queue.empty():
|
|
return
|
|
|
|
for i in range(player_count):
|
|
if not players[i].playing:
|
|
var request = sound_queue.pop_front()
|
|
players[i].stream = request.stream
|
|
players[i].play()
|
|
# only play one queued sound per frame
|
|
break
|
|
|
|
func _sort_by_priority(a: SoundRequest, b: SoundRequest) -> bool:
|
|
return a.priority > b.priority
|
|
|