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



_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

Open Source Applications Foundation "Dev" mailing list
http://lists.osafoundation.org/mailman/listinfo/dev

Reply via email to