Skip to content

Commit a585c61

Browse files
committed
substancial refactoring
Too much to detail, but we have a new naming convention that makes more sense to a human being, and we're using it now.
1 parent d1ea187 commit a585c61

File tree

19 files changed

+133
-178
lines changed

19 files changed

+133
-178
lines changed

README.md

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -72,44 +72,44 @@ This means that we can enforce some degree of *execution order* over *Events* at
7272

7373
### Dispatch
7474
*Dispatch* is a term comparable to *Broadcast*.
75-
When we *Dispatch* an *Event*, it means that we are sending that information to every `EventReceiver` (see next section) that is listening for that *Event type*.
75+
When we *Dispatch* an *Event*, it means that we are sending that information to every `EventThread` (see next section) that is listening for that *Event type*.
7676

7777
Once an *Event* has been *Dispatched*, it cannot be cancelled or modified. This is by design. Think of it as saying that "you cannot unsay something once you have said it."
7878

7979
*Events* can be *Dispatched* from anywhere in your code, regardless of what *Thread* is invoking it. In this sense, *Events* are very much a **fire and forget** process.
8080

81-
### `EventReceiver`
82-
An `EventReceiver` is a `class` inheriting the base type provided by this library called `EventReceiver`.
81+
### `EventThread`
82+
An `EventThread` is a `class` inheriting the base type provided by this library called `EventThread`.
8383

84-
Beneath the surface, `EventReceiver` descends from `Thread`, and is literally what is known as a `Persistent Thread`.
84+
Beneath the surface, `EventThread` descends from `Thread`, and is literally what is known as a `Persistent Thread`.
8585
This means that the `Thread` would typically exist either for a long as your particular application would require it, or even for the entire lifetime of your application.
8686

87-
Unlike most Threads, `EventReceiver` has been built specifically to operate with the lowest possible system resource footprint. When there are no *Events* waiting to be processed by your `EventReceiver`, the Thread will consume absolutely no CPU time, and effectively no power at all.
87+
Unlike most Threads, `EventThread` has been built specifically to operate with the lowest possible system resource footprint. When there are no *Events* waiting to be processed by your `EventThread`, the Thread will consume absolutely no CPU time, and effectively no power at all.
8888

89-
Once your `EventReceiver` receives an *Event* of an `Eventable` type to which it has *subscribed*, it will *wake up* automatically and process any waiting *Events* in its respective *Queue* and *Stack*.
89+
Once your `EventThread` receives an *Event* of an `Eventable` type to which it has *subscribed*, it will *wake up* automatically and process any waiting *Events* in its respective *Queue* and *Stack*.
9090

91-
**Note:** any number of `EventReceiver`s can receive the same *Event*s. This means that you can process the same *Event* for any number of purposes, in any number of ways, with any number of outcomes.
91+
**Note:** any number of `EventThread`s can receive the same *Event*s. This means that you can process the same *Event* for any number of purposes, in any number of ways, with any number of outcomes.
9292

9393
### Event Handler (or Callback)
94-
When you define your `EventReceiver` descendant, you will implement a function called `registerEventListeners`. Within this function (which is invoked automatically every time an Instance of your `EventReceiver` descendant type is initialised) you will register the `Eventable` Types to which your `EventReceiver` is interested; and for each of those, define a suitable *Handler* (or *Callback*) method to process those *Events* whenever they occur.
94+
When you define your `EventThread` descendant, you will implement a function called `registerEventListeners`. Within this function (which is invoked automatically every time an Instance of your `EventThread` descendant type is initialised) you will register the `Eventable` Types to which your `EventThread` is interested; and for each of those, define a suitable *Handler* (or *Callback*) method to process those *Events* whenever they occur.
9595

96-
You will see detailed examples of this in the **Usage** section of this document later, but the key to understand here is that, for each `Eventable` type that your `EventReceiver` is interested in processing, you will be able to register your *Event Handler* for that *Event* type in a single line of code.
96+
You will see detailed examples of this in the **Usage** section of this document later, but the key to understand here is that, for each `Eventable` type that your `EventThread` is interested in processing, you will be able to register your *Event Handler* for that *Event* type in a single line of code.
9797

