Preparations to implement reading Exhibits and Pois from json
This commit is contained in:
@@ -83,9 +83,10 @@ namespace RothenburgAR
|
||||
|
||||
poiXmlPreloader = new PoiXmlPreloader();
|
||||
|
||||
PoiData poiData = poiXmlPreloader.PreloadPoi(testDirectory);
|
||||
List<PoiData> poiData = poiXmlPreloader.PreloadPoi(testDirectory);
|
||||
Assert.NotNull(poiData);
|
||||
Assert.AreEqual("testPoi", poiData.ID);
|
||||
Assert.NotZero(poiData.Count);
|
||||
Assert.AreEqual("testPoi", poiData[0].ID);
|
||||
}
|
||||
|
||||
private void WriteTestPng(string path)
|
||||
|
||||
@@ -33,10 +33,16 @@ namespace RothenburgAR
|
||||
{
|
||||
PoiDataManager.Instance.AddPoiDataSourcePath(PathHelper.POIPath);
|
||||
PoiDataManager.Instance.AddPoiPreloader(new PoiXmlPreloader());
|
||||
|
||||
PoiDataManager.Instance.AddPoiDataSourcePath(PathHelper.ExhibitionPath);
|
||||
PoiDataManager.Instance.AddPoiPreloader(new PoiJsonPreloader());
|
||||
|
||||
PoiDataManager.Instance.LoadEverySourcePath();
|
||||
|
||||
ExhibitionManager.Instance.AddExhibitionSourcePath(PathHelper.ExhibitionPath);
|
||||
ExhibitionManager.Instance.AddExhibitionPreloader(new ExhibitionXmlPreloader());
|
||||
ExhibitionManager.Instance.AddExhibitionPreloader(new ExhibitionJsonPreloader());
|
||||
|
||||
ExhibitionManager.Instance.LoadEverySourcePath(
|
||||
(int maxPaths, int currentPaths, int subMaxExhibitions, int subCurrentExhibition) =>
|
||||
{
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using RothenburgAR.Common;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace RothenburgAR.Exhibition
|
||||
{
|
||||
public class ExhibitionJsonPreloader : IExhibitionPreloader
|
||||
{
|
||||
public bool CanLoadExhibitionDirectory(string exhibitionDirectory)
|
||||
{
|
||||
return false;
|
||||
if (!Directory.Exists(exhibitionDirectory))
|
||||
return false;
|
||||
|
||||
string xmlFilePath = PathHelper.GetXmlPathFromDirectoryPath(exhibitionDirectory);
|
||||
|
||||
if (!File.Exists(xmlFilePath))
|
||||
return false;
|
||||
if (!File.Exists(Path.Combine(exhibitionDirectory, "tracker.xml")))
|
||||
return false;
|
||||
if (!File.Exists(Path.Combine(exhibitionDirectory, "tracker.dat")))
|
||||
return false;
|
||||
|
||||
// Todo: More validations
|
||||
return true;
|
||||
}
|
||||
|
||||
public PreloadedExhibition PreloadExhibition(string exhibitionDirectory)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
string xmlFilePath = PathHelper.GetXmlPathFromDirectoryPath(exhibitionDirectory);
|
||||
|
||||
if (!File.Exists(xmlFilePath))
|
||||
throw new FileNotFoundException(xmlFilePath);
|
||||
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(xmlFilePath);
|
||||
|
||||
// Read the ID from the xml
|
||||
if (doc.DocumentElement == null || doc.DocumentElement.Attributes == null ||
|
||||
doc.DocumentElement.Attributes["id"] == null)
|
||||
throw new InvalidXMLException("Could not read doc.DocumentElement.Attributes['id] ");
|
||||
|
||||
string exhibitionId = doc.DocumentElement.Attributes["id"].Value;
|
||||
|
||||
PreloadedExhibition resultExhibition = new PreloadedExhibition
|
||||
{
|
||||
ContainedExhibits = new List<PreloadedExhibit>(),
|
||||
ID = exhibitionId,
|
||||
DatasetPath = exhibitionDirectory
|
||||
};
|
||||
|
||||
var exhibitNodes = doc.SelectNodes("//exhibition/exhibit");
|
||||
foreach (XmlNode exhibitNode in exhibitNodes)
|
||||
{
|
||||
if (exhibitNode.Attributes == null || exhibitNode.Attributes["id"] == null)
|
||||
{
|
||||
// Todo: Log error
|
||||
continue;
|
||||
}
|
||||
|
||||
var newExhibit = PreloadExhibit(exhibitionDirectory, exhibitNode);
|
||||
resultExhibition.ContainedExhibits.Add(newExhibit);
|
||||
}
|
||||
return resultExhibition;
|
||||
}
|
||||
|
||||
private PreloadedExhibit PreloadExhibit(string exhibitionDirectory, XmlNode exhibitNode)
|
||||
{
|
||||
PreloadedExhibit newExhibit = new PreloadedExhibit();
|
||||
newExhibit.ID = exhibitNode.Attributes["id"].Value;
|
||||
newExhibit.ReferencedPoiEntries = new List<PreloadedPoiReference>();
|
||||
|
||||
// Load Description Text
|
||||
XmlNodeList descrList = exhibitNode.SelectNodes("description/text");
|
||||
if (descrList != null && descrList.Count > 0)
|
||||
{
|
||||
TextElement exhibitDescr = TextElement.BuildFromXmlNode(exhibitionDirectory, descrList);
|
||||
newExhibit.Description = exhibitDescr;
|
||||
}
|
||||
|
||||
// Load Title Text
|
||||
XmlNodeList titleList = exhibitNode.SelectNodes("title/text");
|
||||
if (titleList != null && titleList.Count > 0)
|
||||
{
|
||||
TextElement exhibitTitle = TextElement.BuildFromXmlNode(exhibitionDirectory, titleList);
|
||||
var fontSize = GetFloatFromXmlNode(exhibitNode.SelectSingleNode("title/font"), "size");
|
||||
var boxHeight = GetFloatFromXmlNode(exhibitNode.SelectSingleNode("title/dimensions"), "height");
|
||||
var boxWidth = GetFloatFromXmlNode(exhibitNode.SelectSingleNode("title/dimensions"), "width");
|
||||
|
||||
PreloadedExhibitTitle preTitle = new PreloadedExhibitTitle
|
||||
{
|
||||
Text = exhibitTitle,
|
||||
Position = GetVector3FromXmlNode(exhibitNode.SelectSingleNode("title/position")),
|
||||
Rotation = GetVector3FromXmlNode(exhibitNode.SelectSingleNode("title/rotation")),
|
||||
FontSize = fontSize ?? 20,
|
||||
BoxWidth = boxWidth ?? 200,
|
||||
BoxHeight = boxHeight ?? 25
|
||||
};
|
||||
newExhibit.Title = preTitle;
|
||||
}
|
||||
|
||||
|
||||
// Load POI References
|
||||
XmlNodeList poiRefList = exhibitNode.SelectNodes("poiList/poi");
|
||||
if (poiRefList != null && poiRefList.Count > 0)
|
||||
{
|
||||
foreach (XmlNode poiRefEntry in poiRefList)
|
||||
{
|
||||
if (poiRefEntry.Attributes == null || poiRefEntry.Attributes["ref-id"] == null)
|
||||
continue;
|
||||
|
||||
PreloadedPoiReference poiReference =
|
||||
new PreloadedPoiReference
|
||||
{
|
||||
ReferencedId = poiRefEntry.Attributes["ref-id"].Value,
|
||||
Position = GetVector3FromXmlNode(poiRefEntry.SelectSingleNode("position")),
|
||||
Rotation = GetVector3FromXmlNode(poiRefEntry.SelectSingleNode("rotation")),
|
||||
Scale = GetVector3FromXmlNode(poiRefEntry.SelectSingleNode("scale"))
|
||||
};
|
||||
|
||||
newExhibit.ReferencedPoiEntries.Add(poiReference);
|
||||
}
|
||||
}
|
||||
return newExhibit;
|
||||
}
|
||||
|
||||
private string GetStringFromXmlNode(XmlNode node, string key)
|
||||
{
|
||||
if (node == null)
|
||||
return null;
|
||||
if (node.Attributes == null)
|
||||
return null;
|
||||
if (node.Attributes[key] == null)
|
||||
return null;
|
||||
|
||||
return node.Attributes[key].Value;
|
||||
}
|
||||
|
||||
private float? GetFloatFromXmlNode(XmlNode node, string key)
|
||||
{
|
||||
var str = GetStringFromXmlNode(node, key);
|
||||
if (str == null)
|
||||
return null;
|
||||
try
|
||||
{
|
||||
return float.Parse(str, CultureInfo.InvariantCulture.NumberFormat);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Vector3? GetVector3FromXmlNode(XmlNode node)
|
||||
{
|
||||
if (node == null)
|
||||
return null;
|
||||
if (node.Attributes == null)
|
||||
return null;
|
||||
if (node.Attributes["x"] == null)
|
||||
return null;
|
||||
if (node.Attributes["y"] == null)
|
||||
return null;
|
||||
if (node.Attributes["z"] == null)
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
float posX = float.Parse(node.Attributes["x"].Value,
|
||||
CultureInfo.InvariantCulture.NumberFormat);
|
||||
float posY = float.Parse(node.Attributes["y"].Value,
|
||||
CultureInfo.InvariantCulture.NumberFormat);
|
||||
float posZ = float.Parse(node.Attributes["z"].Value,
|
||||
CultureInfo.InvariantCulture.NumberFormat);
|
||||
|
||||
return new Vector3(posX, posY, posZ);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// TODO: log error
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7806b799db63ba3468e962aea10b2549
|
||||
timeCreated: 1537892587
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,8 +1,10 @@
|
||||
namespace RothenburgAR.PointOfInterest
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace RothenburgAR.PointOfInterest
|
||||
{
|
||||
public interface IPoiPreloader
|
||||
{
|
||||
bool CanLoadPoiDirectory(string poiDirectory);
|
||||
PoiData PreloadPoi(string poiDirectory);
|
||||
List<PoiData> PreloadPoi(string poiDirectory);
|
||||
}
|
||||
}
|
||||
@@ -74,8 +74,11 @@ namespace RothenburgAR.PointOfInterest
|
||||
}
|
||||
try
|
||||
{
|
||||
var newPoi = preloader.PreloadPoi(path);
|
||||
AddPoiData(newPoi);
|
||||
var newPois = preloader.PreloadPoi(path);
|
||||
foreach (var newPoi in newPois)
|
||||
{
|
||||
AddPoiData(newPoi);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
122
Assets/RothenburgAR/Scripts/PointOfInterest/PoiJsonPreloader.cs
Normal file
122
Assets/RothenburgAR/Scripts/PointOfInterest/PoiJsonPreloader.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using RothenburgAR.Common;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RothenburgAR.PointOfInterest
|
||||
{
|
||||
public class PoiJsonPreloader : IPoiPreloader
|
||||
{
|
||||
public bool CanLoadPoiDirectory(string poiDirectory)
|
||||
{
|
||||
//TODO remove
|
||||
return false;
|
||||
|
||||
if (!Directory.Exists(poiDirectory))
|
||||
return false;
|
||||
|
||||
var languageDirs = Directory.GetDirectories(poiDirectory).ToList();
|
||||
foreach (var dir in languageDirs)
|
||||
{
|
||||
var metaFilePath = PathHelper.CombinePaths(poiDirectory, dir, "meta.json");
|
||||
if (!File.Exists(metaFilePath)) return false;
|
||||
}
|
||||
|
||||
// Todo: More validations
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<PoiData> PreloadPoi(string poiDirectory)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
string xmlFilePath = PathHelper.GetXmlPathFromDirectoryPath(poiDirectory);
|
||||
|
||||
if (!File.Exists(xmlFilePath))
|
||||
throw new FileNotFoundException(xmlFilePath);
|
||||
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(xmlFilePath);
|
||||
|
||||
|
||||
// Read the ID from the xml
|
||||
if (doc.DocumentElement == null || doc.DocumentElement.Attributes == null ||
|
||||
doc.DocumentElement.Attributes["id"] == null)
|
||||
throw new InvalidXMLException("Could not read doc.DocumentElement.Attributes['id] ");
|
||||
|
||||
string poiId = doc.DocumentElement.Attributes["id"].Value;
|
||||
|
||||
// Read the description from the xml
|
||||
XmlNodeList descNodes = doc.SelectNodes("//poi/description/text");
|
||||
TextElement descElement = TextElement.BuildFromXmlNode(poiDirectory, descNodes);
|
||||
|
||||
// Read the title from the xml
|
||||
XmlNodeList titleNodes = doc.SelectNodes("//poi/title/text");
|
||||
TextElement titleElement = TextElement.BuildFromXmlNode(poiDirectory, titleNodes);
|
||||
|
||||
|
||||
PoiData poiData = new PoiData
|
||||
{
|
||||
ID = poiId,
|
||||
Description = descElement,
|
||||
Title = titleElement,
|
||||
SourcePath = poiDirectory
|
||||
};
|
||||
|
||||
// Read the model value
|
||||
XmlNode modelNode = doc.SelectSingleNode("//poi/model");
|
||||
if (modelNode != null)
|
||||
{
|
||||
var pathNode = modelNode.SelectSingleNode("path");
|
||||
var scaleNode = modelNode.SelectSingleNode("scale");
|
||||
var rotationNode = modelNode.SelectSingleNode("rotation");
|
||||
var positionNode = modelNode.SelectSingleNode("position");
|
||||
|
||||
var poiModelDescription = new PoiModelDescription
|
||||
{
|
||||
ModelPath = Path.Combine(poiDirectory, pathNode.Attributes["value"].Value),
|
||||
ModelPrefabName = pathNode.Attributes["prefabName"].Value,
|
||||
Scale = GetVector3FromXmlNode(scaleNode).GetValueOrDefault(Vector3.one),
|
||||
Rotation = GetVector3FromXmlNode(rotationNode).GetValueOrDefault(Vector3.zero),
|
||||
Position = GetVector3FromXmlNode(positionNode).GetValueOrDefault(Vector3.zero)
|
||||
};
|
||||
poiData.ModelDescription = poiModelDescription;
|
||||
}
|
||||
return new List<PoiData> { poiData };
|
||||
}
|
||||
|
||||
private Vector3? GetVector3FromXmlNode(XmlNode node)
|
||||
{
|
||||
if (node == null)
|
||||
return null;
|
||||
if (node.Attributes == null)
|
||||
return null;
|
||||
if (node.Attributes["x"] == null)
|
||||
return null;
|
||||
if (node.Attributes["y"] == null)
|
||||
return null;
|
||||
if (node.Attributes["z"] == null)
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
float posX = float.Parse(node.Attributes["x"].Value,
|
||||
CultureInfo.InvariantCulture.NumberFormat);
|
||||
float posY = float.Parse(node.Attributes["y"].Value,
|
||||
CultureInfo.InvariantCulture.NumberFormat);
|
||||
float posZ = float.Parse(node.Attributes["z"].Value,
|
||||
CultureInfo.InvariantCulture.NumberFormat);
|
||||
|
||||
return new Vector3(posX, posY, posZ);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// TODO: log error
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 65621f7647a1d0a40870d6e20203b6b9
|
||||
timeCreated: 1537892587
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Globalization;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using RothenburgAR.Common;
|
||||
@@ -23,7 +24,7 @@ namespace RothenburgAR.PointOfInterest
|
||||
return true;
|
||||
}
|
||||
|
||||
public PoiData PreloadPoi(string poiDirectory)
|
||||
public List<PoiData> PreloadPoi(string poiDirectory)
|
||||
{
|
||||
string xmlFilePath = PathHelper.GetXmlPathFromDirectoryPath(poiDirectory);
|
||||
|
||||
@@ -77,7 +78,7 @@ namespace RothenburgAR.PointOfInterest
|
||||
};
|
||||
poiData.ModelDescription = poiModelDescription;
|
||||
}
|
||||
return poiData;
|
||||
return new List<PoiData> { poiData };
|
||||
}
|
||||
|
||||
private Vector3? GetVector3FromXmlNode(XmlNode node)
|
||||
|
||||
@@ -31,9 +31,11 @@ namespace RothenburgAR.Updater
|
||||
[Serializable]
|
||||
public class VersioncheckAnswer
|
||||
{
|
||||
[JsonProperty]
|
||||
public List<string> languages { get; set; }
|
||||
public List<ExhibitionVersion> data { get; set; }
|
||||
[JsonProperty("languages")]
|
||||
public List<string> Languages { get; set; }
|
||||
|
||||
[JsonProperty("data")]
|
||||
public List<ExhibitionVersion> Data { get; set; }
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace RothenburgAR.Updater
|
||||
|
||||
var answer = VersionAnswer;
|
||||
|
||||
if (answer.data.TrueForAll(d => d.Meta.Status == VersionStatus.ok && d.Tracker.Status == VersionStatus.ok))
|
||||
if (answer.Data.TrueForAll(d => d.Meta.Status == VersionStatus.ok && d.Tracker.Status == VersionStatus.ok))
|
||||
{
|
||||
// no updates required, continue to app
|
||||
LoadMainScene();
|
||||
@@ -159,8 +159,8 @@ namespace RothenburgAR.Updater
|
||||
|
||||
//TODO write languages to file the app can read (so that the languagemanager can decide which languages the user can choose from)
|
||||
|
||||
var updatedMeta = VersionAnswer.data.Where(d => d.Meta.Status == VersionStatus.updated).ToList();
|
||||
var updatedTracker = VersionAnswer.data.Where(d => d.Tracker.Status == VersionStatus.updated).ToList();
|
||||
var updatedMeta = VersionAnswer.Data.Where(d => d.Meta.Status == VersionStatus.updated).ToList();
|
||||
var updatedTracker = VersionAnswer.Data.Where(d => d.Tracker.Status == VersionStatus.updated).ToList();
|
||||
updatedMeta.Union(updatedTracker).ToList().ForEach(updatedExhibition =>
|
||||
{
|
||||
// create exhibition directories
|
||||
@@ -174,7 +174,7 @@ namespace RothenburgAR.Updater
|
||||
updatedMeta.ForEach(d => UpdateMeta(d));
|
||||
updatedTracker.ForEach(d => UpdateTracker(d));
|
||||
|
||||
var deletedData = VersionAnswer.data.Where(d =>
|
||||
var deletedData = VersionAnswer.Data.Where(d =>
|
||||
d.Meta.Status == VersionStatus.deleted
|
||||
|| d.Tracker.Status == VersionStatus.deleted).ToList();
|
||||
deletedData.ForEach(d => DeleteExhibition(d));
|
||||
@@ -188,7 +188,7 @@ namespace RothenburgAR.Updater
|
||||
|
||||
private void UpdateMeta(ExhibitionVersion exhibition)
|
||||
{
|
||||
foreach (var lang in VersionAnswer.languages)
|
||||
foreach (var lang in VersionAnswer.Languages)
|
||||
{
|
||||
var path = PathHelper.CombinePaths(PathHelper.ExhibitionPath, exhibition.Id, lang);
|
||||
var url = exhibition.Meta.UpdateUrl.Replace("{lang}", lang);
|
||||
|
||||
Reference in New Issue
Block a user