Skip to content

Commit 065d4d4

Browse files
EventBus subscriber migration: add missing event types and wire dual-fire publishing (#272)
* Initial plan * Add new EventBus event types, dual-fire publishing, and subscriber migration Co-authored-by: michaelbeale-IL <63321611+michaelbeale-IL@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: michaelbeale-IL <63321611+michaelbeale-IL@users.noreply.github.com>
1 parent 07a2c66 commit 065d4d4

File tree

10 files changed

+288
-4
lines changed

10 files changed

+288
-4
lines changed

src/Libraries/ACATCore.Tests.Architecture/EventBusTests.cs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,93 @@ public void AgentContextChangedEvent_Properties_SetCorrectly()
137137
Assert.AreSame(ctx, evt.Context);
138138
}
139139

140+
[TestMethod]
141+
public void AppQuitEvent_ExtendsEventBase_HasTimestamp()
142+
{
143+
DateTime before = DateTime.UtcNow;
144+
var e = new AppQuitEvent();
145+
DateTime after = DateTime.UtcNow;
146+
147+
Assert.IsTrue(e.Timestamp >= before && e.Timestamp <= after);
148+
}
149+
150+
[TestMethod]
151+
public void AppQuitEvent_CanBePublishedAndReceived()
152+
{
153+
var bus = new EventBus();
154+
AppQuitEvent received = null;
155+
156+
bus.Subscribe<AppQuitEvent>(e => received = e);
157+
bus.Publish(new AppQuitEvent());
158+
159+
Assert.IsNotNull(received);
160+
}
161+
162+
[TestMethod]
163+
public void CalibrationEndEvent_ExtendsEventBase_HasTimestamp()
164+
{
165+
DateTime before = DateTime.UtcNow;
166+
var e = new CalibrationEndEvent();
167+
DateTime after = DateTime.UtcNow;
168+
169+
Assert.IsTrue(e.Timestamp >= before && e.Timestamp <= after);
170+
}
171+
172+
[TestMethod]
173+
public void CalibrationEndEvent_CanBePublishedAndReceived()
174+
{
175+
var bus = new EventBus();
176+
CalibrationEndEvent received = null;
177+
178+
bus.Subscribe<CalibrationEndEvent>(e => received = e);
179+
bus.Publish(new CalibrationEndEvent());
180+
181+
Assert.IsNotNull(received);
182+
}
183+
184+
[TestMethod]
185+
public void DisplaySettingsChangedEvent_ExtendsEventBase_HasTimestamp()
186+
{
187+
DateTime before = DateTime.UtcNow;
188+
var e = new DisplaySettingsChangedEvent();
189+
DateTime after = DateTime.UtcNow;
190+
191+
Assert.IsTrue(e.Timestamp >= before && e.Timestamp <= after);
192+
}
193+
194+
[TestMethod]
195+
public void DisplaySettingsChangedEvent_CanBePublishedAndReceived()
196+
{
197+
var bus = new EventBus();
198+
DisplaySettingsChangedEvent received = null;
199+
200+
bus.Subscribe<DisplaySettingsChangedEvent>(e => received = e);
201+
bus.Publish(new DisplaySettingsChangedEvent());
202+
203+
Assert.IsNotNull(received);
204+
}
205+
206+
[TestMethod]
207+
public void WordPredictionContextChangedEvent_Context_IsPreserved()
208+
{
209+
var ctx = new object();
210+
var e = new WordPredictionContextChangedEvent(ctx);
211+
212+
Assert.AreSame(ctx, e.Context);
213+
}
214+
215+
[TestMethod]
216+
public void WordPredictionContextChangedEvent_CanBePublishedAndReceived()
217+
{
218+
var bus = new EventBus();
219+
WordPredictionContextChangedEvent received = null;
220+
221+
bus.Subscribe<WordPredictionContextChangedEvent>(e => received = e);
222+
bus.Publish(new WordPredictionContextChangedEvent(null));
223+
224+
Assert.IsNotNull(received);
225+
}
226+
140227
// -----------------------------------------------------------------------
141228
// Null guards
142229
// -----------------------------------------------------------------------

src/Libraries/ACATCore.Tests/EventBusTests.cs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,93 @@ public void ConfigurationChangedEvent_Properties_ArePreserved()
248248
Assert.Equal("Dark", e.NewValue);
249249
}
250250

