From b78d67be22f6374274ce714b119a13f2822d8e9a Mon Sep 17 00:00:00 2001 From: Florian Spiess Date: Tue, 26 Oct 2021 12:31:10 +0200 Subject: [PATCH] Implemented SegmentMetadataStore and fixed bug where assertion would prevent initialization of metadata. --- .../CineastApi/Model/Data/MetadataStore.cs | 14 ++--- .../CineastApi/Model/Data/ObjectData.cs | 6 +- .../Model/Data/ObjectMetadataStore.cs | 6 +- .../CineastApi/Model/Data/SegmentData.cs | 23 ++++++- .../Model/Data/SegmentMetadataStore.cs | 61 +++++++++++++++++++ .../Model/Data/SegmentMetadataStore.cs.meta | 11 ++++ .../Model/Registries/SegmentRegistry.cs | 7 +-- 7 files changed, 108 insertions(+), 20 deletions(-) create mode 100644 Runtime/Vitrivr/UnityInterface/CineastApi/Model/Data/SegmentMetadataStore.cs create mode 100644 Runtime/Vitrivr/UnityInterface/CineastApi/Model/Data/SegmentMetadataStore.cs.meta diff --git a/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Data/MetadataStore.cs b/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Data/MetadataStore.cs index 100e814..c0aa23a 100644 --- a/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Data/MetadataStore.cs +++ b/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Data/MetadataStore.cs @@ -12,7 +12,7 @@ public abstract class MetadataStore /// /// Actual internal storage of metadata /// - protected Dictionary> _storage = + protected Dictionary> Storage = new Dictionary>(); public bool Initialized { get; protected set; } @@ -26,19 +26,19 @@ public async Task>> GetAll() await InitializeAsync(); } - return _storage; + return Storage; } public bool DomainExists(string domain) { Assert.IsTrue(Initialized); - return _storage.ContainsKey(domain); + return Storage.ContainsKey(domain); } public string Get(string domain, string key) { Assert.IsTrue(Initialized); - return _storage[domain][key]; + return Storage[domain][key]; } /// @@ -51,7 +51,7 @@ public string Get(string str) var domainAndKey = str.Split('.'); if (domainAndKey.Length >= 1) { - return _storage[domainAndKey[0]][domainAndKey[1]]; + return Storage[domainAndKey[0]][domainAndKey[1]]; } throw new ArgumentException("Cannot retrieve without domain"); @@ -64,7 +64,7 @@ public string Get(string str) public List<(string Key, string Value)> GetDomain(string domain) { Assert.IsTrue(Initialized); - var items = _storage[domain]; + var items = Storage[domain]; return items.Keys.Select(key => (key, items[key])).ToList(); } @@ -75,7 +75,7 @@ public string Get(string str) public bool Exists(string domain, string key) { Assert.IsTrue(Initialized); - return DomainExists(domain) && _storage[domain].ContainsKey(key); + return DomainExists(domain) && Storage[domain].ContainsKey(key); } } } \ No newline at end of file diff --git a/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Data/ObjectData.cs b/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Data/ObjectData.cs index f76f271..e6f16a9 100644 --- a/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Data/ObjectData.cs +++ b/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Data/ObjectData.cs @@ -31,22 +31,20 @@ public class ObjectData /// private List _segments; + public ObjectMetadataStore ObjectMetadata { get; private set; } + /// /// Constructs a new instance with the given id, for lazy loading. /// - /// public ObjectData(string id) { _id = id; ObjectMetadata = new ObjectMetadataStore(_id); } - public ObjectMetadataStore ObjectMetadata { get; private set; } - /// /// Constructs a new instance with the given wrapper content. /// - /// public ObjectData(MediaObjectDescriptor descriptor) { _id = descriptor.ObjectId; diff --git a/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Data/ObjectMetadataStore.cs b/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Data/ObjectMetadataStore.cs index b42475e..38721d5 100644 --- a/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Data/ObjectMetadataStore.cs +++ b/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Data/ObjectMetadataStore.cs @@ -31,12 +31,12 @@ public void Initialize(MediaObjectMetadataQueryResult data) foreach (var meta in data.Content.Where(meta => meta.ObjectId == ObjectId)) { - if (!DomainExists(meta.Domain)) + if (!Storage.ContainsKey(meta.Domain)) { - _storage.Add(meta.Domain, new Dictionary()); + Storage.Add(meta.Domain, new Dictionary()); } - var domain = _storage[meta.Domain]; + var domain = Storage[meta.Domain]; domain.Add(meta.Key, meta.Value); } diff --git a/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Data/SegmentData.cs b/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Data/SegmentData.cs index eaf0c25..65d7b57 100644 --- a/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Data/SegmentData.cs +++ b/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Data/SegmentData.cs @@ -27,23 +27,27 @@ public class SegmentData // TODO: Consider combining lazy loading requests into batch requests every x seconds to reduce request overhead private static readonly SemaphoreSlim InitLock = new SemaphoreSlim(1, 1); + public SegmentMetadataStore SegmentMetadata { get; private set; } + public SegmentData(string id) { _id = id; + SegmentMetadata = new SegmentMetadataStore(_id); } public SegmentData(MediaSegmentDescriptor descriptor) { _descriptor = descriptor; _id = descriptor.SegmentId; + SegmentMetadata = new SegmentMetadataStore(_id); Initialized = true; } /// /// Runs asynchronous segment ID query to initialize the data for this segment. /// - private async Task InitializeAsync() + private async Task InitializeAsync(bool withMetadata = true) { await InitLock.WaitAsync(); try @@ -63,6 +67,11 @@ private async Task InitializeAsync() var result = queryResult.Content[0]; Initialize(result); + + if (withMetadata) + { + await SegmentMetadata.InitializeAsync(); + } } finally { @@ -94,6 +103,18 @@ public void Initialize(MediaSegmentDescriptor data) Initialized = true; } + public void InitializeMeta(MediaSegmentMetadataQueryResult meta) + { + if (SegmentMetadata.Initialized) + { + Debug.LogWarning("Attempt to initialize already initialized segment metadata for media object with " + + $"id \"{Id}\". Using cached data."); + return; + } + + SegmentMetadata.Initialize(meta); + } + /// /// ID of the /// diff --git a/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Data/SegmentMetadataStore.cs b/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Data/SegmentMetadataStore.cs new file mode 100644 index 0000000..e312222 --- /dev/null +++ b/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Data/SegmentMetadataStore.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Org.Vitrivr.CineastApi.Model; +using UnityEngine; + +namespace Vitrivr.UnityInterface.CineastApi.Model.Data +{ + /// + /// Access and local representation of metadata for segments. + /// + [Serializable] + public class SegmentMetadataStore : MetadataStore + { + public SegmentMetadataStore(string id) + { + SegmentId = id; + Initialized = false; + } + + public string SegmentId { get; private set; } + + public void Initialize(MediaSegmentMetadataQueryResult data) + { + if (Initialized) + { + Debug.LogWarning($"Attempted to initialize already initialized metadata for media object {SegmentId}!"); + return; + } + + foreach (var meta in data.Content.Where(meta => meta.SegmentId == SegmentId)) + { + if (!Storage.ContainsKey(meta.Domain)) + { + Storage.Add(meta.Domain, new Dictionary()); + } + + var domain = Storage[meta.Domain]; + domain.Add(meta.Key, meta.Value); + } + + Initialized = true; + } + + public override async Task InitializeAsync() + { + if (Initialized) + { + Debug.LogWarning($"Attempted to initialize already initialized metadata for media object {SegmentId}!"); + return; + } + + var metadataResult = await CineastWrapper.MetadataApi.FindSegMetaByIdAsync(SegmentId); + if (!Initialized) + { + Initialize(metadataResult); + } + } + } +} \ No newline at end of file diff --git a/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Data/SegmentMetadataStore.cs.meta b/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Data/SegmentMetadataStore.cs.meta new file mode 100644 index 0000000..1add9b2 --- /dev/null +++ b/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Data/SegmentMetadataStore.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9f4b1b2ed631f476bb6e7e9f4198037d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Registries/SegmentRegistry.cs b/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Registries/SegmentRegistry.cs index 87dbd4b..627e051 100644 --- a/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Registries/SegmentRegistry.cs +++ b/Runtime/Vitrivr/UnityInterface/CineastApi/Model/Registries/SegmentRegistry.cs @@ -109,7 +109,7 @@ public static void Reset() } /// - /// Whether the given segmentId is known to this registry + /// Whether the given segmentId is known to this registry. /// /// /// @@ -119,14 +119,11 @@ public static bool Exists(string segmentId) } /// - /// Gets the corresponding object of the segment specified + /// Gets the corresponding object of the segment specified. /// - /// - /// /// public static async Task GetObjectOf(string segmentId) { - // TODO might require a dedicated cache if (!Exists(segmentId)) { throw new ArgumentException($"Cannot get object of unknown segment with id {segmentId}");