Skip to content

Commit 383dac0

Browse files
committed
Event Scheduling added
- Event Scheduling has been added throughout the system. - Unit Test coverage for Event Scheduling has also been added.
1 parent ee5ab68 commit 383dac0

File tree

6 files changed

+143
-2
lines changed

6 files changed

+143
-2
lines changed

Sources/EventDrivenSwift/Central/EventCentral.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Singleton for the Central Event Dispatcher.
1616
- Note: This is used when invoking the `queue` and `stack` methods of `Eventable`.
1717
*/
1818
final public class EventCentral: EventDispatcher, EventCentralable {
19+
1920
/**
2021
Singleton Instance of our Central Event Dispatcher
2122
- Author: Simon J. Stuart
@@ -86,6 +87,14 @@ final public class EventCentral: EventDispatcher, EventCentralable {
8687
_shared.eventListener.removeListener(token, typeOf: typeOf)
8788
}
8889

90+
@inline(__always) static public func scheduleQueue(_ event: Eventable, at: DispatchTime, priority: EventPriority) {
91+
_shared.scheduleQueue(event, at: at, priority: priority)
92+
}
93+
94+
@inline(__always) static public func scheduleStack(_ event: Eventable, at: DispatchTime, priority: EventPriority) {
95+
_shared.scheduleStack(event, at: at, priority: priority)
96+
}
97+
8998
/// This just makes it so that your code cannot initialise instances of `EventCentral`. It's a Singleton!
9099
override private init() {}
91100
}

Sources/EventDrivenSwift/Central/EventCentralable.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,24 @@ public protocol EventCentralable {
8989
- typeOf: The Event Type for which the Listener identified by the given `token` is interested
9090
*/
9191
static func removeListener(_ token: UUID, typeOf: Eventable.Type)
92+
93+
/**
94+
Schedule the Event to be dispatched through the Central Queue with the given `priority`
95+
- Author: Simon J. Stuart
96+
- Version: 4.2.0
97+
- Parameters:
98+
- at: The `DispatchTime` after which to dispatch the Event
99+
- priority: The `EventPriority` with which to process the Event
100+
*/
101+
static func scheduleQueue(_ event: Eventable, at: DispatchTime, priority: EventPriority)
102+
103+
/**
104+
Schedule the Event to be dispatched through the Central Stack with the given `priority`
105+
- Author: Simon J. Stuart
106+
- Version: 4.2.0
107+
- Parameters:
108+
- at: The `DispatchTime` after which to dispatch the Event
109+
- priority: The `EventPriority` with which to process the Event
110+
*/
111+
static func scheduleStack(_ event: Eventable, at: DispatchTime, priority: EventPriority)
92112
}

