refreshing the GUI

Derek Atkins warlord@MIT.EDU
30 Nov 2000 10:30:26 -0500


Dave Peticolas <dave@krondo.com> writes:

> Derek Atkins writes:
> > James LewisMoss <jimdres@mindspring.com> writes:
> > 
> > > So a change to data occurs.  The engine has a registered listener in
> > > the GUI Component Manager that it calls to say something has changed.
> > > What happens then?
> > 
> > I suspect that the GUI Component Manager then calls all the components
> > that registered a callback for that particular object.
> 
> Yes, except that components don't register callbacks for particular
> objects. When a refresh cycle occurs, every registered component
> gets a callback with a hash table describing the changes. In general,
> it's difficult to characterize statically which engine objects need
> to be watched.
> 
> For example, a register in multi-line mode needs to change if any
> transaction which is a parent of one of it's splits is changed, and if
> any account which one of its splits is linked to changes.

I don't necessarily see why this is "difficult", per se.  It can
certainly be cumbersome, but that's not the same.  When you open an
account, you know that you want to set a callback on that account and
also on all transactions that touch that account.

Later, if a new transaction is created that touches that account, you
get an "add txn" callback for the account with the new transaction
info.  If a transaction/split is deleted, you get a "delete txn"
callback, either for the account or the txn.  If a transaction split
touching that account is modified, which may include changing the
account of a split, you get a "mod txn" callback (and then possibly an
"add txn" callback for the new split account).

Ok, maybe I'm just blowing smoke here, but it doesn't seem that hard.
Let me look at is like a filesystem, where a directory is an account,
and files are transactions.  You can "link" files across multiple
directories to indicate splits, and you can mount directories within
directories to create account hierarchies.  (Note, a directory _may_
be "mounted" in more than one place, to the filesystem is not
necessarily a tree -- however it can be considered a directed graph).
In this analogy, anytime a new file (transaction) is created, you know
the directory in which is was created (via the create operation).
Every time a new split is made, you know the directory of the split
(via the link operation) as well as the transaction (the file).  Every
time a split is removed, you know the directory of the removed split
(via the remove operation) as well as the transaction (the file).
Every time a transaction is modified, you know the transaction (the
file).

Perhaps this would add up to a LOT of callbacks, having to specify a
callback for each transaction in each "open" account.  In that sense,
yes, it is unwieldy.  However, I don't believe that it is "difficult
to to characterize statically which engine objects need to be
watched."  I think the above model does a fairly decent job, depending
on what the GUI has "open".

> Each time a split is added to the account, potentially more transactions
> and accounts would need to be added to the watch list.

This is true.. So you add a new callback when this happens.  And then
you remove the callback when you close() the GUI.

> Given the relatively small number of gui components, I decided it would
> be easier just to have them all called each time.

Except this doesn't scale to large systems.  If we do get GnuCash to
the point where it is replacing something like QuickBooks, we might
have a system with a centralized engine/data storage and distributed
GUIs where tens or hundreds of users may be accessing data.  You don't
want to be forcing callbacks to all the components (remember that a
change in one GUI may affect the data in another GUI) every time a
change is necessary.  Really, you only want to contact a client if
something they care about has been changed.

> That's right, but I envisioned having only one CM.

Is that one CM for the system, or one CM per GUI?  Imagine a
distributed system with multiple GUIs attached to the same data store
engine.

> Hopefully my previous email explained that well enough?

Yes, your subsequent mail did explain that successfully, but you may
have a locking problem in the case of multiple GUIs touching the same
data.

I'd like to try to come up with a reasonable multi-user design _now_,
even if we're only implementing a single-user application.  That way,
down the road, splitting the GUI, engine, and data store, and adding a
network protocol between the two, would be easier.

> dave

-derek

-- 
       Derek Atkins, SB '93 MIT EE, SM '95 MIT Media Laboratory
       Member, MIT Student Information Processing Board  (SIPB)
       URL: http://web.mit.edu/warlord/      PP-ASEL      N1NWH
       warlord@MIT.EDU                        PGP key available