Skip to content

Commit a0a276e

Browse files
dustindustin
authored andcommitted
Working Formatter multiton pattern to incorporate more serialization/deserialization format classes.
1 parent 2e05add commit a0a276e

File tree

9 files changed

+246
-15
lines changed

9 files changed

+246
-15
lines changed

Assets/Experica/ConditionManager.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ public Dictionary<string, List<object>> ReadConditionFile(string path)
6161
{
6262
return null;
6363
}
64-
return path.ReadYamlFile<Dictionary<string, List<object>>>();
64+
string serializedData = File.ReadAllText(path);
65+
return Formatter.Instance.DeserializeUsingFormat<Dictionary<string, List<object>>>(serializedData, DataFormat.YAML);
6566
}
6667

6768
public Dictionary<string, List<object>> ProcessCondition(Dictionary<string, List<object>> cond)

Assets/Experica/Experiment.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,13 @@ public object GetProperty(Experiment ex, PropertyAccess p)
227227
return p.Getter(ex);
228228
}
229229

230+
/// <summary>
231+
/// Searches the directory for the exact same experiment ran, if it has been ran before, appends or advances the ending
232+
/// number to a datapath and returns it
233+
/// </summary>
234+
/// <param name="ext">The extension to append to end of datapath when creating a new path</param>
235+
/// <param name="searchext">The extenstion to serach for in the directory</param>
236+
/// <returns>A new DataPath corresponding to the experiment ran in order to save it.</returns>
230237
public virtual string GetDataPath(string ext = "", string searchext = "yaml")
231238
{
232239
if (string.IsNullOrEmpty(DataPath))

Assets/Experica/ExperimentLogic.cs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,12 +291,20 @@ protected virtual void SamplePushBlock(int manualblockidx = 0)
291291
condmanager.PushBlock(condmanager.SampleBlockSpace(manualblockidx), envmanager, pushexcludefactors);
292292
}
293293

294+
/// <summary>
295+
/// Returns the
296+
/// </summary>
297+
/// <param name="dataFormat"></param>
298+
/// <returns></returns>
294299
public virtual string DataPath(DataFormat dataFormat)
295300
{
296-
var extension = dataFormat.ToString().ToLower();
297-
return ex.GetDataPath(ext: extension, searchext: extension);
301+
var extension = dataFormat.ToString().ToLower(); // String representation of dataFormat
302+
return ex.GetDataPath(ext: extension, searchext: extension); //
298303
}
299304

305+
/// <summary>
306+
///
307+
/// </summary>
300308
public virtual void SaveData()
301309
{
302310
var ct = condtestmanager.condtest;
@@ -309,13 +317,20 @@ public virtual void SaveData()
309317
}
310318
ex.EnvParam = envmanager.GetActiveParams();
311319

