Skip to content

Commit

Permalink
Working Formatter multiton pattern to incorporate more serialization/…
Browse files Browse the repository at this point in the history
…deserialization format classes.
  • Loading branch information
dustin authored and dustin committed Jun 26, 2019
1 parent 2e05add commit a0a276e
Show file tree
Hide file tree
Showing 9 changed files with 246 additions and 15 deletions.
3 changes: 2 additions & 1 deletion Assets/Experica/ConditionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ public Dictionary<string, List<object>> ReadConditionFile(string path)
{
return null;
}
return path.ReadYamlFile<Dictionary<string, List<object>>>();
string serializedData = File.ReadAllText(path);
return Formatter.Instance.DeserializeUsingFormat<Dictionary<string, List<object>>>(serializedData, DataFormat.YAML);
}

public Dictionary<string, List<object>> ProcessCondition(Dictionary<string, List<object>> cond)
Expand Down
7 changes: 7 additions & 0 deletions Assets/Experica/Experiment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,13 @@ public object GetProperty(Experiment ex, PropertyAccess p)
return p.Getter(ex);
}

/// <summary>
/// Searches the directory for the exact same experiment ran, if it has been ran before, appends or advances the ending
/// number to a datapath and returns it
/// </summary>
/// <param name="ext">The extension to append to end of datapath when creating a new path</param>
/// <param name="searchext">The extenstion to serach for in the directory</param>
/// <returns>A new DataPath corresponding to the experiment ran in order to save it.</returns>
public virtual string GetDataPath(string ext = "", string searchext = "yaml")
{
if (string.IsNullOrEmpty(DataPath))
Expand Down
23 changes: 19 additions & 4 deletions Assets/Experica/ExperimentLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -291,12 +291,20 @@ protected virtual void SamplePushBlock(int manualblockidx = 0)
condmanager.PushBlock(condmanager.SampleBlockSpace(manualblockidx), envmanager, pushexcludefactors);
}

/// <summary>
/// Returns the
/// </summary>
/// <param name="dataFormat"></param>
/// <returns></returns>
public virtual string DataPath(DataFormat dataFormat)
{
var extension = dataFormat.ToString().ToLower();
return ex.GetDataPath(ext: extension, searchext: extension);
var extension = dataFormat.ToString().ToLower(); // String representation of dataFormat
return ex.GetDataPath(ext: extension, searchext: extension); //
}

/// <summary>
///
/// </summary>
public virtual void SaveData()
{
var ct = condtestmanager.condtest;
Expand All @@ -309,13 +317,20 @@ public virtual void SaveData()
}
ex.EnvParam = envmanager.GetActiveParams();

//
switch (config.SaveDataFormat)
{
// Currently Not Implemented.
case DataFormat.EXPERICA:
DataPath(DataFormat.EXPERICA).Save(ex);
string serialzedData = Formatter.Instance.SerialzeDataToFormat(ex, DataFormat.EXPERICA);
File.WriteAllText(DataPath(DataFormat.EXPERICA), serialzedData);
break;
//case DataFormat.HDF5:
//DataPath(DataFormat.YAML).WriteToFile(ex);
// Save the Experiment, enviroment, and data as a YAML File.
default:
DataPath(DataFormat.YAML).WriteYamlFile(ex);
serialzedData = Formatter.Instance.SerialzeDataToFormat(ex, DataFormat.YAML);
File.WriteAllText(DataPath(DataFormat.YAML), serialzedData);
break;
}
ex.DataPath = null;
Expand Down
66 changes: 66 additions & 0 deletions Assets/Experica/Serialization/Formatter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
Formatter.cs is part of the Experica.
Copyright (c) 2016 Li Alex Zhang and Contributors
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
using System;
using System.Collections.Generic;

