-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCompositeLightTransitionReactiveNodeConfigurator.Toggle.cs
More file actions
117 lines (104 loc) · 5.31 KB
/
Copy pathCompositeLightTransitionReactiveNodeConfigurator.Toggle.cs
File metadata and controls
117 lines (104 loc) · 5.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
using CodeCasa.AutomationPipelines.Lights.Extensions;
using CodeCasa.AutomationPipelines.Lights.Nodes;
using CodeCasa.AutomationPipelines.Lights.Timeline;
using CodeCasa.AutomationPipelines.Lights.Toggle;
using CodeCasa.Lights;
using CodeCasa.Lights.Extensions;
using Occurify;
namespace CodeCasa.AutomationPipelines.Lights.ReactiveNode;
internal partial class CompositeLightTransitionReactiveNodeConfigurator<TLight>
{
/// <inheritdoc/>
public ILightTransitionReactiveNodeConfigurator<TLight> AddToggle<T>(IObservable<T> triggerObservable, IEnumerable<LightParameters> lightParameters)
=> AddToggle(triggerObservable, lightParameters.ToArray());
/// <inheritdoc/>
public ILightTransitionReactiveNodeConfigurator<TLight> AddToggle<T>(IObservable<T> triggerObservable,
params LightParameters[] lightParameters)
{
return AddToggle(triggerObservable, configure =>
{
foreach (var lightParameter in lightParameters)
{
configure.Add(lightParameter);
}
});
}
/// <inheritdoc/>
public ILightTransitionReactiveNodeConfigurator<TLight> AddToggle<T>(IObservable<T> triggerObservable, IEnumerable<LightTransition> lightTransitions)
=> AddToggle(triggerObservable, lightTransitions.ToArray());
/// <inheritdoc/>
public ILightTransitionReactiveNodeConfigurator<TLight> AddToggle<T>(IObservable<T> triggerObservable,
params LightTransition[] lightTransitions)
{
return AddToggle(triggerObservable, configure =>
{
foreach (var lightTransition in lightTransitions)
{
configure.Add(lightTransition);
}
});
}
/// <inheritdoc/>
public ILightTransitionReactiveNodeConfigurator<TLight> AddToggle<T>(IObservable<T> triggerObservable, IEnumerable<Func<IServiceProvider, IPipelineNode<LightTransition>>> nodeFactories)
=> AddToggle(triggerObservable, nodeFactories.ToArray());
/// <inheritdoc/>
public ILightTransitionReactiveNodeConfigurator<TLight> AddToggle<T>(IObservable<T> triggerObservable, params Func<IServiceProvider, IPipelineNode<LightTransition>>[] nodeFactories)
{
return AddToggle(triggerObservable, configure =>
{
foreach (var fact in nodeFactories)
{
configure.Add(fact);
}
});
}
/// <inheritdoc/>
public ILightTransitionReactiveNodeConfigurator<TLight> AddToggle<T>(IObservable<T> triggerObservable, Action<ILightTransitionToggleConfigurator<TLight>> configure)
{
var toggleConfigurators = configurators.ToDictionary(kvp => kvp.Key,
kvp => new LightTransitionToggleConfigurator<TLight>(kvp.Value.Light, scheduler));
var compositeToggleConfigurator = new CompositeLightTransitionToggleConfigurator<TLight>(toggleConfigurators, []);
configure(compositeToggleConfigurator);
var shareableTriggerObservable = _observableSharingStrategy.Apply(triggerObservable);
configurators.ForEach(kvp =>
{
var toggleConfig = toggleConfigurators[kvp.Key];
var gracePeriod = toggleConfig.GracePeriod ?? TimeSpan.FromSeconds(1);
kvp.Value.AddNodeSource(shareableTriggerObservable.ToToggleObservable(
lastActivationTime =>
{
var utcNow = DateTime.UtcNow;
if (utcNow - kvp.Value.Light.LastChangedUtc <= gracePeriod &&
(!lastActivationTime.HasValue || utcNow - lastActivationTime > gracePeriod))
{
return !configurators.Values.Any(c => c.Light.IsOn());
}
return configurators.Values.Any(c => c.Light.IsOn());
},
() => new TurnOffThenPassThroughNode(),
toggleConfig.NodeFactories.Select(fact =>
{
return new Func<IPipelineNode<LightTransition>>(() =>
fact.CreateScopedNode(kvp.Value
.ServiceProvider) // Note: This service provider already has the light registered. We scope it further for node lifetime.
);
}),
toggleConfig.ToggleTimeout ?? TimeSpan.FromMilliseconds(1000),
toggleConfig.IncludeOffValue));
});
return this;
}
/// <inheritdoc/>
public ILightTransitionReactiveNodeConfigurator<TLight> AddToggle<T>(IObservable<T> triggerObservable,
Dictionary<ITimeline, LightParameters> timeline, TimeSpan? transitionTimeForTimelineState = null)
=> AddToggle(triggerObservable, c => c.AddTimeline(timeline, transitionTimeForTimelineState));
/// <inheritdoc/>
public ILightTransitionReactiveNodeConfigurator<TLight> AddToggle<T>(IObservable<T> triggerObservable,
Func<IServiceProvider, Dictionary<ITimeline, LightParameters>> timelineFactory,
TimeSpan? transitionTimeForTimelineState = null)
=> AddToggle(triggerObservable, c => c.AddTimeline(timelineFactory, transitionTimeForTimelineState));
/// <inheritdoc/>
public ILightTransitionReactiveNodeConfigurator<TLight> AddToggle<T>(IObservable<T> triggerObservable,
Action<ITimelineConfigurator> configure)
=> AddToggle(triggerObservable, c => c.AddTimeline(configure));
}