Digital PCT265 story PCT-135: Change filtering fix, disable partial page updates, move manager newDataReceived.

This commit is contained in:
Hedden, Kyle Matthew 2024-05-21 14:00:07 -04:00
parent 8135a126ed
commit f403e34d7d

View File

@ -105,10 +105,6 @@ import MVMCore
hasDataUpdate = true
loadObject.pageJSON = pagesLoaded.optionalDictionaryForKey(pageType)
// TODO: Parse parsePageJSON modifies the page model on a different thread than
// the UI update which could cause discrepancies. Parse should return the resulting
// object and assignment should be synchronized on handleNewData(model: ).
// Separate page updates from the module updates to avoid unecessary resets to behaviors and full re-renders.
do {
pageModel = try parsePageJSON(loadObject: loadObject)
@ -262,11 +258,13 @@ import MVMCore
// Replace again in case there is a template level child.
if let replaced = try? newTemplateModel.replaceChildMolecule(with: molecule) {
// Only recognize the molecules that actually changed.
debugLog("Behavior updated \(changes) in template model.")
changes = changes.filter({ model in
behaviorUpdatedModels.contains { $0.id == model.id }
})
behaviorUpdatedModels.append(contentsOf: changes)
if changes.count > 0 {
debugLog("\(behavior) updated \(changes) in template model.")
changes = changes.filter({ model in
!behaviorUpdatedModels.contains { $0.id == model.id }
})
behaviorUpdatedModels.append(contentsOf: changes)
}
} else {
debugLog("Failed to replace \(molecule) in the template model.")
}
@ -289,37 +287,36 @@ import MVMCore
if let originalModel, // We had a prior.
let newPageModel = newPageModel as? TemplateModelProtocol,
originalModel.id != newPageModel.id {
let diffs = newPageModel.deepCompare(against: originalModel) { new, old in
!new.isEqual(to: old)
}
debugLog("Page molecule updates\n\(diffs.map {"\($0.mine) vs. \($0.theirs)"}.joined(separator: "\n"))")
pageUpdatedModels = diffs.compactMap { $0.theirs as? MoleculeModelProtocol }
// This isn't ready yet. handleNewData for the ListTemplate triggers a row item reset and full rebuild + StackTemplate isn't targeting individual refreshes anyway.
// pageUpdatedModels = originalModel.findAllTheirsNotEqual(against: newPageModel)
// debugLog("Page molecule updates\n\(pageUpdatedModels)")
isFirstRender = true // Instead force a full render whenever there is a page data change.
}
let allUpdatedMolecules = isFirstRender ? [] : behaviorUpdatedModels + pageUpdatedModels
let allUpdatedMolecules = behaviorUpdatedModels //+ pageUpdatedModels
isFirstRender = false
// Notify the manager of new data.
// Warning: Some flows cause table reloads. Until the UI update is decoupled, should be after the updateUI.
manager?.newDataReceived?(in: self)
// Dispatch to decouple execution. First massage data through template classes, then render.
Task { @MainActor in
if allUpdatedMolecules.isEmpty {
if allUpdatedMolecules.isEmpty || isFirstRender {
debugLog("Performing full page render...")
updateUI()
} else {
debugLog("Performing partial render of \(allUpdatedMolecules) molecules...")
updateUI(for: allUpdatedMolecules)
}
// Notify the manager of new data.
// Warning: Some flows cause table reloads. Until the UI update is decoupled, should be after the updateUI.
manager?.newDataReceived?(in: self)
}
}
/// Applies the latest model to the UI.
open func updateUI(for molecules: [MoleculeModelProtocol]? = nil) {
isFirstRender = false
executeBehaviors { (behavior: PageMoleculeTransformationBehavior) in
behavior.willRender(rootMolecules: molecules ?? getRootMolecules(), delegateObjectIVar)
}