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 #define ACEDIA_REDUCED_ANNOUNCE
00031
00032 #include "acedia_config.hpp"
00033
00034 #ifdef ACEDIA_WINDOWS
00035 #pragma warning( disable : 4099 )
00036
00037 #endif
00038
00039 #include "message.hpp"
00040 #include "actorref.hpp"
00041 #include "referencecounted.hpp"
00042
00043 #include <sstream>
00044
00045 #include <iostream>
00046 using std::cout;
00047 using std::endl;
00048
00049 namespace acedia
00050 {
00051 namespace details
00052 {
00053 class MessageData : public ReferenceCounted
00054 {
00055
00056 friend class acedia::util::Singleton<acedia::details::MessageData>;
00057
00058 MessageData() :
00059 ReferenceCounted(10), length(0), arr(NULL),
00060 sender(), receiver()
00061 {
00062 }
00063
00064 public:
00065
00066 boost::uint32_t length;
00067
00068 Any *arr;
00069
00070 ActorRef sender;
00071 ActorRef receiver;
00072
00073
00074 MessageData(boost::uint32_t len, const ActorRef &msgSender,
00075 const ActorRef &msgReceiver) :
00076 ReferenceCounted(1), length(len), arr(NULL),
00077 sender(msgSender), receiver(msgReceiver)
00078 {
00079 if (len > 0) arr = new Any[len];
00080 }
00081
00082 virtual ~MessageData()
00083 {
00084 if (arr) delete[] arr;
00085 }
00086
00087 };
00088
00089 ProxyFactory::~ProxyFactory() { }
00090 }
00091 }
00092
00093 static acedia::util::Singleton<acedia::details::MessageData> m_dummyMessageData;
00094
00095 namespace acedia
00096 {
00097
00098 void Message::set(int N, const Any **values, const ActorRef &msgSender, const ActorRef &msgReceiver)
00099 {
00100 data = new details::MessageData(N, msgSender, msgReceiver);
00101 for (int i = 0; i < N; ++i)
00102 {
00103 data->arr[i] = *(values[i]);
00104 }
00105 }
00106
00107 Message::Message() : data(m_dummyMessageData.instance())
00108 {
00109 data->ref();
00110 }
00111
00112 Message::Message(details::MessageData *mdata) : data(mdata)
00113 {
00114 data->ref();
00115 }
00116
00117 Message::Message(const ActorRef &msgSender, const ActorRef &msgReceiver) :
00118 data(NULL)
00119 {
00120 set(0, NULL, msgSender, msgReceiver);
00121 }
00122
00123 Message::Message(const ActorRef &msgSender, const ActorRef &msgReceiver, const Any &v1)
00124 : data(NULL)
00125 {
00126 const Any *arr[] = { &v1 };
00127 set(1, arr, msgSender, msgReceiver);
00128 }
00129
00130 Message::Message(const ActorRef &msgSender, const ActorRef &msgReceiver, const Any &v1, const Any &v2)
00131 : data(NULL)
00132 {
00133 const Any *arr[] = { &v1, &v2 };
00134 set(2, arr, msgSender, msgReceiver);
00135 }
00136
00137 Message::Message(const ActorRef &msgSender, const ActorRef &msgReceiver, const Any &v1, const Any &v2, const Any &v3)
00138 : data(NULL)
00139 {
00140 const Any *arr[] = { &v1, &v2, &v3 };
00141 set(3, arr, msgSender, msgReceiver);
00142 }
00143
00144 Message::Message(const ActorRef &msgSender, const ActorRef &msgReceiver, const Any &v1, const Any &v2, const Any &v3, const Any &v4)
00145 : data(NULL)
00146 {
00147 const Any *arr[] = { &v1, &v2, &v3, &v4 };
00148 set(4, arr, msgSender, msgReceiver);
00149 }
00150
00151 Message::Message(const ActorRef &msgSender, const ActorRef &msgReceiver, const Any &v1, const Any &v2, const Any &v3, const Any &v4, const Any &v5)
00152 : data(NULL)
00153 {
00154 const Any *arr[] = { &v1, &v2, &v3, &v4, &v5 };
00155 set(5, arr, msgSender, msgReceiver);
00156 }
00157
00158 Message::Message(const ActorRef &msgSender, const ActorRef &msgReceiver, const Any &v1, const Any &v2, const Any &v3, const Any &v4, const Any &v5, const Any &v6)
00159 : data(NULL)
00160 {
00161 const Any *arr[] = { &v1, &v2, &v3, &v4, &v5, &v6 };
00162 set(6, arr, msgSender, msgReceiver);
00163 }
00164
00165 Message::Message(const ActorRef &msgSender, const ActorRef &msgReceiver, const Any &v1, const Any &v2, const Any &v3, const Any &v4, const Any &v5, const Any &v6, const Any &v7)
00166 : data(NULL)
00167 {
00168 const Any *arr[] = { &v1, &v2, &v3, &v4, &v5, &v6, &v7 };
00169 set(7, arr, msgSender, msgReceiver);
00170 }
00171
00172 Message::Message(const ActorRef &msgSender, const ActorRef &msgReceiver, const Any &v1, const Any &v2, const Any &v3, const Any &v4, const Any &v5, const Any &v6, const Any &v7, const Any &v8)
00173 : data(NULL)
00174 {
00175 const Any *arr[] = { &v1, &v2, &v3, &v4, &v5, &v6, &v7, &v8 };
00176 set(8, arr, msgSender, msgReceiver);
00177 }
00178
00179 Message::Message(const ActorRef &msgSender, const ActorRef &msgReceiver, const Any &v1, const Any &v2, const Any &v3, const Any &v4, const Any &v5, const Any &v6, const Any &v7, const Any &v8, const Any &v9)
00180 : data(NULL)
00181 {
00182 const Any *arr[] = { &v1, &v2, &v3, &v4, &v5, &v6, &v7, &v8, &v9 };
00183 set(9, arr, msgSender, msgReceiver);
00184 }
00185
00186
00187 Message::Message(const Message &other) : AnyArray(), data(other.data)
00188 {
00189 data->ref();
00190 }
00191
00192 Message::~Message()
00193 {
00194 if (!data->deref())
00195 {
00196 delete data;
00197 }
00198 }
00199
00200 ActorRef &Message::sender() const
00201 {
00202 return data->sender;
00203 }
00204
00205 ActorRef &Message::receiver() const
00206 {
00207 return data->receiver;
00208 }
00209
00210 Message &Message::operator=(const Message &other)
00211 {
00212 if (!data->deref()) delete data;
00213 other.data->ref();
00214 data = other.data;
00215 return *this;
00216 }
00217
00218 boost::uint32_t Message::length() const
00219 {
00220 return data->length;
00221 }
00222
00223 const Any &Message::at(boost::uint32_t pos) const
00224 {
00225 if (pos >= length()) throw IndexOutOfBoundsException("acedia::Message out of bounds");
00226 return data->arr[pos];
00227 }
00228
00229 bool Message::operator==(const Message &other) const
00230 {
00231 if (length() == other.length())
00232 {
00233 if (isEmpty()) return true;
00234 for (boost::uint32_t i = 0; i < length(); ++i)
00235 {
00236 if (at(i) != other.at(i)) return false;
00237 }
00238 return true;
00239 }
00240 return false;
00241 }
00242
00243 String Message::serializeToString()
00244 {
00245 static String verificator("acedia::NetworkMessage");
00246 std::ostringstream ostr;
00247 boost::archive::text_oarchive oar(ostr);
00248 boost::uint32_t sndr = sender().realActorId();
00249 boost::uint32_t rcvr = receiver().realActorId();
00250 boost::uint32_t lngt = length();
00251 oar << verificator;
00252 oar << sndr;
00253 oar << rcvr;
00254 oar << lngt;
00255 for (boost::uint32_t i = 0; i < length(); ++i)
00256 {
00257 at(i).val->serialize(oar);
00258 }
00259
00260 return ostr.str();
00261 }
00262
00263 Message Message::deserializeFrom(const char* str, details::ProxyFactory* factory)
00264 {
00265 std::istringstream istr(str);
00266 boost::archive::text_iarchive iar(istr);
00267 String verification;
00268 boost::uint32_t rcver, snder, len;
00269 iar >> verification;
00270 if (verification != "acedia::NetworkMessage")
00271 {
00272 ACEDIA_THROW(NotDeserializableException, "Received string not deserializable (verification failed)");
00273 }
00274 iar >> snder;
00275 iar >> rcver;
00276 iar >> len;
00277
00278 ActorRef senderRef;
00279 if (snder != 0) senderRef = factory->get(snder);
00280
00281 ActorRef receiverRef;
00282 if (rcver != 0) receiverRef = details::getInstanceById(rcver);
00283 details::MessageData *mdata = new details::MessageData(len, senderRef, receiverRef);
00284 for (boost::uint32_t i = 0; i < len; ++i)
00285 {
00286 String className;
00287 iar >> className;
00288
00289 MetaClass* mc = getMetaClass(className);
00290 if (!mc || mc == details::MetaClassImpl<void>::instance())
00291 {
00292 ACEDIA_THROW(NotDeserializableException, "Could not load meta class for requestet class");
00293 }
00294 mdata->arr[i].val = mc->deserialize(iar);
00295 }
00296 return Message(mdata);
00297 }
00298
00299 String Message::toString(bool verbose) const
00300 {
00301 std::ostringstream ostr;
00302 ostr << "Message";
00303 if (verbose)
00304 {
00305 ostr << "[sender="
00306 << util::AsString<ActorRef>::get(sender()).const_str()
00307 << ",receiver="
00308 << util::AsString<ActorRef>::get(receiver()).const_str()
00309 << "]";
00310 }
00311 ostr << "(";
00312 for (::size_t i = 0; i < length(); ++i)
00313 {
00314 if (i > 0) ostr << ", ";
00315 ostr << at(i).toString(verbose).const_str();
00316 }
00317 ostr << ")";
00318 return ostr.str();
00319 }
00320
00321 bool Message::isMessage() const { return true; }
00322
00323 }