Click to See Complete Forum and Search --> : Receiving events from multiple sources
Joel Ryan
08-31-2000, 11:48 AM
Hello all
I'm looking for a work-around to the problem of not being able to
have one object receive events from an unknown number of sources.
Here's my idea. Please tell if it's valid/what you think:
An object to receive events implements the interface
IMessageNotifiable. This is how it receives events.
The interface IMessageNotifiable contains procedures that represent
events that can be raised.
An object that will raise events contains a collection of objects that
expose the IMessageNotifiable interface. When it raises an event, it
loops through the objects in its collection and calls a procedure (in
effect raising the event). I know this is more work to raise an event
but it allows many people to receive the event.
-- Joel
Ian Drake
08-31-2000, 02:43 PM
Joel,
It's a good Idea in theory, but when you think you are "in
effect raising the event" you're not. Your making a procedure call and that
as you know is handled much different. I've seen someone try to do this
in a big project, and it flopped. I though it look great on paper. There
was an IParent interface in which every child had a reference to its creators
IParent interface. Not only did this create circular references, but it
didn't bubble up the events as was hoped.
My advise:
Make a Timer DLL by making an activeX dll, adding a form, putting a timer
on the form. Change the Class name to cTimer, add Methods Dissable and Enable,
add property let/get Interval, declare the form with events, declare the
Timer_Fire event, on class_ini create an intstance of the form, and then
wrap the timer on the form up with class.
NEXT
In the class that implements the IMessageNotifiable declare and create the
timer DLL(with events) then when the IMessageNotifiable.Notify function is
called enable the timer with an interval of 1. Put the code that you would
have normally put in the IMessageNotifiable.Notify function in the timerDLL_timer_fire
event handler.
That complicates your Interface and neat way of doing things doesn't it.
The only other way you could do what you want is to go through the API.
Good Luck
Ian Drake
Joel Ryan <jryan@vsi-hq.com> wrote:
>Hello all
> I'm looking for a work-around to the problem of not being able to
>have one object receive events from an unknown number of sources.
>Here's my idea. Please tell if it's valid/what you think:
>
>An object to receive events implements the interface
>IMessageNotifiable. This is how it receives events.
>
>The interface IMessageNotifiable contains procedures that represent
>events that can be raised.
>
>An object that will raise events contains a collection of objects that
>expose the IMessageNotifiable interface. When it raises an event, it
>loops through the objects in its collection and calls a procedure (in
>effect raising the event). I know this is more work to raise an event
>but it allows many people to receive the event.
>
>-- Joel
>
Mark Alexander Bertenshaw
08-31-2000, 08:31 PM
Joel -
I see nothing wrong in this mechanism, and I have implemented something
similar myself. However, as Ian Drake has mentioned, you will have the
problem of circular references. To solve this, you will have to use weak
references in all your items (pointing back to the collection object). You
might not be very confident using this, since they are a bit risky if you
don't understand what is going on in that you can easily crash your
application.
As for all that stuff using timers et al, I think that it sounds a wee bit
over the top.
--
Mark Alexander Bertenshaw
Programmer/Analyst
PrimeResponse
Brentford
UK
"Joel Ryan" <jryan@vsi-hq.com> wrote in message
news:39AE702A.7DF6A3A0@vsi-hq.com...
> Hello all
> I'm looking for a work-around to the problem of not being able to
> have one object receive events from an unknown number of sources.
> Here's my idea. Please tell if it's valid/what you think:
>
> An object to receive events implements the interface
> IMessageNotifiable. This is how it receives events.
>
> The interface IMessageNotifiable contains procedures that represent
> events that can be raised.
>
> An object that will raise events contains a collection of objects that
> expose the IMessageNotifiable interface. When it raises an event, it
> loops through the objects in its collection and calls a procedure (in
> effect raising the event). I know this is more work to raise an event
> but it allows many people to receive the event.
>
> -- Joel
>
Anthony Jones
09-01-2000, 03:35 PM
Joel,
I agree with Mark's comments and I have also done the same. However, it
does put the burden of managing multiple receivers on your own code. It
also requires the receiver's code to register and deregister their interest
in a specific set of events.
You might consider using a Mediator pattern. Below is code I have posted
before on this subject. This code was originally designed to allow
multiple children to communicate back with their parent via events so it
will need adjusting for your use.
The basic concept in this solution is to have single instance of an event
raising class which also implements an interface which has a matching set
of methods that raise the events.
All the receiver needs is a WithEvents reference to the instance of the
Mediator class. All the senders need to do is hold a reference to the
mediator class and call the appropriate method for the event it wishes to
raise.
The mediator thus allows any number of receivers to receive events from any
number of senders. The code burden is next to nothing.
Of course price paid is (I'm told since I have never actually measured)
lack of performance. Also the order in which the listeners will be
notified it may be important to you. In which case you cannot rely on VB's
event model.
=== Code ===
'Mediator Class
'If the source of the event is unimportant drop the parameter
Event Changed(Item as Child)
Public Sub Changed(Item as Child)
RaiseEvent Item
End Sub
'Parent Class
Private mcol as Collection
Private WithEvents moMediator as Mediator
'Code when adding child somewhere
mcol.Add oChild, oChild.Name (or whatever)
Set oChild.Mediator = moMediator
Private Sub moMediator_Changed(Item as Child)
'Do Stuff
End Sub
'Child Class
Private moMediator as Mediator
Friend Property Set Mediator(ByVal voMediator as Mediator)
Set moMediator = voMediator
End Property
Public Property Let Name (rsName as String)
msName = rsName
moMediator.Changed Me
End Property
=== End Code ===
--
Anthony Jones
Nuesoft Ltd
John Perkins
09-02-2000, 10:57 AM
You have just described a well-known and proven pattern that is called "Observer".
It's in the "Design Patterns" book by Gamma et. al.
For anyone who cares, I've been working in Java and was happy to find that
it has support for this kind of pattern built in.
-John
Joel Ryan <jryan@vsi-hq.com> wrote:
>Hello all
> I'm looking for a work-around to the problem of not being able to
>have one object receive events from an unknown number of sources.
>Here's my idea. Please tell if it's valid/what you think:
>
>An object to receive events implements the interface
>IMessageNotifiable. This is how it receives events.
>
>The interface IMessageNotifiable contains procedures that represent
>events that can be raised.
>
>An object that will raise events contains a collection of objects that
>expose the IMessageNotifiable interface. When it raises an event, it
>loops through the objects in its collection and calls a procedure (in
>effect raising the event). I know this is more work to raise an event
>but it allows many people to receive the event.
>
>-- Joel
>
Mark Alexander Bertenshaw
09-03-2000, 08:52 PM
John -
That's very interesting. I have played with Java, and what impresses me
with the language is that the designers have taken time to put so much
useful built-in code. I remember being amazed that I didn't have to go and
buy 3rd party code for internet access - the whole **** range of internet
functionality was already built-in! Now only if Java could get faster and
have a standardised decent (i.e. VB-like) IDE, I would definitely go the
whole hog and make the leap.
--
Mark Alexander Bertenshaw
Programmer/Analyst
PrimeResponse
Brentford
UK
"John Perkins" <perk_j@yahoo.com> wrote in message
news:39b10747$1@news.devx.com...
>
> You have just described a well-known and proven pattern that is called
"Observer".
> It's in the "Design Patterns" book by Gamma et. al.
>
> For anyone who cares, I've been working in Java and was happy to find that
> it has support for this kind of pattern built in.
>
> -John
>
>
> Joel Ryan <jryan@vsi-hq.com> wrote:
> >Hello all
> > I'm looking for a work-around to the problem of not being able to
> >have one object receive events from an unknown number of sources.
> >Here's my idea. Please tell if it's valid/what you think:
> >
> >An object to receive events implements the interface
> >IMessageNotifiable. This is how it receives events.
> >
> >The interface IMessageNotifiable contains procedures that represent
> >events that can be raised.
> >
> >An object that will raise events contains a collection of objects that
> >expose the IMessageNotifiable interface. When it raises an event, it
> >loops through the objects in its collection and calls a procedure (in
> >effect raising the event). I know this is more work to raise an event
> >but it allows many people to receive the event.
> >
> >-- Joel
> >
>
André de Oliveira
10-10-2000, 11:59 AM
"Mark Alexander Bertenshaw" <mark.bertenshaw@virgin.net> wrote in message
news:39b2e3b4@news.devx.com...
>
> That's very interesting. I have played with Java, and what impresses me
> with the language is that the designers have taken time to put so much
> useful built-in code. I remember being amazed that I didn't have to go
and
> buy 3rd party code for internet access - the whole **** range of internet
> functionality was already built-in! Now only if Java could get faster and
> have a standardised decent (i.e. VB-like) IDE, I would definitely go the
> whole hog and make the leap.
>
From what I´ve seen, Borland JBuilder gives Java the IDE it needed.
Unfortunately, speed is still an issue. The whole bottleneck is Java´s
choice of graphic architecture. Expect a drop in performance when the IDE
has to custom draw itself entirely, not using the operating system´s native
controls (Windows API). Java achieved a level of architectural elegance
where control appearance is pluggable - the "skin" metaphor; the demos are
amazing. If only they went far enough to allow the drawing engine to be
pluggable, too. That is, forget the damned VM and use controls directly from
the underlying OS/ browser/ graphic environment. Microsoft´s Foundation
Classes for Java would be great for this, but now with MS plans for .NET
there is no chance Java will evolve in this direction anymore. By the way,
for these very same reasons, visual applications developed on .NET will
probably draw lightning fast in Microsoft´s platforms, and terribly slow in
other operating systems (if they ever run on them at all).
About the Observer pattern: it is a great solution for the described
scenario. We use it to implement a solution to catch errors and alerts, and
log them simultaneously into a database and a text file. The Observable
operation Adds the two Observers into an internal list. The possible
Notifications are also defined as classes, and when an error or alert
occurs, an ErrorNotification or AlertNotification object is created,
broadcast and destroyed. In our case, the Observer never sees the
Observable, only the Notifications. I think it´s the way it should be. If
there is any need to make anything to the Observable from the Observer, they
should reverse roles with an identical and parallel implementation.
I´ve seen comments about VB having problems with self-referencing interfaces
because its finalization model is non-deterministic (reference counting).
We´re using Delphi, and its finalization model is deterministic: objects
must be explicitly destroyed (as in C++). But if you inherit your classes
from the TComponent base class, you can forget about it, because its
constructor asks for an owner for the new object, and their destruction
becomes enchained: if you destroy the owner, all the owned objects and their
owned objects are destroyed together. You have the option to use
reference-counted interfaces if you want, but it´s not a popular solution.
--
André de Oliveira
Software Engineer
São Paulo - Brazil
devx.com
Copyright WebMediaBrands Inc. All Rights Reserved