Skip to content

Commit 7b2587b

Browse files
author
Jared Bienz
committed
Saving and restoring frames from json strings.
1 parent b1bf79e commit 7b2587b

File tree

10 files changed

+342
-26
lines changed

10 files changed

+342
-26
lines changed

SpatialAlignment-Unity/Assembly-CSharp.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,8 +831,10 @@
831831
<Compile Include="Assets\SpatialAlignment\Persistence\ISpatialAlignmentStore.cs" />
832832
<Compile Include="Assets\SpatialAlignment\Persistence\Json\JsonStore.cs" />
833833
<Compile Include="Assets\SpatialAlignment\Persistence\Json\SpatialFrameConverter.cs" />
834+
<Compile Include="Assets\SpatialAlignment\Persistence\Json\Vector3Converter.cs" />
834835
<Compile Include="Assets\SpatialAlignment\SpatialAlignmentManager.cs" />
835836
<Compile Include="Assets\SpatialAlignment\SpatialFrame.cs" />
837+
<Compile Include="Assets\SpatialAlignment\SpatialFrameCollection.cs" />
836838
<Compile Include="Assets\SpatialAlignment\Strategies\AlignmentStrategy.cs" />
837839
<Compile Include="Assets\SpatialAlignment\Strategies\IAlignmentStrategy.cs" />
838840
<Compile Include="Assets\SpatialAlignment\Strategies\MultiParentAlignment.cs" />

