diff --git a/src/Artemis.Core/Attributes/DataModelProperty.cs b/src/Artemis.Core/Attributes/DataModelProperty.cs
deleted file mode 100644
index 2135665d0..000000000
--- a/src/Artemis.Core/Attributes/DataModelProperty.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System;
-
-namespace Artemis.Core.Attributes
-{
- public class DataModelPropertyAttribute : Attribute
- {
- public string DisplayName { get; set; }
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/DataModelDescription.cs b/src/Artemis.Core/Models/DataModelDescription.cs
deleted file mode 100644
index c7d950777..000000000
--- a/src/Artemis.Core/Models/DataModelDescription.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace Artemis.Core.Models
-{
- public class DataModelDescription
- {
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.Core/Plugins/Abstract/DataModels/Attributes/DataModelIgnoreAttribute.cs b/src/Artemis.Core/Plugins/Abstract/DataModels/Attributes/DataModelIgnoreAttribute.cs
new file mode 100644
index 000000000..0dd67b97a
--- /dev/null
+++ b/src/Artemis.Core/Plugins/Abstract/DataModels/Attributes/DataModelIgnoreAttribute.cs
@@ -0,0 +1,8 @@
+using System;
+
+namespace Artemis.Core.Plugins.Abstract.DataModels.Attributes
+{
+ public class DataModelIgnoreAttribute : Attribute
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Plugins/Abstract/DataModels/DataModel.cs b/src/Artemis.Core/Plugins/Abstract/DataModels/DataModel.cs
index f96b551da..7e72eeaec 100644
--- a/src/Artemis.Core/Plugins/Abstract/DataModels/DataModel.cs
+++ b/src/Artemis.Core/Plugins/Abstract/DataModels/DataModel.cs
@@ -1,11 +1,5 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Artemis.Core.Exceptions;
-using Artemis.Core.Plugins.Abstract.DataModels.Attributes;
-using Artemis.Core.Plugins.Exceptions;
+using Artemis.Core.Plugins.Abstract.DataModels.Attributes;
using Artemis.Core.Plugins.Models;
-using SkiaSharp;
namespace Artemis.Core.Plugins.Abstract.DataModels
{
@@ -16,54 +10,9 @@ namespace Artemis.Core.Plugins.Abstract.DataModels
///
public PluginInfo PluginInfo { get; internal set; }
- ///
- /// Gets whether this data model is initialized
- ///
- public bool Initialized { get; private set; }
-
///
/// Gets the describing this data model
///
public DataModelPropertyAttribute DataModelDescription { get; internal set; }
-
- ///
- /// If found on this type, returns the for the provided property name
- ///
- /// The name of the property on to look for
- public DataModelPropertyAttribute GetPropertyAttribute(string propertyName)
- {
- var propertyInfo = GetType().GetProperty(propertyName);
- if (propertyInfo == null)
- return null;
-
- return (DataModelPropertyAttribute) Attribute.GetCustomAttribute(propertyInfo, typeof(DataModelPropertyAttribute));
- }
-
- internal void Initialize()
- {
- // Doubt this will happen but let's make sure
- if (Initialized)
- throw new ArtemisCoreException("Data model already initialized, wut");
-
- foreach (var propertyInfo in GetType().GetProperties())
- {
- var dataModelPropertyAttribute = (DataModelPropertyAttribute) Attribute.GetCustomAttribute(propertyInfo, typeof(DataModelPropertyAttribute));
- if (dataModelPropertyAttribute == null || !typeof(DataModel).IsAssignableFrom(propertyInfo.PropertyType))
- continue;
-
- // If the property is a nested datamodel create an instance and initialize it
- var instance = (DataModel) Activator.CreateInstance(propertyInfo.PropertyType, true);
- if (instance == null)
- throw new ArtemisCoreException($"Failed to create instance of child datamodel at {propertyInfo.Name}");
-
- instance.PluginInfo = PluginInfo;
- instance.DataModelDescription = dataModelPropertyAttribute;
- instance.Initialize();
-
- propertyInfo.SetValue(this, instance);
- }
-
- Initialized = true;
- }
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/DataModelService.cs b/src/Artemis.Core/Services/DataModelService.cs
index 7719b8005..e5cdd5273 100644
--- a/src/Artemis.Core/Services/DataModelService.cs
+++ b/src/Artemis.Core/Services/DataModelService.cs
@@ -61,37 +61,26 @@ namespace Artemis.Core.Services
}
}
- public DataModelDescription GetMainDataModelDescription()
- {
- var dataModelDescription = new DataModelDescription();
-
- return dataModelDescription;
- }
-
private void PluginServiceOnPluginEnabled(object sender, PluginEventArgs e)
{
if (e.PluginInfo.Instance is Module module && module.InternalExpandsMainDataModel)
{
- if (!module.InternalDataModel.Initialized)
+ if (module.InternalDataModel.DataModelDescription == null)
{
module.InternalDataModel.DataModelDescription = module.InternalGetDataModelDescription();
if (module.InternalDataModel.DataModelDescription == null)
throw new ArtemisPluginException(module.PluginInfo, "Module overrides GetDataModelDescription but returned null");
-
- module.InternalDataModel.Initialize();
}
_dataModelExpansions.Add(module.InternalDataModel);
}
else if (e.PluginInfo.Instance is BaseDataModelExpansion dataModelExpansion)
{
- if (!dataModelExpansion.InternalDataModel.Initialized)
+ if (dataModelExpansion.InternalDataModel.DataModelDescription == null)
{
dataModelExpansion.InternalDataModel.DataModelDescription = dataModelExpansion.GetDataModelDescription();
if (dataModelExpansion.InternalDataModel.DataModelDescription == null)
throw new ArtemisPluginException(dataModelExpansion.PluginInfo, "Data model expansion overrides GetDataModelDescription but returned null");
-
- dataModelExpansion.InternalDataModel.Initialize();
}
_dataModelExpansions.Add(dataModelExpansion.InternalDataModel);
diff --git a/src/Artemis.Core/Services/Interfaces/IDataModelService.cs b/src/Artemis.Core/Services/Interfaces/IDataModelService.cs
index 91052248f..c8a1089e0 100644
--- a/src/Artemis.Core/Services/Interfaces/IDataModelService.cs
+++ b/src/Artemis.Core/Services/Interfaces/IDataModelService.cs
@@ -1,10 +1,13 @@
-using Artemis.Core.Models;
+using System.Collections.ObjectModel;
+using Artemis.Core.Models;
using Artemis.Core.Plugins.Abstract.DataModels;
namespace Artemis.Core.Services.Interfaces
{
public interface IDataModelService : IArtemisService
{
+ ReadOnlyCollection DataModelExpansions { get; }
+
///
/// Add an expansion to the datamodel to be available for use after the next update
///
@@ -16,11 +19,5 @@ namespace Artemis.Core.Services.Interfaces
///
///
void RemoveExpansion(DataModel baseDataModelExpansion);
-
- ///
- /// Generates a data model description for the main datamodel including all it's expansions
- ///
- /// The generated data model description
- DataModelDescription GetMainDataModelDescription();
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/DataModelVisualization/DataModelGroupViewModel.cs b/src/Artemis.UI/DataModelVisualization/DataModelGroupViewModel.cs
new file mode 100644
index 000000000..e313194bc
--- /dev/null
+++ b/src/Artemis.UI/DataModelVisualization/DataModelGroupViewModel.cs
@@ -0,0 +1,11 @@
+using Artemis.Core.Plugins.Abstract.DataModels.Attributes;
+using Stylet;
+
+namespace Artemis.UI.DataModelVisualization
+{
+ public abstract class DataModelVisualizationViewModel : PropertyChangedBase
+ {
+ public DataModelPropertyAttribute PropertyDescription { get; protected set; }
+ public DataModelViewModel Parent { get; protected set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/DataModelVisualization/DataModelPropertyViewModel.cs b/src/Artemis.UI/DataModelVisualization/DataModelPropertyViewModel.cs
new file mode 100644
index 000000000..8ab70d14c
--- /dev/null
+++ b/src/Artemis.UI/DataModelVisualization/DataModelPropertyViewModel.cs
@@ -0,0 +1,23 @@
+using System.Reflection;
+using Artemis.Core.Plugins.Abstract.DataModels.Attributes;
+using FastMember;
+
+namespace Artemis.UI.DataModelVisualization
+{
+ public class DataModelPropertyViewModel : DataModelVisualizationViewModel
+ {
+ private readonly ObjectAccessor _accessor;
+
+ public DataModelPropertyViewModel(PropertyInfo propertyInfo, DataModelPropertyAttribute propertyDescription, DataModelViewModel parent)
+ {
+ _accessor = ObjectAccessor.Create(parent.Model);
+
+ PropertyInfo = propertyInfo;
+ Parent = parent;
+ PropertyDescription = propertyDescription;
+ }
+
+ public PropertyInfo PropertyInfo { get; }
+ public object Value => _accessor[PropertyInfo.Name];
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/DataModelVisualization/DataModelViewModel.cs b/src/Artemis.UI/DataModelVisualization/DataModelViewModel.cs
index cc514063a..c38c4fd73 100644
--- a/src/Artemis.UI/DataModelVisualization/DataModelViewModel.cs
+++ b/src/Artemis.UI/DataModelVisualization/DataModelViewModel.cs
@@ -1,54 +1,57 @@
using System;
-using System.Linq;
-using Artemis.Core.Attributes;
-using Artemis.Core.Plugins.Abstract.DataModels;
-using Artemis.UI.Exceptions;
+using Artemis.Core.Plugins.Abstract.DataModels.Attributes;
+using Humanizer;
using Stylet;
namespace Artemis.UI.DataModelVisualization
{
- public class DataModelViewModel : PropertyChangedBase
+ public class DataModelViewModel : DataModelVisualizationViewModel
{
- public DataModelViewModel(DataModel dataModel)
+ public DataModelViewModel()
{
- if (!DataModel.Initialized)
- throw new ArtemisUIException("Cannot create view model for data model that is not yet initialized");
-
- DataModel = dataModel;
+ Children = new BindableCollection();
}
- public DataModelViewModel(DataModel parent, DataModel dataModel)
+ public DataModelViewModel(object model, DataModelPropertyAttribute propertyDescription, DataModelViewModel parent)
{
- if (!DataModel.Initialized)
- throw new ArtemisUIException("Cannot create view model for data model that is not yet initialized");
-
+ Model = model;
+ PropertyDescription = propertyDescription;
Parent = parent;
- DataModel = dataModel;
+ Children = new BindableCollection();
+
+ PopulateProperties();
}
- public DataModel DataModel { get; }
- public DataModel Parent { get; set; }
+ public object Model { get; }
+ public BindableCollection Children { get; set; }
-
- private void PopulateProperties()
+ public void PopulateProperties()
{
- foreach (var propertyInfo in DataModel.GetType().GetProperties())
+ Children.Clear();
+ foreach (var propertyInfo in Model.GetType().GetProperties())
{
- var dataModelPropertyAttribute = (DataModelPropertyAttribute) Attribute.GetCustomAttribute(propertyInfo, typeof(DataModelPropertyAttribute));
- if (dataModelPropertyAttribute == null)
+ // Skip properties decorated with DataModelIgnore
+ if (Attribute.IsDefined(propertyInfo, typeof(DataModelIgnoreAttribute)))
continue;
- // For child data models create another data model view model
- if (typeof(DataModel).IsAssignableFrom(propertyInfo.PropertyType))
+ var dataModelPropertyAttribute = (DataModelPropertyAttribute) Attribute.GetCustomAttribute(propertyInfo, typeof(DataModelPropertyAttribute));
+ // If no DataModelProperty attribute was provided, pull one out of our ass
+ if (dataModelPropertyAttribute == null)
+ dataModelPropertyAttribute = new DataModelPropertyAttribute {Name = propertyInfo.Name.Humanize()};
+
+ // For value types create a child view model if the value type is not null
+ if (propertyInfo.PropertyType.IsValueType)
{
+ var value = propertyInfo.GetValue(Model);
+ if (value == null)
+ continue;
+
+ Children.Add(new DataModelViewModel(value, dataModelPropertyAttribute, this));
}
- // For primitives, create a property view model
+ // For primitives, create a property view model, it may be null that is fine
else if (propertyInfo.PropertyType.IsPrimitive)
{
- }
- // For anything else check if it has any child primitives and if so create a property container view model
- else if (propertyInfo.PropertyType.GetProperties().Any(p => p.PropertyType.IsPrimitive))
- {
+ Children.Add(new DataModelPropertyViewModel(propertyInfo, dataModelPropertyAttribute, this));
}
}
}
diff --git a/src/Artemis.UI/Services/DataModelVisualizationService.cs b/src/Artemis.UI/Services/DataModelVisualizationService.cs
new file mode 100644
index 000000000..703a98505
--- /dev/null
+++ b/src/Artemis.UI/Services/DataModelVisualizationService.cs
@@ -0,0 +1,30 @@
+using Artemis.Core.Services.Interfaces;
+using Artemis.UI.DataModelVisualization;
+using Artemis.UI.Services.Interfaces;
+
+namespace Artemis.UI.Services
+{
+ public class DataModelVisualizationService : IDataModelVisualizationService
+ {
+ private readonly IDataModelService _dataModelService;
+
+ public DataModelVisualizationService(IDataModelService dataModelService)
+ {
+ _dataModelService = dataModelService;
+ }
+
+ public DataModelViewModel GetMainDataModelVisualization()
+ {
+ var viewModel = new DataModelViewModel();
+ foreach (var dataModelExpansion in _dataModelService.DataModelExpansions)
+ viewModel.Children.Add(new DataModelViewModel(dataModelExpansion, dataModelExpansion.DataModelDescription, viewModel));
+
+ return viewModel;
+ }
+ }
+
+ public interface IDataModelVisualizationService : IArtemisUIService
+ {
+ public DataModelViewModel GetMainDataModelVisualization();
+ }
+}
\ No newline at end of file