diff --git a/Assets/Scripts/Configuration/Configuration.cs b/Assets/Scripts/Configuration/Configuration.cs index 06ed9da9e..1d9a0965c 100644 --- a/Assets/Scripts/Configuration/Configuration.cs +++ b/Assets/Scripts/Configuration/Configuration.cs @@ -5,7 +5,6 @@ using System.Linq; using Netherlands3D.Coordinates; using Netherlands3D.Twin.Features; -using Newtonsoft.Json; using SimpleJSON; using UnityEngine; using UnityEngine.Events; @@ -19,7 +18,6 @@ public class Configuration : ScriptableObject, IConfiguration [SerializeField] private string title = "Amersfoort"; [SerializeField] private Coordinate origin = new(CoordinateSystem.RD, 161088, 503050, 300); - [JsonProperty(ItemIsReference = true)] [SerializeField] public List Features = new(); public string Title @@ -42,15 +40,21 @@ public Coordinate Origin } } - [JsonIgnore] public UnityEvent OnOriginChanged = new(); - [JsonIgnore] public UnityEvent OnTitleChanged = new(); + /// + /// By default, we should start the setup wizard to configure the twin, unless configuration was successfully + /// loaded from the URL or from the Configuration File. + /// + public bool ShouldStartSetup { get; set; } = true; + + public UnityEvent OnOriginChanged = new(); + public UnityEvent OnTitleChanged = new(); /// /// Overwrites the contents of this Scriptable Object with the serialized JSON file at the provided location. /// public IEnumerator PopulateFromFile(string externalConfigFilePath) { - Debug.Log($"Attempting to load configuration from ${externalConfigFilePath}"); + Debug.Log($"Attempting to load configuration from {externalConfigFilePath}"); using UnityWebRequest request = UnityWebRequest.Get(externalConfigFilePath); yield return request.SendWebRequest(); if (request.result == UnityWebRequest.Result.Success) @@ -59,7 +63,8 @@ public IEnumerator PopulateFromFile(string externalConfigFilePath) var json = request.downloadHandler.text; // populate object and when settings are missing, use the defaults from the provided object - JsonConvert.PopulateObject(json, this); + Populate(JSON.Parse(json)); + ShouldStartSetup = false; } else { @@ -69,30 +74,37 @@ public IEnumerator PopulateFromFile(string externalConfigFilePath) yield return null; } - public bool Populate(Uri url) + public void Populate(Uri url) { var queryParameters = new NameValueCollection(); url.Query.ParseAsQueryString(queryParameters); - - return Populate(queryParameters); + Populate(queryParameters); } - public bool Populate(NameValueCollection queryParameters) + public void Populate(NameValueCollection queryParameters) { - if (UrlContainsConfiguration(queryParameters) == false) + if (UrlContainsConfiguration(queryParameters)) { - return false; + ShouldStartSetup = false; + } + + var originFromQueryString = queryParameters.Get("origin"); + if (string.IsNullOrEmpty(originFromQueryString) == false) + { + LoadOriginFromString(originFromQueryString); + } + + var featuresFromQueryString = queryParameters.Get("features"); + if (featuresFromQueryString != null) + { + LoadFeaturesFromString(featuresFromQueryString); } - LoadOriginFromString(queryParameters.Get("origin")); - LoadFeaturesFromString(queryParameters.Get("features")); foreach (var feature in Features) { var config = feature.configuration as IConfiguration; config?.Populate(queryParameters); } - - return true; } public string ToQueryString() @@ -118,19 +130,26 @@ public string ToQueryString() public void Populate(JSONNode jsonNode) { - Title = jsonNode["title"]; + if (jsonNode["title"]) + { + Title = jsonNode["title"]; + } + Origin = new Coordinate( jsonNode["origin"]["epsg"], jsonNode["origin"]["x"], jsonNode["origin"]["y"], jsonNode["origin"]["z"] ); + Debug.Log($"Set origin '{Origin}' from Configuration file"); + foreach (var element in jsonNode["features"]) { var feature = Features.FirstOrDefault(feature => feature.Id == element.Key); if (!feature) continue; feature.Populate(element.Value); + if (feature.IsEnabled) Debug.Log($"Enabled feature '{feature.Id}' from Configuration file"); } } @@ -173,6 +192,7 @@ private void LoadOriginFromString(string origin) int.TryParse(originParts[2].Trim(), out int z); Origin = new Coordinate(CoordinateSystem.RD, x, y, z); + Debug.Log($"Set origin '{Origin}' from URL"); } private void LoadFeaturesFromString(string features) @@ -181,6 +201,7 @@ private void LoadFeaturesFromString(string features) foreach (var feature in Features) { feature.IsEnabled = featureIdentifiers.Contains(feature.Id); + if (feature.IsEnabled) Debug.Log($"Enabled feature '{feature.Id}' from URL"); } } } diff --git a/Assets/Scripts/Configuration/Configurator.cs b/Assets/Scripts/Configuration/Configurator.cs index f8f2a7f94..95ea54177 100644 --- a/Assets/Scripts/Configuration/Configurator.cs +++ b/Assets/Scripts/Configuration/Configurator.cs @@ -42,7 +42,12 @@ public IEnumerator Execute() url = debugUrl; #endif - if (string.IsNullOrEmpty(url) || configuration.Populate(new Uri(url)) == false) + if (string.IsNullOrEmpty(url) == false) + { + configuration.Populate(new Uri(url)); + } + + if (configuration.ShouldStartSetup) { StartSetup(); } diff --git a/Assets/Scripts/Configuration/Indicators/Configuration.cs b/Assets/Scripts/Configuration/Indicators/Configuration.cs index 2a1687f1a..ba9f84b90 100644 --- a/Assets/Scripts/Configuration/Indicators/Configuration.cs +++ b/Assets/Scripts/Configuration/Indicators/Configuration.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Specialized; -using Newtonsoft.Json; +using Netherlands3D.Twin.Features; using SimpleJSON; using UnityEngine; using UnityEngine.Events; @@ -24,23 +24,24 @@ public string DossierId } } - public bool Populate(NameValueCollection queryParameters) + public void Populate(NameValueCollection queryParameters) { var id = queryParameters.Get("indicators.dossier"); - if (id == null) return false; + if (id == null) return; + Debug.Log($"Set dossier id '{id}' from URL"); DossierId = id; - - return true; } public string ToQueryString() { - return $"indicators.dossier=${dossierId}"; + return $"indicators.dossier={dossierId}"; } public void Populate(JSONNode jsonNode) { + if (string.IsNullOrEmpty(jsonNode["dossierId"])) return; + DossierId = jsonNode["dossierId"]; } diff --git a/Assets/Scripts/Configuration/Indicators/DossierLoader.cs b/Assets/Scripts/Configuration/Indicators/DossierLoader.cs index b317eedaf..172565113 100644 --- a/Assets/Scripts/Configuration/Indicators/DossierLoader.cs +++ b/Assets/Scripts/Configuration/Indicators/DossierLoader.cs @@ -20,6 +20,12 @@ private void OnDisable() private void OnDossierStartLoading(string dossierId) { + if (string.IsNullOrEmpty(dossierId)) + { + dossier.Close(); + return; + } + StartCoroutine(dossier.Open(dossierId)); } diff --git a/Packages/eu.netherlands3d.twin-features/CHANGELOG.md b/Packages/eu.netherlands3d.twin-features/CHANGELOG.md index b723c536d..ce64337d7 100644 --- a/Packages/eu.netherlands3d.twin-features/CHANGELOG.md +++ b/Packages/eu.netherlands3d.twin-features/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this package will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Added + +- IConfiguration interface to declare configuration per feature including SimpleJSON mapping and QueryParameter mapping +- IQueryStringMapper to help populate feature configuration from a URI string +- ISimpleJsonMapper to help populate feature configuration from a JSON object + ## [1.0.0] - 2023-06-13 + ### Changes + - Initial release diff --git a/Packages/eu.netherlands3d.twin-features/Scripts/IConfiguration.cs b/Packages/eu.netherlands3d.twin-features/Scripts/IConfiguration.cs index cabc14fc8..3a81fa32d 100644 --- a/Packages/eu.netherlands3d.twin-features/Scripts/IConfiguration.cs +++ b/Packages/eu.netherlands3d.twin-features/Scripts/IConfiguration.cs @@ -1,6 +1,4 @@ -using Netherlands3D.Twin.Features; - -namespace Netherlands3D.Twin +namespace Netherlands3D.Twin.Features { public interface IConfiguration : ISimpleJsonMapper, IQueryStringMapper { diff --git a/Packages/eu.netherlands3d.twin-features/Scripts/IQueryStringMapper.cs b/Packages/eu.netherlands3d.twin-features/Scripts/IQueryStringMapper.cs index d8d27107c..cc4753cb2 100644 --- a/Packages/eu.netherlands3d.twin-features/Scripts/IQueryStringMapper.cs +++ b/Packages/eu.netherlands3d.twin-features/Scripts/IQueryStringMapper.cs @@ -1,10 +1,10 @@ using System.Collections.Specialized; -namespace Netherlands3D.Twin +namespace Netherlands3D.Twin.Features { public interface IQueryStringMapper { - bool Populate(NameValueCollection queryParameters); + void Populate(NameValueCollection queryParameters); string ToQueryString(); } } \ No newline at end of file