Nodes - Implemented saving/loading

Nodes - Added data model node
This commit is contained in:
Robert committed 2021-08-10 16:52:24 +02:00
1 parent 61d7f1e1fb
commit afc4bee7ac
29 files changed
+730 -157

No files matched your search

@@ -72,7 +72,12 @@ namespace Artemis.Core
SubscribeToDataModelStore();
}
internal DataModelPath(DataModel? target, DataModelPathEntity entity)
/// <summary>
/// Creates a new instance of the <see cref="DataModelPath" /> class based on a <see cref="DataModelPathEntity" />
/// </summary>
/// <param name="target"></param>
/// <param name="entity"></param>
public DataModelPath(DataModel? target, DataModelPathEntity entity)
{
Target = target;
Path = entity.Path;
@@ -110,7 +115,10 @@ namespace Artemis.Core
/// </summary>
public IReadOnlyCollection<DataModelPathSegment> Segments => _segments.ToList().AsReadOnly();
internal DataModelPathEntity Entity { get; }
/// <summary>
/// Gets the entity used for persistent storage
/// </summary>
public DataModelPathEntity Entity { get; }
internal Func<object, object>? Accessor { get; private set; }
@@ -173,6 +181,52 @@ namespace Artemis.Core
return string.IsNullOrWhiteSpace(Path) ? "this" : Path;
}
/// <summary>
/// Occurs whenever the path becomes invalid
/// </summary>
public event EventHandler? PathInvalidated;
/// <summary>
/// Occurs whenever the path becomes valid
/// </summary>
public event EventHandler? PathValidated;
/// <summary>
/// Releases the unmanaged resources used by the object and optionally releases the managed resources.
/// </summary>
/// <param name="disposing">
/// <see langword="true" /> to release both managed and unmanaged resources;
/// <see langword="false" /> to release only unmanaged resources.
/// </param>
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_disposed = true;
DataModelStore.DataModelAdded -= DataModelStoreOnDataModelAdded;
DataModelStore.DataModelRemoved -= DataModelStoreOnDataModelRemoved;
Invalidate();
}
}
/// <summary>
/// Invokes the <see cref="PathInvalidated" /> event
/// </summary>
protected virtual void OnPathValidated()
{
PathValidated?.Invoke(this, EventArgs.Empty);
}
/// <summary>
/// Invokes the <see cref="PathValidated" /> event
/// </summary>
protected virtual void OnPathInvalidated()
{
PathInvalidated?.Invoke(this, EventArgs.Empty);
}
internal void Invalidate()
{
Target?.RemoveDataModelPath(this);
@@ -262,27 +316,24 @@ namespace Artemis.Core
DataModelStore.DataModelAdded += DataModelStoreOnDataModelAdded;
DataModelStore.DataModelRemoved += DataModelStoreOnDataModelRemoved;
}
#region IDisposable
/// <summary>
/// Releases the unmanaged resources used by the object and optionally releases the managed resources.
/// </summary>
/// <param name="disposing">
/// <see langword="true" /> to release both managed and unmanaged resources;
/// <see langword="false" /> to release only unmanaged resources.
/// </param>
protected virtual void Dispose(bool disposing)
private void DataModelStoreOnDataModelAdded(object? sender, DataModelStoreEvent e)
{
if (disposing)
{
_disposed = true;
if (e.Registration.DataModel.Module.Id != Entity.DataModelId)
return;
DataModelStore.DataModelAdded -= DataModelStoreOnDataModelAdded;
DataModelStore.DataModelRemoved -= DataModelStoreOnDataModelRemoved;
Invalidate();
Target = e.Registration.DataModel;
Initialize();
}
Invalidate();
}
private void DataModelStoreOnDataModelRemoved(object? sender, DataModelStoreEvent e)
{
if (e.Registration.DataModel.Module.Id != Entity.DataModelId)
return;
Invalidate();
Target = null;
}
/// <inheritdoc />
@@ -292,8 +343,6 @@ namespace Artemis.Core
GC.SuppressFinalize(this);
}
#endregion
#region Storage
/// <inheritdoc />
@@ -324,58 +373,5 @@ namespace Artemis.Core
}
#endregion
#region Event handlers
private void DataModelStoreOnDataModelAdded(object? sender, DataModelStoreEvent e)
{
if (e.Registration.DataModel.Module.Id != Entity.DataModelId)
return;
Invalidate();
Target = e.Registration.DataModel;
Initialize();
}
private void DataModelStoreOnDataModelRemoved(object? sender, DataModelStoreEvent e)
{
if (e.Registration.DataModel.Module.Id != Entity.DataModelId)
return;
Invalidate();
Target = null;
}
#endregion
#region Events
/// <summary>
/// Occurs whenever the path becomes invalid
/// </summary>
public event EventHandler? PathInvalidated;
/// <summary>
/// Occurs whenever the path becomes valid
/// </summary>
public event EventHandler? PathValidated;
/// <summary>
/// Invokes the <see cref="PathInvalidated" /> event
/// </summary>
protected virtual void OnPathValidated()
{
PathValidated?.Invoke(this, EventArgs.Empty);
}
/// <summary>
/// Invokes the <see cref="PathValidated" /> event
/// </summary>
protected virtual void OnPathInvalidated()
{
PathInvalidated?.Invoke(this, EventArgs.Empty);
}
#endregion
}
}
@@ -7,6 +7,7 @@ using Artemis.Core.LayerEffects.Placeholder;
using Artemis.Core.Properties;
using Artemis.Storage.Entities.Profile;
using Artemis.Storage.Entities.Profile.Abstract;
using Newtonsoft.Json;
using SkiaSharp;
namespace Artemis.Core
@@ -66,6 +67,8 @@ namespace Artemis.Core
internal void LoadRenderElement()
{
DisplayCondition = RenderElementEntity.NodeScript != null ? new NodeScript<bool>(RenderElementEntity.NodeScript) : null;
// DisplayCondition = RenderElementEntity.DisplayCondition != null
// ? new DataModelConditionGroup(null, RenderElementEntity.DisplayCondition)
// : new DataModelConditionGroup(null);
@@ -97,6 +100,8 @@ namespace Artemis.Core
}
// Conditions
DisplayCondition?.Save();
RenderElementEntity.NodeScript = DisplayCondition?.Entity;
// RenderElementEntity.DisplayCondition = DisplayCondition?.Entity;
// DisplayCondition?.Save();
@@ -126,7 +131,7 @@ namespace Artemis.Core
// The play mode dictates whether to stick to the main segment unless the display conditions contains events
bool stickToMainSegment = (Timeline.PlayMode == TimelinePlayMode.Repeat || Timeline.EventOverlapMode == TimeLineEventOverlapMode.Toggle) && DisplayConditionMet;
// if (DisplayCondition != null && DisplayCondition.ContainsEvents && Timeline.EventOverlapMode != TimeLineEventOverlapMode.Toggle)
// stickToMainSegment = false;
// stickToMainSegment = false;
Timeline.Update(TimeSpan.FromSeconds(deltaTime), stickToMainSegment);
}
@@ -386,50 +391,51 @@ namespace Artemis.Core
if (Timeline.EventOverlapMode != TimeLineEventOverlapMode.Toggle)
_toggledOnByEvent = false;
DisplayCondition.Run();
bool conditionMet = DisplayCondition.Result;
// TODO: Handle this nicely, right now when there's only an exit node we assume true
bool conditionMet = DisplayCondition.Nodes.Count() == 1 || DisplayCondition.Result;
if (Parent is RenderProfileElement parent && !parent.DisplayConditionMet)
conditionMet = false;
// if (!DisplayCondition.ContainsEvents)
// {
// // Regular conditions reset the timeline whenever their condition is met and was not met before that
// if (conditionMet && !DisplayConditionMet && Timeline.IsFinished)
// Timeline.JumpToStart();
// // If regular conditions are no longer met, jump to the end segment if stop mode requires it
// if (!conditionMet && Timeline.StopMode == TimelineStopMode.SkipToEnd)
// Timeline.JumpToEndSegment();
// }
// else if (conditionMet)
if (conditionMet)
{
if (Timeline.EventOverlapMode == TimeLineEventOverlapMode.Toggle)
{
_toggledOnByEvent = !_toggledOnByEvent;
if (_toggledOnByEvent)
Timeline.JumpToStart();
}
else
{
// Event conditions reset if the timeline finished
if (Timeline.IsFinished)
{
Timeline.JumpToStart();
}
// and otherwise apply their overlap mode
else
{
if (Timeline.EventOverlapMode == TimeLineEventOverlapMode.Restart)
Timeline.JumpToStart();
else if (Timeline.EventOverlapMode == TimeLineEventOverlapMode.Copy)
Timeline.AddExtraTimeline();
// The third option is ignore which is handled below:
// done
}
}
// Regular conditions reset the timeline whenever their condition is met and was not met before that
if (conditionMet && !DisplayConditionMet && Timeline.IsFinished)
Timeline.JumpToStart();
// If regular conditions are no longer met, jump to the end segment if stop mode requires it
if (!conditionMet && Timeline.StopMode == TimelineStopMode.SkipToEnd)
Timeline.JumpToEndSegment();
}
// else if (conditionMet)
// {
// if (Timeline.EventOverlapMode == TimeLineEventOverlapMode.Toggle)
// {
// _toggledOnByEvent = !_toggledOnByEvent;
// if (_toggledOnByEvent)
// Timeline.JumpToStart();
// }
// else
// {
// // Event conditions reset if the timeline finished
// if (Timeline.IsFinished)
// {
// Timeline.JumpToStart();
// }
// // and otherwise apply their overlap mode
// else
// {
// if (Timeline.EventOverlapMode == TimeLineEventOverlapMode.Restart)
// Timeline.JumpToStart();
// else if (Timeline.EventOverlapMode == TimeLineEventOverlapMode.Copy)
// Timeline.AddExtraTimeline();
// // The third option is ignore which is handled below:
//
// // done
// }
// }
// }
DisplayConditionMet = Timeline.EventOverlapMode == TimeLineEventOverlapMode.Toggle
? _toggledOnByEvent