- Your Widget Set For OpenGL
Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | Related Pages

usignal.hpp

00001 /*************************************************************************** 00002 LibUFO - UI For OpenGL 00003 copyright : (C) 2001-2005 by Johannes Schmidt 00004 email : schmidtjf at users.sourceforge.net 00005 ------------------- 00006 00007 file : include/ufo/signals/usignal.hpp 00008 begin : Thu Jul 18 2002 00009 $Id: usignal.hpp,v 1.11 2005/09/15 10:22:44 schmidtjf Exp $ 00010 ***************************************************************************/ 00011 00012 /*************************************************************************** 00013 * This library is free software; you can redistribute it and/or * 00014 * modify it under the terms of the GNU Lesser General Public * 00015 * License as published by the Free Software Foundation; either * 00016 * version 2.1 of the License, or (at your option) any later version. * 00017 * * 00018 * This library is distributed in the hope that it will be useful, * 00019 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00021 * Lesser General Public License for more details. * 00022 * * 00023 * You should have received a copy of the GNU Lesser General Public * 00024 * License along with this library; if not, write to the Free Software * 00025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 00026 ***************************************************************************/ 00027 00028 #ifndef USIGNAL_HPP 00029 #define USIGNAL_HPP 00030 00031 // ripped from sigc++/signal.h (created by m4 macro) 00032 // Copyright 2000, Karl Einar Nelson 00033 00034 //#include "uslotbase.h" 00035 #include "uslot.hpp" 00036 00037 #include <list> 00038 00039 namespace ufo { 00040 00045 class USignalBase { 00046 public: 00047 USignalBase() {} 00048 ~USignalBase() { 00049 for (SlotIterator iter = _slots.begin(); 00050 iter != _slots.end(); 00051 ++iter) { 00052 delete (*iter); 00053 } 00054 _slots.clear(); 00055 } 00056 00057 public: 00058 void push_front(USlotBase * slot) { 00059 _slots.push_front(slot); 00060 } 00061 bool remove(const USlotBase * slot) { 00062 bool ret = false; 00063 for (SlotIterator iter = _slots.begin(); 00064 iter != _slots.end(); 00065 ++iter) { 00066 if ((*iter)->equals(slot)) { 00067 (*iter)->node()->notify(false); 00068 ret = true; 00069 break; 00070 } 00071 } 00072 return ret; 00073 } 00074 protected: 00075 bool final_remove(const USlotBase * slot) { 00076 bool ret = false; 00077 for (SlotIterator iter = _slots.begin(); 00078 iter != _slots.end(); 00079 ++iter) { 00080 if ((*iter)->equals(slot)) { 00081 // remove garbage 00082 delete (*iter); 00083 _slots.erase(iter); 00084 ret = true; 00085 break; 00086 } 00087 } 00088 return ret; 00089 } 00090 protected: 00091 std::list<USlotBase*> _slots; 00092 typedef std::list<USlotBase*>::iterator SlotIterator; 00093 }; 00094 00095 // 00096 // signals 00097 // 00098 00099 00100 class USignal0 : public USignalBase { 00101 public: 00102 typedef USlot0 InSlotType; 00103 00104 void connect(const InSlotType & s) { 00105 push_front(new InSlotType(s)); 00106 } 00107 bool disconnect(const InSlotType & s) { 00108 return remove(&s); 00109 } 00110 00111 void operator()() { 00112 emit(); 00113 } 00114 void emit() { 00115 for (SlotIterator iter = _slots.begin();iter != _slots.end();) { 00116 InSlotType * slot = static_cast<InSlotType*>(*iter); 00117 if (!slot->node()->died()) { 00118 (*slot)(); 00119 } 00120 ++iter; 00121 if (slot->node()->died()) { 00122 final_remove(slot); 00123 } 00124 } 00125 } 00126 }; 00127 00128 template <typename P1> 00129 class USignal1 : public USignalBase { 00130 public: 00131 typedef USlot1<P1> InSlotType; 00132 00133 void connect(const InSlotType & s) { 00134 push_front(new InSlotType(s)); 00135 } 00136 bool disconnect(const InSlotType & s) { 00137 return remove(&s); 00138 } 00139 00140 void operator()(typename UTrait<P1>::ref p1) { 00141 emit(p1); 00142 } 00143 void emit(typename UTrait<P1>::ref p1) { 00144 for (SlotIterator iter = _slots.begin();iter != _slots.end();) { 00145 InSlotType * slot = static_cast<InSlotType*>(*iter); 00146 if (!slot->node()->died()) { 00147 (*slot)(p1); 00148 } 00149 ++iter; 00150 if (slot->node()->died()) { 00151 final_remove(slot); 00152 } 00153 } 00154 } 00155 }; 00156 00157 00158 template <typename P1,typename P2> 00159 class USignal2 : public USignalBase { 00160 public: 00161 typedef USlot2<P1, P2> InSlotType; 00162 00163 void connect(const InSlotType & s) { 00164 push_front(new InSlotType(s)); 00165 } 00166 bool disconnect(const InSlotType & s) { 00167 return remove(&s); 00168 } 00169 00170 void operator()(typename UTrait<P1>::ref p1, typename UTrait<P2>::ref p2) { 00171 emit(p1, p2); 00172 } 00173 void emit(typename UTrait<P1>::ref p1, typename UTrait<P2>::ref p2) { 00174 for (SlotIterator iter = _slots.begin();iter != _slots.end();) { 00175 InSlotType * slot = static_cast<InSlotType*>(*iter); 00176 if (!slot->node()->died()) { 00177 (*slot)(p1, p2); 00178 } 00179 ++iter; 00180 if (slot->node()->died()) { 00181 final_remove(slot); 00182 } 00183 } 00184 } 00185 }; 00186 00187 00188 template <typename P1, typename P2, typename P3> 00189 class USignal3 : public USignalBase { 00190 public: 00191 typedef USlot3<P1, P2, P3> InSlotType; 00192 00193 void connect(const InSlotType & s) { 00194 push_front(new InSlotType(s)); 00195 } 00196 bool disconnect(const InSlotType & s) { 00197 return remove(&s); 00198 } 00199 00200 void operator()(typename UTrait<P1>::ref p1, typename UTrait<P2>::ref p2, 00201 typename UTrait<P3>::ref p3) { 00202 emit(p1, p2, p3); 00203 } 00204 void emit(typename UTrait<P1>::ref p1, typename UTrait<P2>::ref p2, 00205 typename UTrait<P3>::ref p3) { 00206 for (SlotIterator iter = _slots.begin();iter != _slots.end();) { 00207 InSlotType * slot = static_cast<InSlotType*>(*iter); 00208 if (!slot->node()->died()) { 00209 (*slot)(p1, p2, p3); 00210 } 00211 ++iter; 00212 if (slot->node()->died()) { 00213 final_remove(slot); 00214 } 00215 } 00216 } 00217 }; 00218 00219 template <typename P1, typename P2, typename P3, typename P4> 00220 class USignal4 : public USignalBase { 00221 public: 00222 typedef USlot4<P1, P2, P3, P4> InSlotType; 00223 00224 void connect(const InSlotType & s) { 00225 push_front(new InSlotType(s)); 00226 } 00227 bool disconnect(const InSlotType & s) { 00228 return remove(&s); 00229 } 00230 00231 void operator()(typename UTrait<P1>::ref p1, typename UTrait<P2>::ref p2, 00232 typename UTrait<P3>::ref p3, typename UTrait<P4>::ref p4) { 00233 emit(p1, p2, p3, p4); 00234 } 00235 void emit(typename UTrait<P1>::ref p1, typename UTrait<P2>::ref p2, 00236 typename UTrait<P3>::ref p3, typename UTrait<P4>::ref p4) { 00237 for (SlotIterator iter = _slots.begin();iter != _slots.end();) { 00238 InSlotType * slot = static_cast<InSlotType*>(*iter); 00239 if (!slot->node()->died()) { 00240 (*slot)(p1, p2, p3, p4); 00241 } 00242 ++iter; 00243 if (slot->node()->died()) { 00244 final_remove(slot); 00245 } 00246 } 00247 } 00248 }; 00249 } // namespace ufo 00250 00251 #endif // USIGNAL_HPP

The libUFO Project - written by Johannes Schmidt