251+
[Fact]
252+
public void AppQuitEvent_ExtendsEventBase_HasTimestamp()
253+
{
254+
DateTime before = DateTime.UtcNow;
255+
var e = new AppQuitEvent();
256+
DateTime after = DateTime.UtcNow;
257+
258+
Assert.InRange(e.Timestamp, before, after);
259+
}
260+
261+
[Fact]
262+
public void AppQuitEvent_CanBePublishedAndReceived()
263+
{
264+
var bus = new EventBus();
265+
AppQuitEvent received = null;
266+
267+
bus.Subscribe<AppQuitEvent>(e => received = e);
268+
bus.Publish(new AppQuitEvent());
269+
270+
Assert.NotNull(received);
271+
}
272+
273+
[Fact]
274+
public void CalibrationEndEvent_ExtendsEventBase_HasTimestamp()
275+
{
276+
DateTime before = DateTime.UtcNow;
277+
var e = new CalibrationEndEvent();
278+
DateTime after = DateTime.UtcNow;
279+
280+
Assert.InRange(e.Timestamp, before, after);
281+
}
282+
283+
[Fact]
284+
public void CalibrationEndEvent_CanBePublishedAndReceived()
285+
{
286+
var bus = new EventBus();
287+
CalibrationEndEvent received = null;
288+
289+
bus.Subscribe<CalibrationEndEvent>(e => received = e);
290+
bus.Publish(new CalibrationEndEvent());
291+
292+
Assert.NotNull(received);
293+
}
294+
295+
[Fact]
296+
public void DisplaySettingsChangedEvent_ExtendsEventBase_HasTimestamp()
297+
{
298+
DateTime before = DateTime.UtcNow;
299+
var e = new DisplaySettingsChangedEvent();
300+
DateTime after = DateTime.UtcNow;
301+
302+
Assert.InRange(e.Timestamp, before, after);
303+
}
304+
305+
[Fact]
306+
public void DisplaySettingsChangedEvent_CanBePublishedAndReceived()
307+
{
308+
var bus = new EventBus();
309+
DisplaySettingsChangedEvent received = null;
310+
311+
bus.Subscribe<DisplaySettingsChangedEvent>(e => received = e);
312+
bus.Publish(new DisplaySettingsChangedEvent());
313+
314+
Assert.NotNull(received);
315+
}
316+
317+
[Fact]
318+
public void WordPredictionContextChangedEvent_Context_IsPreserved()
319+
{
320+
var ctx = new object();
321+
var e = new WordPredictionContextChangedEvent(ctx);
322+
323+
Assert.Same(ctx, e.Context);
324+
}
325+
326+
[Fact]
327+
public void WordPredictionContextChangedEvent_CanBePublishedAndReceived()
328+
{
329+
var bus = new EventBus();
330+
WordPredictionContextChangedEvent received = null;
331+
332+
bus.Subscribe<WordPredictionContextChangedEvent>(e => received = e);
333+
bus.Publish(new WordPredictionContextChangedEvent(null));
334+
335+
Assert.NotNull(received);
336+
}
337+
251338
// ----------------------------------------------------------------
252339
// Helpers
253340
// ----------------------------------------------------------------

src/Libraries/ACATCore/ACAT.Core.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,7 @@
571571
<Compile Include="EventManagement\EventBase.cs" />
572572
<Compile Include="EventManagement\IEventBus.cs" />
573573
<Compile Include="EventManagement\EventBus.cs" />
574+
<Compile Include="EventManagement\ApplicationEvents.cs" />
574575
<Compile Include="EventManagement\PanelEvents.cs" />
575576
<Compile Include="EventManagement\AgentEvents.cs" />
576577
<Compile Include="EventManagement\ActuatorEvents.cs" />

src/Libraries/ACATCore/ActuatorManagement/ActuatorManager.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,16 @@ public bool Init(IEnumerable<String> extensionDirs)
302302

303303
_initInProgress = false;
304304

305-
Context.AppPanelManager.EvtAppQuit += AppPanelManager_EvtAppQuit;
305+
if (_eventBus != null)
306+
{
307+
// Prefer EventBus subscription (new pattern)
308+
_eventBus.Subscribe<AppQuitEvent>(OnAppQuit);
309+
}
310+
else
311+
{
312+
// Fallback to legacy delegate when EventBus is not available
313+
Context.AppPanelManager.EvtAppQuit += AppPanelManager_EvtAppQuit;
314+
}
306315

307316
return retVal;
308317
}
@@ -664,6 +673,7 @@ public void NotifyStartCalibration(CalibrationNotifyEventArgs args)
664673
public void NotifyEndCalibration()
665674
{
666675
EvtCalibrationEndNotify?.Invoke(this, new EventArgs());
676+
_eventBus?.Publish(new CalibrationEndEvent());
667677
}
668678

669679
public IActuator GetKeyboardActuator()
@@ -918,6 +928,17 @@ private void AppPanelManager_EvtAppQuit(object sender, EventArgs e)
918928
_actuators.OnAppQuit();
919929
}
920930

931+
/// <summary>
932+
/// EventBus handler for when the application exits.
933+
/// Replaces the legacy <see cref="AppPanelManager_EvtAppQuit"/> delegate subscription
934+
/// when <see cref="IEventBus"/> is available.
935+
/// </summary>
936+
/// <param name="evt">The app quit event</param>
937+
private void OnAppQuit(AppQuitEvent evt)
938+
{
939+
_actuators.OnAppQuit();
940+
}
941+
921942
/// <summary>
922943
/// Looks at the queue that has calibration requests and handles
923944
/// them in the order they were received

src/Libraries/ACATCore/EventManagement/ActuatorEvents.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,12 @@ public ActuatorSwitchActivatedEvent(string switchName)
3131
/// </summary>
3232
public string SwitchName { get; }
3333
}
34+
35+
/// <summary>
36+
/// Published when actuator calibration ends.
37+
/// Replaces the legacy <c>IActuatorManager.EvtCalibrationEndNotify</c> delegate.
38+
/// </summary>
39+
public class CalibrationEndEvent : EventBase
40+
{
41+
}
3442
}

