00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
#ifndef USIGNAL_HPP
00029
#define USIGNAL_HPP
00030
00031
00032
00033
00034
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
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
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 }
00250
00251
#endif // USIGNAL_HPP