How about this:
We already have wxSynchronizeWidget on the widget. Add a new method on
the widget called something like processNotificationForDirtying, or a
better name that you choose. All notifications are processed by this
process routine. You can implement yours on wxCalendar to accumulate
hints and always dirty the block. I can implement mine on wxTable to
only dirty the block if it the data that's changed is on the screen. In
either case SyncronizeWidget is called when it's dirtied.
With this solution you get what you want for Calendar and I get what I
want for Table.
The irony of your solution is we already have a list of notifcations
that are maintained by the repository. You take that list and create an
entirely new list, then process them later. I just process the list
once at the beginning instead of creating a new list and delaying the
processing.
Also, I was curious to know if you ever ignored notifications when
dragging events on the calendar, editing events or side effects of
redrawing. I wouldn't be surprised if that would eliminate a bunch of
unnecessary synchronizeWidget calls. It did for the Table.
Alec Flett wrote:
John Anderson wrote:
Blocks and widgets doen't really have a controller. But I don't really
care about that. If you want to make a controller we can do that.
yes, they do have a controller, although its very rudimentary - its the
dirty block mechanism.
Actually there is a lot of "controller" functionallity today and it's
mostly part of the widget, e.g. clicking on a widgets, dragging, cut,
copy paste, etc.
What
I really care about is a performance issue. I want to be able to
process the notifications for my table, ignore changes to items that
aren't visible and ONLY keep a dirty bit if the change affects
something on the screen
So I think what we're really debating about is how the "dirtying" works.
Lets see if I've got you position correct. If everything goes according
to what you say:
1) when changes come in, you want to flag a block dirty only if the
changes affect the given block. Each block can do some pre-processing
to determine which changes are relevant.
2) when the block is dirtied, the block is resynchronized during the
onidle loop
3) its up to the block to have saved some sort of hint about what is
actually affected during 1), so that when the synchronize happens, they
know what to update on screen
Advantages: blocks are only "dirtied" and resynchronized (i.e.
synchronizeWidget() is called) only if the notifications caused a
relevant change.
Disadvantage: hints must be processed once when they come in as
parameters from notification callbacks (in 1) above) to filter out the
relevant hints, or transform the hints into block-specific hints. Then
the filtered/transformed hints need to be processed again during 3),
when the block has to look through the hints to see what specifically
needs to be updated
You need to process the event or the hint in either scheme, so
processing isn't a disadvantage. However, only the widget know whether
the notification can be ignored, e.g. doesn't affect the screen. I
don't need any further hints to be saved. All I need is an bool that
causes SynchronizeWidget to be called, just like we do today.
Here's what I'm suggesting:
1) when changes come in, they are unconditionally accumulated. Blocks
are "dirty" if any notifications have come in for that block
2) when the "dirty blocks" are synchronized via synchronizeWidget(),
the blocks decide if they need to actually rebuild themselves based on
the hints that came in.
Advantages: hints are processed in one place - synchronizeWidget().
further, the same hints, in the same format, are used across all
blocks. No special code needs to be written to decide which blocks are
"dirty" and which aren't.
Disadvantages: blocks may be considered "dirty" even if
synchronizeWidget() ends up doing nothing.
don't
want to accumulate your hints on my
block because I'll never use them.
That makes no sense, unless you really want to think of them as 'Alec's
personal hints' - because its the same exact information, bit for bit,
that you'd be processing in your table. I'd just pass them to you in
synchronizeWidget, rather than inventing a new way for blocks to
intervene in the block-dirtying process.
I think of them as Calendar's hints, since Tables don't need them. What
we don't agree on is the need for a widget specific function to process
notifications and a widget specific hints. And I think some widgets,
e.g. Tables don't event need hints for SynchronizeWidget. Although I
could see adding them later, but they could very well be widget
specific, e.g. row and column information..
I'm suggesting a general mechanism for all blocks rather than
requiring each block to figure out how to defer the hints until the
synchronize. In my mind, that is simpler, more general, and much easier
to maintain.
Alec
It
just makes things way more
efficient if we can process notificaitons as we go instead of storing
them to process later. Surely we can think of a way to do this that
works with your MVC view of CPIA, right?
John
Alec Flett wrote:
John Anderson wrote:
I'd still vote for this hint accumulation to be block specific, e.g.
Calendar only. Consider the case where you did some very large
operation and didn't get back to the idle loop for a long time. Also,
for many blocks, e.g. Table and Calendar most if not all the hint
information doesn't need to be kept around until synchronization, it
can be processed when the event is handled and never needs to be stored.
I think that doing that would once again break the MVC paradigm in
CPIA. It seems like you're saying that for some operations, the model
should be talking directly to the view, and bypass the controller.. the
notification mechanism is a pretty key part of the controller. The
controller (in this case the block synchronizing code) needs to ensure
that mutations to the model are propagated to the view in the order
they happen. If the model (blocks) immediately updates the view
(widgets) in some cases, but notifications are also coming in
asynchronously via the synchronizeWidget() call, then things are more
or less guaranteed to get out of sync.
Plus I'm not really sure why accumulating a list of hints is harmful.
Maybe you're worried about memory usage? The hints are tuples of things
like (collection, operation, item) and maybe 1-2 other parameters.
We're talking about 16-32 bytes per hint - only 16k even if tons of
events come in. They don't take up a lot of memory, and python lists
are very efficient.
Maybe you're worried that if 10,000 hints are passed in via
wxSynchronizeWidget() that the widget in question would waste a lot of
time processing 10,000 hints? I feel like that is an optimization we
can make on a per-widget level - if 10,000 hints come in, then we just
blow away the widget and rebuild it from the block data. But we make
that call when we hit performance limits - we don't prematurely
optimize that now.
Alec
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Open Source Applications Foundation "Dev" mailing list
http://lists.osafoundation.org/mailman/listinfo/dev
|