98-
This makes it extremely easy to manage and maintain the *Event Subscriptions* that each `EventReceiver` has been implemented to process.
98+
This makes it extremely easy to manage and maintain the *Event Subscriptions* that each `EventThread` has been implemented to process.
9999

100100
## Performance-Centric
101101
`EventDrivenSwift` is designed specifically to provide the best possible performance balance both at the point of *Dispatching* an *Event*, as well as at the point of *Processing* an *Event*.
102102

103-
With this in mind, `EventDrivenSwift` provides a *Central Event Dispatch Handler* by default. Whenever you *Dispatch* an *Event* through either a *Queue* or *Stack*, it will be immediately enqueued within the *Central Event Dispatch Handler*, where it will subsequently be *Dispatched* to all registered `EventReceiver`s through its own *Thread*.
103+
With this in mind, `EventDrivenSwift` provides a *Central Event Dispatch Handler* by default. Whenever you *Dispatch* an *Event* through either a *Queue* or *Stack*, it will be immediately enqueued within the *Central Event Dispatch Handler*, where it will subsequently be *Dispatched* to all registered `EventThread`s through its own *Thread*.
104104

105105
This means that there is a near-zero wait time between instructing an *Event* to *Dispatch*, and continuing on in the invoking Thread's execution.
106106

107-
Despite using an intermediary Handler in this manner, the time between *Dispatch* of an *Event* and the *Processing* of that *Event* by each `EventReceiver` is **impressively short!** This makes `EventDrivenSwift` more than useful for performance-critical applications, including videogames!
107+
Despite using an intermediary Handler in this manner, the time between *Dispatch* of an *Event* and the *Processing* of that *Event* by each `EventThread` is **impressively short!** This makes `EventDrivenSwift` more than useful for performance-critical applications, including videogames!
108108

