mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-11 11:26:27 +00:00
Core - Fix data model and event condition bugs found by the tests (#910)
* Core - Fix removing dynamic children and checking which properties are in use - DataModel.RemoveDynamicChild compared the value of each child with the child that was passed in, so it never removed anything. - IsPropertyInUse with includeChildren matched paths by their start, so a path to "Integers" made "Integer" count as in use. Children are now matched on what follows a dot. * Core - Fix data model paths around saving, removed children and stored types - The constructors saved the path before setting it up, while it was still invalid, so a new path stored nothing and didn't follow its data model leaving and returning to the store until it was saved. - Removing the dynamic child a path points to left the path valid and reading a default value, it now becomes invalid like when the child was never there. - The stored type of a path is now also looked up in all loaded assemblies, Type.GetType only found it in Artemis.Core and the .NET libraries, not in plugins or SkiaSharp. * Core - Only let event conditions react to what happens after they start watching - A trigger from before the condition watched its event, for example long before the profile was activated, counted as new and played the element once. Triggers now count from the moment the condition starts watching its path. - A condition on a plain value treated the first value it saw as a change and played the element on the first frame. The first value is now taken as the starting value.
This commit is contained in:
1 parent
a25d0f0c9c
commit
6df81b19b1
7 files changed
+108
-50
No files matched your search
@@ -17,8 +17,10 @@ public class EventCondition : CorePropertyChanged, INodeScriptCondition
|
||||
private NodeScript<bool> _script;
|
||||
private DefaultNode _startNode;
|
||||
private DataModelPath? _eventPath;
|
||||
private DateTime _lastProcessedTrigger;
|
||||
// Only what happens after the condition starts watching its path counts, see StartWatching
|
||||
private DateTime _lastProcessedTrigger = DateTime.Now;
|
||||
private object? _lastProcessedValue;
|
||||
private bool _hasProcessedValue;
|
||||
private EventOverlapMode _overlapMode;
|
||||
private EventToggleOffMode _toggleOffMode;
|
||||
private EventTriggerMode _triggerMode;
|
||||
@@ -64,7 +66,11 @@ public class EventCondition : CorePropertyChanged, INodeScriptCondition
|
||||
public DataModelPath? EventPath
|
||||
{
|
||||
get => _eventPath;
|
||||
set => SetAndNotify(ref _eventPath, value);
|
||||
set
|
||||
{
|
||||
if (SetAndNotify(ref _eventPath, value))
|
||||
StartWatching();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -243,6 +249,15 @@ public class EventCondition : CorePropertyChanged, INodeScriptCondition
|
||||
Script.AddNode(newStartNode);
|
||||
}
|
||||
|
||||
private void StartWatching()
|
||||
{
|
||||
// Triggers and values from before the condition watched the path don't count, otherwise for example an event that
|
||||
// triggered long before the profile was activated would still play the element once
|
||||
_lastProcessedTrigger = DateTime.Now;
|
||||
_lastProcessedValue = null;
|
||||
_hasProcessedValue = false;
|
||||
}
|
||||
|
||||
private bool Evaluate()
|
||||
{
|
||||
if (EventPath == null)
|
||||
@@ -258,6 +273,14 @@ public class EventCondition : CorePropertyChanged, INodeScriptCondition
|
||||
}
|
||||
else if (_startNode is EventConditionValueChangedStartNode valueChangedNode)
|
||||
{
|
||||
// The first value seen is where the value starts, not a change
|
||||
if (!_hasProcessedValue)
|
||||
{
|
||||
_lastProcessedValue = value;
|
||||
_hasProcessedValue = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Equals(value, _lastProcessedValue))
|
||||
return false;
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@ public class DataModelPath : IStorageModel, IDisposable, IPluginFeatureDependent
|
||||
|
||||
_segments = [];
|
||||
|
||||
Save();
|
||||
Initialize();
|
||||
Save();
|
||||
SubscribeToDataModelStore();
|
||||
}
|
||||
|
||||
@@ -47,8 +47,8 @@ public class DataModelPath : IStorageModel, IDisposable, IPluginFeatureDependent
|
||||
|
||||
_segments = [];
|
||||
|
||||
Save();
|
||||
Initialize();
|
||||
Save();
|
||||
SubscribeToDataModelStore();
|
||||
}
|
||||
|
||||
@@ -67,8 +67,8 @@ public class DataModelPath : IStorageModel, IDisposable, IPluginFeatureDependent
|
||||
|
||||
_segments = [];
|
||||
|
||||
Save();
|
||||
Initialize();
|
||||
Save();
|
||||
SubscribeToDataModelStore();
|
||||
}
|
||||
|
||||
@@ -165,11 +165,20 @@ public class DataModelPath : IStorageModel, IDisposable, IPluginFeatureDependent
|
||||
|
||||
// Fall back to stored type
|
||||
if (!string.IsNullOrWhiteSpace(Entity.Type))
|
||||
return Type.GetType(Entity.Type);
|
||||
return FindType(Entity.Type);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Type? FindType(string fullName)
|
||||
{
|
||||
// The type is stored without its assembly, Type.GetType only finds it in Artemis.Core and the .NET libraries. Types
|
||||
// of plugins and other libraries (like SKColor) are found by looking through the loaded assemblies
|
||||
return Type.GetType(fullName) ?? AppDomain.CurrentDomain.GetAssemblies()
|
||||
.Select(assembly => assembly.GetType(fullName))
|
||||
.FirstOrDefault(type => type != null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the property description of the property this path points to
|
||||
/// </summary>
|
||||
|
||||
@@ -286,8 +286,16 @@ public class DataModelPathSegment : IDisposable
|
||||
|
||||
private void DynamicChildOnDynamicChildRemoved(object? sender, DynamicDataModelChildEventArgs e)
|
||||
{
|
||||
if (e.DynamicChild.BaseValue == _dynamicDataModel)
|
||||
// Like when a child is added, initialize the path again so it no longer points to the removed child
|
||||
if (e.Key == Identifier)
|
||||
{
|
||||
DataModelPath.Invalidate();
|
||||
DataModelPath.Initialize();
|
||||
}
|
||||
else if (e.DynamicChild.BaseValue == _dynamicDataModel)
|
||||
{
|
||||
DataModelPath.Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
Reference in new issue
Block a user