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_ACTOR_REF_H
00031 #define ACEDIA_ACTOR_REF_H
00032 
00033 #include "any.hpp"
00034 #include "message.hpp"
00035 #include "abstractactor.hpp"
00036 
00037 #include <boost/archive/text_oarchive.hpp>
00038 #include <boost/archive/text_iarchive.hpp>
00039 
00040 namespace acedia
00041 {
00042 
00043     
00044     namespace details { class Mailman; }
00045 
00054     class ActorRef
00055     {
00056 
00057         friend class boost::serialization::access;
00058         friend struct details::MockActorPrivate;
00059         friend class details::Mailman;
00060         friend class AbstractActor;
00061         friend class ActorProxy;
00062         friend class Actor;
00063         friend void link(ActorRef,ActorRef);
00064 
00065         AbstractActor *actor;
00066 
00067         
00068         bool m_weak;
00069 
00070     public:
00071 
00072         ActorRef() throw();
00073 
00074         inline ActorRef(AbstractActor *myActor, bool isWeakReference = false) :
00075                 actor(myActor), m_weak(isWeakReference)
00076         {
00077             assert(actor != NULL);
00078             if (!m_weak) actor->ref();
00079         }
00080 
00081         ActorRef(const ActorRef &other);
00082 
00083         ~ActorRef();
00084 
00085         inline bool operator==(const ActorRef &other) const throw()
00086         {
00087             return actor == other.actor;
00088         }
00089 
00090         inline bool operator!=(const ActorRef &other) const throw()
00091         {
00092             return actor != other.actor;
00093         }
00094 
00098         inline void send(const Message &msg)
00099         {
00100             actor->enqueue(msg);
00101         }
00102 
00107         void linkExited(boost::int32_t why, const ActorRef &who) throw();
00108 
00109         ActorRef &operator=(const ActorRef &other);
00110 
00111         
00117         bool isValid() const;
00118 
00122         boost::uint32_t actorId() const;
00123 
00129         boost::uint32_t realActorId() const;
00130 
00134         inline bool isFarRef() const { return actor->isFarRef(); }
00135 
00136         
00137         inline bool operator<(const ActorRef &other) const
00138         {
00139             return actor < other.actor;
00140         }
00141 
00142     };
00143 
00144     namespace details { ActorRef getInstanceById(boost::uint32_t id); }
00145 
00146 } 
00147 
00148 
00149 namespace acedia
00150 {
00151     namespace util
00152     {
00153         template<>
00154         struct AsString<ActorRef>
00155         {
00156             inline static String get(const ActorRef& value)
00157             {
00158                 String result;
00159                 if (value.isValid())
00160                 {
00161                     if (value.isFarRef())
00162                     {
00163                         result += "RemoteActor(id=";
00164                         result += AsString<boost::int32_t>::get(value.realActorId());
00165                         result += ")";
00166                     }
00167                     else
00168                     {
00169                         result += "LocalActor(id=";
00170                         result += AsString<boost::int32_t>::get(value.actorId());
00171                         result += ")";
00172                     }
00173                 }
00174                 else
00175                 {
00176                     result = "InvalidActor";
00177                 }
00178                 return result;
00179             }
00180         };
00181     }
00182 }
00183 
00184 #endif // ACEDIA_ACTOR_REF_H