109109
## Built on `Observable`
110-
`EventDrivenSwift` is built on top of our [`Observable` library](https://github.com/flowduino/observable), and `EventReceiver` descends from `ObservableThread`, meaning that it supports full *Observer Pattern* behaviour as well as *Event-Driven* behaviour.
110+
`EventDrivenSwift` is built on top of our [`Observable` library](https://github.com/flowduino/observable), and `EventThread` descends from `ObservableThread`, meaning that it supports full *Observer Pattern* behaviour as well as *Event-Driven* behaviour.
111111

112-
Put simply: you can Observe `EventReceiver`s anywhere in your code that it is necessary, including from SwiftUI Views.
112+
Put simply: you can Observe `EventThread`s anywhere in your code that it is necessary, including from SwiftUI Views.
113113

114114
This means that your application can dynamically update your Views in response to *Events* being received and processed, making your application truly and fully multi-threaded, without you having to produce code to handle the intra-Thread communication yourself.
115115

@@ -191,14 +191,14 @@ temperatureEvent.stack(priority: .highest)
191191
```
192192
Above would be with `.highest` *Priority*.
193193

194-
### Defining an `EventReceiver`
195-
So, we have an *Event* type, and we are able to *Dispatch* it through a *Queue* or a *Stack*, with whatever *Priority* we desire. Now we need to define an `EventReceiver` to listen for and process our `TemperatureEvent`s.
194+
### Defining an `EventThread`
195+
So, we have an *Event* type, and we are able to *Dispatch* it through a *Queue* or a *Stack*, with whatever *Priority* we desire. Now we need to define an `EventThread` to listen for and process our `TemperatureEvent`s.
196196

197197
**Note:** Code example in this section was updated for Version 2.0.0 due to considerable improvements, which necessitated changing the Interface slightly (for the better)
198198

199199
```swift
200-
class TemperatureProcessor: EventReceiver {
201-
/// Register our Event Listeners for this EventReceiver
200+
class TemperatureProcessor: EventThread {
201+
/// Register our Event Listeners for this EventThread
202202
override func registerEventListeners() {
203203
addEventCallback(onTemperatureEvent, forEventType: TemperatureEvent.self)
204204
}
@@ -211,7 +211,7 @@ class TemperatureProcessor: EventReceiver {
211211
```
212212
Before we dig into the implementation of `onTemperatureEvent`, which can basically do whatever we would want to do with the data provided in the `TemperatureEvent`, let's take a moment to understand what is happening in the above code.
213213

214-
Firstly, `TemperatureProcessor` inherits from `EventReceiver`, which is where all of the magic happens to receive *Events* and register our *Listeners* (or *Callbacks* or *Handlers*).
214+
Firstly, `TemperatureProcessor` inherits from `EventThread`, which is where all of the magic happens to receive *Events* and register our *Listeners* (or *Callbacks* or *Handlers*).
215215

216216
The function `registerEventListeners` will be called automatically when an instance of `TemperatureProcessor` is created. Within this method, we call `addEventCallback` to register `onTemperatureEvent` so that it will be invoked every time an *Event* of type `TemperatureEvent` is *Dispatched*.
217217

@@ -255,7 +255,7 @@ Now, let's actually do something with our `TemperatureEvent` in the `onTemperatu
255255
}
256256
}
257257
```
258-
The above code is intended to be illustrative, rather than *useful*. Our `onTemperatureEvent` passes *Event*'s encapsulated `temperatureInCelsius` to a public variable (which could then be read by other code as necessary) as part of our `EventReceiver`, and also pre-calculates a `TemperatureRating` based on the Temperature value received in the *Event*.
258+
The above code is intended to be illustrative, rather than *useful*. Our `onTemperatureEvent` passes *Event*'s encapsulated `temperatureInCelsius` to a public variable (which could then be read by other code as necessary) as part of our `EventThread`, and also pre-calculates a `TemperatureRating` based on the Temperature value received in the *Event*.
259259

260260
Ultimately, your code can do whatever you wish with the *Event*'s *Payload* data!
261261

@@ -290,8 +290,8 @@ print("Temp Rating: \(temperatureProcessor.temperatureRating)")
290290
```
291291

292292
Now you have a little Playground code to visually confirm that your *Events* are being processed. You can modify this to see what happens.
293-
### Observing an `EventReceiver`
294-
Remember, `EventRecevier`s are also *Observable*, so we can not only receive and operate on *Events*, we can also notify *Observers* in response to *Events*.
293+
### Observing an `EventThread`
294+
Remember, `EventThread`s are also *Observable*, so we can not only receive and operate on *Events*, we can also notify *Observers* in response to *Events*.
295295

296296
Let's take a look at a simple example based on the examples above.
297297
We shall begin by defining an *Observer Protocol*:
@@ -312,7 +312,7 @@ Now let's modify the `onTemperatureEvent` method we implemented in the previous
312312
}
313313
}
314314
```
315-
Now, every time a `TemperatureEvent` is processed by the `EventReceiver`, it will also notify any direct *Observers* as well.
315+
Now, every time a `TemperatureEvent` is processed by the `EventThread`, it will also notify any direct *Observers* as well.
316316

317317
It should be noted that this functionality serves as a *complement* to *Event-Driven* behaviour, as there is no "one size fits all" solution to every requirement in software. It is often neccessary to combine methodologies to achieve the best results.
318318

@@ -348,10 +348,10 @@ With the *Event* type defined, we can now once more expand our `onTemperatureEve
348348
```
349349
As you can see, we can create and *Dispatch* an *Event* in a single operation. This is because *Events* should be considered to be "fire and forget". You need only retain a copy of the *Event* within the *Dispatching Method* if you wish to use its values later in the same operation. Otherwise, just create it and *Dispatch* it together, as shown above.
350350

351-
Now that we've walked through these basic Usage Examples, see if you can produce your own `EventReceiver` to process `TemperatureRatingEvent`s. Everything you need to achieve this has already been demonstrated in this document.
351+
Now that we've walked through these basic Usage Examples, see if you can produce your own `EventThread` to process `TemperatureRatingEvent`s. Everything you need to achieve this has already been demonstrated in this document.
352352

353-
## `UIEventReceiver`
354-
Version 2.0.0 introduced the `UIEventReceiver` base class, which operates exactly the same way as `EventReciever`, with the notable difference being that your registered *Event* Callbacks will **always** be invoked on the `MainActor` (or "UI Thread"). You can simply inherit from `UIEventReceiver` instead of `EventReceiver` whenever it is imperative for one or more *Event* Callbacks to execute on the `MainActor`.
353+
## `UIEventThread`
354+
Version 2.0.0 introduced the `UIEventThread` base class, which operates exactly the same way as `EventThread`, with the notable difference being that your registered *Event* Callbacks will **always** be invoked on the `MainActor` (or "UI Thread"). You can simply inherit from `UIEventThread` instead of `EventThread` whenever it is imperative for one or more *Event* Callbacks to execute on the `MainActor`.
355355

356356
## `EventListener`
357357
Version 3.0.0 introduced the `EventListener` concept to the Library.
@@ -414,7 +414,7 @@ This way, when an *Event* is no longer relevant to your code, you can simply cal
414414

415415
## Features Coming Soon
416416
`EventDrivenSwift` is an evolving and ever-improving Library, so here is a list of the features you can expect in future releases:
417-
- **Event Pools** - A superset expanding upon a given `EventReceiver` descendant type to provide pooled processing based on given scaling rules and conditions.
417+
- **Event Pools** - A superset expanding upon a given `EventThread` descendant type to provide pooled processing based on given scaling rules and conditions.
418418

419419
These are the features intended for the next Release, which will either be *3.2.0* or *4.0.0* depending on whether these additions require interface-breaking changes to the interfaces in version *3.1.0*.
420420

Sources/EventDrivenSwift/Central/EventCentral.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,27 +28,27 @@ final public class EventCentral: EventDispatcher, EventCentralable {
2828
- Author: Simon J. Stuart
2929
- Version: 1.0.0
3030
*/
31-
@inline(__always) public static var shared: EventDispatchable {
31+
@inline(__always) public static var shared: EventDispatching {
3232
@inline(__always) get {
3333
return _shared
3434
}
3535
}
3636

37-
@inline(__always) public static subscript() -> EventDispatchable {
37+
@inline(__always) public static subscript() -> EventDispatching {
3838
@inline(__always) get {
3939
return _shared
4040
}
4141
}
4242

43-
@inline(__always) public static func addReceiver(_ receiver: EventReceivable, forEventType: Eventable.Type) {
43+
@inline(__always) public static func addReceiver(_ receiver: EventReceiving, forEventType: Eventable.Type) {
4444
_shared.addReceiver(receiver, forEventType: forEventType)
4545
}
4646

47-
@inline(__always) public static func removeReceiver(_ receiver: EventReceivable, forEventType: Eventable.Type) {
47+
@inline(__always) public static func removeReceiver(_ receiver: EventReceiving, forEventType: Eventable.Type) {
4848
_shared.removeReceiver(receiver, forEventType: forEventType)
4949
}
5050

51-
@inline(__always) public static func removeReceiver(_ receiver: EventReceivable) {
51+
@inline(__always) public static func removeReceiver(_ receiver: EventReceiving) {
5252
_shared.removeReceiver(receiver)
5353
}
5454

Sources/EventDrivenSwift/Central/EventCentralable.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,21 @@ public protocol EventCentralable {
1414
- Author: Simon J. Stuart
1515
- Version: 1.0.0
1616
*/
17-
static func addReceiver(_ receiver: any EventReceivable, forEventType: Eventable.Type)
17+
static func addReceiver(_ receiver: any EventReceiving, forEventType: Eventable.Type)
1818

1919
/**
2020
Unregisters the given `receiver` from the given `Eventable` Type for the Central Event Dispatcher
2121
- Author: Simon J. Stuart
2222
- Version: 1.0.0
2323
*/
24-
static func removeReceiver(_ receiver: any EventReceivable, forEventType: Eventable.Type)
24+
static func removeReceiver(_ receiver: any EventReceiving, forEventType: Eventable.Type)
2525

2626
/**
2727
Unregisters the given `receiver` from all `Eventable` Types from the Central Event Dispatcher
2828
- Author: Simon J. Stuart
2929
- Version: 1.0.0
3030
*/
31-
static func removeReceiver(_ receiver: any EventReceivable)
31+
static func removeReceiver(_ receiver: any EventReceiving)
3232

3333
/**
3434
Adds the given `event` to the Central Event Queue with the given `priority`

Sources/EventDrivenSwift/EventDispatcher/EventDispatcher.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ import Observable
1616
- Version: 1.0.0
1717
- Note: While you can inherit from and even create instances of `EventDispatcher`, best practice would be to use `EventCentral.shared` as the central Event Dispatcher.
1818
*/
19-
open class EventDispatcher: EventHandler, EventDispatchable {
19+
open class EventDispatcher: EventHandler, EventDispatching {
2020
struct ReceiverContainer {
21-
weak var receiver: (any EventReceivable)?
21+
weak var receiver: (any EventReceiving)?
2222
}
2323

2424
/**
@@ -28,7 +28,7 @@ open class EventDispatcher: EventHandler, EventDispatchable {
2828
*/
2929
@ThreadSafeSemaphore private var receivers = [String:[ReceiverContainer]]()
3030

31-
public func addReceiver(_ receiver: any EventReceivable, forEventType: Eventable.Type) {
31+
public func addReceiver(_ receiver: any EventReceiving, forEventType: Eventable.Type) {
3232
let eventTypeName = String(reflecting: forEventType)
3333

3434
_receivers.withLock { receivers in
@@ -49,7 +49,7 @@ open class EventDispatcher: EventHandler, EventDispatchable {
4949
}
5050
}
5151

52-
public func removeReceiver(_ receiver: any EventReceivable, forEventType: Eventable.Type) {
52+
public func removeReceiver(_ receiver: any EventReceiving, forEventType: Eventable.Type) {
5353
let eventTypeName = String(reflecting: forEventType)
5454

5555
_receivers.withLock { receivers in
@@ -63,7 +63,7 @@ open class EventDispatcher: EventHandler, EventDispatchable {
6363
}
6464
}
6565

66-
public func removeReceiver(_ receiver: any EventReceivable) {
66+
public func removeReceiver(_ receiver: any EventReceiving) {
6767
_receivers.withLock { receivers in
6868
for (eventTypeName, bucket) in receivers { /// Iterate every Event Type
6969
var newBucket = bucket // Copy the Bucket

Sources/EventDrivenSwift/EventDispatcher/EventDispatchable.swift renamed to Sources/EventDrivenSwift/EventDispatcher/EventDispatching.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// EventDispatchable.swift
2+
// EventDispatching.swift
33
// Copyright (c) 2022, Flowduino
44
// Authored by Simon J. Stuart on 4th August 2022
55
//
@@ -13,25 +13,25 @@ import Foundation
1313
- Author: Simon J. Stuart
1414
- Version: 1.0.0
1515
*/
16-
public protocol EventDispatchable: EventHandlable {
16+
public protocol EventDispatching: EventHandling {
1717
/**
1818
Registers the given `receiver` for the given `Eventable` Type
1919
- Author: Simon J. Stuart
2020
- Version: 1.0.0
2121
*/
22-
func addReceiver(_ receiver: any EventReceivable, forEventType: Eventable.Type)
22+
func addReceiver(_ receiver: any EventReceiving, forEventType: Eventable.Type)
2323

2424
/**
2525
Unregisters the given `receiver` from the given `Eventable` Type
2626
- Author: Simon J. Stuart
2727
- Version: 1.0.0
2828
*/
29-
func removeReceiver(_ receiver: any EventReceivable, forEventType: Eventable.Type)
29+
func removeReceiver(_ receiver: any EventReceiving, forEventType: Eventable.Type)
3030

3131
/**
3232
Unregisters the given `receiver` from all `Eventable` Types
3333
- Author: Simon J. Stuart
3434
- Version: 1.0.0
3535
*/
36-
func removeReceiver(_ receiver: any EventReceivable)
36+
func removeReceiver(_ receiver: any EventReceiving)
3737
}

0 commit comments

Comments
 (0)