Commit 27a275bc authored by Jesse Freeman's avatar Jesse Freeman

Created a new service layer allowing classes to register themselves with the...

Created a new service layer allowing classes to register themselves with the ChipManager and expose functionality to the chips without being tightly coupled to their APIs. Fixed bugs and missing code in SoundChip and MusicChip. Corrected ColorData Hex color conversion to be more accurate and added RoundToInt to the MathUtil. General code cleanup and other updated to bring SDK codebase in line with above changes.
parent 524f6e4e
......@@ -15,8 +15,6 @@
//
using System;
using System.Collections.Generic;
using System.Text;
namespace PixelVisionSDK.Chips
{
......@@ -100,48 +98,6 @@ namespace PixelVisionSDK.Chips
active = false;
}
// /// <summary>
// /// This methods sets up the foundation for serializing a component as
// /// JSON. It automatically creates a json wrapper before calling
// /// CustomSerializedData().
// /// </summary>
// /// <returns>string</returns>
// public virtual string SerializeData()
// {
// var sb = new StringBuilder();
// sb.Append("{");
// CustomSerializedData(sb);
// sb.Append("}");
// return sb.ToString();
// }
//
// /// <summary>
// /// Override this to add custom json data to the serialized string
// /// passed in by the StringBuilder reference.
// /// </summary>
// /// <param name="sb">
// /// A StringBuilder reference to add additional json string properties
// /// to.
// /// </param>
// public virtual void CustomSerializedData(StringBuilder sb)
// {
// // Override to add custom data
// }
//
// /// <summary>
// /// Override this to method to handle your own custom de-serialized
// /// logic. It expects a Dictionary with a string as the key and a
// /// generic object as the value.
// /// </summary>
// /// <param name="data">
// /// A Dictionary with a string as the key and a generic object as the
// /// value.
// /// </param>
// public virtual void DeserializeData(Dictionary<string, object> data)
// {
// throw new NotImplementedException();
// }
public virtual void Init()
{
}
......
......@@ -36,12 +36,12 @@ namespace PixelVisionSDK.Chips
public int maxTracks = 8; // max number of instruments playing notes
public float nextBeatTimestamp;
protected float[] noteHZ; // a lookup table of all musical notes in Hz
protected int notesPerTrack = 32;
protected float[] noteStartFrequency; // same, but for sfxr frequency 0..1 range
public int notesPerTrack = 32;
public float[] noteStartFrequency; // same, but for sfxr frequency 0..1 range
protected float noteTickS = 30.0f / 120.0f; // (30.0f/120.0f) = 120BPM eighth notes
protected float noteTickSEven;
protected float noteTickSOdd;
protected long sequencerBeatNumber;
public long sequencerBeatNumber;
protected int sequencerLoopNum;
public bool songCurrentlyPlaying;
protected SongData[] songDataCollection = new SongData[0];
......@@ -71,13 +71,18 @@ namespace PixelVisionSDK.Chips
{
if (songDataCollection[i] == null)
{
songDataCollection[i] = new SongData("Untitled" + i);
songDataCollection[i] = CreateNewSongData("Untitled" + i);
}
}
}
}
}
public virtual SongData CreateNewSongData(string name)
{
return new SongData(name);
}
public int totalTracks
{
get { return soundChip.totalChannels; }
......@@ -199,7 +204,7 @@ namespace PixelVisionSDK.Chips
//TODO not implemented yet
}
public override void Reset()
public void ResetSong()
{
activeSongData.Reset();
LoadInstruments(activeSongData);
......@@ -267,7 +272,7 @@ namespace PixelVisionSDK.Chips
sequencerBeatNumber++; // next beat will use array index +1
}
protected void LoadInstruments(SongData song)
public void LoadInstruments(SongData song)
{
var trackCount = song.tracks.Length;
......@@ -284,7 +289,7 @@ namespace PixelVisionSDK.Chips
}
}
protected void UpdateNoteTickLengths()
public void UpdateNoteTickLengths()
{
noteTickS = 30.0f / activeSongData.speedInBPM; // (30.0f/120.0f) = 120BPM eighth notes [tempo]
noteTickSOdd = noteTickS * swingRhythmFactor; // small beat
......@@ -321,6 +326,9 @@ namespace PixelVisionSDK.Chips
protected void UpdateMusicNotes()
{
for (var x = 0; x < notesPerTrack; x++)
{
// Need to make sure we only play tracks that exists
if (tracksPerLoop < activeSongData.tracks.Length)
{
for (var y = 0; y < tracksPerLoop; y++)
{
......@@ -333,6 +341,7 @@ namespace PixelVisionSDK.Chips
}
}
}
}
}
......
......@@ -58,7 +58,7 @@ namespace PixelVisionSDK.Chips
for (var i = 0; i < value; i++)
{
if (sounds[i] == null)
sounds[i] = CreateEmptySoundData();
sounds[i] = CreateEmptySoundData("Untitled" + i.ToString("D2"));
}
}
}
......@@ -83,15 +83,15 @@ namespace PixelVisionSDK.Chips
public void ClearSound(int index)
{
// TODO need to see if there is a better way to revert a sound
sounds[index] = CreateEmptySoundData();
sounds[index] = CreateEmptySoundData("Untitled"+index.ToString("D2"));
}
/// <summary>
/// This stub methods is designed to be overriden with a Factory to
/// This stub methods is designed to be overridden with a Factory to
/// create new sound instances that implement the ISoundData interface.
/// </summary>
/// <returns></returns>
public virtual ISoundData CreateEmptySoundData()
public virtual ISoundData CreateEmptySoundData(string name = "Untitled")
{
throw new NotImplementedException(
"Need to create a new ISoundData type and override SoundCollection CreateEmptySoundData method.");
......@@ -184,6 +184,16 @@ namespace PixelVisionSDK.Chips
return channels[index];
}
public string ReadLabel(int id)
{
return ReadSound(id).name;
}
public void UpdateLabel(int id, string name)
{
ReadSound(id).name = name;
}
}
}
\ No newline at end of file
......@@ -17,6 +17,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using PixelVisionSDK.Services;
namespace PixelVisionSDK.Chips
{
......@@ -28,7 +29,7 @@ namespace PixelVisionSDK.Chips
/// managing the life-cycle of chips as they are created and destroy in the
/// engine.
/// </summary>
public class ChipManager : IGameLoop
public class ChipManager : IGameLoop, IServiceLocator
{
protected Dictionary<string, AbstractChip> chips = new Dictionary<string, AbstractChip>();
......@@ -152,11 +153,18 @@ namespace PixelVisionSDK.Chips
// TODO create a chip
var type = Type.GetType(id);
var chipInstance = Activator.CreateInstance(type) as AbstractChip;
ActivateChip(id, chipInstance);
AbstractChip chipInstance;
//Debug.Log("Chip Manager: Create new instance of " + id);
try
{
chipInstance = Activator.CreateInstance(type) as AbstractChip;
ActivateChip(id, chipInstance);
}
catch (Exception)
{
throw new Exception("Chip '"+id+"' could not be created.");
}
return chipInstance;
}
......@@ -200,16 +208,16 @@ namespace PixelVisionSDK.Chips
}
/// <summary>
/// This method calls the Activate method on a <paramref name="chip" />
/// This method calls the Activate method on a chip
/// if it exists in the manager. This method can be used to register
/// <see cref="chips" /> as well as register them with unique IDs. Chips
/// chips as well as register them with unique IDs. Chips
/// registered without class names will not be restored correctly
/// through the serialization API.
/// </summary>
/// <param name="id">
/// The name of the chip. This should be the fully qualified class name
/// if you want to automatically create the instance if one doesn't
/// exist. The supplied <paramref name="chip" /> will be registered to
/// exist. The supplied chip will be registered to
/// this id.
/// </param>
/// <param name="chip">
......@@ -219,19 +227,20 @@ namespace PixelVisionSDK.Chips
{
if (HasChip(id))
{
//TODO do we need to dissable the old chip first
//TODO do we need to disable the old chip first
chips[id] = chip;
}
else
{
//TODO fixed bug here but need to make sure we don't need to do this above
chips.Add(id, chip);
}
if (chip is IUpdate)
updateChips.Add(chip as IUpdate);
if (chip is IDraw)
drawChips.Add(chip as IDraw);
}
chip.Activate(engine);
}
......@@ -265,6 +274,46 @@ namespace PixelVisionSDK.Chips
}
}
protected Dictionary<string, IService> _services = new Dictionary<string, IService>();
public Dictionary<string, IService> services
{
get { return _services; }
}
/// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <param name="service"></param>
public void AddService(string id, IService service)
{
// Add the service to the managed list
if (services.ContainsKey(id))
{
// If the service exists, overwrite it
services[id] = service;
}
else
{
// If the service doesn't exist, create a new reference to it
services.Add(id, service);
}
// Add a reference of the service locator
service.RegisterService(this);
}
public IService GetService(string id)
{
if (services.ContainsKey(id))
return services[id];
throw new ApplicationException("The requested service '" + id + "' is not registered");
}
}
}
\ No newline at end of file
......@@ -16,7 +16,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PixelVisionSDK.Utils;
//using UnityEngine;
......@@ -172,6 +171,7 @@ namespace PixelVisionSDK.Chips
//Debug.Log("Game: Configure");
engine.currentGame = this;
//TODO this needs to be a service
apiBridge = engine.apiBridge;
ready = true;
}
......
......@@ -15,8 +15,6 @@
//
using System;
using System.Collections.Generic;
using System.Text;
using PixelVisionSDK.Utils;
namespace PixelVisionSDK.Chips
......@@ -57,6 +55,19 @@ namespace PixelVisionSDK.Chips
private bool invalid;
protected Vector pageSize = new Vector(8, 8);
public string[] hexColors
{
get
{
var colors = new string[total];
Array.Copy(_colors, colors, total);
return colors;
}
}
/// <summary>
/// Defines the total number of colors per virtual page.
/// </summary>
......@@ -188,7 +199,7 @@ namespace PixelVisionSDK.Chips
public void UpdateColorAt(int index, string color)
{
if (index > _colors.Length)
if (index > _colors.Length || index < 0)
return;
if (ColorData.ValidateColor(color))
......
......@@ -48,6 +48,17 @@ namespace PixelVisionSDK.Chips
}
}
public string[] hexColors {
get
{
var colors = new string[total];
Array.Copy(_colors, colors, total);
return colors;
}
}
public int total
{
get { return _colors.Length; }
......
......@@ -14,9 +14,6 @@
// Shawn Rakowski - @shwany
//
using System;
using System.Collections.Generic;
using System.Text;
using PixelVisionSDK.Utils;
namespace PixelVisionSDK.Chips
......@@ -90,7 +87,7 @@ namespace PixelVisionSDK.Chips
/// </summary>
public void Draw()
{
//TODO this should run through all the draw calls and composit them to the textureData
//TODO this should run through all the draw calls and composite them to the textureData
// Reset the sprite counter after a draw
......
......@@ -294,10 +294,19 @@ namespace PixelVisionSDK.Chips
public static string Split(string str, int chunkSize)
{
var total = (double) str.Length;
var split = Enumerable.Range(0, (int) Math.Ceiling(total / chunkSize))
var split = Enumerable.Range(0, (int) Math.Floor(total / chunkSize))
.Select(i => str.Substring(i * chunkSize, chunkSize)).ToArray();
return string.Join("\n", split);
var text = string.Join("\n", split);
var newTotal = text.Length;
if (total > newTotal)
{
text += "\n" + str.Substring(newTotal);
}
return text;
}
}
......
......@@ -28,6 +28,7 @@ namespace PixelVisionSDK.Chips
/// An array of the supported <see cref="colors" /> in the chip.
/// </summary>
ColorData[] colors { get; }
string[] hexColors { get; }
/// <summary>
/// The <see cref="total" /> number of <see cref="colors" /> in the chip.
......
......@@ -15,9 +15,7 @@
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PixelVisionSDK.Utils;
namespace PixelVisionSDK.Chips
......@@ -51,11 +49,6 @@ namespace PixelVisionSDK.Chips
//protected Vector2 pageSize = new Vector2(128, 128);
protected int pageWidth = 128;
/// <summary>
/// A flag to toggle whether pixel data should be serialized.
/// </summary>
public bool serializePixelData;
/// <summary>
/// The global <see cref="width" /> of sprites in the engine. By default
/// this is set to 8.
......
......@@ -37,8 +37,9 @@ namespace PixelVisionSDK.Chips
{
protected ControllerInput[] controllers = new ControllerInput[2];
protected IKeyInput keyInput;
protected IMouseInput mouseInput;
protected IKeyInput keyInput { get; set; }
protected IMouseInput mouseInput { get; set; }
public bool mouseInputActive
{
......@@ -75,7 +76,7 @@ namespace PixelVisionSDK.Chips
{
get
{
if (keyInputActive)
if (!keyInputActive)
return "";
return keyInput.inputString;
......@@ -84,7 +85,7 @@ namespace PixelVisionSDK.Chips
public bool GetKeyUp(int key)
{
if (keyInputActive)
if (!keyInputActive)
return false;
return keyInput.GetKeyUp(key);
......@@ -92,7 +93,7 @@ namespace PixelVisionSDK.Chips
public bool GetKey(int key)
{
if (keyInputActive)
if (!keyInputActive)
return false;
return keyInput.GetKey(key);
......@@ -100,7 +101,7 @@ namespace PixelVisionSDK.Chips
public bool GetKeyDown(int key)
{
if (keyInputActive)
if (!keyInputActive)
return false;
return keyInput.GetKeyDown(key);
......@@ -141,7 +142,7 @@ namespace PixelVisionSDK.Chips
}
}
public void Update(float timeDelta)
public virtual void Update(float timeDelta)
{
foreach (var controllerInput in controllers)
{
......
......@@ -15,45 +15,18 @@
//
using System.Collections.Generic;
using System.Text;
using PixelVisionSDK.Chips;
namespace PixelVisionSDK
{
public class ControllerInput : ISave, ILoad
public class ControllerInput
{
private readonly Dictionary<Buttons, IButtonState> buttonState = new Dictionary<Buttons, IButtonState>();
protected float delay;
public float inputDelay = 0.1f;
public void DeserializeData(Dictionary<string, object> data)
{
//throw new NotImplementedException();
}
public string SerializeData()
{
var sb = new StringBuilder();
sb.Append("{");
CustomSerializedData(sb);
sb.Append("}");
return sb.ToString();
}
public void CustomSerializedData(StringBuilder sb)
{
// sb.Append("[");
// var total = buttonState.Count;
// for (int i = 0; i < total; i++)
// {
// sb.Append("\"controller"+i+"\":" + buttonState[i].SerializeData());
// }
//
// sb.Append("]");
}
public void Update(float timeDelta)
{
foreach (var item in buttonState)
......@@ -124,14 +97,6 @@ namespace PixelVisionSDK
return buttonState;
}
// void OnGUI()
// {
// Event e = Event.current;
// if (e.isKey)
// Debug.Log("Detected key code: " + e.keyCode);
//
// }
}
}
\ No newline at end of file
......@@ -14,9 +14,6 @@
// Shawn Rakowski - @shwany
//
using System.Collections.Generic;
using System.Text;
namespace PixelVisionSDK
{
......@@ -26,7 +23,7 @@ namespace PixelVisionSDK
/// IInvalidate interfaces and provides as standard API for serializing
/// the data it contains via the CustomSerializeData() method.
/// </summary>
public abstract class AbstractData : ISave, ILoad, IInvalidate
public abstract class AbstractData : IInvalidate
{
protected bool _invalid;
......@@ -65,52 +62,6 @@ namespace PixelVisionSDK
_invalid = false;
}
/// <summary>
/// The DeserializeData method allows you to pass in a
/// Dictionary with a string as the key and a generic object for the
/// value. This can be manually parsed to convert each key/value pair
/// into data used to configure the class that
/// implements this interface.
/// </summary>
/// <param name="data">
/// A Dictionary with a string as the key and a generic object as the
/// value.
/// </param>
public virtual void DeserializeData(Dictionary<string, object> data)
{
// override with custom parsing logic
}
/// <summary>
/// Use this method to create a new StringBuilder instance and wrap any
/// custom serialized data by leveraging the CustomSerializedData()
/// method.
/// </summary>
/// <returns name="String">
/// A string JSON object.
/// </returns>
public virtual string SerializeData()
{
var sb = new StringBuilder();
sb.Append("{");
CustomSerializedData(sb);
sb.Append("}");
return sb.ToString();
}
/// <summary>
/// Use this method to add additional serialized string data to the
/// supplied StringBuilder instance.
/// </summary>
/// <param name="sb">
/// A reference to a StringBuilder which is supplied by the
/// SerializedData() method.
/// </param>
public virtual void CustomSerializedData(StringBuilder sb)
{
// override with custom serialized data
}
}
}
\ No newline at end of file
......@@ -17,6 +17,7 @@
using System;
using System.Globalization;
using System.Text.RegularExpressions;
using PixelVisionSDK.Utils;
namespace PixelVisionSDK
{
......@@ -34,6 +35,24 @@ namespace PixelVisionSDK
protected float _r;
public void FromHex(string hexColor)
{
float tmpR, tmpG, tmpB;
HexToColor(hexColor, out tmpR, out tmpG, out tmpB);
r = tmpR;
g = tmpG;
b = tmpB;
}
public void FromRGB(float r = 0f, float g = 0f, float b = 0f)
{
this.r = r;
this.g = g;
this.b = b;
}
/// <summary>
/// Use this constructor for setting the ColorData instance up
/// with RBG values.
......@@ -43,9 +62,7 @@ namespace PixelVisionSDK
/// <param name="b"></param>
public ColorData(float r = 0f, float g = 0f, float b = 0f)
{
this.r = r;
this.g = g;
this.b = b;
FromRGB(r, g, b);
}
/// <summary>
......@@ -55,13 +72,7 @@ namespace PixelVisionSDK
/// <param name="hexColor"></param>
public ColorData(string hexColor)
{
float tmpR, tmpG, tmpB;
HexToColor(hexColor, out tmpR, out tmpG, out tmpB);
r = tmpR;
g = tmpG;
b = tmpB;
FromHex(hexColor);
}
/// <summary>
......@@ -109,9 +120,10 @@ namespace PixelVisionSDK
/// <returns></returns>
public static string ColorToHex(float r, float g, float b)