Skip to content

Commit 3d5544f

Browse files
author
Joanna May
authored
Merge pull request #130 from xodial/xodial/on-start-stop
feat: add OnStart/OnStop to LogicBlock
2 parents e6fcbbe + 1a44a6e commit 3d5544f

File tree

3 files changed

+53
-10
lines changed

3 files changed

+53
-10
lines changed

Chickensoft.LogicBlocks.Tests/test/fixtures/FakeLogicBlock.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,10 @@ public static class Output {
156156
public partial class FakeLogicBlock : LogicBlock<FakeLogicBlock.State> {
157157
public Func<Transition>? InitialState { get; set; }
158158

159+
public Action? OnStartCalled { get; set; }
160+
161+
public Action? OnStopCalled { get; set; }
162+
159163
public List<Exception> Exceptions { get; } = new();
160164

161165
public override Transition GetInitialState() =>
@@ -167,6 +171,10 @@ public FakeLogicBlock(Action<Exception>? onError = null) {
167171
_onError = onError;
168172
}
169173

174+
public override void OnStart() => OnStartCalled?.Invoke();
175+
176+
public override void OnStop() => OnStopCalled?.Invoke();
177+
170178
~FakeLogicBlock() { }
171179

172180
protected override void HandleError(Exception e) {

Chickensoft.LogicBlocks.Tests/test/src/LogicBlockTest.cs

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -327,20 +327,24 @@ public void StartsManuallyAndIgnoresStartWhenProcessing() {
327327
[Fact]
328328
public void StartEntersState() {
329329
var enterCalled = false;
330+
var onStartCalled = false;
330331
var context = new FakeContext();
331332
var block = new FakeLogicBlock() {
332333
InitialState = () =>
333334
new FakeLogicBlock.Transition(new FakeLogicBlock.State.OnEnterState() {
334335
Callback = (previous) => enterCalled = true
335-
})
336+
}),
337+
OnStartCalled = () => onStartCalled = true
336338
};
337339

338340
enterCalled.ShouldBeFalse();
341+
onStartCalled.ShouldBeFalse();
339342

340343
block.Start();
341344
block.Start(); // Should do nothing.
342345

343346
enterCalled.ShouldBeTrue();
347+
onStartCalled.ShouldBeTrue();
344348
}
345349

346350
[Fact]
@@ -357,31 +361,50 @@ public void StartDoesNothingIfProcessing() {
357361
logic.Value.ShouldBeOfType<FakeLogicBlock.State.StateA>();
358362
}
359363

364+
[Fact]
365+
public void ImplicitStartCallsOnStart() {
366+
var onStartCalled = false;
367+
var logic = new FakeLogicBlock() {
368+
OnStartCalled = () => onStartCalled = true
369+
};
370+
371+
logic.Input(new FakeLogicBlock.Input.InputOne(2, 3));
372+
373+
onStartCalled.ShouldBeTrue();
374+
}
375+
360376
[Fact]
361377
public void StopExitsState() {
362378
var exitCalled = false;
379+
var onStopCalled = false;
363380
var context = new FakeContext();
364381
var block = new FakeLogicBlock() {
365382
InitialState = () => new FakeLogicBlock.Transition(
366383
new FakeLogicBlock.State.OnExitState() {
367384
Callback = (previous) => exitCalled = true
368385
}
369-
)
386+
),
387+
OnStopCalled = () => onStopCalled = true
370388
};
371389

372390
exitCalled.ShouldBeFalse();
391+
onStopCalled.ShouldBeFalse();
373392

374393
block.Start();
375394
block.Stop();
376395
block.Stop(); // Should do nothing.
377396

378397
exitCalled.ShouldBeTrue();
398+
onStopCalled.ShouldBeTrue();
379399
}
380400

381401
[Fact]
382402
public void StopDoesNothingIfProcessing() {
403+
var onStopCalled = false;
383404
var context = new FakeContext();
384-
var logic = new FakeLogicBlock();
405+
var logic = new FakeLogicBlock() {
406+
OnStopCalled = () => onStopCalled = true
407+
};
385408
logic.InitialState = () => new FakeLogicBlock.Transition(
386409
new FakeLogicBlock.State.OnExitState() {
387410
Callback = (previous) => logic.Stop()
@@ -390,6 +413,8 @@ public void StopDoesNothingIfProcessing() {
390413

391414
logic.Input(new FakeLogicBlock.Input.InputOne(2, 3));
392415
logic.IsStarted.ShouldBeTrue();
416+
417+
onStopCalled.ShouldBeFalse();
393418
}
394419

395420
[Fact]

Chickensoft.LogicBlocks/src/LogicBlock.cs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -226,10 +226,18 @@ public void Start() {
226226
Flush();
227227
}
228228

229+
/// <summary>
230+
/// Called when the logic block is started. Override this method to
231+
/// perform any initialization logic.
232+
/// </summary>
233+
public virtual void OnStart() { }
234+
229235
/// <inheritdoc />
230236
public void Stop() {
231237
if (IsProcessing || _value is null) { return; }
232238

239+
OnStop();
240+
233241
// Repeatedly exit and detach the current state until there is none.
234242
ChangeState(null);
235243

@@ -239,6 +247,12 @@ public void Stop() {
239247
_value = null;
240248
}
241249

250+
/// <summary>
251+
/// Called when the logic block is stopped. Override this method to
252+
/// perform any cleanup logic.
253+
/// </summary>
254+
public virtual void OnStop() { }
255+
242256
/// <inheritdoc />
243257
public TState ForceReset(TState state) {
244258
if (IsProcessing) {
@@ -386,6 +400,8 @@ internal TState ProcessInputs<TInputType>(
386400

387401
if (_value is null) {
388402
// No state yet. Let's get the first state going!
403+
OnStart();
404+
Blackboard.InstantiateAnyMissingSavedData();
389405
ChangeState(RestoredState as TState ?? GetInitialState().State);
390406
RestoredState = null;
391407
}
@@ -500,13 +516,7 @@ TState fallback
500516
/// </summary>
501517
/// <returns>The resting state.</returns>
502518
[MethodImpl(MethodImplOptions.AggressiveInlining)]
503-
private TState Flush() {
504-
if (_value is null) {
505-
Blackboard.InstantiateAnyMissingSavedData();
506-
}
507-
508-
return ProcessInputs<int>();
509-
}
519+
private TState Flush() => ProcessInputs<int>();
510520

511521
/// <summary>
512522
/// Determines if two logic blocks are equivalent. Logic blocks are equivalent

0 commit comments

Comments
 (0)