From 8470d06eb72a19228ac2c57abfb5021ed3d1eb34 Mon Sep 17 00:00:00 2001 From: Robert Date: Thu, 1 Oct 2020 19:07:28 +0200 Subject: [PATCH] Dynamic data models - Expanded data model API --- .../Plugins/DataModelExpansions/DataModel.cs | 93 ++++++++++++++++--- 1 file changed, 79 insertions(+), 14 deletions(-) diff --git a/src/Artemis.Core/Plugins/DataModelExpansions/DataModel.cs b/src/Artemis.Core/Plugins/DataModelExpansions/DataModel.cs index e9a063eef..edeee260a 100644 --- a/src/Artemis.Core/Plugins/DataModelExpansions/DataModel.cs +++ b/src/Artemis.Core/Plugins/DataModelExpansions/DataModel.cs @@ -10,6 +10,8 @@ namespace Artemis.Core.DataModelExpansions { public abstract class DataModel { + private readonly Dictionary _dynamicDataModels = new Dictionary(); + /// /// Gets the plugin info this data model belongs to /// @@ -28,6 +30,83 @@ namespace Artemis.Core.DataModelExpansions [DataModelIgnore] public bool IsExpansion { get; internal set; } + /// + /// Gets an read-only dictionary of all dynamic data models + /// + [DataModelIgnore] + public ReadOnlyDictionary DynamicDataModels => new ReadOnlyDictionary(_dynamicDataModels); + + /// + /// Returns a read-only collection of all properties in this datamodel that are to be ignored + /// + /// + public ReadOnlyCollection GetHiddenProperties() + { + if (PluginInfo.Instance is ProfileModule profileModule) + return profileModule.HiddenProperties; + if (PluginInfo.Instance is BaseDataModelExpansion dataModelExpansion) + return dataModelExpansion.HiddenProperties; + + return new List().AsReadOnly(); + } + + /// + /// Adds a dynamic data model to this data model + /// + /// The dynamic data model to add + /// The key of the child, must be unique to this data model + /// An optional name, if not provided the key will be used in a humanized form + /// An optional description + public void AddDynamicChild(DataModel dynamicDataModel, string key, string name = null, string description = null) + { + if (_dynamicDataModels.ContainsKey(key)) + { + throw new ArtemisCoreException($"Cannot add a dynamic data model with key '{key}' " + + "because the key is already in use on this data model."); + } + + if (_dynamicDataModels.ContainsValue(dynamicDataModel)) + { + var existingKey = _dynamicDataModels.First(kvp => kvp.Value == dynamicDataModel).Key; + throw new ArtemisCoreException($"Cannot add a dynamic data model with key '{key}' " + + $"because the dynamic data model is already added with key '{existingKey}."); + } + + _dynamicDataModels.Add(key, dynamicDataModel); + } + + /// + /// Removes a dynamic data model from the data model by its key + /// + /// The key of the dynamic data model to remove + public void RemoveDynamicChildByKey(string key) + { + _dynamicDataModels.Remove(key); + } + + /// + /// Removes a dynamic data model from this data model + /// + /// The dynamic data model to remove + public void RemoveDynamicChild(DataModel dynamicDataModel) + { + var keys = _dynamicDataModels.Where(kvp => kvp.Value == dynamicDataModel).Select(kvp => kvp.Key).ToList(); + foreach (var key in keys) + _dynamicDataModels.Remove(key); + } + + /// + /// Gets a dynamic data model of type by its key + /// + /// The type of data model you expect + /// The unique key of the dynamic data model + /// If found, the dynamic data model + public T GetDynamicChild(string key) where T : DataModel + { + _dynamicDataModels.TryGetValue(key, out var value); + return value as T; + } + internal bool ContainsPath(string path) { var parts = path.Split('.'); @@ -98,19 +177,5 @@ namespace Artemis.Core.DataModelExpansions var child = GetTypeAtPath(path); return child.GenericTypeArguments.Length > 0 ? child.GenericTypeArguments[0] : null; } - - /// - /// Returns a read-only list of all properties in this datamodel that are to be ignored - /// - /// - public ReadOnlyCollection GetHiddenProperties() - { - if (PluginInfo.Instance is ProfileModule profileModule) - return profileModule.HiddenProperties; - if (PluginInfo.Instance is BaseDataModelExpansion dataModelExpansion) - return dataModelExpansion.HiddenProperties; - - return new List().AsReadOnly(); - } } } \ No newline at end of file