[chuck-users] Observer and Observable
David Michael
david.michael at gmail.com
Tue Jan 30 23:40:36 EST 2007
I realize that the Event model in Chuck handles events, but it seems
to be implicitly time-based.
This is a good thing.
I could be completely mistaken, but it seems that for something to
respond to an event, a t(s)hread is f(sp)orked, time is stopped, and
the thread waits for an event to come in from another running thread
before proceeding. But what if you want a process in a thread to
change from an event, but not to stop what it's doing waiting for
said event. There may be a Chuckish way to approach this, but here is
a possible solution.
In some experiments, I implemented a simple Observer pattern for
signaling without being dependent on time, i.e., to send events to
objects within a single thread (named like in Java classes minus some
functions) ... not sure if this is useful, but it initially began as
an experiment in efficiency. At the moment, using Observer type
signals over Events does not seem to save any cpu, but it did allow
me to spawn 1/3 fewer threads. In a situation where you have many
instances that need events without keeping their own time, this might
useful.
To use: extend Observer class for all objects you want to register
with an signal producer (an Observable)... and visa versa (extend
Observable) for those who are going to be sending signal. You will
need to write a Signal class or something equivalent to get a rich
message to the receivers (Observers), but whatever. For more on the
topic for those unfamiliar with what I am talking about, see Java
Observer/Observable - signal/slot in C++ or Head First Design
Patterns, which has a nice clear explanation (and some corny pictures).
Also for those interested, I also have a Dispatcher class for a
collection of Observables, indexed by string. More like sig/slot.
I suppose you could also create "ObservableObservers" if you just
renamed the class and stuck the Observer update() function in
Observable. Same basic concept though: event signaling without Events.
Please let me know if I have any typos, or if the example program is
convoluted or just doesnt work.
David
class Observer
{
function void update(){} // receive
}
class Observable
{
20 => int size; // this could be any size... just be reasonable.
In the near-term this should be a "dynamic array"
Observer observers[size];
int count;
function void addObserver(Observer o) // subscribe
{
if(count < size){
o @=> this.observers[count];
count++;
}
}
// is this properly garbage collected?
// if its not, there could be orphaned objects, and a growing
application, right?
function void deleteObserver(Observer o) // unsubscribe
{
for(0 => int i; i < count; i++){
if( observers[i] == o ){
if(i >= 0 && i < count)
{
for(i => int j; j < count; j++)
{
observers[i + 1] @=> observers[i];
}
}
count--;
}
}
}
function void notifyObservers() // publish
{
for(0 => int i; i < count; i++){
this.observers[i].update(s);
}
}
}
class Receiver extends Observer
{
func void update()
{
<<< "I got something." >>>;
}
}
// make some instances
Receiver r;
Receiver r2;
Observable observable;
// register the observers (who receive) with the observable (who
signals)
observable.addObserver(r);
observable.addObserver(r2);
// send the signal
observable.notifyObservers();
// should print:
// $ "I got something"
// $ "I got something"
// remove an observer
observable.deleteObserver(r2);
// send the signal
observable.notifyObservers();
// should print:
// $ "I got something"
More information about the chuck-users
mailing list