When doing batch updating of a wxDataViewCtrl with a wxDataViewModel, using ItemsChanged to signal updates to existing items it is causing the macOS NSOutlineView to reload and resort on every item (calling reloadItem:). This is extremely slow and quickly overwhelms the main thread with a minimal amount of objects ~1500 causing hangs.
Using the batch update API ItemsChanged on wxDataViewModel triggers the NSOutlineView to reload the item (and possibly subitems) and redraw for each item in the array. This quickly overwhelms the OS control and effectively hangs the app.
bool wxOSXDataViewModelNotifier::ItemsChanged(wxDataViewItemArray const& items) { size_t const noOfItems = items.GetCount(); for (size_t indexItem=0; indexItem<noOfItems; ++indexItem) if (m_DataViewCtrlPtr->GetDataViewPeer()->Update(GetOwner()->GetParent(items[indexItem]),items[indexItem])) //This needs to change { // send for all changed items a wxWidgets event: wxDataViewEvent dataViewEvent(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED,m_DataViewCtrlPtr,items[indexItem]); m_DataViewCtrlPtr->HandleWindowEvent(dataViewEvent); } else return false; // if this location is reached all items have been updated: AdjustRowHeights(items); AdjustAutosizedColumns(); // done: return true; }
All items should be inserted into the model, then the control is resorted and redrawn one time after insertions are complete.
Something like this:
wxDataViewItemArray itemsChanged; .... for (_node in updatedNotes) itemsChanged.Add(_node); ItemsChanged(itemsChanged);
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
cc @hwiesmann who I believe originally wrote this code
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Looking at the code more, this is a tough one. I know my intention is to update multiple items with the same parent, thus only requiring the parent to be refreshed one time. However, the kit is trying to do something in a more generic manor which isn't wrong per se, but results in a major performance problem. Also, in some cases, refreshing the parent items would be the wrong choice, so changing this behavior to refresh just parent nodes isn't ideal either.
This leads me back to this comment. In some of these edge cases it would be useful to have the ability to turn off notifiers and then be able to turn them back on causing a full control refresh (or maybe just refreshing passed in items?) instead of trying to guess the users intention and getting it wrong like in this case.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()