Skip to content

Commit

Permalink
KOMODO-6: Change Sound to return sound ID
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesaorson committed Mar 27, 2020
1 parent b986670 commit 1a413e0
Show file tree
Hide file tree
Showing 84 changed files with 452 additions and 482 deletions.
9 changes: 5 additions & 4 deletions Common/Behaviors/PlayerBehavior.cs
@@ -1,10 +1,9 @@
using Komodo.Core.ECS.Components;
using System;

using Color = Microsoft.Xna.Framework.Color;
using GameTime = Microsoft.Xna.Framework.GameTime;

using SoundEffectInstance = Microsoft.Xna.Framework.Audio.SoundEffectInstance;

namespace Common.Behaviors
{
public class PlayerBehavior : BehaviorComponent
Expand All @@ -21,7 +20,7 @@ public PlayerBehavior(int playerIndex) : base()
#region Public Members
public int PlayerIndex { get; }
public SoundComponent Sound { get; private set; }
public SoundEffectInstance SoundInstance { get; private set; }
public Guid SoundInstance { get; private set; }
#endregion Public Members

#region Protected Members
Expand Down Expand Up @@ -49,6 +48,8 @@ public override void Initialize()
{
Parent.AddComponent(new MoveBehavior(PlayerIndex));
}
Sound = new SoundComponent("audio/sample");
Parent.AddComponent(Sound);

Parent.AddComponent(
new TextComponent("fonts/font", Color.Black, Game?.DefaultSpriteShader, $"Test {PlayerIndex}")
Expand All @@ -60,7 +61,7 @@ public override void Initialize()
}
public override void Update(GameTime gameTime)
{
if (Sound != null && SoundInstance == null)
if (Sound != null && SoundInstance == Guid.Empty)
{
SoundInstance = Sound.Play();
}
Expand Down
111 changes: 56 additions & 55 deletions Komodo/Core/ECS/Components/SoundComponent.cs
Expand Up @@ -23,14 +23,14 @@ public class SoundComponent : Component
/// <param name="soundPath">File path to a compiled <see cref="Microsoft.Xna.Framework.Audio.SoundEffect"/> content file.</param>
public SoundComponent(string soundPath) : base(true, null)
{
_instances = new List<SoundEffectInstance>();
_instances = new Dictionary<Guid, SoundEffectInstance>();
SoundPath = soundPath;
}
#endregion Constructors

#region Destructor
/// <summary>
/// Stops all <see cref="Microsoft.Xna.Framework.Audio.SoundEffectInstance"/> objects found in <see cref="Instances"/>.
/// Stops all sound instance found in <see cref="_instances"/>.
/// </summary>
~SoundComponent()
{
Expand All @@ -41,11 +41,6 @@ public SoundComponent(string soundPath) : base(true, null)
#region Members

#region Public Members
/// <summary>
/// Collection of current and valid <see cref="Microsoft.Xna.Framework.Audio.SoundEffectInstance"/> objects.
/// </summary>
public List<SoundEffectInstance> Instances => _instances;

/// <summary>
/// Raw sound data loaded from disk.
/// </summary>
Expand All @@ -58,7 +53,7 @@ public SoundComponent(string soundPath) : base(true, null)
#endregion Public Members

#region Internal Members
internal List<SoundEffectInstance> _instances { get; set; }
internal Dictionary<Guid, SoundEffectInstance> _instances { get; set; }
#endregion Internal Members

#endregion Members
Expand All @@ -67,14 +62,15 @@ public SoundComponent(string soundPath) : base(true, null)

#region Public Member Methods
/// <summary>
/// Changes the intensity of a valid sound instance found in <see cref="Instances"/>.
/// Changes the intensity of a valid sound instance found in <see cref="_instances"/>.
/// </summary>
/// <param name="sound">Specific instance that will have its volume intensity modified.</param>
/// <param name="id">Identifier for the instance that will have its volume intensity modified.</param>
/// <param name="volume">Value, clamped between 0 and 1, representing the volume intensity.</param>
public void ChangeVolume(SoundEffectInstance sound, float volume)
public void ChangeVolume(Guid id, float volume)
{
if (IsValidInstance(sound))
if (IsValidInstance(id))
{
var instance = _instances[id];
if (volume < 0f)
{
volume = 0f;
Expand All @@ -83,64 +79,66 @@ public void ChangeVolume(SoundEffectInstance sound, float volume)
{
volume = 1f;
}
sound.Volume = volume;
instance.Volume = volume;
}
}

/// <summary>
/// Clears all <see cref="Microsoft.Xna.Framework.Audio.SoundEffectInstance"/> objects found in <see cref="Instances"/>, stopping all of them immediately.
/// Clears all sound instances, stopping all of them immediately.
/// </summary>
public void Clear()
{
var instances = Instances.ToList();
foreach (var instance in instances)
foreach (var id in _instances.Keys)
{
Stop(instance);
Stop(id);
}
Instances.Clear();
_instances.Clear();
}

/// <summary>
/// Checks whether or not a <see cref="Microsoft.Xna.Framework.Audio.SoundEffectInstance"/> is not null, not disposed, and is present in <see cref="Instances"/>.
/// Checks whether or not a sound instance exists and is not disposed.
/// </summary>
/// <param name="instance"></param>
/// <returns>Whether or not the <see cref="Microsoft.Xna.Framework.Audio.SoundEffectInstance"/> is valid.</returns>
public bool IsValidInstance(SoundEffectInstance instance)
/// <param name="id">Identifier of the instance to check.</param>
/// <returns>Whether or not the id represents a valid sound instance.</returns>
public bool IsValidInstance(Guid id)
{
return instance != null && !instance.IsDisposed && Instances.Contains(instance);
bool instanceExists = _instances.TryGetValue(id, out SoundEffectInstance instance);
return instanceExists && !instance.IsDisposed;
}

/// <summary>
/// Pauses the given <see cref="Microsoft.Xna.Framework.Audio.SoundEffectInstance"/> if the instance is present on the SoundComponent.
/// Pauses the given sound if the instance is present on the SoundComponent.
/// </summary>
/// <param name="soundToPause">Specific instance to pause.</param>
public void Pause(SoundEffectInstance soundToPause)
/// <param name="id">Identifier for the specific instance to pause.</param>
public void Pause(Guid id)
{
if (IsValidInstance(soundToPause))
if (IsValidInstance(id))
{
soundToPause.Pause();
var instance = _instances[id];
instance.Pause();
}
}

/// <summary>
/// Pauses all <see cref="Microsoft.Xna.Framework.Audio.SoundEffectInstance"/> objects found in <see cref="Instances"/>.
/// Pauses all sound instances found in <see cref="_instances"/>.
/// </summary>
public void PauseAll()
{
foreach (var instance in Instances)
foreach (var id in _instances.Keys)
{
Pause(instance);
Pause(id);
}
}

/// <summary>
/// Creates a <see cref="Microsoft.Xna.Framework.Audio.SoundEffectInstance"/> from <see cref="Sound"/>.
/// Creates a sound instance from <see cref="Sound"/>.
/// </summary>
/// <param name="loop">The <see cref="Microsoft.Xna.Framework.Audio.SoundEffectInstance"/> will continue to repeat until paused or stopped.</param>
/// <param name="loop">The sound instance will continue to repeat until paused or stopped.</param>
/// <param name="shouldLayerSound"></param>
/// <returns>A <see cref="Microsoft.Xna.Framework.Audio.SoundEffectInstance"/> handle for pausing, resuming, and stopping.</returns>
public SoundEffectInstance Play(bool loop = false, bool shouldLayerSound = true)
/// <returns>A sound instance ID for pausing, resuming, and stopping.</returns>
public Guid Play(bool loop = false, bool shouldLayerSound = true)
{
var id = Guid.Empty;
if (Sound != null)
{
var instance = Sound.CreateInstance();
Expand All @@ -149,49 +147,52 @@ public SoundEffectInstance Play(bool loop = false, bool shouldLayerSound = true)
{
Clear();
}
Instances.Add(instance);
id = Guid.NewGuid();
_instances[id] = instance;
instance.Play();

return instance;
}
return null;
return id;
}

/// <summary>
/// Resumes a paused <see cref="Microsoft.Xna.Framework.Audio.SoundEffectInstance"/>.
/// Resumes a paused sound instance.
/// </summary>
/// <param name="soundToResume"><see cref="Microsoft.Xna.Framework.Audio.SoundEffectInstance"/> to resume playing.</param>
public void Resume(SoundEffectInstance soundToResume)
/// <param name="id">Sound instance to resume playing.</param>
public void Resume(Guid id)
{
if (IsValidInstance(soundToResume) && soundToResume.State == SoundState.Paused)
if (IsValidInstance(id))
{
soundToResume.Resume();
var instance = _instances[id];
if (instance.State == SoundState.Paused)
{
instance.Resume();
}
}
}

/// <summary>
/// Stops a <see cref="Microsoft.Xna.Framework.Audio.SoundEffectInstance"/>. Stopping a sound will remove the <see cref="Microsoft.Xna.Framework.Audio.SoundEffectInstance"/> from <see cref="Instances"/>.
/// Stops a sound instance. Stopping a sound will remove the instance from <see cref="_instances"/>.
/// </summary>
/// <param name="soundToStop"><see cref="Microsoft.Xna.Framework.Audio.SoundEffectInstance"/> to stop.</param>
public void Stop(SoundEffectInstance soundToStop)
/// <param name="id">Identifier for sound to stop.</param>
public void Stop(Guid id)
{
if (IsValidInstance(soundToStop))
if (IsValidInstance(id))
{
soundToStop.Stop();
Instances.Remove(soundToStop);
soundToStop.Dispose();
var instance = _instances[id];
instance.Stop();
_instances.Remove(id);
instance.Dispose();
}
}

/// <summary>
/// Stops all <see cref="Microsoft.Xna.Framework.Audio.SoundEffectInstance"/> objects found in <see cref="Instances"/>.
/// Stops all sound instances found in <see cref="_instances"/>.
/// </summary>
public void StopAll()
{
var instances = Instances.ToList();
foreach (var instance in instances)
foreach (var id in _instances.Keys)
{
Stop(instance);
Stop(id);
}
}
#endregion Public Member Methods
Expand Down
8 changes: 5 additions & 3 deletions Komodo/Core/ECS/Systems/SoundSystem.cs
Expand Up @@ -280,12 +280,14 @@ private bool RemoveSoundComponent([NotNull] SoundComponent componentToRemove)
/// <param name="_">Time passed since last <see cref="Komodo.Core.Game.Update(GameTime)"/>.</param>
private void UpdateComponent(SoundComponent component, GameTime _)
{
var instances = new List<SoundEffectInstance>();
foreach (var instance in component.Instances)
var instances = new Dictionary<Guid, SoundEffectInstance>();
foreach (var pair in component._instances)
{
var id = pair.Key;
var instance = pair.Value;
if (instance.State != SoundState.Stopped)
{
instances.Add(instance);
instances[id] = instance;
}
}

Expand Down

0 comments on commit 1a413e0

Please sign in to comment.