Profiles - Finished moving and improving timeline logic

This commit is contained in:
Robert committed 2020-10-29 19:49:24 +01:00
1 parent 4ede3876d4
commit 458fd2a704
20 files changed
+351 -245

No files matched your search

@@ -137,16 +137,18 @@ namespace Artemis.Core
/// <summary>
/// Updates the smoothing progress of the data binding
/// </summary>
/// <param name="deltaTime">The time in seconds that passed since the last update</param>
public void Update(double deltaTime)
/// <param name="timeline">The timeline to apply during update</param>
public void Update(Timeline timeline)
{
if (_disposed)
throw new ObjectDisposedException("DataBinding");
// Data bindings cannot go back in time like brushes
deltaTime = Math.Max(0, deltaTime);
TimeSpan deltaTime = timeline.LastDelta;
if (deltaTime < TimeSpan.Zero)
deltaTime = TimeSpan.Zero;
_easingProgress = _easingProgress.Add(TimeSpan.FromSeconds(deltaTime));
_easingProgress = _easingProgress.Add(deltaTime);
if (_easingProgress > EasingTime)
_easingProgress = EasingTime;
}
+34 -29
View File
@@ -34,14 +34,12 @@ namespace Artemis.Core
_layerEffects = new List<BaseLayerEffect>();
_expandedPropertyGroups = new List<string>();
ApplyRenderElementDefaults();
Parent.AddChild(this);
}
internal Folder(Profile profile, ProfileElement parent, FolderEntity folderEntity)
{
FolderEntity = folderEntity;
EntityId = folderEntity.Id;
Profile = profile;
@@ -52,11 +50,21 @@ namespace Artemis.Core
_layerEffects = new List<BaseLayerEffect>();
_expandedPropertyGroups = new List<string>();
Load();
UpdateChildrenTimelineLength();
}
/// <summary>
/// Gets a boolean indicating whether this folder is at the root of the profile tree
/// </summary>
public bool IsRootFolder => Parent == Profile;
/// <summary>
/// Gets the longest timeline of all this folders children
/// </summary>
public Timeline LongestChildTimeline { get; private set; }
internal FolderEntity FolderEntity { get; set; }
internal override RenderElementEntity RenderElementEntity => FolderEntity;
@@ -80,11 +88,8 @@ namespace Artemis.Core
if (!Enabled)
return;
// Ensure the layer must still be displayed
UpdateDisplayCondition();
// Update the layer timeline
UpdateTimeLines(deltaTime);
UpdateTimeline(deltaTime);
foreach (ProfileElement child in Children)
child.Update(deltaTime);
@@ -94,8 +99,7 @@ namespace Artemis.Core
public override void Reset()
{
DisplayConditionMet = false;
TimeLine = TimelineLength;
ExtraTimeLines.Clear();
Timeline.JumpToStart();
foreach (ProfileElement child in Children)
child.Reset();
@@ -108,7 +112,7 @@ namespace Artemis.Core
throw new ObjectDisposedException("Folder");
base.AddChild(child, order);
UpdateTimeLineLength();
UpdateChildrenTimelineLength();
CalculateRenderProperties();
}
@@ -119,7 +123,7 @@ namespace Artemis.Core
throw new ObjectDisposedException("Folder");
base.RemoveChild(child);
UpdateTimeLineLength();
UpdateChildrenTimelineLength();
CalculateRenderProperties();
}
@@ -147,14 +151,21 @@ namespace Artemis.Core
OnRenderPropertiesUpdated();
}
protected internal override void UpdateTimeLineLength()
private void UpdateChildrenTimelineLength()
{
TimelineLength = !Children.Any() ? TimeSpan.Zero : Children.OfType<RenderProfileElement>().Max(c => c.TimelineLength);
if (StartSegmentLength + MainSegmentLength + EndSegmentLength > TimelineLength)
TimelineLength = StartSegmentLength + MainSegmentLength + EndSegmentLength;
Timeline longest = new Timeline() {MainSegmentLength = TimeSpan.Zero};
foreach (ProfileElement profileElement in Children)
{
if (profileElement is Folder folder && folder.LongestChildTimeline.Length > longest.Length)
longest = folder.LongestChildTimeline;
else if (profileElement is Layer layer &&
layer.Timeline.PlayMode == TimelinePlayMode.Once &&
layer.Timeline.StopMode == TimelineStopMode.Finish &&
layer.Timeline.Length > longest.Length)
longest = layer.Timeline;
}
if (Parent is RenderProfileElement parent)
parent.UpdateTimeLineLength();
LongestChildTimeline = longest;
}
protected override void Dispose(bool disposing)
@@ -208,8 +219,6 @@ namespace Artemis.Core
#region Rendering
private TimeSpan _lastRenderTime;
public override void Render(SKCanvas canvas, SKImageInfo canvasInfo)
{
if (Disposed)
@@ -222,28 +231,24 @@ namespace Artemis.Core
if (Path == null)
return;
RenderFolder(TimeLine, canvas, canvasInfo);
RenderFolder(Timeline, canvas, canvasInfo);
}
private void PrepareForRender(TimeSpan timeLine)
private void PrepareForRender(Timeline timeline)
{
double renderDelta = (timeLine - _lastRenderTime).TotalSeconds;
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled))
{
baseLayerEffect.BaseProperties?.Update(timeLine, renderDelta);
baseLayerEffect.Update(renderDelta);
baseLayerEffect.BaseProperties?.Update(timeline);
baseLayerEffect.Update(timeline.LastDelta.TotalSeconds);
}
_lastRenderTime = timeLine;
}
private void RenderFolder(TimeSpan timeLine, SKCanvas canvas, SKImageInfo canvasInfo)
private void RenderFolder(Timeline timeline, SKCanvas canvas, SKImageInfo canvasInfo)
{
if (timeLine > TimelineLength)
if (Timeline.IsFinished && LongestChildTimeline.IsFinished)
return;
PrepareForRender(timeLine);
PrepareForRender(timeline);
if (_folderBitmap == null)
{
+21 -36
View File
@@ -45,14 +45,14 @@ namespace Artemis.Core
_expandedPropertyGroups = new List<string>();
Initialize();
ApplyRenderElementDefaults();
Parent.AddChild(this);
}
internal Layer(Profile profile, ProfileElement parent, LayerEntity layerEntity)
{
LayerEntity = layerEntity;
EntityId = layerEntity.Id;
Profile = profile;
Parent = parent;
General = new LayerGeneralProperties();
@@ -176,14 +176,6 @@ namespace Artemis.Core
ActivateLayerBrush();
}
/// <inheritdoc />
public override void Reset()
{
DisplayConditionMet = false;
TimeLine = TimelineLength;
ExtraTimeLines.Clear();
}
#region Storage
internal override void Load()
@@ -258,9 +250,7 @@ namespace Artemis.Core
#endregion
#region Rendering
private TimeSpan _lastRenderTime;
/// <inheritdoc />
public override void Update(double deltaTime)
{
@@ -270,16 +260,15 @@ namespace Artemis.Core
if (!Enabled)
return;
// Ensure the layer must still be displayed
UpdateDisplayCondition();
// Update the layer timeline
UpdateTimeLines(deltaTime);
UpdateTimeline(deltaTime);
}
protected internal override void UpdateTimeLineLength()
/// <inheritdoc />
public override void Reset()
{
TimelineLength = StartSegmentLength + MainSegmentLength + EndSegmentLength;
DisplayConditionMet = false;
Timeline.JumpToStart();
}
/// <inheritdoc />
@@ -298,35 +287,31 @@ namespace Artemis.Core
if (LayerBrush?.BaseProperties?.PropertiesInitialized == false || LayerBrush?.BrushType != LayerBrushType.Regular)
return;
RenderLayer(TimeLine, canvas);
foreach (TimeSpan extraTimeLine in ExtraTimeLines)
RenderLayer(extraTimeLine, canvas);
RenderLayer(Timeline, canvas);
foreach (Timeline extraTimeline in Timeline.ExtraTimelines)
RenderLayer(extraTimeline, canvas);
}
private void PrepareForRender(TimeSpan renderTime)
private void PrepareForRender(Timeline timeline)
{
double renderDelta = (renderTime - _lastRenderTime).TotalSeconds;
General.Update(renderTime, renderDelta);
Transform.Update(renderTime, renderDelta);
LayerBrush.BaseProperties?.Update(renderTime, renderDelta);
LayerBrush.Update(renderDelta);
General.Update(timeline);
Transform.Update(timeline);
LayerBrush.BaseProperties?.Update(timeline);
LayerBrush.Update(timeline.LastDelta.TotalSeconds);
foreach (BaseLayerEffect baseLayerEffect in LayerEffects.Where(e => e.Enabled))
{
baseLayerEffect.BaseProperties?.Update(renderTime, renderDelta);
baseLayerEffect.Update(renderDelta);
baseLayerEffect.BaseProperties?.Update(timeline);
baseLayerEffect.Update(timeline.LastDelta.TotalSeconds);
}
_lastRenderTime = renderTime;
}
private void RenderLayer(TimeSpan timeLine, SKCanvas canvas)
private void RenderLayer(Timeline timeline, SKCanvas canvas)
{
if (timeLine > TimelineLength)
if (timeline.IsFinished)
return;
PrepareForRender(timeLine);
PrepareForRender(timeline);
if (_layerBitmap == null)
{
@@ -40,8 +40,7 @@ namespace Artemis.Core
/// <summary>
/// Updates the layer properties internal state
/// </summary>
/// <param name="renderTime">The current position in the timeline</param>
/// <param name="deltaTime">The position difference since last update</param>
void Update(TimeSpan renderTime, double deltaTime);
/// <param name="timeline">The timeline to apply to the property</param>
void Update(Timeline timeline);
}
}
@@ -34,20 +34,18 @@ namespace Artemis.Core
/// <inheritdoc />
public string Path { get; private set; }
/// <summary>
/// Updates the property, applying keyframes and data bindings to the current value
/// </summary>
public void Update(TimeSpan time, double deltaTime)
/// <inheritdoc />
public void Update(Timeline timeline)
{
if (_disposed)
throw new ObjectDisposedException("LayerProperty");
CurrentValue = BaseValue;
if (ProfileElement.ApplyKeyframesEnabled)
UpdateKeyframes(time);
UpdateKeyframes(timeline);
if (ProfileElement.ApplyDataBindingsEnabled)
UpdateDataBindings(deltaTime);
UpdateDataBindings(timeline);
OnUpdated();
}
@@ -125,8 +123,7 @@ namespace Artemis.Core
return;
_baseValue = value;
Update(ProfileElement.TimeLine, 0);
OnCurrentValueSet();
ReapplyUpdate();
}
}
@@ -169,8 +166,7 @@ namespace Artemis.Core
// Force an update so that the base value is applied to the current value and
// keyframes/data bindings are applied using the new base value
Update(ProfileElement.TimeLine, 0);
OnCurrentValueSet();
ReapplyUpdate();
}
/// <summary>
@@ -185,6 +181,13 @@ namespace Artemis.Core
CurrentValue = DefaultValue;
}
private void ReapplyUpdate()
{
ProfileElement.Timeline.ClearDelta();
Update(ProfileElement.Timeline);
OnCurrentValueSet();
}
#endregion
#region Keyframes
@@ -294,13 +297,13 @@ namespace Artemis.Core
_keyframes = _keyframes.OrderBy(k => k.Position).ToList();
}
private void UpdateKeyframes(TimeSpan time)
private void UpdateKeyframes(Timeline timeline)
{
if (!KeyframesSupported || !KeyframesEnabled)
return;
// The current keyframe is the last keyframe before the current time
CurrentKeyframe = _keyframes.LastOrDefault(k => k.Position <= time);
CurrentKeyframe = _keyframes.LastOrDefault(k => k.Position <= timeline.Position);
// Keyframes are sorted by position so we can safely assume the next keyframe's position is after the current
int nextIndex = _keyframes.IndexOf(CurrentKeyframe) + 1;
NextKeyframe = _keyframes.Count > nextIndex ? _keyframes[nextIndex] : null;
@@ -314,7 +317,7 @@ namespace Artemis.Core
else
{
TimeSpan timeDiff = NextKeyframe.Position - CurrentKeyframe.Position;
float keyframeProgress = (float) ((time - CurrentKeyframe.Position).TotalMilliseconds / timeDiff.TotalMilliseconds);
float keyframeProgress = (float) ((timeline.Position - CurrentKeyframe.Position).TotalMilliseconds / timeDiff.TotalMilliseconds);
float keyframeProgressEased = (float) Easings.Interpolate(keyframeProgress, CurrentKeyframe.EasingFunction);
UpdateCurrentValue(keyframeProgress, keyframeProgressEased);
}
@@ -361,7 +364,7 @@ namespace Artemis.Core
{
return _dataBindingRegistrations;
}
public void RegisterDataBindingProperty<TProperty>(Expression<Func<T, TProperty>> propertyExpression, DataBindingConverter<T, TProperty> converter)
{
if (_disposed)
@@ -416,11 +419,11 @@ namespace Artemis.Core
OnDataBindingDisabled(new LayerPropertyEventArgs<T>(dataBinding.LayerProperty));
}
private void UpdateDataBindings(double deltaTime)
private void UpdateDataBindings(Timeline timeline)
{
foreach (IDataBinding dataBinding in _dataBindings)
{
dataBinding.Update(deltaTime);
dataBinding.Update(timeline);
dataBinding.Apply();
}
}
@@ -484,12 +487,10 @@ namespace Artemis.Core
_keyframes.Clear();
try
{
_keyframes.AddRange(Entity.KeyframeEntities.Select(k => new LayerPropertyKeyframe<T>(
JsonConvert.DeserializeObject<T>(k.Value),
k.Position,
(Easings.Functions) k.EasingFunction,
this
)));
_keyframes.AddRange(
Entity.KeyframeEntities.Where(k => k.Position <= ProfileElement.Timeline.Length)
.Select(k => new LayerPropertyKeyframe<T>(JsonConvert.DeserializeObject<T>(k.Value), k.Position, (Easings.Functions) k.EasingFunction, this))
);
}
catch (JsonException e)
{
@@ -198,12 +198,12 @@ namespace Artemis.Core
layerPropertyGroup.ApplyToEntity();
}
internal void Update(TimeSpan renderTime, double deltaTime)
internal void Update(Timeline timeline)
{
foreach (ILayerProperty layerProperty in LayerProperties)
layerProperty.Update(renderTime, deltaTime);
layerProperty.Update(timeline);
foreach (LayerPropertyGroup layerPropertyGroup in LayerPropertyGroups)
layerPropertyGroup.Update(renderTime, deltaTime);
layerPropertyGroup.Update(timeline);
}
private void InitializeProperty(PropertyInfo propertyInfo, PropertyDescriptionAttribute propertyDescription)
@@ -17,6 +17,7 @@ namespace Artemis.Core
{
ApplyDataBindingsEnabled = true;
ApplyKeyframesEnabled = true;
Timeline = new Timeline();
LayerEffectStore.LayerEffectAdded += LayerEffectStoreOnLayerEffectAdded;
LayerEffectStore.LayerEffectRemoved += LayerEffectStoreOnLayerEffectRemoved;
@@ -30,8 +31,8 @@ namespace Artemis.Core
? new DataModelConditionGroup(null, RenderElementEntity.DisplayCondition)
: new DataModelConditionGroup(null);
Timeline = RenderElementEntity.Timeline != null
? new Timeline(RenderElementEntity.Timeline)
Timeline = RenderElementEntity.Timeline != null
? new Timeline(RenderElementEntity.Timeline)
: new Timeline();
ActivateEffects();
@@ -70,7 +71,17 @@ namespace Artemis.Core
/// <summary>
/// Gets the timeline associated with this render element
/// </summary>
public Timeline? Timeline { get; private set; }
public Timeline Timeline { get; private set; }
/// <summary>
/// Updates the <see cref="Timeline"/> according to the provided <paramref name="deltaTime"/> and current display condition status
/// </summary>
public void UpdateTimeline(double deltaTime)
{
// The play mode dictates whether to stick to the main segment unless the display conditions contains events
bool stickToMainSegment = Timeline.PlayMode == TimelinePlayMode.Repeat && (DisplayConditionMet || DisplayCondition != null && DisplayCondition.ContainsEvents);
Timeline.Update(TimeSpan.FromSeconds(deltaTime), stickToMainSegment);
}
#endregion
@@ -297,6 +308,9 @@ namespace Artemis.Core
/// </summary>
public bool ApplyDataBindingsEnabled { get; set; }
/// <summary>
/// Evaluates the display conditions on this element and applies any required changes to the <see cref="Timeline"/>
/// </summary>
public void UpdateDisplayCondition()
{
if (DisplayCondition == null)
@@ -306,26 +320,30 @@ namespace Artemis.Core
}
bool conditionMet = DisplayCondition.Evaluate();
// Regular conditions reset the timeline whenever their condition is met and was not met before that
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 && DisplayConditionMet && Timeline.StopMode == TimelineStopMode.SkipToEnd)
Timeline.JumpToEndSegment();
}
// Event conditions reset if the timeline finished and otherwise apply their overlap mode
else if (conditionMet)
{
// 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
}
}
+118 -13
View File
@@ -64,11 +64,14 @@ namespace Artemis.Core
private TimelinePlayMode _playMode;
private TimelineStopMode _stopMode;
private readonly List<Timeline> _extraTimelines;
private TimeSpan _startSegmentLength;
private TimeSpan _mainSegmentLength;
private TimeSpan _endSegmentLength;
/// <summary>
/// Gets the parent this timeline is an extra timeline of
/// </summary>
public Timeline Parent { get; }
public Timeline? Parent { get; }
/// <summary>
/// Gets the current position of the timeline
@@ -81,13 +84,21 @@ namespace Artemis.Core
/// <summary>
/// Gets the delta that was applied during the last call to <see cref="Update" />
/// <para>
/// Note: If this is an extra timeline <see cref="LastDelta" /> is always equal to <see cref="DeltaToParent" />
/// </para>
/// </summary>
public TimeSpan LastDelta
{
get => _lastDelta;
get => Parent == null ? _lastDelta : DeltaToParent;
private set => SetAndNotify(ref _lastDelta, value);
}
/// <summary>
/// Gets the delta to this timeline's <see cref="Parent" />
/// </summary>
public TimeSpan DeltaToParent => Parent != null ? Position - Parent.Position : TimeSpan.Zero;
/// <summary>
/// Gets or sets the mode in which the render element starts its timeline when display conditions are met
/// </summary>
@@ -124,7 +135,7 @@ namespace Artemis.Core
/// <summary>
/// Gets a boolean indicating whether the timeline has finished its run
/// </summary>
public bool IsFinished => Position > Length;
public bool IsFinished => Position > Length || Length == TimeSpan.Zero;
#region Segments
@@ -136,17 +147,41 @@ namespace Artemis.Core
/// <summary>
/// Gets or sets the length of the start segment
/// </summary>
public TimeSpan StartSegmentLength { get; set; }
public TimeSpan StartSegmentLength
{
get => _startSegmentLength;
set
{
if (SetAndNotify(ref _startSegmentLength, value))
NotifySegmentShiftAt(TimelineSegment.Start, false);
}
}
/// <summary>
/// Gets or sets the length of the main segment
/// </summary>
public TimeSpan MainSegmentLength { get; set; }
public TimeSpan MainSegmentLength
{
get => _mainSegmentLength;
set
{
if (SetAndNotify(ref _mainSegmentLength, value))
NotifySegmentShiftAt(TimelineSegment.Main, false);
}
}
/// <summary>
/// Gets or sets the length of the end segment
/// </summary>
public TimeSpan EndSegmentLength { get; set; }
public TimeSpan EndSegmentLength
{
get => _endSegmentLength;
set
{
if (SetAndNotify(ref _endSegmentLength, value))
NotifySegmentShiftAt(TimelineSegment.End, false);
}
}
/// <summary>
/// Gets or sets the start position of the main segment
@@ -154,7 +189,11 @@ namespace Artemis.Core
public TimeSpan MainSegmentStartPosition
{
get => StartSegmentEndPosition;
set => StartSegmentEndPosition = value;
set
{
StartSegmentEndPosition = value;
NotifySegmentShiftAt(TimelineSegment.Main, true);
}
}
/// <summary>
@@ -163,7 +202,11 @@ namespace Artemis.Core
public TimeSpan EndSegmentStartPosition
{
get => MainSegmentEndPosition;
set => MainSegmentEndPosition = value;
set
{
MainSegmentEndPosition = value;
NotifySegmentShiftAt(TimelineSegment.End, true);
}
}
/// <summary>
@@ -172,7 +215,11 @@ namespace Artemis.Core
public TimeSpan StartSegmentEndPosition
{
get => StartSegmentLength;
set => StartSegmentLength = value;
set
{
StartSegmentLength = value;
NotifySegmentShiftAt(TimelineSegment.Start, false);
}
}
/// <summary>
@@ -181,7 +228,11 @@ namespace Artemis.Core
public TimeSpan MainSegmentEndPosition
{
get => StartSegmentEndPosition + MainSegmentLength;
set => MainSegmentLength = value - StartSegmentEndPosition >= TimeSpan.Zero ? value - StartSegmentEndPosition : TimeSpan.Zero;
set
{
MainSegmentLength = value - StartSegmentEndPosition >= TimeSpan.Zero ? value - StartSegmentEndPosition : TimeSpan.Zero;
NotifySegmentShiftAt(TimelineSegment.Main, false);
}
}
/// <summary>
@@ -190,11 +241,41 @@ namespace Artemis.Core
public TimeSpan EndSegmentEndPosition
{
get => MainSegmentEndPosition + EndSegmentLength;
set => EndSegmentLength = value - MainSegmentEndPosition >= TimeSpan.Zero ? value - MainSegmentEndPosition : TimeSpan.Zero;
set
{
EndSegmentLength = value - MainSegmentEndPosition >= TimeSpan.Zero ? value - MainSegmentEndPosition : TimeSpan.Zero;
NotifySegmentShiftAt(TimelineSegment.End, false);
}
}
internal TimelineEntity Entity { get; set; }
/// <summary>
/// Notifies the right segments in a way that I don't have to think about it
/// </summary>
/// <param name="segment">The segment that was updated</param>
/// <param name="startUpdated">Whether the start point of the <paramref name="segment" /> was updated</param>
private void NotifySegmentShiftAt(TimelineSegment segment, bool startUpdated)
{
if (segment <= TimelineSegment.End)
{
if (startUpdated || segment < TimelineSegment.End)
NotifyOfPropertyChange(nameof(EndSegmentStartPosition));
NotifyOfPropertyChange(nameof(EndSegmentEndPosition));
}
if (segment <= TimelineSegment.Main)
{
if (startUpdated || segment < TimelineSegment.Main)
NotifyOfPropertyChange(nameof(MainSegmentStartPosition));
NotifyOfPropertyChange(nameof(MainSegmentEndPosition));
}
if (segment <= TimelineSegment.Start) NotifyOfPropertyChange(nameof(StartSegmentEndPosition));
NotifyOfPropertyChange(nameof(Length));
}
#endregion
#endregion
@@ -213,6 +294,9 @@ namespace Artemis.Core
if (stickToMainSegment && Position >= MainSegmentStartPosition)
Position = MainSegmentStartPosition + TimeSpan.FromMilliseconds(Position.TotalMilliseconds % MainSegmentLength.TotalMilliseconds);
foreach (Timeline extraTimeline in _extraTimelines)
extraTimeline.Update(delta, false);
}
/// <summary>
@@ -225,6 +309,8 @@ namespace Artemis.Core
LastDelta = TimeSpan.Zero - Position;
Position = TimeSpan.Zero;
_extraTimelines.Clear();
}
/// <summary>
@@ -237,6 +323,8 @@ namespace Artemis.Core
LastDelta = EndSegmentStartPosition - Position;
Position = EndSegmentStartPosition;
_extraTimelines.Clear();
}
/// <summary>
@@ -249,6 +337,8 @@ namespace Artemis.Core
LastDelta = EndSegmentEndPosition - Position;
Position = EndSegmentEndPosition;
_extraTimelines.Clear();
}
/// <summary>
@@ -258,12 +348,20 @@ namespace Artemis.Core
/// <param name="stickToMainSegment">Whether to stick to the main segment, wrapping around if needed</param>
public void Override(TimeSpan position, bool stickToMainSegment)
{
_extraTimelines.Clear();
LastDelta = position - Position;
Position = position;
if (stickToMainSegment && Position >= MainSegmentStartPosition)
Position = MainSegmentStartPosition + TimeSpan.FromMilliseconds(Position.TotalMilliseconds % MainSegmentLength.TotalMilliseconds);
_extraTimelines.Clear();
}
/// <summary>
/// Sets the <see cref="LastDelta" /> to <see cref="TimeSpan.Zero" />
/// </summary>
public void ClearDelta()
{
LastDelta = TimeSpan.Zero;
}
#endregion
@@ -295,6 +393,13 @@ namespace Artemis.Core
#endregion
}
internal enum TimelineSegment
{
Start,
Main,
End
}
/// <summary>
/// Represents a mode for render elements to start their timeline when display conditions are met
/// </summary>