Sources/EventDrivenSwift/Event/Eventable.swift

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,26 @@ public protocol Eventable {
3434
*/
3535
func stack(priority: EventPriority)
3636

37+
/**
38+
Schedule the Event to be dispatched through the Central Queue with the given `priority`
39+
- Author: Simon J. Stuart
40+
- Version: 4.2.0
41+
- Parameters:
42+
- at: The `DispatchTime` after which to dispatch the Event
43+
- priority: The `EventPriority` with which to process the Event
44+
*/
45+
func scheduleQueue(at: DispatchTime, priority: EventPriority)
46+
47+
/**
48+
Schedule the Event to be dispatched through the Central Stack with the given `priority`
49+
- Author: Simon J. Stuart
50+
- Version: 4.2.0
51+
- Parameters:
52+
- at: The `DispatchTime` after which to dispatch the Event
53+
- priority: The `EventPriority` with which to process the Event
54+
*/
55+
func scheduleStack(at: DispatchTime, priority: EventPriority)
56+
3757
/**
3858
Registers an Event Listner Callback for the given `Eventable` Type with the Central Event Listener
3959
- Author: Simon J. Stuart
@@ -74,14 +94,22 @@ extension Eventable {
7494
- Version: 1.0.0
7595
*/
7696
extension Eventable {
77-
public func queue(priority: EventPriority = .normal) {
97+
@inline(__always) public func queue(priority: EventPriority = .normal) {
7898
EventCentral.queueEvent(self, priority: priority)
7999
}
80100

81-
public func stack(priority: EventPriority = .normal) {
101+
@inline(__always) public func stack(priority: EventPriority = .normal) {
82102
EventCentral.stackEvent(self, priority: priority)
83103
}
84104

105+
@inline(__always) public func scheduleQueue(at: DispatchTime, priority: EventPriority = .normal) {
106+
EventCentral.scheduleQueue(self, at: at, priority: priority)
107+
}
108+
109+
@inline(__always) public func scheduleStack(at: DispatchTime, priority: EventPriority = .normal) {
110+
EventCentral.scheduleStack(self, at: at, priority: priority)
111+
}
112+
85113
@discardableResult static public func addListener<TEvent: Eventable>(_ requester: AnyObject?, _ callback: @escaping TypedEventCallback<TEvent>, executeOn: ExecuteEventOn = .requesterThread) -> EventListenerHandling {
86114
return EventCentral.addListener(requester, callback, forEventType: Self.self, executeOn: executeOn)
87115
}

Sources/EventDrivenSwift/EventHandler/EventHandler.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,23 @@ open class EventHandler: ObservableThread, EventHandling {
9393
eventsPending.signal()
9494
}
9595

96+
public func scheduleQueue(_ event: any Eventable, at: DispatchTime, priority: EventPriority) {
97+
Task {
98+
DispatchQueue.main.asyncAfter(deadline: at) {
99+
self.queueEvent(event, priority: priority)
100+
}
101+
}
102+
}
103+
104+
public func scheduleStack(_ event: any Eventable, at: DispatchTime, priority: EventPriority) {
105+
Task {
106+
DispatchQueue.main.asyncAfter(deadline: at) {
107+
self.stackEvent(event, priority: priority)
108+
}
109+
}
110+
}
111+
112+
96113
/**
97114
Processes an Event
98115
- Author: Simon J. Stuart

Sources/EventDrivenSwift/EventHandler/EventHandling.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,26 @@ public protocol EventHandling {
3434
*/
3535
func stackEvent(_ event: any Eventable, priority: EventPriority)
3636

37+
/**
38+
Schedule the Event to be dispatched with the given `priority`
39+
- Author: Simon J. Stuart
40+
- Version: 4.2.0
41+
- Parameters:
42+
- at: The `DispatchTime` after which to dispatch the Event
43+
- priority: The `EventPriority` with which to process the Event
44+
*/
45+
func scheduleQueue(_ event: any Eventable, at: DispatchTime, priority: EventPriority)
46+
47+
/**
48+
Schedule the Event to be dispatched with the given `priority`
49+
- Author: Simon J. Stuart
50+
- Version: 4.2.0
51+
- Parameters:
52+
- at: The `DispatchTime` after which to dispatch the Event
53+
- priority: The `EventPriority` with which to process the Event
54+
*/
55+
func scheduleStack(_ event: any Eventable, at: DispatchTime, priority: EventPriority)
56+
3757
/**
3858
The number of Events currently pending in the Queue and Stack combined
3959
- Author: Simon J. Stuart
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//
2+
// BasicEventSchedulingTests.swift
3+
//
4+
//
5+
// Created by Simon Stuart on 28/08/2022.
6+
//
7+
8+
import XCTest
9+
import ThreadSafeSwift
10+
@testable import EventDrivenSwift
11+
12+
final class BasicEventSchedulingTests: XCTestCase {
13+
private struct TestEvent: Eventable {
14+
public var foo: String
15+
}
16+
17+
@ThreadSafeSemaphore private var testValue: String = "Hello"
18+
private var exp: XCTestExpectation? = nil
19+
private var executed: DispatchTime? = nil
20+
21+
func testPerformanceExample() throws {
22+
TestEvent.addListener(self, { (event: TestEvent, priority) in
23+
print("TestEvent where foo = \(event.foo)")
24+
self.testValue = event.foo
25+
self.executed = DispatchTime.now()
26+
self.exp?.fulfill()
27+
}, executeOn: .taskThread)
28+
29+
exp = expectation(description: "Event Executed")
30+
31+
XCTAssertEqual(testValue, "Hello")
32+
let scheduledFor = DispatchTime.now() + TimeInterval().advanced(by: 4) // Schedule for T+5 seconds
33+
TestEvent(foo: "World").scheduleQueue(at: scheduledFor)
34+
35+
let result = XCTWaiter.wait(for: [exp!], timeout: 5.0)
36+
37+
XCTAssertNotEqual(result, .timedOut)
38+
39+
XCTAssertEqual(testValue, "World")
40+
XCTAssertNotNil(executed)
41+
if executed != nil {
42+
XCTAssertLessThan(scheduledFor, executed!)
43+
XCTAssertLessThan(executed!, scheduledFor + TimeInterval().advanced(by: 4.001))
44+
}
45+
}
46+
47+
}

0 commit comments

Comments
 (0)