namespace Experica
{
public sealed class Formatter
{
// This can be static in a console/desktop application, just be wary of potential memory issues
private Dictionary<DataFormat, IFormat> _formats = new Dictionary<DataFormat, IFormat>();

private static readonly Lazy<Formatter> lazy = new Lazy<Formatter>(() => new Formatter());

public static Formatter Instance { get { return lazy.Value; } }

/// <summary>
/// Get the current active policy of the given type.
/// </summary>
/// <param name="type">The type of policy to retrieve.</param>
/// <returns>The current active policy of the given type</returns>
private IFormat GetActiveFormat(DataFormat format)
{
if (!_formats.ContainsKey(format))
{
var str = format.ToString() + "Format";
Type type = Type.GetType("Experica." + format.ToString() + "Format");
var obj = (IFormat)Activator.CreateInstance(type);
_formats[format] = obj;
}

return _formats[format];
}

public string SerialzeDataToFormat<T>(T obj, DataFormat format)
{
IFormat formatToUse = GetActiveFormat(format);
return formatToUse.Serialize(obj);
}

public T DeserializeUsingFormat<T>(string data, DataFormat format)
{
IFormat formatToUse = GetActiveFormat(format);
return formatToUse.Deserialize<T>(data);
}
}
}
29 changes: 29 additions & 0 deletions Assets/Experica/Serialization/IFormat.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
IFormat.cs is part of the Experica.
Copyright (c) 2016 Li Alex Zhang and Contributors
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
namespace Experica
{
public interface IFormat
{
string Serialize<T>(T obj);
T Deserialize<T>(string data);
}
}
93 changes: 93 additions & 0 deletions Assets/Experica/Serialization/YAMLFormat.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
Yaml.cs is part of the Experica.
Copyright (c) 2016 Li Alex Zhang and Contributors
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
using UnityEngine;
using System;
using YamlDotNet.Serialization;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using System.Runtime.Serialization;
using System.IO;

namespace Experica
{
public class YamlTypeConverter : IYamlTypeConverter
{
public bool Accepts(Type type)
{
if (type == typeof(Vector2) || type == typeof(Vector3) || type == typeof(Vector4) || type == typeof(Color))
{
return true;
}
return false;
}

public object ReadYaml(IParser parser, Type type)
{
var o = ((Scalar)parser.Current).Value.Convert(type);
parser.MoveNext();
return o;
}

public void WriteYaml(IEmitter emitter, object value, Type type)
{
emitter.Emit(new Scalar(value.Convert<string>()));
}
}

public class YAMLFormat : IFormat
{
ISerializer serializer;
IDeserializer deserializer;

public YAMLFormat()
{
var yamlvlabconverter = new YamlTypeConverter();
serializer = new SerializerBuilder().DisableAliases().EmitDefaults().IgnoreFields().WithTypeConverter(yamlvlabconverter).Build();
deserializer = new DeserializerBuilder().IgnoreUnmatchedProperties().IgnoreFields().WithTypeConverter(yamlvlabconverter).Build();
}

//public static void WriteYamlFile<T>(this string path, T data)
//{
// File.WriteAllText(path, serializer.Serialize(data));
//}

//public static T ReadYamlFile<T>(string path)
//{
// return deserializer.Deserialize<T>(File.ReadAllText(path));
//}

//public static T DeserializeYaml<T>(string data)
//{
// return deserializer.Deserialize<T>(data);
//}

public string Serialize<T>(T obj)
{
return serializer.Serialize(obj);
}

public T Deserialize<T>(string data)
{
return deserializer.Deserialize<T>(data);
}
}
}
14 changes: 11 additions & 3 deletions Assets/ExperimentManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ public class ExperimentManager : MonoBehaviour
public List<string> exids = new List<string>();
public ExperimentLogic el;

//Formatter for Serialization and Deserialization
Formatter formatter = Formatter.Instance;

