mirror of
https://github.com/divkit/divkit.git
synced 2026-06-06 20:07:59 +00:00
DivVariablesStorage refactoring
This commit is contained in:
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user