DivVariablesStorage refactoring

This commit is contained in:
pkurchatov
2023-03-24 17:29:55 +03:00
parent 17d913c60b
commit aa0ff01e2f
3 changed files with 42 additions and 45 deletions
@@ -22,15 +22,15 @@ public final class DivTriggersStorage {
self.variablesStorage = variablesStorage
self.actionHandler = actionHandler
self.urlOpener = urlOpener
variablesStorage.changeEvents.addObserver { [unowned self] event in
variablesStorage.addObserver { [unowned self] event in
let cardIdTriggersPairs = makeCardIdTriggersPairsForEvent(event)
cardIdTriggersPairs.forEach { (cardId, triggers) in
tryRunTriggerActions(
triggers: triggers,
cardId: cardId,
changesVariablesNames: event.kind.names,
newVariables: event.variables.new.makeVariables(for: cardId),
oldVariables: event.variables.old.makeVariables(for: cardId)
newVariables: event.newValues.makeVariables(for: cardId),
oldVariables: event.oldValues.makeVariables(for: cardId)
)
}
}.dispose(in: autodisposePool)
@@ -36,9 +36,9 @@ public enum DivVariableValue: Equatable {
public typealias DivVariables = [DivVariableName: DivVariableValue]
public final class DivVariablesStorage {
public struct Variables {
var global: DivVariables = [:]
var local: [DivCardID: DivVariables] = [:]
public struct Values {
public internal(set) var global: DivVariables = [:]
public internal(set) var local: [DivCardID: DivVariables] = [:]
func makeVariables(for cardId: DivCardID) -> DivVariables {
global + (local[cardId] ?? [:])
@@ -52,25 +52,14 @@ public final class DivVariablesStorage {
case global(Set<DivVariableName>)
}
public struct VariablesValues {
public let old: Variables
public let new: Variables
init(
old: Variables,
new: Variables
) {
self.old = old
self.new = new
}
}
public let kind: Kind
public let variables: VariablesValues
public let oldValues: Values
public let newValues: Values
init(kind: Kind, variables: VariablesValues) {
init(kind: Kind, oldValues: Values, newValues: Values) {
self.kind = kind
self.variables = variables
self.oldValues = oldValues
self.newValues = newValues
}
}
@@ -79,7 +68,7 @@ public final class DivVariablesStorage {
changeEventsPipe.signal
}
private var storage = Variables()
private var storage = Values()
private let rwLock = RWLock()
public init() {}
@@ -96,19 +85,20 @@ public final class DivVariablesStorage {
cardId: DivCardID,
variables: DivVariables
) {
let oldVariables = storage
let oldValues = storage
rwLock.write {
storage.local[cardId] = variables
}
let changedVariables = makeChangedVariables(
old: rwLock.read { oldVariables.local[cardId] ?? [:] },
old: rwLock.read { oldValues.local[cardId] ?? [:] },
new: variables
)
if changedVariables.isEmpty { return }
update(with: ChangeEvent(
update(ChangeEvent(
kind: .local(cardId, changedVariables),
variables: ChangeEvent.VariablesValues(old: oldVariables, new: storage)
oldValues: oldValues,
newValues: storage
))
}
@@ -128,14 +118,15 @@ public final class DivVariablesStorage {
variables: DivVariables,
triggerUpdate: Bool
) {
let oldVariables = storage
let oldValues = storage
storage.global = variables
if triggerUpdate {
let changedVariables = makeChangedVariables(old: oldVariables.global, new: variables)
let changedVariables = makeChangedVariables(old: oldValues.global, new: variables)
if changedVariables.isEmpty { return }
update(with: ChangeEvent(
update(ChangeEvent(
kind: .global(changedVariables),
variables: ChangeEvent.VariablesValues(old: oldVariables, new: storage)
oldValues: oldValues,
newValues: storage
))
}
}
@@ -155,11 +146,15 @@ public final class DivVariablesStorage {
public func reset() {
rwLock.write {
storage = Variables()
storage = Values()
}
}
private func update(with event: ChangeEvent) {
public func addObserver(_ action: @escaping (ChangeEvent) -> Void) -> Disposable {
changeEvents.addObserver(action)
}
private func update(_ event: ChangeEvent) {
onMainThread { [weak self] in
self?.changeEventsPipe.send(event)
}
@@ -188,23 +183,25 @@ extension DivVariablesStorage: DivVariableUpdater {
rwLock.write {
var cardVariables = storage.local[cardId]
if let localValue = cardVariables?[name] {
let oldStorage = storage
let oldValues = storage
let isUpdated = cardVariables?
.update(name: name, oldValue: localValue, value: value) ?? false
storage.local[cardId] = cardVariables
if isUpdated {
update(with: ChangeEvent(
update(ChangeEvent(
kind: .local(cardId, [name]),
variables: ChangeEvent.VariablesValues(old: oldStorage, new: storage)
oldValues: oldValues,
newValues: storage
))
}
} else if let globalValue = storage.global[name] {
let oldVariables = storage
let oldValues = storage
let isUpdated = storage.global.update(name: name, oldValue: globalValue, value: value)
if isUpdated {
update(with: ChangeEvent(
update(ChangeEvent(
kind: .global([name]),
variables: ChangeEvent.VariablesValues(old: oldVariables, new: storage)
oldValues: oldValues,
newValues: storage
))
}
} else {
@@ -171,8 +171,8 @@ final class DivVariablesStorageTest: XCTestCase {
storage.update(cardId: cardId, name: "string_var", value: "new value")
XCTAssertEqual(.local(cardId, ["string_var"]), event?.kind)
XCTAssertEqual(variables, event?.variables.old.makeVariables(for: cardId))
XCTAssertEqual(makeVariables(), event?.variables.new.makeVariables(for: cardId))
XCTAssertEqual(variables, event?.oldValues.makeVariables(for: cardId))
XCTAssertEqual(makeVariables(), event?.newValues.makeVariables(for: cardId))
}
func test_set_SendsUpdateEvent() {
@@ -230,8 +230,8 @@ final class DivVariablesStorageTest: XCTestCase {
storage.set(variables: globalVariables, triggerUpdate: true)
XCTAssertEqual(.global(["global_var"]), event?.kind)
XCTAssertEqual([:], event?.variables.old.global)
XCTAssertEqual(globalVariables, event?.variables.new.global)
XCTAssertEqual([:], event?.oldValues.global)
XCTAssertEqual(globalVariables, event?.newValues.global)
}
func test_setGlobalVariables_SendsUpdateEvent_ForUpdatedVariablesOnly() {
@@ -243,8 +243,8 @@ final class DivVariablesStorageTest: XCTestCase {
storage.set(variables: newVariables, triggerUpdate: true)
XCTAssertEqual(.global(["string_var", "int_var"]), event?.kind)
XCTAssertEqual(variables, event?.variables.old.global)
XCTAssertEqual(newVariables, event?.variables.new.global)
XCTAssertEqual(variables, event?.oldValues.global)
XCTAssertEqual(newVariables, event?.newValues.global)
}
func test_setGlobalVariables_DoesNotSendUpdateEvent_WhenTriggerUpdateIsFalse() {