-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathSplitEventActionTask.swift
More file actions
62 lines (48 loc) · 2.01 KB
/
SplitEventActionTask.swift
File metadata and controls
62 lines (48 loc) · 2.01 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
// Created by Javier L. Avrudsky on 7/6/18
import Foundation
internal typealias SplitActionWithMetadata<T: EventMetadata> = @Sendable (T) -> ()
class SplitEventActionTask: SplitEventTask, @unchecked Sendable {
private var eventHandler: SplitAction?
private var eventHandlerWithMetadata: EventMetadataHandler?
private var queue: DispatchQueue?
var event: SplitEvent
var runInBackground: Bool = false
init<T: EventMetadata>(action: @escaping SplitActionWithMetadata<T>, event: SplitEvent, runInBackground: Bool = false, queue: DispatchQueue? = nil) {
self.event = event
self.runInBackground = runInBackground
self.queue = queue
// Preserve the concrete type using type erasure container
self.eventHandlerWithMetadata = TypedEventMetadataHandler(action: action)
}
init(action: @escaping SplitAction, event: SplitEvent, runInBackground: Bool = false, queue: DispatchQueue? = nil) {
self.eventHandler = action
self.event = event
self.runInBackground = runInBackground
self.queue = queue
}
func takeQueue() -> DispatchQueue? {
defer { queue = nil }
return queue
}
func run(_ metadata: EventMetadata?) {
eventHandler?()
if let metadata = metadata {
eventHandlerWithMetadata?.execute(metadata)
}
}
}
// MARK: This below is used to preserve the concrete type of the event, since the pipeline uses the erased type.
// Type erasure container to preserve concrete type information
private protocol EventMetadataHandler: Sendable {
func execute(_ metadata: EventMetadata)
}
private struct TypedEventMetadataHandler<T: EventMetadata>: EventMetadataHandler {
let action: SplitActionWithMetadata<T>
func execute(_ metadata: EventMetadata) {
guard let typed = metadata as? T else {
Logger.e("Wrong metadata type for event handler. Expected \(T.self), got \(type(of: metadata)).")
return
}
action(typed)
}
}