Datamodel - WIP stuff, need this on a diff. PC

This commit is contained in:
SpoinkyNL committed 2020-06-23 22:49:27 +02:00
1 parent 920aea6695
commit 2b7a507725
23 files changed
+392 -161

No files matched your search

@@ -0,0 +1,40 @@
using Artemis.Core.Plugins.Abstract.DataModels;
using Artemis.Core.Plugins.Abstract.DataModels.Attributes;
namespace Artemis.Core.Plugins.Abstract
{
/// <summary>
/// Allows you to expand the application-wide datamodel
/// </summary>
public abstract class BaseDataModelExpansion<T> : BaseDataModelExpansion where T : DataModel
{
/// <summary>
/// The data model driving this module
/// </summary>
public T DataModel
{
get => (T) InternalDataModel;
internal set => InternalDataModel = value;
}
}
/// <summary>
/// For internal use only, to implement your own layer property type, extend <see cref="BaseDataModelExpansion{T}" />
/// instead.
/// </summary>
public abstract class BaseDataModelExpansion : Plugin
{
internal DataModel InternalDataModel { get; set; }
public abstract void Update(double deltaTime);
/// <summary>
/// Override to provide your own data model description. By default this returns a description matching your plugin
/// name and description
/// </summary>
/// <returns></returns>
public virtual DataModelPropertyAttribute GetDataModelDescription()
{
return new DataModelPropertyAttribute {Name = PluginInfo.Name, Description = PluginInfo.Description};
}
}
}
@@ -1,11 +0,0 @@
namespace Artemis.Core.Plugins.Abstract
{
/// <inheritdoc />
/// <summary>
/// Allows you to expand the application-wide datamodel
/// </summary>
public abstract class DataModelExpansion : Plugin
{
public abstract void Update(double deltaTime);
}
}
@@ -1,8 +1,10 @@
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.Models;
using SkiaSharp;
namespace Artemis.Core.Plugins.Abstract.DataModels
@@ -23,39 +25,63 @@ namespace Artemis.Core.Plugins.Abstract.DataModels
typeof(SKPoint)
};
protected DataModel(Module module)
{
Module = module;
Validate();
}
public Module Module { get; }
/// <summary>
/// Gets the plugin info this data model belongs to
/// </summary>
public PluginInfo PluginInfo { get; internal set; }
/// <summary>
/// Recursively validates the current datamodel, ensuring all properties annotated with
/// <see cref="DataModelPropertyAttribute" /> are of supported types.
/// Gets whether this data model is initialized
/// </summary>
/// <returns></returns>
public bool Validate()
public bool Initialized { get; private set; }
/// <summary>
/// Gets the <see cref="DataModelPropertyAttribute" /> describing this data model
/// </summary>
public DataModelPropertyAttribute DataModelDescription { get; internal set; }
/// <summary>
/// If found on this type, returns the <see cref="DataModelPropertyAttribute" /> for the provided property name
/// </summary>
/// <param name="propertyName">The name of the property on to look for</param>
public DataModelPropertyAttribute GetPropertyAttribute(string propertyName)
{
return ValidateType(GetType());
var propertyInfo = GetType().GetProperty(propertyName);
if (propertyInfo == null)
return null;
return (DataModelPropertyAttribute) Attribute.GetCustomAttribute(propertyInfo, typeof(DataModelPropertyAttribute));
}
private bool ValidateType(Type type)
internal void Initialize()
{
foreach (var propertyInfo in type.GetProperties())
// 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)
continue;
// If the a nested datamodel, ensure the properties on there are valid
// If the a nested datamodel create an instance and initialize it
if (typeof(DataModel).IsAssignableFrom(propertyInfo.PropertyType))
ValidateType(propertyInfo.PropertyType);
{
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);
}
else if (!SupportedTypes.Contains(propertyInfo.PropertyType))
{
// Show a useful error for plugin devs
throw new ArtemisPluginException(Module.PluginInfo,
throw new ArtemisPluginException(PluginInfo,
$"Plugin datamodel contains property of unsupported type {propertyInfo.PropertyType.Name}. \r\n\r\n" +
$"Property name: {propertyInfo.Name}\r\n" +
$"Property declared on: {propertyInfo.DeclaringType?.Name ?? "-"} \r\n\r\n" +
@@ -63,7 +89,7 @@ namespace Artemis.Core.Plugins.Abstract.DataModels
}
}
return true;
Initialized = true;
}
}
}
+54 -12
View File
@@ -1,17 +1,65 @@
using System.Collections.Generic;
using Artemis.Core.Models.Surface;
using Artemis.Core.Plugins.Abstract.DataModels;
using Artemis.Core.Plugins.Abstract.DataModels.Attributes;
using Artemis.Core.Plugins.Abstract.ViewModels;
using SkiaSharp;
namespace Artemis.Core.Plugins.Abstract
{
/// <inheritdoc />
/// <summary>
/// Allows you to add support for new games/applications while utilizing your own data model
/// </summary>
public abstract class Module<T> : Module where T : DataModel
{
/// <summary>
/// The data model driving this module
/// </summary>
public T DataModel
{
get => (T) InternalDataModel;
internal set => InternalDataModel = value;
}
/// <summary>
/// Gets or sets whether this module must also expand the main data model
/// <para>
/// Note: If expanding the main data model is all you want your plugin to do, create a
/// <see cref="BaseDataModelExpansion" /> plugin instead.
/// </para>
/// </summary>
public bool ExpandsDataModel
{
get => InternalExpandsMainDataModel;
set => InternalExpandsMainDataModel = value;
}
/// <summary>
/// Override to provide your own data model description. By default this returns a description matching your plugin
/// name and description
/// </summary>
/// <returns></returns>
public virtual DataModelPropertyAttribute GetDataModelDescription()
{
return new DataModelPropertyAttribute {Name = PluginInfo.Name, Description = PluginInfo.Description};
}
internal override DataModelPropertyAttribute InternalGetDataModelDescription()
{
return GetDataModelDescription();
}
}
/// <summary>
/// Allows you to add support for new games/applications
/// </summary>
public abstract class Module : Plugin
{
internal DataModel InternalDataModel { get; set; }
internal bool InternalExpandsMainDataModel { get; set; }
/// <summary>
/// The modules display name that's shown in the menu
/// </summary>
@@ -23,17 +71,6 @@ namespace Artemis.Core.Plugins.Abstract
/// </summary>
public string DisplayIcon { get; set; }
/// <summary>
/// The optional datamodel driving this module
/// </summary>
public DataModel DataModel { get; set; }
/// <summary>
/// Whether or not this module expands upon the main data model. If set to true any data in main data model can be
/// accessed by profiles in this module
/// </summary>
public bool ExpandsMainDataModel { get; protected set; }
/// <summary>
/// Called each frame when the module must update
/// </summary>
@@ -54,5 +91,10 @@ namespace Artemis.Core.Plugins.Abstract
/// </summary>
/// <returns></returns>
public abstract IEnumerable<ModuleViewModel> GetViewModels();
internal virtual DataModelPropertyAttribute InternalGetDataModelDescription()
{
return null;
}
}
}
@@ -4,7 +4,6 @@ using Artemis.Core.Plugins.Models;
namespace Artemis.Core.Plugins.Abstract
{
/// <inheritdoc />
/// <summary>
/// This is the base plugin type, use the other interfaces such as Module to create plugins
/// </summary>
@@ -2,10 +2,58 @@
using Artemis.Core.Exceptions;
using Artemis.Core.Models.Profile;
using Artemis.Core.Models.Surface;
using Artemis.Core.Plugins.Abstract.DataModels;
using Artemis.Core.Plugins.Abstract.DataModels.Attributes;
using SkiaSharp;
namespace Artemis.Core.Plugins.Abstract
{
/// <summary>
/// Allows you to add support for new games/applications while utilizing Artemis' profile engine and your own data model
/// </summary>
public abstract class ProfileModule<T> : ProfileModule where T : DataModel
{
/// <summary>
/// The data model driving this module
/// </summary>
public T DataModel
{
get => (T)InternalDataModel;
internal set => InternalDataModel = value;
}
/// <summary>
/// Gets or sets whether this module must also expand the main data model
/// <para>
/// Note: If expanding the main data model is all you want your plugin to do, create a
/// <see cref="BaseDataModelExpansion" /> plugin instead.
/// </para>
/// </summary>
public bool ExpandsDataModel
{
get => InternalExpandsMainDataModel;
set => InternalExpandsMainDataModel = value;
}
/// <summary>
/// Override to provide your own data model description. By default this returns a description matching your plugin
/// name and description
/// </summary>
/// <returns></returns>
public virtual DataModelPropertyAttribute GetDataModelDescription()
{
return new DataModelPropertyAttribute { Name = PluginInfo.Name, Description = PluginInfo.Description };
}
internal override DataModelPropertyAttribute InternalGetDataModelDescription()
{
return GetDataModelDescription();
}
}
/// <summary>
/// Allows you to add support for new games/applications while utilizing Artemis' profile engine
/// </summary>
public abstract class ProfileModule : Module
{
public Profile ActiveProfile { get; private set; }