Skip to content

Commit 60213ef

Browse files
author
Jack Brookes
committed
Adressess #25, settings now reference the parent object
1 parent 17b9784 commit 60213ef

File tree

9 files changed

+194
-23
lines changed

9 files changed

+194
-23
lines changed

Assets/UXF/Scripts/Etc/Block.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace UXF
88
/// <summary>
99
/// A set of trials, often used to group a number of consecutive Trial objects that share something in common.
1010
/// </summary>
11-
public class Block
11+
public class Block : ISettingsContainer
1212
{
1313
/// <summary>
1414
/// List of trials associated with this block
@@ -33,7 +33,7 @@ public class Block
3333
/// <summary>
3434
/// Block settings. These will be overridden by trial settings if set.
3535
/// </summary>
36-
public Settings settings = Settings.empty;
36+
public Settings settings { get; private set; }
3737

3838
/// <summary>
3939
/// The session associated with this block
@@ -48,9 +48,10 @@ public class Block
4848
/// <param name="session"></param>
4949
public Block(uint numberOfTrials, Session session)
5050
{
51+
settings = Settings.empty;
5152
this.session = session;
5253
this.session.blocks.Add(this);
53-
settings.SetParent(this.session.settings);
54+
settings.SetParent(session);
5455
for (int i = 0; i < numberOfTrials; i++)
5556
{
5657
var t = new Trial(this);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System;
2+
using System.Linq;
3+
using System.Collections;
4+
using System.Collections.Generic;
5+
using UnityEngine;
6+
7+
namespace UXF
8+
{
9+
public interface ISettingsContainer
10+
{
11+
Settings settings { get; }
12+
}
13+
}

Assets/UXF/Scripts/Etc/ISettingsContainer.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/UXF/Scripts/Etc/Settings.cs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class Settings
1616
/// </summary>
1717
public static Settings empty { get { return new Settings(new Dictionary<string, object>()); } }
1818

19-
Settings parentSettings;
19+
ISettingsContainer parentSettingsContainer;
2020
/// <summary>
2121
/// The underlying dictionary
2222
/// </summary>
@@ -45,14 +45,25 @@ public Settings(Dictionary<string, object> dict)
4545
}
4646
}
4747

48+
/// <summary>
49+
/// Add all the keys and values from `dict` to the settings.
50+
/// </summary>
51+
/// <param name="dict">Dictionary to add.</param>
52+
public void UpdateWithDict(Dictionary<string, object> dict)
53+
{
54+
// add all keys to new dictionary
55+
dict
56+
.ToList()
57+
.ForEach(x => baseDict[x.Key] = x.Value);
58+
}
4859

4960
/// <summary>
5061
/// Sets the parent setting object, which is accessed when a setting is not found in the dictionary.
5162
/// </summary>
5263
/// <param name="parent"></param>
53-
public void SetParent(Settings parent)
64+
public void SetParent(ISettingsContainer parent)
5465
{
55-
parentSettings = parent;
66+
parentSettingsContainer = parent;
5667
}
5768

5869
/// <summary>
@@ -190,11 +201,18 @@ protected object Get(string key)
190201
}
191202
catch (KeyNotFoundException)
192203
{
193-
if (parentSettings != null)
204+
if (parentSettingsContainer != null && parentSettingsContainer.settings != null)
194205
{
195-
return parentSettings.Get(key);
206+
return parentSettingsContainer.settings.Get(key);
196207
}
197-
throw new KeyNotFoundException(string.Format("The key \"{0}\" was not found in the settings heirarchy. Use UXF Session Debugger (UXF menu at top of unity editor) to check your settings are being applied correctly.", key));
208+
throw new KeyNotFoundException(
209+
string.Format(
210+
"The key \"{0}\" was not found in the settings heirarchy. "
211+
+ "Use UXF Session Debugger (UXF menu at top of unity editor) "
212+
+ "to check your settings are being applied correctly.",
213+
key
214+
)
215+
);
198216
}
199217
}
200218

