Currently notifiers types are hard coded, where listeners make assumptions about the content each region shows.
This fails when the contents of a window is defined by add-ons, or defined dynamically.
Typical cases are:
- Add-ons expose buttons for properties not accessed by default for those regions.
- Manipulators in the view-port may control properties which users will expect to be refreshed when changed elsewhere (2.8 only).
I'm proposing to update this system with a dynamic and more general system using the publish-subscribe pattern.
This task was prompted by manipulators not responding updates to changes elsewhere, currently there are many noticeable glitches.
- As the interface is constricted (manipulators and properties), the region subscribes to changes from the properties.
- Upon modification, changes to the property are published. (RNA property update)
- Subscribers are notified of the change (their callbacks are executed).
- RNA properties will be one type of message, we may want to use this system for listening to other kinds of changes (listening to file-system message for example).
I expect RNA property messages cover most cases, keeping option open to have other kinds of messages just helps to be future proof.
- There is some overlap with bpy.app.handlers since it should be possible to listen to changes to Scene.frame_current which is similar to frame_change_post handler.
The difference is this system is intended for refreshing the interface after a change - and they should never make destructive changes, also - unlike bpy.app.handlers you wont have pre/post conditions.
- It's not well defined how granular publish/subscribe messages should be.
- Only publishing changes from ID data-blocks is too course.
- Publishing changes to individual vertices is too fine grained.
I'd suggest to make array-elements an exception, where an (ID-data-block + mesh-vertex-property) pair could be used, avoiding the issue of treating each vertex separately.
There is still some areas that aren't well defined: how should we handle modifiers or fcurve properties for example as a single unit, or handle each property separately.
This can be changed as we go, so I'm not too worried about this.
- It may be useful for Python to be able to subscribe to messages too.
There is nothing to prevent this from being supported, however it's not part of this initial proposal.
- Performance: keeping the overhead of maintaining the messages low.
Each full-redraw will create a set of data to listen out for - which need to be stored for fast matching in the case a change is made.
I'm mostly concerned with the overhead of allocation, hashing and de-duplicating.
This may not end up being slower overall than our current notifier system, which redraws often *just-incase* a change elsewhere is needed.
Nevertheless there is a difference with the old notifier system, where the inefficiencies happen when listening to changes instead of when drawing buttons and manipulators.
- Migrating from the existing notifier system.
This will be kept in-place initially, we should be able to phase it out.
- Exactly how the 3D view should subscribe to changes from mesh/lamp... etc.
We may end up needing to listen to changes on a per-datablock level in this case.
Even then - if there are 1000 objects in the view. Would this add 1000 listeners on each redraw?
Suggest in this case we don't attempt to track individual ID's the draw-manager for each 3D view can listen to a fixed set of properties with PointerRNA.id.data set to NULL, with the down-side that changes to an object will cause a redraw even if it's not in the view.
This is at least no worse than the current system.
- As with the current notifier system, we'll need to make sure stale data is cleared.