Page 1 of 1

Efficiently filling an ObservableCollection<T>?

Posted: 09 Jul 2021, 19:01
by HateDread
Tonight was my first time using ObservableCollection<T>, and I was surprised to not find equivalents of std::vector's reserve and resize, or inserting ranges of elements (inc. overload to move instead of copy, although less useful for my purposes).

If I have a collection coming from the game/engine layer outside of the UI, e.g. a std::vector<SomeUnit>, and I want to fill out an ObservableCollection<SomeUnitModel> or equivalent, my go-to pattern would be to reserve the collection size up-front to avoid multiple allocations, and then to iterate and add. In serious perf situations, esp. if the insertion required some more expensive conversion step, I would resize up-front and run a parallel for split by index.

Some of that would be a bit much for now, but just curious why those functions aren't available. Is there a way to get down to the memory of the base vector under the collection?

EDIT: On further inspection, it only takes objects by pointer anyway. It's not clear whether it owns the memory or not; I'm guessing not? How is it intended to be used; with some backing memory behind it that actually owns the objects?

Re: Efficiently filling an ObservableCollection<T>?

Posted: 14 Jul 2021, 13:57
by jsantos
ObservableCollection mimics the C# API but nothing stops your from creating your own implementation of IList, INotifyCollectionChanged and INotifyPropertyChanged following our implementation. In fact, BaseCollection exposes the internal vector as protected so I think you could even inherit from ObservableCollection and get access to that vector to handle memory in a more efficient way.

We have plans to directly support custom array implementations (std::vector, Noesis::Vector or your own implementation) as bindable collection in the future.

These collection use internally BaseComponent instances and they own the memory using our reference counting mechanism.