SpatialAlignment-Unity/Assets/SpatialAlignment-Examples/Persistence/Scripts/PersistenceExampleManager.cs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,68 @@ namespace Microsoft.SpatialAlignment.Persistence
3535
{
3636
public class PersistenceExampleManager : MonoBehaviour
3737
{
38+
#region Constants
39+
private const string SampleData = @"
40+
[
41+
{
42+
""id"": ""Parent1"",
43+
""AlignmentStrategy"": {
44+
""$type"": ""Microsoft.SpatialAlignment.SimulatedAlignment, Assembly-CSharp"",
45+
""currentAccuracy"": {
46+
""x"": 0.0,
47+
""y"": 0.0,
48+
""z"": 0.0
49+
},
50+
""currentState"": ""Resolved""
51+
}
52+
},
53+
{
54+
""id"": ""Parent2"",
55+
""AlignmentStrategy"": {
56+
""$type"": ""Microsoft.SpatialAlignment.SimulatedAlignment, Assembly-CSharp"",
57+
""currentAccuracy"": {
58+
""x"": 0.0,
59+
""y"": 0.0,
60+
""z"": 0.0
61+
},
62+
""currentState"": ""Resolved""
63+
}
64+
},
65+
{
66+
""id"": ""Parent3"",
67+
""AlignmentStrategy"": {
68+
""$type"": ""Microsoft.SpatialAlignment.SimulatedAlignment, Assembly-CSharp"",
69+
""currentAccuracy"": {
70+
""x"": 0.0,
71+
""y"": 0.0,
72+
""z"": 0.0
73+
},
74+
""currentState"": ""Resolved""
75+
}
76+
}
77+
]";
78+
#endregion // Constants
79+
3880
#region Member Variables
3981
private JsonStore store;
4082
#endregion // Member Variables
4183

4284
#region Unity Inspector Variables
85+
[SerializeField]
4386
public List<SpatialFrame> Frames = new List<SpatialFrame>();
4487
#endregion // Unity Inspector Variables
4588

4689
private async Task LoadAsync()
4790
{
91+
using (StringReader sr = new StringReader(SampleData))
92+
{
93+
using (JsonTextReader jr = new JsonTextReader(sr))
94+
{
95+
await store.LoadDocumentAsync(jr);
96+
}
97+
}
4898

99+
// Debug.Log($"Loaded {} frames.");
49100
}
50101

51102
private async Task SaveAsync()
@@ -73,7 +124,8 @@ private async Task SaveAsync()
73124
void Start()
74125
{
75126
store = new JsonStore();
76-
var t = SaveAsync();
127+
// var t = SaveAsync();
128+
var t = LoadAsync();
77129
t.Wait();
78130
}
79131
}

SpatialAlignment-Unity/Assets/SpatialAlignment/Persistence/Json/JsonStore.cs

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
//
2525

2626
using Newtonsoft.Json;
27+
using Newtonsoft.Json.Converters;
2728
using System;
2829
using System.Collections;
2930
using System.Collections.Generic;
@@ -39,7 +40,7 @@ namespace Microsoft.SpatialAlignment.Persistence.Json
3940
public class JsonStore : ISpatialAlignmentStore
4041
{
4142
#region Member Variables
42-
private Dictionary<string, SpatialFrame> frames = new Dictionary<string, SpatialFrame>();
43+
private SpatialFrameCollection frames = new SpatialFrameCollection();
4344
#endregion // Member Variables
4445

4546
#region Internal Methods
@@ -51,8 +52,10 @@ private JsonSerializer CreateSerializer()
5152
// Make pretty
5253
settings.Formatting = Formatting.Indented;
5354

54-
// Add converter
55+
// Add converters
5556
settings.Converters.Add(new SpatialFrameConverter());
57+
settings.Converters.Add(new StringEnumConverter());
58+
settings.Converters.Add(new Vector3Converter());
5659

5760
// Enable automatic type name handling to allow extensions for alignment strategies
5861
// WARNING: Must implement ISerializationBinder to safely handle instantiation
@@ -81,7 +84,7 @@ public Task LoadDocumentAsync(JsonReader reader)
8184
// Unload all existing objects
8285
foreach (var frame in frames)
8386
{
84-
GameObject.DestroyImmediate(frame.Value.gameObject);
87+
GameObject.DestroyImmediate(frame.gameObject);
8588
}
8689
frames.Clear();
8790

@@ -92,10 +95,7 @@ public Task LoadDocumentAsync(JsonReader reader)
9295
var loadedFrames = ser.Deserialize<List<SpatialFrame>>(reader);
9396

9497
// Add each frame to the lookup table
95-
foreach (var frame in loadedFrames)
96-
{
97-
frames[frame.ID] = frame;
98-
}
98+
frames.AddRange(loadedFrames);
9999

100100
// No tasks to await yet. May move portions of this
101101
// method into a parallel task.
@@ -109,8 +109,8 @@ public Task<SpatialFrame> LoadFrameAsync(string id)
109109
if (string.IsNullOrEmpty(id)) throw new ArgumentException(nameof(id));
110110

111111
// Try to get from lookup table
112-
SpatialFrame frame;
113-
frames.TryGetValue(id, out frame);
112+
SpatialFrame frame = null;
113+
if (frames.Contains(id)) { frame = frames[id]; }
114114

115115
// Return as result
116116
return Task.FromResult(frame);
@@ -121,12 +121,9 @@ public async Task SaveDocumentAsync(JsonWriter writer)
121121
// Validate
122122
if (writer == null) throw new ArgumentNullException(nameof(writer));
123123

124-
// Get as list
125-
List<SpatialFrame> saveFrames = frames.Values.ToList<SpatialFrame>();
126-
127124
// If any of the alignment strategies uses native persistence,
128125
// save them first.
129-
foreach (SpatialFrame frame in saveFrames)
126+
foreach (SpatialFrame frame in frames)
130127
{
131128
INativePersistence np = frame.AlignmentStrategy as INativePersistence;
132129
if (np != null)
@@ -139,7 +136,7 @@ public async Task SaveDocumentAsync(JsonWriter writer)
139136
JsonSerializer ser = CreateSerializer();
140137

141138
// Serialize the list of frames
142-
ser.Serialize(writer, saveFrames);
139+
ser.Serialize(writer, frames);
143140
}
144141

145142
/// <inheritdoc />
@@ -148,14 +145,8 @@ public Task SaveFrameAsync(SpatialFrame frame)
148145
// Validate
149146
if (frame == null) throw new ArgumentNullException(nameof(frame));
150147

151-
// Make sure something else doesn't already have this ID
152-
if ((frames.ContainsKey(frame.ID) && (frames[frame.ID] != frame)))
153-
{
154-
throw new InvalidOperationException($"A different frame already exists with ID '{frame.ID}'");
155-
}
156-
157148
// Add it into the lookup table
158-
frames[frame.ID] = frame;
149+
frames.Add(frame);
159150

160151
// Done
161152
return Task.CompletedTask;

SpatialAlignment-Unity/Assets/SpatialAlignment/Persistence/Json/SpatialFrameConverter.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
5353
// Deserialize into the instance
5454
serializer.Populate(reader, frame);
5555

56+
// Update the game object name to match
57+
go.name = frame.Id;
58+
5659
// Return the frame
5760
return frame;
5861
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
//
2+
// Copyright (c) Microsoft. All rights reserved.
3+
// Licensed under the MIT license.
4+
//
5+
// MIT License:
6+
// Permission is hereby granted, free of charge, to any person obtaining
7+
// a copy of this software and associated documentation files (the
8+
// "Software"), to deal in the Software without restriction, including
9+
// without limitation the rights to use, copy, modify, merge, publish,
10+
// distribute, sublicense, and/or sell copies of the Software, and to
11+
// permit persons to whom the Software is furnished to do so, subject to
12+
// the following conditions:
13+
//
14+
// The above copyright notice and this permission notice shall be
15+
// included in all copies or substantial portions of the Software.
16+
//
17+
// THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND,
18+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21+
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22+
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23+
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24+
//
25+
26+
using Newtonsoft.Json;
27+
using System;
28+
using System.Collections.Generic;
29+
using System.Linq;
30+
using System.Text;
31+
using System.Threading.Tasks;
32+
using UnityEngine;
33+
34+
namespace Microsoft.SpatialAlignment.Persistence.Json
35+
{
36+
public class Vector3Converter : JsonConverter
37+
{
38+
public override bool CanConvert(Type objectType)
39+
{
40+
return typeof(Vector3).IsAssignableFrom(objectType);
41+
}
42+
43+
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
44+
{
45+
// Deserialize from the reader into a token
46+
var token = serializer.Deserialize(reader);
47+
48+
// Now deserialize the token into a Vector
49+
return JsonConvert.DeserializeObject<Vector3>(token.ToString());
50+
}
51+
52+
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
53+
{
54+
// We know that value is a Vector3
55+
Vector3 vector = (Vector3)value;
56+
57+
// Start the object
58+
writer.WriteStartObject();
59+
60+
// Write x, y and Z fields
61+
writer.WritePropertyName("x");
62+
writer.WriteValue(vector.x);
63+
writer.WritePropertyName("y");
64+
writer.WriteValue(vector.y);
65+
writer.WritePropertyName("z");
66+
writer.WriteValue(vector.z);
67+
68+
// Finish the object
69+
writer.WriteEndObject();
70+
}
71+
}
72+
}

SpatialAlignment-Unity/Assets/SpatialAlignment/Persistence/Json/Vector3Converter.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.

SpatialAlignment-Unity/Assets/SpatialAlignment/SpatialFrame.cs

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,48 @@ public class SpatialFrame : MonoBehaviour
5454
private string id;
5555
#endregion // Unity Inspector Variables
5656

57+
#region Overridables / Event Triggers
58+
/// <summary>
59+
/// Occurs when the value of the <see cref="Id"/> property has changed.
60+
/// </summary>
61+
protected virtual void OnIdChanged()
62+
{
63+
this.IdChanged?.Invoke(this, EventArgs.Empty);
64+
}
65+
#endregion // Overridables / Event Triggers
66+
5767
#region Public Properties
58-
/// <inheritdoc />
68+
/// <summary>
69+
/// Gets the <see cref="IAlignmentStrategy"/> that is being used to align the frame.
70+
/// </summary>
5971
[DataMember]
6072
public virtual IAlignmentStrategy AlignmentStrategy { get => GetComponent<IAlignmentStrategy>(); }
6173

62-
/// <inheritdoc />
63-
public virtual string ID { get => id; set => id = value; }
74+
/// <summary>
75+
/// Gets or sets a unique ID for the frame.
76+
/// </summary>
77+
/// <remarks>
78+
/// A unique ID for the frame.
79+
/// </remarks>
80+
public virtual string Id
81+
{
82+
get => id;
83+
set
84+
{
85+
if (id != value)
86+
{
87+
id = value;
88+
OnIdChanged();
89+
}
90+
}
91+
}
6492
#endregion // Public Properties
93+
94+
#region Public Methods
95+
/// <summary>
96+
/// Raised when the value of the <see cref="Id"/> property has changed.
97+
/// </summary>
98+
public event EventHandler IdChanged;
99+
#endregion // Public Methods
65100
}
66101
}

0 commit comments

Comments
 (0)