For Programmers: Free Programming Magazines  


Home > Archive > Smalltalk > October 2007 > How to build efficient models that update with events?









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author How to build efficient models that update with events?
Tim M

2007-10-18, 8:13 am

I've been thinking about a recent project and how I struggled to get a good
model that would let my UI correctly stay up to date from different changes.
I'm hoping that some of the "old smalltalkers with beards" might offer some
insight.

By example, I have a sitation similar to the following:

Imagine an applicaton that shows different disk space usage - the total size
of different directories, up to the total size and free space of the disk
(this isn't my app, and I don't want to get dragged into too many nitty gritty
details of disk IO - however I wanted an example of a model that is a Tree
like structure e.g. a Disk has Directories, Directories have sub-Directories
or Files, Files have a size).

So if I consider the top level - say my UI is a big pie chart of space used
and space free - if I save a file to a subdirectory, I want that pie chart
to update. Similarly there is another window that shows the latest file update
(the date and time).

So I could imagine in my code I have something like

aFile save.
aDirectory add: aFile

These methods might be implemented (badly?) as:

"File"[color=darkred]
aStream nextPutAll: self bytes. "or whatever disk stuff needs to happen"
self
trigger: #sizeChanged: with: self size;
trigger: #dateChanged: with: self timestamp

"Directory"[color=darkred]
self contents add: aFile.
self triggerContentsChanged.
[color=darkred]
self trigger: #contentsChanged
self parent iFNotNil: [ :value | value triggerContentsChanged ]


The implemenation of #triggerContentsChanged is what is bothering me - it
can cause a "storm" of events because my graph could be showing the size
of a subdirectory (it might not be showing size from the disk but maybe from
\home\documents). It also requires every node to know its parent - although
that seems inevitable with most Tree widgets that I've seen. I can think
of a simple optimization where I just trigger the root object with the change,
and my UI just listens to events on the root and then discards uneeded ones
e.g.

self root trigger: #contentsChanged: with: self

[color=darkred]

aChangedItem isChildOf: currentSelection ifFalse: [ ^self "discard
event"]
....

Also with the #save method, it seems like you have to trigger a wide number
of attributes - possibly I can get around this by having a more generic event
whose contents is an object that describes the change e.g.
self trigger: #itemChanged: with: (SizeChange new: self size) + (DateChange
new: self timestamp)


Am I on the write track here - or am I missing something obvious? I've heard
that the VW Announcments framework might help with this - although my understanding
is that while it might give me a hierarchy of event objects so I can listen
for a higher level event - I'm still going to propogate a chain of events
unless I do the "self root" optimisation?

I also haven't touched on what happens if I add multiple files - do I really
want to generate a single event for each? I guess If I use the single event
with an Object parameter, I could make that Object a MultiEvent and add all
my changes to the same instance.

Anyway - this is long enough and I'm interested in comments/help?

Thanks,

Tim


Cesar Rabak

2007-10-18, 7:13 pm

Tim M escreveu:
> I've been thinking about a recent project and how I struggled to get a
> good model that would let my UI correctly stay up to date from different
> changes. I'm hoping that some of the "old smalltalkers with beards"
> might offer some insight.
>
> By example, I have a sitation similar to the following:
>
> Imagine an applicaton that shows different disk space usage - the total
> size of different directories, up to the total size and free space of
> the disk (this isn't my app, and I don't want to get dragged into too
> many nitty gritty details of disk IO - however I wanted an example of a
> model that is a Tree like structure e.g. a Disk has Directories,
> Directories have sub-Directories or Files, Files have a size).


OK.

>
> So if I consider the top level - say my UI is a big pie chart of space
> used and space free - if I save a file to a subdirectory, I want that
> pie chart to update. Similarly there is another window that shows the
> latest file update (the date and time).


Now things begin to become interesting. Depending upon the widget you
decide to put in the UI the changes are more or less 'disruptive' to
your UI and may require full repaint. If you were showing the file sizes
on a spreadsheet like I/F only one rung would be affected (out the adds
and deletes).

>
> So I could imagine in my code I have something like
>
> aFile save.
> aDirectory add: aFile


This seems to imply that the only changes in the environment would be
done through the application, so directory changes done elsewhere in the
system would be sensed only after an internal event.

Is this part of your spec or just acceptable behaviour?

>
> These methods might be implemented (badly?) as:
>
> "File"
> aStream nextPutAll: self bytes. "or whatever disk stuff needs to happen"
> self trigger: #sizeChanged: with: self size;
> trigger: #dateChanged: with: self timestamp
>
> "Directory"
> self contents add: aFile.
> self triggerContentsChanged.
>
> self trigger: #contentsChanged
> self parent iFNotNil: [ :value | value triggerContentsChanged ]
>
>
> The implemenation of #triggerContentsChanged is what is bothering me -
> it can cause a "storm" of events because my graph could be showing the
> size of a subdirectory (it might not be showing size from the disk but
> maybe from \home\documents). It also requires every node to know its
> parent - although that seems inevitable with most Tree widgets that I've
> seen. I can think of a simple optimization where I just trigger the root
> object with the change, and my UI just listens to events on the root and
> then discards uneeded ones e.g.


Even with the trickery you propose the events have to be sent to all the
leaves of your tree.

>
> self root trigger: #contentsChanged: with: self
>
>
>
> aChangedItem isChildOf: currentSelection ifFalse: [ ^self "discard
> event"]
> ....
>
> Also with the #save method, it seems like you have to trigger a wide
> number of attributes - possibly I can get around this by having a more
> generic event whose contents is an object that describes the change e.g.
> self trigger: #itemChanged: with: (SizeChange new: self size) +
> (DateChange new: self timestamp)
>
>
> Am I on the write track here - or am I missing something obvious? I've
> heard that the VW Announcments framework might help with this - although
> my understanding is that while it might give me a hierarchy of event
> objects so I can listen for a higher level event - I'm still going to
> propogate a chain of events unless I do the "self root" optimisation?


Yes. The only change in the use of announcements is a certain cleanness
in syntax although it makes the code harder to track (or said in other
words, less OO).

>
> I also haven't touched on what happens if I add multiple files - do I
> really want to generate a single event for each? I guess If I use the
> single event with an Object parameter, I could make that Object a
> MultiEvent and add all my changes to the same instance.


If you have the homologous UI operation, it seems sensible, otherwise
all ways I can think of seem hairy to me.

>
> Anyway - this is long enough and I'm interested in comments/help?


HTH
bgridle1@progressive.com

2007-10-22, 7:15 pm

The only object that cares about a change is the parent directory.
The GUI pie should update only when the associated directory has a
change.
If you are getting recalculations cascading down directories, you need
to cache the results of computations, so each directory has caches its
total space, and only refigures it when one of it's files changes.

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com