Digital PCT265 defect CXTDT-579050: Change batching to the UI.
This commit is contained in:
parent
d8d4b37d1d
commit
4cbf15a3a7
@ -70,41 +70,34 @@ import Combine
|
||||
observingForResponses = NotificationCenter.default.publisher(for: NSNotification.Name(rawValue: NotificationResponseLoaded))
|
||||
.receive(on: self.pageUpdateQueue) // Background serial queue.
|
||||
.map { [weak self] notification in
|
||||
guard let self = self else { return (nil, nil, nil) }
|
||||
// Get the page data.
|
||||
let pageUpdates = self.extractInterestedPageType(from: notification.userInfo?.optionalDictionaryForKey(KeyPageMap) ?? [:])
|
||||
// Convert the page data into a new model.
|
||||
var pageModel: PageModelProtocol? = nil
|
||||
if let pageUpdates {
|
||||
do {
|
||||
// TODO: Rewiring to parse from plain JSON rather than this protocol indirection.
|
||||
pageModel = try (self as? any TemplateProtocol & PageBehaviorHandlerProtocol & MVMCoreViewControllerProtocol)?.parseTemplate(pageJSON: pageUpdates)
|
||||
} catch {
|
||||
if let coreError = MVMCoreErrorObject.createErrorObject(for: error, location: "updateJSON for pageType: \(String(describing: self.pageType))") {
|
||||
MVMCoreLoggingHandler.shared()?.addError(toLog: coreError)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Get the module data.
|
||||
let moduleUpdates = self.extractInterestedModules(from: notification.userInfo?.optionalDictionaryForKey(KeyModuleMap) ?? [:])
|
||||
// Bundle the transformations.
|
||||
return (pageUpdates, pageModel, moduleUpdates)
|
||||
self?.pullUpdates(from: notification) ?? (nil, nil, nil)
|
||||
}
|
||||
.filter { (pageUpdates: [String : Any]?, pageModel: PageModelProtocol?, moduleUpdates: [String : Any]?) in
|
||||
// Skip any non-updates.
|
||||
(pageUpdates != nil && pageModel != nil) || (moduleUpdates != nil && moduleUpdates!.count > 0)
|
||||
}
|
||||
// Opportunity: Merge all module only updates into one event.
|
||||
// Merge all page and module updates into one update event.
|
||||
//.print("[Update pipe] merging")
|
||||
.scan((nil, nil, nil)) { accumulator, next in
|
||||
// Always take the latest page and the latest modules with same key.
|
||||
return (next.0, next.1, next.2?.mergingRight(accumulator.2 ?? [:]))
|
||||
}
|
||||
//.print("[Update pipe] into buffer")
|
||||
// Hold onto the latest merged state until UI is ready for an update. Keep only the latest from scan.
|
||||
.buffer(size: 1, prefetch: .byRequest, whenFull: .dropOldest)
|
||||
//.print("[Update pipe] out of buffer")
|
||||
// Delay allowing the previous model update to settle before triggering a re-render.
|
||||
.buffer(size: 100, prefetch: .byRequest, whenFull: .dropOldest)
|
||||
.flatMap(maxPublishers: .max(1)) { Just($0).delay(for: .seconds(0.1), scheduler: RunLoop.main) }
|
||||
.flatMap(maxPublishers: .max(1)) { buffer in
|
||||
Just(buffer).delay(for: .seconds(0.1), scheduler: RunLoop.main)
|
||||
}
|
||||
.sink { [weak self] (pageUpdates: [String : Any]?, pageModel: PageModelProtocol?, moduleUpdates: [String : Any]?) in
|
||||
guard let self = self else { return }
|
||||
if let pageUpdates, let pageModel {
|
||||
if let pageUpdates, pageModel != nil {
|
||||
self.loadObject?.pageJSON = pageUpdates
|
||||
}
|
||||
var mergedModuleUpdates = (loadObject?.modulesJSON ?? [:]).mergingLeft(moduleUpdates ?? [:])
|
||||
let mergedModuleUpdates = (loadObject?.modulesJSON ?? [:]).mergingLeft(moduleUpdates ?? [:])
|
||||
self.loadObject?.modulesJSON = mergedModuleUpdates
|
||||
self.debugLog("Applying async update page model \(pageModel.debugDescription) and modules \(mergedModuleUpdates.keys) to page.")
|
||||
self.handleNewData(pageModel)
|
||||
}
|
||||
}
|
||||
@ -115,6 +108,28 @@ import Combine
|
||||
self.observingForResponses = nil
|
||||
}
|
||||
|
||||
func pullUpdates(from notification: Notification) -> (pageUpdates: [String : Any]?, pageModel: PageModelProtocol?, moduleUpdates: [String : Any]?) {
|
||||
// Get the page data.
|
||||
let pageUpdates = extractInterestedPageType(from: notification.userInfo?.optionalDictionaryForKey(KeyPageMap) ?? [:])
|
||||
// Convert the page data into a new model.
|
||||
var pageModel: PageModelProtocol? = nil
|
||||
if let pageUpdates {
|
||||
do {
|
||||
// TODO: Rewiring to parse from plain JSON rather than this protocol indirection.
|
||||
pageModel = try (self as? any TemplateProtocol & PageBehaviorHandlerProtocol & MVMCoreViewControllerProtocol)?.parseTemplate(pageJSON: pageUpdates)
|
||||
} catch {
|
||||
if let coreError = MVMCoreErrorObject.createErrorObject(for: error, location: "updateJSON for pageType: \(String(describing: self.pageType))") {
|
||||
MVMCoreLoggingHandler.shared()?.addError(toLog: coreError)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Get the module data.
|
||||
let moduleUpdates = extractInterestedModules(from: notification.userInfo?.optionalDictionaryForKey(KeyModuleMap) ?? [:])
|
||||
debugLog("Receiving page \(pageModel?.pageType ?? "none") & \(moduleUpdates?.keys.description ?? "none") modules from \((notification.userInfo?["MVMCoreLoadObject"] as? MVMCoreLoadObject)?.requestParameters?.url?.absoluteString ?? "")")
|
||||
// Bundle the transformations.
|
||||
return (pageUpdates, pageModel, moduleUpdates)
|
||||
}
|
||||
|
||||
open func pagesToListenFor() -> [String]? {
|
||||
guard let pageType = loadObject?.pageType else { return nil }
|
||||
return [pageType]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user