Mercurial > dillo_port1.3
annotate lout/signal.cc @ 2048:5060d415a85a
clickable menu items (even those introducing submenus) MUST have callbacks
I clicked on the "Panel size" item itself instead of any of the
options in its submenu, and: Segfault!
author | corvid <corvid@lavabit.com> |
---|---|
date | Thu, 26 May 2011 02:51:18 +0000 |
parents | d7dbd3dcfa38 |
children |
rev | line source |
---|---|
347 | 1 /* |
2 * Dillo Widget | |
3 * | |
4 * Copyright 2005-2007 Sebastian Geerken <sgeerken@dillo.org> | |
5 * | |
6 * This program is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 3 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
972
d7dbd3dcfa38
Updated the GPL copyright note in the source files
Detlef Riekenberg <wine.dev@web.de>
parents:
928
diff
changeset
|
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
347 | 18 */ |
19 | |
20 | |
21 | |
22 #include "signal.hh" | |
23 | |
24 namespace lout { | |
25 namespace signal { | |
26 | |
27 using namespace container::typed; | |
28 | |
29 // ------------ | |
30 // Emitter | |
31 // ------------ | |
32 | |
33 Emitter::Emitter () | |
34 { | |
35 receivers = new List <Receiver> (false); | |
36 } | |
37 | |
38 Emitter::~Emitter () | |
39 { | |
928
7771cf243ca6
's/if(/if (/g' 's/for(/for (/g' 's/while(/while (/g', and indentation.
Jorge Arellano Cid <jcid@dillo.org>
parents:
347
diff
changeset
|
40 for (Iterator<Receiver> it = receivers->iterator (); it.hasNext (); ) { |
347 | 41 Receiver *receiver = it.getNext (); |
42 receiver->unconnectFrom (this); | |
43 } | |
44 delete receivers; | |
45 } | |
46 | |
47 void Emitter::intoStringBuffer(misc::StringBuffer *sb) | |
48 { | |
49 sb->append ("<emitter: "); | |
50 receivers->intoStringBuffer (sb); | |
51 sb->append (">"); | |
52 } | |
53 | |
54 void Emitter::unconnect (Receiver *receiver) | |
55 { | |
56 receivers->removeRef (receiver); | |
57 } | |
58 | |
59 /** | |
60 * \brief Connect a receiver to the emitter. | |
61 * | |
62 * This is protected, a sub class should define a wrapper, with the respective | |
63 * receiver as an argument, to gain type safety. | |
64 */ | |
65 void Emitter::connect (Receiver *receiver) | |
66 { | |
67 receivers->append (receiver); | |
68 receiver->connectTo (this); | |
69 } | |
70 | |
71 /** | |
72 * \brief Emit a void signal. | |
73 * | |
74 * This method should be called by a wrapper (return value void), which | |
75 * \em folds the signal, and delegates the emission to here. | |
76 */ | |
77 void Emitter::emitVoid (int signalNo, int argc, Object **argv) | |
78 { | |
928
7771cf243ca6
's/if(/if (/g' 's/for(/for (/g' 's/while(/while (/g', and indentation.
Jorge Arellano Cid <jcid@dillo.org>
parents:
347
diff
changeset
|
79 for (Iterator <Receiver> it = receivers->iterator (); it.hasNext (); ) { |
347 | 80 Receiver *receiver = it.getNext(); |
81 emitToReceiver (receiver, signalNo, argc, argv); | |
82 } | |
83 } | |
84 | |
85 /** | |
86 * \brief Emit a boolean signal. | |
87 * | |
88 * This method should be called by a wrapper, which \em folds the signal, | |
89 * delegates the emission to here, and returns the same boolean value. | |
90 */ | |
91 bool Emitter::emitBool (int signalNo, int argc, Object **argv) | |
92 { | |
93 bool b = false, bt; | |
94 | |
928
7771cf243ca6
's/if(/if (/g' 's/for(/for (/g' 's/while(/while (/g', and indentation.
Jorge Arellano Cid <jcid@dillo.org>
parents:
347
diff
changeset
|
95 for (Iterator <Receiver> it = receivers->iterator (); it.hasNext (); ) { |
347 | 96 Receiver *receiver = it.getNext(); |
97 // Note: All receivers are called, even if one returns true. | |
98 // Therefore, something like | |
99 // b = b || emitToReceiver (receiver, signalNo, argc, argv); | |
100 // does not work. | |
101 bt = emitToReceiver (receiver, signalNo, argc, argv); | |
102 b = b || bt; | |
103 } | |
104 | |
105 return b; | |
106 } | |
107 | |
108 | |
109 // -------------- | |
110 // Receiver | |
111 // -------------- | |
112 | |
113 Receiver::Receiver() | |
114 { | |
115 emitters = new List <Emitter> (false); | |
116 } | |
117 | |
118 Receiver::~Receiver() | |
119 { | |
928
7771cf243ca6
's/if(/if (/g' 's/for(/for (/g' 's/while(/while (/g', and indentation.
Jorge Arellano Cid <jcid@dillo.org>
parents:
347
diff
changeset
|
120 for (Iterator<Emitter> it = emitters->iterator(); it.hasNext(); ) { |
347 | 121 Emitter *emitter = it.getNext(); |
122 emitter->unconnect (this); | |
123 } | |
124 delete emitters; | |
125 } | |
126 | |
127 void Receiver::intoStringBuffer(misc::StringBuffer *sb) | |
128 { | |
129 // emitters are not listed, to prevent recursion | |
130 sb->append ("<receiver>"); | |
131 } | |
132 | |
133 void Receiver::connectTo(Emitter *emitter) | |
134 { | |
135 emitters->append (emitter); | |
136 } | |
137 | |
138 void Receiver::unconnectFrom(Emitter *emitter) | |
139 { | |
140 emitters->removeRef (emitter); | |
141 } | |
142 | |
143 // ------------------------ | |
144 // ObservedObject | |
145 // ------------------------ | |
146 | |
147 bool ObservedObject::DeletionEmitter::emitToReceiver (Receiver *receiver, | |
148 int signalNo, | |
149 int argc, Object **argv) | |
150 { | |
151 object::TypedPointer <ObservedObject> *p = | |
152 (object::TypedPointer<ObservedObject>*)argv[0]; | |
153 ((DeletionReceiver*)receiver)->deleted (p->getTypedValue ()); | |
154 return false; | |
155 } | |
156 | |
157 void ObservedObject::DeletionEmitter::emitDeletion (ObservedObject *obj) | |
158 { | |
159 object::TypedPointer <ObservedObject> p(obj); | |
160 object::Object *argv[1] = { &p }; | |
161 emitVoid (0, 1, argv); | |
162 } | |
163 | |
164 ObservedObject::~ObservedObject() | |
165 { | |
166 deletionEmitter.emitDeletion (this); | |
167 } | |
168 | |
169 } // namespace signal | |
170 } // namespace lout |