I notice the mmap code modifies EditViewBase so as to update the
mmapped segment when something is found to have changed in the
edit view. This looks surpassing iffy to me: what if something
changes while there are many edit views visible, or none? does
the mmapped segment get updated many times, or never?
It looks like this code could do with having its refresh logic
sorted out in much the same way as some of the other bits we've
been discussing lately. So let me go over the possibilities we
have for managing refreshes now.
The problem: My code wants to know when something's changed in
the composition or a segment (or the studio or elsewhere) so
that it knows it has to do a refresh, but it doesn't necessarily
want to refresh immediately anything changes (better to batch
and do the refresh when the data is next needed, or when we're
next idle).
There are two parts to this.
1. We have to make sure we get control somehow during the next
event loop or whenever the refresh is to happen. For edit
views, we do this by attaching the command history's
commandExecuted signal to our QWidget update method, which
causes Qt to batch an update request and call paintEvent on
the widget from the next event loop.
This part is less obvious for something that is not a widget,
like the mmap management code. I'm sure it's possible to
register that Qt should call us back during the next event
loop even if we aren't a widget, though. Also, invoking
this from commandExecuted means that we miss out on things
that change without using commands (including some very
obvious things like changing the transpose level on a
segment).
2. When we get control, we have to know what's changed so
that we can refresh it. The two different ways to do this
are:
a. Use RefreshStatuses. These exist on Composition and
Segment at the moment. To use these, we request a
refresh status ID from the Composition or Segment, and
that gives us a personal refresh status for that object:
we can reset it, and then query whether it's changed
since you did so. This has its problems:
* Although the Segment refresh status includes handy
information about which region of the Segment has
changed, the Composition status tells us nothing
except that _something_ has changed. This is why the
segment canvas has that complicated code that compares
the Composition against its stored set of Segments to
find out whether a Segment has been added or removed
or what. It's much harder to come up with a good
structure for explaining changes in the Composition
than it is for the Segment.
* If we want to get refresh status for lots of things --
such as all the segments in a composition -- then we
have to keep track of refresh status IDs for all of
them separately.
b. Use Observers. These have existed for a while on Segment
and now (since the merge) exist on Composition as well.
To use these, we attach as an observer to each object
we're interested in, and that gives us a callback
immediately something changes; we can use that callback
to make a note of what's changed, for use when we get
to our refresh function. Problems here:
* We need to attach and detach our observers explicitly.
* It imposes an overhead on modifications to the Segment
or Composition, because our observer's callback has to
be called every time something changes.
* Storing a record of what has changed, for our own use,
is basically the same problem as making a refresh
status object that can describe it to us -- except it
means the code is duplicated across all observers.
As to how best to use all this, my gut feel is that we should
probably work to make the refresh status code do what we need,
in cases where it doesn't now. This mostly means enhancing the
Composition to use a dedicated RefreshStatus object that can
actually describe things like segments added and removed rather
than just noting that "something happened". It also means
finding a way for non-widgets to get notification from an event
loop in the same way as widgets' batched paintEvent calls.
What d'you think? I could just go ahead and do some of this,
I guess.
Chris
-------------------------------------------------------
This SF.net email is sponsored by: VM Ware
With VMware you can run multiple operating systems on a single machine.
WITHOUT REBOOTING! Mix Linux / Windows / Novell virtual machines at the
same time. Free trial click here: http://www.vmware.com/wl/offer/345/0
_______________________________________________
Rosegarden-devel mailing list
[EMAIL PROTECTED] - use the link below to unsubscribe
https://lists.sourceforge.net/lists/listinfo/rosegarden-devel