320+
//
312321
switch (config.SaveDataFormat)
313322
{
323+
// Currently Not Implemented.
314324
case DataFormat.EXPERICA:
315-
DataPath(DataFormat.EXPERICA).Save(ex);
325+
string serialzedData = Formatter.Instance.SerialzeDataToFormat(ex, DataFormat.EXPERICA);
326+
File.WriteAllText(DataPath(DataFormat.EXPERICA), serialzedData);
316327
break;
328+
//case DataFormat.HDF5:
329+
//DataPath(DataFormat.YAML).WriteToFile(ex);
330+
// Save the Experiment, enviroment, and data as a YAML File.
317331
default:
318-
DataPath(DataFormat.YAML).WriteYamlFile(ex);
332+
serialzedData = Formatter.Instance.SerialzeDataToFormat(ex, DataFormat.YAML);
333+
File.WriteAllText(DataPath(DataFormat.YAML), serialzedData);
319334
break;
320335
}
321336
ex.DataPath = null;
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
Formatter.cs is part of the Experica.
3+
Copyright (c) 2016 Li Alex Zhang and Contributors
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a
6+
copy of this software and associated documentation files (the "Software"),
7+
to deal in the Software without restriction, including without limitation
8+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
9+
and/or sell copies of the Software, and to permit persons to whom the
10+
Software is furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included
13+
in all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
20+
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
*/
22+
using System;
23+
using System.Collections.Generic;
24+
25+
namespace Experica
26+
{
27+
public sealed class Formatter
28+
{
29+
// This can be static in a console/desktop application, just be wary of potential memory issues
30+
private Dictionary<DataFormat, IFormat> _formats = new Dictionary<DataFormat, IFormat>();
31+
32+
private static readonly Lazy<Formatter> lazy = new Lazy<Formatter>(() => new Formatter());
33+
34+
public static Formatter Instance { get { return lazy.Value; } }
35+
36+
/// <summary>
37+
/// Get the current active policy of the given type.
38+
/// </summary>
39+
/// <param name="type">The type of policy to retrieve.</param>
40+
/// <returns>The current active policy of the given type</returns>
41+
private IFormat GetActiveFormat(DataFormat format)
42+
{
43+
if (!_formats.ContainsKey(format))
44+
{
45+
var str = format.ToString() + "Format";
46+
Type type = Type.GetType("Experica." + format.ToString() + "Format");
47+
var obj = (IFormat)Activator.CreateInstance(type);
48+
_formats[format] = obj;
49+
}
50+
51+
return _formats[format];
52+
}
53+
54+
public string SerialzeDataToFormat<T>(T obj, DataFormat format)
55+
{
56+
IFormat formatToUse = GetActiveFormat(format);
57+
return formatToUse.Serialize(obj);
58+
}
59+
60+
public T DeserializeUsingFormat<T>(string data, DataFormat format)
61+
{
62+
IFormat formatToUse = GetActiveFormat(format);
63+
return formatToUse.Deserialize<T>(data);
64+
}
65+
}
66+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
IFormat.cs is part of the Experica.
3+
Copyright (c) 2016 Li Alex Zhang and Contributors
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a
6+
copy of this software and associated documentation files (the "Software"),
7+
to deal in the Software without restriction, including without limitation
8+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
9+
and/or sell copies of the Software, and to permit persons to whom the
10+
Software is furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included
13+
in all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
20+
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
*/
22+
namespace Experica
23+
{
24+
public interface IFormat
25+
{
26+
string Serialize<T>(T obj);
27+
T Deserialize<T>(string data);
28+
}
29+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
Yaml.cs is part of the Experica.
3+
Copyright (c) 2016 Li Alex Zhang and Contributors
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a
6+
copy of this software and associated documentation files (the "Software"),
7+
to deal in the Software without restriction, including without limitation
8+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
9+
and/or sell copies of the Software, and to permit persons to whom the
10+
Software is furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included
13+
in all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
20+
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
*/
22+
using UnityEngine;
23+
using System;
24+
using YamlDotNet.Serialization;
25+
using YamlDotNet.Core;
26+
using YamlDotNet.Core.Events;
27+
using System.Runtime.Serialization;
28+
using System.IO;
29+
30+
namespace Experica
31+
{
32+
public class YamlTypeConverter : IYamlTypeConverter
33+
{
34+
public bool Accepts(Type type)
35+
{
36+
if (type == typeof(Vector2) || type == typeof(Vector3) || type == typeof(Vector4) || type == typeof(Color))
37+
{
38+
return true;
39+
}
40+
return false;
41+
}
42+
43+
public object ReadYaml(IParser parser, Type type)
44+
{
45+
var o = ((Scalar)parser.Current).Value.Convert(type);
46+
parser.MoveNext();
47+
return o;
48+
}
49+
50+
public void WriteYaml(IEmitter emitter, object value, Type type)
51+
{
52+
emitter.Emit(new Scalar(value.Convert<string>()));
53+
}
54+
}
55+
56+
public class YAMLFormat : IFormat
57+
{
58+
ISerializer serializer;
59+
IDeserializer deserializer;
60+
61+
public YAMLFormat()
62+
{
63+
var yamlvlabconverter = new YamlTypeConverter();
64+
serializer = new SerializerBuilder().DisableAliases().EmitDefaults().IgnoreFields().WithTypeConverter(yamlvlabconverter).Build();
65+
deserializer = new DeserializerBuilder().IgnoreUnmatchedProperties().IgnoreFields().WithTypeConverter(yamlvlabconverter).Build();
66+
}
67+
68+
//public static void WriteYamlFile<T>(this string path, T data)
69+
//{
70+
// File.WriteAllText(path, serializer.Serialize(data));
71+
//}
72+
73+
//public static T ReadYamlFile<T>(string path)
74+
//{
75+
// return deserializer.Deserialize<T>(File.ReadAllText(path));
76+
//}
77+
78+
//public static T DeserializeYaml<T>(string data)
79+
//{
80+
// return deserializer.Deserialize<T>(data);
81+
//}
82+
83+
public string Serialize<T>(T obj)
84+
{
85+
return serializer.Serialize(obj);
86+
}
87+
88+
public T Deserialize<T>(string data)
89+
{
90+
return deserializer.Deserialize<T>(data);
91+
}
92+
}
93+
}

Assets/ExperimentManager.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ public class ExperimentManager : MonoBehaviour
3838
public List<string> exids = new List<string>();
3939
public ExperimentLogic el;
4040

41+
//Formatter for Serialization and Deserialization
42+
Formatter formatter = Formatter.Instance;
43+
4144
public void GetExFiles()
4245
{
4346
var exfiledir = uicontroller.config.ExDir;
@@ -67,7 +70,9 @@ public void GetExFiles()
6770

6871
public Experiment LoadEx(string exfilepath)
6972
{
70-
var ex = exfilepath.ReadYamlFile<Experiment>();
73+
string serializedData = File.ReadAllText(exfilepath);
74+
Experiment ex = formatter.DeserializeUsingFormat<Experiment>(serializedData, DataFormat.YAML);
75+
7176
if (string.IsNullOrEmpty(ex.ID))
7277
{
7378
ex.ID = Path.GetFileNameWithoutExtension(exfilepath);
@@ -149,7 +154,9 @@ public bool NewEx(string id, string idcopyfrom)
149154
{
150155
if (!exids.Contains(id) && exids.Contains(idcopyfrom))
151156
{
152-
var ex = exfiles[exids.IndexOf(idcopyfrom)].ReadYamlFile<Experiment>();
157+
string serialzedData = File.ReadAllText(exfiles[exids.IndexOf(idcopyfrom)]);
158+
Experiment ex = formatter.DeserializeUsingFormat<Experiment>(serialzedData, DataFormat.YAML);
159+
153160
ex.ID = id;
154161
ex.Name = id;
155162
LoadEL(ValidateExperiment(ex));
@@ -204,7 +211,8 @@ public void SaveEx(string id)
204211
ex.EnvParam = elhistory[i].envmanager.GetParams();
205212
try
206213
{
207-
exfiles[exids.IndexOf(id)].WriteYamlFile(ex);
214+
string serialzedData = formatter.SerialzeDataToFormat(ex, DataFormat.YAML);
215+
File.WriteAllText(exfiles[exids.IndexOf(id)], serialzedData);
208216
}
209217
finally
210218
{

Assets/Tests/YamlTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ namespace Experica.Test
3030
{
3131
public class YamlTests
3232
{
33-
string yaml = "Ori: [0, 45, 90, 135]\n" +
33+
string yamlString = "Ori: [0, 45, 90, 135]\n" +
3434
"SpatialPhase: [0, 0.25, 0.5, 0.75]";
3535

3636
[Test]
3737
public void YamlReadWrite()
3838
{
39-
var cond = yaml.DeserializeYaml<Dictionary<string, List<object>>>();
39+
//var cond = Yaml.DeserializeYaml<Dictionary<string, List<object>>>(yamlString);
4040
}
4141

4242
// A UnityTest behaves like a coroutine in PlayMode

Assets/UIController/UIController.cs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ public class UIController : MonoBehaviour
6363
public ConditionPanel condpanel;
6464
public ConditionTestPanel ctpanel;
6565

66+
// Used for serialization and deserialization across all formats
67+
public Formatter formatter;
68+
6669
/// <summary>
6770
/// Awake is called when the script instance is being loaded. Awake is called only
6871
/// a single time.See the following URL for more information:
@@ -71,10 +74,12 @@ public class UIController : MonoBehaviour
7174
/// </summary>
7275
void Awake()
7376
{
77+
formatter = Formatter.Instance;
7478
// Check for CommandConfigManager.yaml existance
7579
if (File.Exists(configmanagerpath))
7680
{
77-
configmanager = configmanagerpath.ReadYamlFile<CommandConfigManager>();
81+
string serializedData = File.ReadAllText(configmanagerpath);
82+
configmanager = formatter.DeserializeUsingFormat<CommandConfigManager>(serializedData, DataFormat.YAML);
7883
}
7984
if (configmanager == null)
8085
{
@@ -102,8 +107,9 @@ public CommandConfig LoadConfig(string configfilepath, bool otherwisedefault = t
102107
// Check if the file exists at the specified path, if so, load it.
103108
if (File.Exists(configfilepath))
104109
{
105-
// Deserialize the text using extension method.
106-
cfg = configfilepath.ReadYamlFile<CommandConfig>();
110+
// Deserialize the text
111+
string serializedData = File.ReadAllText(configfilepath);
112+
cfg = formatter.DeserializeUsingFormat<CommandConfig>(serializedData, DataFormat.YAML);
107113
}
108114

109115
// Use default config settings
@@ -188,7 +194,8 @@ void OnApplicationQuit()
188194
{
189195
SaveConfig();
190196
}
191-
configmanagerpath.WriteYamlFile(configmanager);
197+
string dataToWrite = formatter.SerialzeDataToFormat(configmanager, DataFormat.YAML);
198+
File.WriteAllText(configmanagerpath, dataToWrite);
192199
}
193200

194201
public void SaveConfig()
@@ -204,7 +211,8 @@ public void SaveConfig()
204211
}
205212
if (!string.IsNullOrEmpty(configmanager.LastConfigFilePath))
206213
{
207-
configmanager.LastConfigFilePath.WriteYamlFile(config);
214+
string serializedData = formatter.SerialzeDataToFormat(config, DataFormat.YAML);
215+
File.WriteAllText(configmanager.LastConfigFilePath, serializedData);
208216
}
209217
}
210218

@@ -459,6 +467,10 @@ public void OnEndStopExperiment()
459467
GC.Collect();
460468
}
461469

470+
/// <summary>
471+
/// When the SaveData Button is pushed in the Control Panel the experiment manager saves
472+
/// the YAML file.
473+
/// </summary>
462474
public void SaveData()
463475
{
464476
if (exmanager.el != null)

0 commit comments

Comments
 (0)