public void GetExFiles()
{
var exfiledir = uicontroller.config.ExDir;
Expand Down Expand Up @@ -67,7 +70,9 @@ public void GetExFiles()

public Experiment LoadEx(string exfilepath)
{
var ex = exfilepath.ReadYamlFile<Experiment>();
string serializedData = File.ReadAllText(exfilepath);
Experiment ex = formatter.DeserializeUsingFormat<Experiment>(serializedData, DataFormat.YAML);

if (string.IsNullOrEmpty(ex.ID))
{
ex.ID = Path.GetFileNameWithoutExtension(exfilepath);
Expand Down Expand Up @@ -149,7 +154,9 @@ public bool NewEx(string id, string idcopyfrom)
{
if (!exids.Contains(id) && exids.Contains(idcopyfrom))
{
var ex = exfiles[exids.IndexOf(idcopyfrom)].ReadYamlFile<Experiment>();
string serialzedData = File.ReadAllText(exfiles[exids.IndexOf(idcopyfrom)]);
Experiment ex = formatter.DeserializeUsingFormat<Experiment>(serialzedData, DataFormat.YAML);

ex.ID = id;
ex.Name = id;
LoadEL(ValidateExperiment(ex));
Expand Down Expand Up @@ -204,7 +211,8 @@ public void SaveEx(string id)
ex.EnvParam = elhistory[i].envmanager.GetParams();
try
{
exfiles[exids.IndexOf(id)].WriteYamlFile(ex);
string serialzedData = formatter.SerialzeDataToFormat(ex, DataFormat.YAML);
File.WriteAllText(exfiles[exids.IndexOf(id)], serialzedData);
}
finally
{
Expand Down
4 changes: 2 additions & 2 deletions Assets/Tests/YamlTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ namespace Experica.Test
{
public class YamlTests
{
string yaml = "Ori: [0, 45, 90, 135]\n" +
string yamlString = "Ori: [0, 45, 90, 135]\n" +
"SpatialPhase: [0, 0.25, 0.5, 0.75]";

[Test]
public void YamlReadWrite()
{
var cond = yaml.DeserializeYaml<Dictionary<string, List<object>>>();
//var cond = Yaml.DeserializeYaml<Dictionary<string, List<object>>>(yamlString);
}

// A UnityTest behaves like a coroutine in PlayMode
Expand Down
22 changes: 17 additions & 5 deletions Assets/UIController/UIController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ public class UIController : MonoBehaviour
public ConditionPanel condpanel;
public ConditionTestPanel ctpanel;

// Used for serialization and deserialization across all formats
public Formatter formatter;

/// <summary>
/// Awake is called when the script instance is being loaded. Awake is called only
/// a single time.See the following URL for more information:
Expand All @@ -71,10 +74,12 @@ public class UIController : MonoBehaviour
/// </summary>
void Awake()
{
formatter = Formatter.Instance;
// Check for CommandConfigManager.yaml existance
if (File.Exists(configmanagerpath))
{
configmanager = configmanagerpath.ReadYamlFile<CommandConfigManager>();
string serializedData = File.ReadAllText(configmanagerpath);
configmanager = formatter.DeserializeUsingFormat<CommandConfigManager>(serializedData, DataFormat.YAML);
}
if (configmanager == null)
{
Expand Down Expand Up @@ -102,8 +107,9 @@ public CommandConfig LoadConfig(string configfilepath, bool otherwisedefault = t
// Check if the file exists at the specified path, if so, load it.
if (File.Exists(configfilepath))
{
// Deserialize the text using extension method.
cfg = configfilepath.ReadYamlFile<CommandConfig>();
// Deserialize the text
string serializedData = File.ReadAllText(configfilepath);
cfg = formatter.DeserializeUsingFormat<CommandConfig>(serializedData, DataFormat.YAML);
}

// Use default config settings
Expand Down Expand Up @@ -188,7 +194,8 @@ void OnApplicationQuit()
{
SaveConfig();
}
configmanagerpath.WriteYamlFile(configmanager);
string dataToWrite = formatter.SerialzeDataToFormat(configmanager, DataFormat.YAML);
File.WriteAllText(configmanagerpath, dataToWrite);
}

public void SaveConfig()
Expand All @@ -204,7 +211,8 @@ public void SaveConfig()
}
if (!string.IsNullOrEmpty(configmanager.LastConfigFilePath))
{
configmanager.LastConfigFilePath.WriteYamlFile(config);
string serializedData = formatter.SerialzeDataToFormat(config, DataFormat.YAML);
File.WriteAllText(configmanager.LastConfigFilePath, serializedData);
}
}

Expand Down Expand Up @@ -459,6 +467,10 @@ public void OnEndStopExperiment()
GC.Collect();
}

/// <summary>
/// When the SaveData Button is pushed in the Control Panel the experiment manager saves
/// the YAML file.
/// </summary>
public void SaveData()
{
if (exmanager.el != null)
Expand Down

0 comments on commit a0a276e

Please sign in to comment.