CrossingOver/addons/resonate/sound_manager/pool_entity.gd
2024-03-14 00:53:46 -03:00

158 lines
4.4 KiB
GDScript

class_name PoolEntity
extends RefCounted
## An abstract/static class to house all of the common PooledAudioStreamPlayer* functionality.
const ResonateSettings = preload("../shared/resonate_settings.gd")
enum FollowType {DISABLED, IDLE, PHYSICS}
## Create a new PooledAudioStreamPlayer*.
static func create(p_base) -> Variant:
p_base.process_mode = Node.PROCESS_MODE_ALWAYS
return p_base
## Configure a PooledAudioStreamPlayer*.
static func configure(p_base, p_streams: Array, p_reserved: bool, p_bus: String, p_poly: bool, p_volume: float, p_pitch: float, p_mode: Node.ProcessMode) -> bool:
p_base.streams = p_streams
p_base.poly = p_poly
p_base.bus = p_bus
p_base.process_mode = p_mode
p_base.reserved = p_reserved
p_base.releasing = false
p_base.volume_db = p_volume if not p_poly else 0.0
p_base.pitch_scale = p_pitch if not p_poly else 1.0
p_base.base_volume = p_volume
p_base.base_pitch = p_pitch
p_base.follow_target = null
p_base.follow_type = FollowType.DISABLED
if not p_base.poly:
return false
var _settings = ResonateSettings.new()
var max_polyphony = ProjectSettings.get_setting(
_settings.MAX_POLYPHONY_SETTING_NAME,
_settings.MAX_POLYPHONY_SETTING_DEFAULT)
p_base.stream = AudioStreamPolyphonic.new()
p_base.max_polyphony = max_polyphony
p_base.stream.polyphony = max_polyphony
return true
## Attach a PooledAudioStreamPlayer* to a position or node.
static func attach_to(p_base, p_node: Variant) -> void:
if p_node == null:
return
if ResonateUtils.is_vector(p_node):
p_base.global_position = p_node
if ResonateUtils.is_node(p_node):
p_base.follow_target = p_node
p_base.follow_type = FollowType.IDLE
## Sync a PooledAudioStreamPlayer*'s transform with its target's when applicable.
static func sync_process(p_base) -> void:
if p_base.follow_target == null:
return
if not is_instance_valid(p_base.follow_target):
return
if p_base.follow_type != FollowType.IDLE:
return
p_base.global_position = p_base.follow_target.global_position
## Sync a PooledAudioStreamPlayer*'s transform with its target's
## when applicable during the physics step.
static func sync_physics_process(p_base) -> void:
if p_base.follow_target == null:
return
if not is_instance_valid(p_base.follow_target):
return
if p_base.follow_type != FollowType.PHYSICS:
return
p_base.global_position = p_base.follow_target.global_position
## Trigger a PooledAudioStreamPlayer*.
static func trigger(p_base, p_varied: bool, p_pitch: float, p_volume: float) -> bool:
if p_base.streams.size() == 0:
push_warning("Resonate - The player [%s] does not contain any streams, ensure you're using the SoundManager to instance it correctly." % p_base.name)
return false
var next_stream = p_base.streams.pick_random()
if not p_base.poly and p_varied:
p_base.volume_db = p_volume
p_base.pitch_scale = p_pitch
if not p_base.poly:
p_base.stream = next_stream
return true
var playback = p_base.get_stream_playback() as AudioStreamPlaybackPolyphonic
if p_varied:
playback.play_stream(next_stream, 0, p_volume, p_pitch)
else:
playback.play_stream(next_stream, 0, p_base.base_volume, p_base.base_pitch)
return false
## Reset the volume of a PooledAudioStreamPlayer*.
static func reset_volume(p_base) -> void:
p_base.volume_db = p_base.base_volume
## Reset the pitch of a PooledAudioStreamPlayer*.
static func reset_pitch(p_base) -> void:
p_base.pitch_scale = p_base.base_pitch
## Reset both the volume and pitch of a PooledAudioStreamPlayer*.
static func reset_all(p_base) -> void:
p_base.volume_db = p_base.base_volume
p_base.pitch_scale = p_base.base_pitch
## Release a PooledAudioStreamPlayer* back into the pool.
static func release(p_base, p_finish_playing: bool) -> void:
if p_base.releasing:
return
var has_loops = p_base.streams.any(ResonateUtils.is_stream_looped)
if p_finish_playing and has_loops:
push_warning("Resonate - The player [%s] has looping streams and therefore will never release itself back to the pool (as playback continues indefinitely). It will be forced to stop." % p_base.name)
p_base.stop()
if not p_finish_playing:
p_base.stop()
p_base.reserved = false
p_base.process_mode = Node.PROCESS_MODE_ALWAYS
p_base.releasing = true
p_base.released.emit()
## A callback to release a PooledAudioStreamPlayer* when it finishes playing.
static func finished(p_base) -> void:
if p_base.reserved:
return
p_base.release()