src/Libraries/ACATCore/EventManagement/AgentEvents.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,27 @@ public AgentContextChangedEvent(string agentName, object context)
4242
/// </summary>
4343
public object Context { get; }
4444
}
45+
46+
/// <summary>
47+
/// Published when the word prediction context changes.
48+
/// Replaces the legacy word prediction context delegate.
49+
/// </summary>
50+
public class WordPredictionContextChangedEvent : EventBase
51+
{
52+
/// <summary>
53+
/// Initializes a new instance of <see cref="WordPredictionContextChangedEvent"/>.
54+
/// </summary>
55+
/// <param name="context">
56+
/// Application-defined context object (may be <c>null</c>).
57+
/// </param>
58+
public WordPredictionContextChangedEvent(object context)
59+
{
60+
Context = context;
61+
}
62+
63+
/// <summary>
64+
/// Gets the application-defined context object for the word prediction context.
65+
/// </summary>
66+
public object Context { get; }
67+
}
4568
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
////////////////////////////////////////////////////////////////////////////
2+
//
3+
// Copyright 2013-2019; 2023 Intel Corporation
4+
// SPDX-License-Identifier: Apache-2.0
5+
//
6+
//
7+
// ApplicationEvents.cs
8+
//
9+
// Event types for application lifecycle notifications (quit).
10+
//
11+
////////////////////////////////////////////////////////////////////////////
12+
13+
namespace ACAT.Core.EventManagement
14+
{
15+
/// <summary>
16+
/// Published when the application is about to quit.
17+
/// Replaces the legacy <c>IPanelManager.EvtAppQuit</c> delegate.
18+
/// </summary>
19+
public class AppQuitEvent : EventBase
20+
{
21+
}
22+
}

src/Libraries/ACATCore/EventManagement/PanelEvents.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,12 @@ public PanelActivateEvent(string panelClass)
7171
/// </summary>
7272
public string PanelClass { get; }
7373
}
74+
75+
/// <summary>
76+
/// Published when the display settings (e.g. resolution) change.
77+
/// Replaces the legacy <c>IPanelManager.EvtDisplaySettingsChanged</c> delegate.
78+
/// </summary>
79+
public class DisplaySettingsChangedEvent : EventBase
80+
{
81+
}
7482
}

src/Libraries/ACATCore/PanelManagement/PanelManager.cs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,16 @@ public bool Init(IEnumerable<string> extensionDirs)
442442
}
443443

444444
Context.AppActuatorManager.EvtCalibrationStartNotify += AppActuatorManager_EvtCalibrationStartNotify;
445-
Context.AppActuatorManager.EvtCalibrationEndNotify += AppActuatorManager_EvtCalibrationEndNotify;
445+
if (_eventBus != null)
446+
{
447+
// Prefer EventBus subscription for CalibrationEnd (new pattern)
448+
_eventBus.Subscribe<CalibrationEndEvent>(OnCalibrationEnd);
449+
}
450+
else
451+
{
452+
// Fallback to legacy delegate when EventBus is not available
453+
Context.AppActuatorManager.EvtCalibrationEndNotify += AppActuatorManager_EvtCalibrationEndNotify;
454+
}
446455
return retVal;
447456
}
448457

@@ -587,6 +596,7 @@ internal void NotifyPanelPreShow(PanelPreShowEventArg arg)
587596
internal void NotifyQuitApplication()
588597
{
589598
EvtAppQuit?.Invoke(_instance, new EventArgs());
599+
_eventBus?.Publish(new AppQuitEvent());
590600
}
591601

592602
/// <summary>
@@ -637,6 +647,17 @@ private void AppActuatorManager_EvtCalibrationEndNotify(object sender, EventArgs
637647
//WindowActivityMonitor.GetActiveWindowAsync();
638648
}
639649

650+
/// <summary>
651+
/// EventBus handler for calibration end.
652+
/// Replaces the legacy <see cref="AppActuatorManager_EvtCalibrationEndNotify"/> delegate
653+
/// subscription when <see cref="IEventBus"/> is available.
654+
/// </summary>
655+
/// <param name="evt">The calibration end event</param>
656+
private void OnCalibrationEnd(CalibrationEndEvent evt)
657+
{
658+
AppActuatorManager_EvtCalibrationEndNotify(this, EventArgs.Empty);
659+
}
660+
640661
private void AppActuatorManager_EvtCalibrationStartNotify(ActuatorManagement.CalibrationNotifyEventArgs args)
641662
{
642663
_actuatorCalibrationInProgress = true;
@@ -772,6 +793,7 @@ private void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
772793
_logger?.LogDebug("Display Resolution changed. Working area is {WorkingArea}", Screen.PrimaryScreen.WorkingArea);
773794

774795
EvtDisplaySettingsChanged?.Invoke(sender, e);
796+
_eventBus?.Publish(new DisplaySettingsChangedEvent());
775797
}
776798
}
777799
}

0 commit comments

Comments
 (0)