On Thu, 25 May 2006 15:06:23 -0400, Harry Vennik <[EMAIL PROTECTED]>
wrote:
Op donderdag 25 mei 2006 17:08, schreef Youness Alaoui:
On Thu, 25 May 2006 06:55:10 -0400, Harry Vennik <[EMAIL PROTECTED]>
[CUT]
and have all those events get directed to the same function ? it's
easier
this way. (also, we want to abstract gui and protocol rigght ? so the
protocol shouldn't know what *is* a visual data.. for the
abook/contact/account/protocol/whatever, the psm is just an option of a
contact, it doesn't know if our GUI shows the PSM or if it's hidden...
Hehe, I had to give it some name, at first I called it
contactDataChange, but
then I thought that might be too general, but I still wanted to limit the
number of events, because the change of a nick, psm or dp will be of
interest
in the same places most of the time.
WOOOOOW, so far we agree ! :) it's rare that both our brains are in sync
on a design :P cool :)
> Also, about the abook structure: do not have group objects contain
> contact objects (however, in the gui part, a clgroup should contain
one or
> more clcontact objects).
> In the abook part, a contact should keep references to the groups it
> belongs to, and the abook object itself keeps references to all
contact
> objects and all group objects (either implicit or explicit), to pass
on
> the calls that modify contact or group data.
no, I think crossreferencing is better, but I understand your point..
the
contacts should have the groups they belong to (groups, as in objects,
not
the groupids, if we want the group ids, we'll loop through the objects
and
do a cget -gid), but the groups should also have a reference to the
contacts they have.. think about it, you want to mass message a group,
so
you do
$group getContacts
and it does :
method getcontacts { } {
set account $parent
set contacts [$account getContacts]
set my_contacts [list]
foreach contact $contacts {
set groups [$contact getGroups]
foreach group $groups {
if { $group == $self } { lappend my_contacts $group }
}
}
return $my_contacts
}
it does seem to work, but is not really the way to do it, a group is
there
to 'group' smoething, so it should have children, if a group has no
children, then it's empty.
Question is a contact's parent is the group or is the account.. I'd say
the account, simply because you can be part of multiple groups, but only
one account defines you.
You know, I hate cross-referencing! Why? because it is always redundant,
and
may thus cause errors (e.g. a contact referring to a group, but that
group
not to the contact). Yes, that would be simply a bug, but still that is
what's likely to happen with redundant data.
And how to code it cross-referencing in a safe way? The group cannot
access
contact data and the contact cannot access group data. So if you have
[$group
contact add $contact] $group will have to call some method on $contact...
let's say [$contact group add $self]... that wil work. But now someone
does
[$contact group add $group] somewhere in the code, and things are messed
up... so we will need to have $contact call [$group contact add $self]
and
the {contact add} method on the group should refuse adding a contact
that is
already there (or we will have an endless loop)...
Hmm, you can also simply forbid the use of [$contact group add $group],
and
pray noone will sin...
So, that's one side of the story...
Humm.. again, we agree :D don't say wow yet, because I'm convinced that
cross referencing should be avoided, but not yet convinced on how you want
to do it.. this is another design phase that needs some brainstorming, if
we think about, what is a group ? it's an important thing, it's not only a
GUI thing, I mean, you don't delete a contact from your CL, you delete it
from groups, you can have a same contact in more than one group, and you
can have a contact in no group too.. a group contains contacts, so it's a
parent, a contact doesn't contain groups, so it shouldn't be a parent, the
reference goes from group to contact.. so it's account->group->contact and
account->contact (for no group), but group is not a *real* parent, since a
contact can be part of multiple groups, so it's a total mess.. we could
either have cross referencing, making sure that the consistency is kept by
having what you said, $contact add group -> $group add contact -> $contact
add group, where the last one wouldn't do anything because the group is
already known as containing that contact.
but it's not the only thing, there's also copy from one group to another,
moving a contact, deleting a contact from a group, etc...
Checking for consistency would be a maze if we did it inside group and
contact... so how about having a 'groupmanager' object, its sole purpose
would be to manage the contacts and the groups relations between each
other, so the 'consistency' wil lbe done in a single place.
we'd have one groupmanager object per account, and we could either have
the $contact and $gorup objects have a reference to the groupmanager or
simply do each time a [$account cget -groupmanager] (or do it once in the
constructor if we make that option readonly).
The groupmanager object would take care of that cross referencing (without
having a rela xref) and will allow us to easily [$groupmanager contact
move $oldgroup $newgroup] or [$groupmanager contact copy $togroup].. it's
internal structure would need a brainstorming too, I like to use arrays,
because it's faster than a list (hashtable) and is easier to reference
than doing an lsearch/lindex/lrange... so how about 2 arrays, one with the
contacts, one with the groups, the key is the name of the object, the
value is the list of children.. so
method getcontacts { } { return [array names contacts] }
method getgroups { } {retun [array names groups] }
method contactHasNoGroup {contact} { return [expr [llength [set
contacts($contact)]] == 0 ? 1 : 0] }
method contactInGroups { contact } { return [set contacts($contact)] }
etc...
there will be cross referencing, but inside one object between two arrays,
not cross referencing between multiple objects,e ach referencing each
other... you like it, or it needs more brainstorming ? I just popped that
idea out of my head, so it's far from being the perfect design plan..
Now the other side... your code example. Theoretically the cleanest way
to do
it, but really not too efficient... So we need something else, and yeah,
cross-referencing seems a fix, or maybe reference the other way around
(group
to contact only) but then you have a problem with [$contact getGroups]
and we
need that too... So that's my second reason to hate cross-referencing:
you
can hardly avoid it!
But in this case, I incorporated the way around the problem in my design
by
referencing only from contact to group in the data layer (abook), but
referencing group to contact in the gui layer! (In the gui layer we have
to
reference group to contact because every clcontact is a child of a
clgroup,
and not the other way around). I cannot think of any situation where we
might
want referencing from group to contact, except in the gui, because in
everything we operate on contacts, not groups. Groups are there only to
provide a way for users to group their contacts in the gui!
Okay, to get back to your example: Send message to a group? no prob...
create
a convo with all contacts in the group, and have fun! clgroup can do the
job,
without using group.
Don't we still have cross referencing then? Yeah in some sense we do,
but now
it is spread across layers that already are supposed to monitor each
other,
and the cross-reference is checked because every change involves an
event,
and the other side will get updated, and we're a lot safer IMO.
I see what you want here, but his can be VERY confusing, unless we had two
teams, one working on gui, the other on protocol, they don't know each
other, they don't touch each other's code, they don't even have access to
it.. you're right about the contacts being children of the grops in the
gui only, but in the protocol, it has no real meaning, they're not
children, the gids are just a property of the contact... anyways, I don't
know, tell me what you think about my proposal above, and we can talk
about this over MSN later...
[CUT]
Of course, all the eventing system, listeners, etc.. wouldn't be
rewritten
in each object, but will all use a single API from ::events:: that would
keep track of all the listeners for each object and would call the
listener's action method when an event is fired, etc...
also, this allows us to have a lot less functions processed each time an
event is fired... think about it, you have one contact that changes his
state, so ALL clgroup and clcontact widgets get called ? if you have 200
contacts in your list, then you'll have 200 "if { $contact != $parent}
return" called ?
What we have now is the same as having a global hook, it's
dangerous...What do you think ?
KaKaRoTo
I agree with the idea to have events per object. I had that idea myself
too!
But I'd do it slightly different:
[$contact on nickChange "$self nickChangeMethod"]
yes, sure a command is better than a combination object/method 'cause we
can add args, but it also adds some problems, how you're going to code it ?
eval $command $args
I've been using 'eval' so much in chameleon I know it's defects, it's
really difficult to deal with lists, imagine you have the command "$self
nickChangeMethod $email"
and the method is
method nickChangeMethod { email newnick }
now it all works, great, then we add the non-im contacts, the command
becomes, once expanded a :
"_self_variable_value nickChangeMEthod " ($email disappeared since it
contains nothing)
and the eval will result in the calling : [$self nickChangeMethod
$newnick] which results in a really nice "wrong number of args"
A solution would be to use [list $self nickChangeMethod $email] but i
don't remember exactly, but this could also cause problems in other
situations (where it will say "$self nickchangeMethod $email" is an
unknown command, thinkin the 2 spaces and 3 words are all part of the
command name (yes we can have a command name with a space, just list it).
And there, the solution would be to use {$self... } instead of [list ..]
but then, you get the error where the $variables are not expanded..
and I'm not talking about having a $args expanded from 1 list to 10 args
or stay 1 arg... anyways
etc...
oups, sorry, I got really off topic here, anyways, using the command is
fine with me but I'd prefer we think about it a little more if it's fine
with you.
Within the contact object [$self fire nickChange] will fire the event.
Please note that nothing in the clgui will need to listen for events on
all
contacts, but some other gui parts may need to do so, so we might allow
to
do so by [$account on contactNickChange "$self nickChangeMethod"], and
have
in the Account class something like [$contact on nickChange "$self fire
contactNickChange $args"] for each contact being added.
no, I don't like that, I'd prefer to have
$acount on contactadded "$self new contact"
method {new contact} {contact} { $contact on nickChange "$self
nickChangeMethod" }
you have tha tin java too, I used it once, I have a listener on something,
and I have a listener on the toplevel window, a ComponentListener that
adds my listener to each component created...
The methods 'on' and 'fire' are likely to be delegated to some event
system
component, that will register the event.
the on keyword I don't like, it's like "do this on this event".. actually
a lot of things can happen on that event, the listener thing looks nicer,
you know you're just a listener amongst others.. also the 'on' word could
lead to confusion with 'on/off', but hey, who will code and use the events
if he doesn't even know what 'on' is there for.. so it's really just an
'esthetical' choice.. I'd go with the listeners thing, but it's not
something to debate on, as long as we decide ons something.
Argh, why do we use snit??? We should use something base on inheritance
instead of delegation! Then we can have a common baseclass that has the
event
system, and no need to do [delegate method on to ....] in every class
that
needs to expose events. Shall we switch over to [incr Tcl]? It is much
better
than snit.
Harry
oh oh... are we not agreeing on something?
no, please, dont' start the debate on snit vs. incr tcl... I don't know
snit, so I had to read the man pages yesterday, and I liked it a lot, I
don't know about incr tcl, but snit looks really good, we need to delegate
stuff, in our case delegating is better than inheritence.. it's kind of
the same as inheritence, and it doesn't bother us to write 'delegate
method on to eventsystem' and 'delegate method fire to eventsystem', two
lines.. what did you loose ? you could even make it in a macro...
in incr tcl, you'd also need to write that you inherit from the
eventsystem anyways, so there's no real diff, apart from the fact that we
already have snit implemented everywhere...
--
KaKaRoTo
-------------------------------------------------------
All the advantages of Linux Managed Hosting--Without the Cost and Risk!
Fully trained technicians. The highest number of Red Hat certifications in
the hosting industry. Fanatical Support. Click to learn more
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=107521&bid=248729&dat=121642
_______________________________________________
Amsn-devel mailing list
Amsn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/amsn-devel