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
00029
00030 #ifndef ACEDIA_ABSTRACT_ACTOR_H
00031 #define ACEDIA_ABSTRACT_ACTOR_H
00032
00033 #include "referencecounted.hpp"
00034
00035 #include <boost/bind.hpp>
00036 #include <boost/cstdint.hpp>
00037 #include <boost/function.hpp>
00038
00039 namespace acedia
00040 {
00041
00052 namespace exit_reasons {
00053
00058 static const boost::int32_t NOT_EXITED = -1;
00059
00063 static const boost::int32_t NORMAL_EXIT = 0;
00064
00069 static const boost::int32_t UNHANDLED_EXCEPTION = 1;
00070
00074 static const boost::int32_t LINK_EXITED = 2;
00075
00080 static const boost::int32_t REMOTE_LINK_UNREACHABLE = 3;
00081
00087 static const boost::int32_t USER_DEFINED_REASON = 0xFF;
00088
00089 }
00090
00091
00092 class Any;
00093 class Message;
00094 class ActorRef;
00095 namespace details
00096 {
00097 class DummyActor;
00098 struct MockActorPrivate;
00099 }
00100
00105 class AbstractActor : public ReferenceCounted
00106 {
00107
00108 friend class Actor;
00109 friend class ActorRef;
00110 friend class ActorProxy;
00111 friend class details::DummyActor;
00112
00113 friend class MockActor;
00114 friend struct details::MockActorPrivate;
00115
00116 bool m_isFarRef;
00117 boost::uint32_t m_id;
00118 boost::int32_t m_exitReason;
00119 ActorRef *m_self;
00120
00121
00122
00123
00124
00125 AbstractActor(bool farRef = false, bool dummy = false) throw();
00126
00127 public:
00128
00134 inline bool isFarRef() { return m_isFarRef; }
00135
00136 virtual ~AbstractActor();
00137
00141 virtual void enqueue(const Message &msg) = 0;
00142
00146 virtual void linkTo(const ActorRef& who) = 0;
00147
00156 virtual bool backlinkTo(ActorRef& who) = 0;
00157
00162 inline boost::int32_t exitReason() const throw()
00163 {
00164 return m_exitReason;
00165 }
00166
00171 inline boost::uint32_t id() const throw() { return m_id; }
00172
00173 protected:
00174
00179 ActorRef& self() { return *m_self; }
00180
00187 void forward(const Message& what, ActorRef& whom);
00188
00192 void send(ActorRef& receiver, const Any& v1);
00193
00194 void send(ActorRef& receiver, const Any& v1, const Any& v2);
00195
00196 void send(ActorRef& receiver, const Any& v1, const Any& v2,
00197 const Any& v3);
00198
00199 void send(ActorRef& receiver,
00200 const Any& v1, const Any& v2, const Any& v3, const Any& v4);
00201
00202 void send(ActorRef& receiver,
00203 const Any& v1, const Any& v2, const Any& v3, const Any& v4,
00204 const Any& v5);
00205
00206 void send(ActorRef& receiver,
00207 const Any& v1, const Any& v2, const Any& v3, const Any& v4,
00208 const Any& v5, const Any& v6);
00209
00210 void send(ActorRef& receiver,
00211 const Any& v1, const Any& v2, const Any& v3, const Any& v4,
00212 const Any& v5, const Any& v6, const Any& v7);
00213
00214 void send(ActorRef& receiver,
00215 const Any& v1, const Any& v2, const Any& v3, const Any& v4,
00216 const Any& v5, const Any& v6, const Any& v7, const Any& v8);
00217
00218 void send(ActorRef& receiver,
00219 const Any& v1, const Any& v2, const Any& v3, const Any& v4,
00220 const Any& v5, const Any& v6, const Any& v7, const Any& v8,
00221 const Any& v9);
00222
00226 template<class C>
00227 inline boost::function0<void> method(void (C::*m)())
00228 {
00229 return boost::bind(m, ((C*) this));
00230 }
00231
00232 template<class C, typename T1>
00233 inline boost::function1<void,T1> method(void (C::*m)(T1))
00234 {
00235 return boost::bind(m, ((C*) this),_1);
00236 }
00237
00238 template<class C, typename T1, typename T2>
00239 inline boost::function2<void,T1,T2> method(void (C::*m)(T1,T2))
00240 {
00241 return boost::bind(m, ((C*) this),_1,_2);
00242 }
00243
00244 template<class C, typename T1, typename T2, typename T3>
00245 inline boost::function3<void,T1,T2,T3> method(void (C::*m)(T1,T2,T3))
00246 {
00247 return boost::bind(m, ((C*) this),_1,_2,_3);
00248 }
00249
00250 template<class C, typename T1, typename T2, typename T3, typename T4>
00251 inline boost::function4<void,T1,T2,T3,T4>
00252 method(void (C::*m)(T1,T2,T3,T4))
00253 {
00254 return boost::bind(m, ((C*) this),_1,_2,_3,_4);
00255 }
00256
00257 template<class C, typename T1, typename T2, typename T3, typename T4,
00258 typename T5>
00259 inline boost::function5<void,T1,T2,T3,T4,T5>
00260 method(void (C::*m)(T1,T2,T3,T4,T5))
00261 {
00262 return boost::bind(m,((C*) this),_1,_2,_3,_4,_5);
00263 }
00264
00265 template<class C, typename T1, typename T2, typename T3, typename T4,
00266 typename T5, typename T6>
00267 inline boost::function6<void,T1,T2,T3,T4,T5,T6>
00268 method(void (C::*m)(T1,T2,T3,T4,T5,T6))
00269 {
00270 return boost::bind(m,((C*) this),_1,_2,_3,_4,_5,_6);
00271 }
00272
00273 template<class C, typename T1, typename T2, typename T3, typename T4,
00274 typename T5, typename T6, typename T7>
00275 inline boost::function7<void,T1,T2,T3,T4,T5,T6,T7>
00276 method(void (C::*m)(T1,T2,T3,T4,T5,T6,T7))
00277 {
00278 return boost::bind(m,((C*) this),_1,_2,_3,_4,_5,_6,_7);
00279 }
00280
00281 template<class C, typename T1, typename T2, typename T3, typename T4,
00282 typename T5, typename T6, typename T7, typename T8>
00283 inline boost::function8<void,T1,T2,T3,T4,T5,T6,T7,T8>
00284 method(void (C::*m)(T1,T2,T3,T4,T5,T6,T7,T8))
00285 {
00286 return boost::bind(m,((C*) this),_1,_2,_3,_4,_5,_6,_7,_8);
00287 }
00288
00289 template<class C, typename T1, typename T2, typename T3, typename T4,
00290 typename T5, typename T6, typename T7, typename T8, typename T9>
00291 inline boost::function9<void,T1,T2,T3,T4,T5,T6,T7,T8,T9>
00292 method(void (C::*m)(T1,T2,T3,T4,T5,T6,T7,T8,T9))
00293 {
00294 return boost::bind(m,((C*) this),_1,_2,_3,_4,_5,_6,_7,_8,_9);
00295 }
00296
00297 };
00298
00299 }
00300
00301
00302 #endif // ACEDIA_ABSTRACT_ACTOR_H