Assets/UXF/Scripts/Etc/Trial.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace UXF
1313
/// The base unit of experiments. A Trial is usually a singular attempt at a task by a participant after/during the presentation of a stimulus.
1414
/// </summary>
1515
[Serializable]
16-
public class Trial
16+
public class Trial : ISettingsContainer
1717
{
1818

1919
/// <summary>
@@ -46,7 +46,7 @@ public class Trial
4646
/// <summary>
4747
/// Trial settings. These will override block settings if set.
4848
/// </summary>
49-
public Settings settings = Settings.empty;
49+
public Settings settings { get; private set; }
5050

5151
/// <summary>
5252
/// Dictionary of results in a order.
@@ -58,6 +58,7 @@ public class Trial
5858
/// </summary>
5959
internal Trial(Block trialBlock)
6060
{
61+
settings = Settings.empty;
6162
SetReferences(trialBlock);
6263
}
6364

@@ -69,7 +70,7 @@ private void SetReferences(Block trialBlock)
6970
{
7071
block = trialBlock;
7172
session = block.session;
72-
settings.SetParent(block.settings);
73+
settings.SetParent(block);
7374
}
7475

7576
/// <summary>

Assets/UXF/Scripts/Session.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace UXF
1616
/// </summary>
1717
[ExecuteInEditMode]
1818
[RequireComponent(typeof(FileIOManager))]
19-
public class Session : MonoBehaviour
19+
public class Session : MonoBehaviour, ISettingsContainer
2020
{
2121
[Header(":: Behaviour")]
2222
/// <summary>
@@ -147,7 +147,7 @@ public class Session : MonoBehaviour
147147
/// <summary>
148148
/// Settings for the experiment. These are provided on initialisation of the session.
149149
/// </summary>
150-
public Settings settings;
150+
public Settings settings { get; private set; }
151151

152152
/// <summary>
153153
/// Returns true if current trial is in progress
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
using UnityEngine;
2+
using UnityEditor;
3+
using UnityEngine.TestTools;
4+
using NUnit.Framework;
5+
using System;
6+
using System.Linq;
7+
using System.Collections;
8+
using System.Collections.Generic;
9+
using System.IO;
10+
11+
namespace UXF.Tests
12+
{
13+
14+
public class TestSessionBehaviour
15+
{
16+
17+
[Test]
18+
public void TestEndOnDestroy()
19+
{
20+
Session session = CreateSession("endondestroy");
21+
session.endOnDestroy = true;
22+
session.blocks[0].trials[0].Begin();
23+
session.blocks[0].trials[0].End();
24+
session.blocks[0].trials[1].Begin();
25+
26+
string path = session.FullPath;
27+
GameObject.DestroyImmediate(session.gameObject);
28+
29+
// read the file to check data
30+
string[] lines = File.ReadAllLines(Path.Combine(session.FullPath, "trial_results.csv"));
31+
Assert.AreEqual(6, lines.Length);
32+
33+
// filter blank lines, should only be 1 header + 2 trials
34+
Assert.AreEqual(
35+
3,
36+
lines.Where((line) => !string.IsNullOrEmpty(line)).Count()
37+
);
38+
}
39+
40+
[Test]
41+
public void TestDontEndOnDestroy()
42+
{
43+
Session session = CreateSession("dontendondestroy");
44+
session.endOnDestroy = false;
45+
session.blocks[0].trials[0].Begin();
46+
session.blocks[0].trials[0].End();
47+
session.blocks[0].trials[1].Begin();
48+
49+
string path = session.FullPath;
50+
GameObject.DestroyImmediate(session.gameObject);
51+
52+
// check csv file didnt get written
53+
Assert.False(File.Exists(Path.Combine(session.FullPath, "trial_results.csv")));
54+
}
55+
56+
[Test]
57+
public void TestEndAfterLastTrial()
58+
{
59+
Session session = CreateSession("endafterlasttrial");
60+
session.endAfterLastTrial = true;
61+
session.onTrialEnd.AddListener(session.EndIfLastTrial);
62+
63+
foreach (var trial in session.Trials)
64+
{
65+
trial.Begin();
66+
trial.End();
67+
}
68+
69+
Assert.False(session.hasInitialised);
70+
71+
// read the file to check data
72+
string[] lines = File.ReadAllLines(Path.Combine(session.FullPath, "trial_results.csv"));
73+
Assert.AreEqual(6, lines.Length);
74+
}
75+
76+
Session CreateSession(string ppidExtra)
77+
{
78+
GameObject gameObject = new GameObject();
79+
FileIOManager fileIOManager = gameObject.AddComponent<FileIOManager>();
80+
SessionLogger sessionLogger = gameObject.AddComponent<SessionLogger>();
81+
Session session = gameObject.AddComponent<Session>();
82+
83+
session.AttachReferences(
84+
fileIOManager
85+
);
86+
87+
sessionLogger.AttachReferences(
88+
fileIOManager,
89+
session
90+
);
91+
92+
sessionLogger.Initialise();
93+
94+
fileIOManager.debug = true;
95+
fileIOManager.Begin();
96+
97+
string experimentName = "unit_test";
98+
string ppid = "test_behaviour_" + ppidExtra;
99+
session.Begin(experimentName, ppid, "example_output");
100+
101+
// generate trials
102+
session.CreateBlock(2);
103+
session.CreateBlock(3);
104+
105+
return session;
106+
}
107+
108+
}
109+
110+
}

Assets/UXF/Scripts/Tests/Editor/TestSessionBehaviour.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/UXF/Scripts/Tests/Editor/TestSettings.cs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,19 +97,25 @@ public void GetSetSettings()
9797
[Test]
9898
public void CascadeSettings()
9999
{
100+
GameObject go = new GameObject();
101+
Session s = go.AddComponent<Session>();
102+
Block b = s.CreateBlock();
103+
Trial t = b.CreateTrial();
104+
100105
Dictionary<string, object> dict = MiniJSON.Json.Deserialize(jsonString) as Dictionary<string, object>;
101-
Settings settings = new Settings(dict);
106+
b.settings.UpdateWithDict(dict);
102107

103-
Settings subSettings = Settings.empty;
104-
subSettings.SetParent(settings);
108+
t.settings.SetValue("key1", "test");
109+
t.settings.SetValue("key2", 100);
105110

106-
subSettings.SetValue("key1", "test");
107-
subSettings.SetValue("key2", 100);
111+
Assert.AreEqual(t.settings.GetString("string"), "The quick brown fox \"jumps\" over the lazy dog ");
112+
Assert.AreEqual(t.settings.GetString("key1"), "test");
113+
Assert.AreEqual(t.settings.GetInt("key2"), 100);
114+
Assert.Throws<KeyNotFoundException>(() => b.settings.GetObject("key1"));
108115

109-
Assert.AreEqual(subSettings.GetString("string"), "The quick brown fox \"jumps\" over the lazy dog ");
110-
Assert.AreEqual(subSettings.GetString("key1"), "test");
111-
Assert.AreEqual(subSettings.GetInt("key2"), 100);
112-
Assert.Throws<KeyNotFoundException>(() => settings.GetObject("key3"));
116+
Assert.Throws<KeyNotFoundException>(() => t.settings.GetObject("key3"));
117+
Assert.Throws<KeyNotFoundException>(() => b.settings.GetObject("key3"));
118+
Assert.IsNull(s.settings);
113119
}
114120

115121
}

0 commit comments

Comments
 (0)