diff options
author | jcid <devnull@localhost> | 2008-09-24 18:44:40 +0200 |
---|---|---|
committer | jcid <devnull@localhost> | 2008-09-24 18:44:40 +0200 |
commit | c377e06400f138325a9a9d43d91a9272691867a1 (patch) | |
tree | 49f3ca1c46af11a058a68714899d4137ec717618 /lout/signal.cc | |
parent | 642f9b3e747859a7256ea12fab9f9ed50aa9253a (diff) |
- Moved the dw2 tree into dillo2's tree.
Diffstat (limited to 'lout/signal.cc')
-rw-r--r-- | lout/signal.cc | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/lout/signal.cc b/lout/signal.cc new file mode 100644 index 00000000..46aae626 --- /dev/null +++ b/lout/signal.cc @@ -0,0 +1,171 @@ +/* + * Dillo Widget + * + * Copyright 2005-2007 Sebastian Geerken <sgeerken@dillo.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + + +#include "signal.hh" + +namespace lout { +namespace signal { + +using namespace container::typed; + +// ------------ +// Emitter +// ------------ + +Emitter::Emitter () +{ + receivers = new List <Receiver> (false); +} + +Emitter::~Emitter () +{ + for(Iterator<Receiver> it = receivers->iterator (); it.hasNext (); ) { + Receiver *receiver = it.getNext (); + receiver->unconnectFrom (this); + } + delete receivers; +} + +void Emitter::intoStringBuffer(misc::StringBuffer *sb) +{ + sb->append ("<emitter: "); + receivers->intoStringBuffer (sb); + sb->append (">"); +} + +void Emitter::unconnect (Receiver *receiver) +{ + receivers->removeRef (receiver); +} + +/** + * \brief Connect a receiver to the emitter. + * + * This is protected, a sub class should define a wrapper, with the respective + * receiver as an argument, to gain type safety. + */ +void Emitter::connect (Receiver *receiver) +{ + receivers->append (receiver); + receiver->connectTo (this); +} + +/** + * \brief Emit a void signal. + * + * This method should be called by a wrapper (return value void), which + * \em folds the signal, and delegates the emission to here. + */ +void Emitter::emitVoid (int signalNo, int argc, Object **argv) +{ + for(Iterator <Receiver> it = receivers->iterator (); it.hasNext (); ) { + Receiver *receiver = it.getNext(); + emitToReceiver (receiver, signalNo, argc, argv); + } +} + +/** + * \brief Emit a boolean signal. + * + * This method should be called by a wrapper, which \em folds the signal, + * delegates the emission to here, and returns the same boolean value. + */ +bool Emitter::emitBool (int signalNo, int argc, Object **argv) +{ + bool b = false, bt; + + for(Iterator <Receiver> it = receivers->iterator (); it.hasNext (); ) { + Receiver *receiver = it.getNext(); + // Note: All receivers are called, even if one returns true. + // Therefore, something like + // b = b || emitToReceiver (receiver, signalNo, argc, argv); + // does not work. + bt = emitToReceiver (receiver, signalNo, argc, argv); + b = b || bt; + } + + return b; +} + + +// -------------- +// Receiver +// -------------- + +Receiver::Receiver() +{ + emitters = new List <Emitter> (false); +} + +Receiver::~Receiver() +{ + for(Iterator<Emitter> it = emitters->iterator(); it.hasNext(); ) { + Emitter *emitter = it.getNext(); + emitter->unconnect (this); + } + delete emitters; +} + +void Receiver::intoStringBuffer(misc::StringBuffer *sb) +{ + // emitters are not listed, to prevent recursion + sb->append ("<receiver>"); +} + +void Receiver::connectTo(Emitter *emitter) +{ + emitters->append (emitter); +} + +void Receiver::unconnectFrom(Emitter *emitter) +{ + emitters->removeRef (emitter); +} + +// ------------------------ +// ObservedObject +// ------------------------ + +bool ObservedObject::DeletionEmitter::emitToReceiver (Receiver *receiver, + int signalNo, + int argc, Object **argv) +{ + object::TypedPointer <ObservedObject> *p = + (object::TypedPointer<ObservedObject>*)argv[0]; + ((DeletionReceiver*)receiver)->deleted (p->getTypedValue ()); + return false; +} + +void ObservedObject::DeletionEmitter::emitDeletion (ObservedObject *obj) +{ + object::TypedPointer <ObservedObject> p(obj); + object::Object *argv[1] = { &p }; + emitVoid (0, 1, argv); +} + +ObservedObject::~ObservedObject() +{ + deletionEmitter.emitDeletion (this); +} + +} // namespace signal +} // namespace lout |