Sirikata
liboh/plugins/js/EmersonMessagingManager.hpp
Go to the documentation of this file.
00001 // Copyright (c) 2011 Sirikata Authors. All rights reserved.
00002 // Use of this source code is governed by a BSD-style license that can
00003 // be found in the LICENSE file.
00004 
00005 #ifndef __EMERSON_MESSAGING_MANAGER_HPP__
00006 #define __EMERSON_MESSAGING_MANAGER_HPP__
00007 
00008 #include <map>
00009 #include <sirikata/core/odp/SST.hpp>
00010 #include <sirikata/core/network/ObjectMessage.hpp>
00011 #include <string>
00012 #include <sstream>
00013 #include <sirikata/core/util/Liveness.hpp>
00014 #include <sirikata/oh/ObjectHostContext.hpp>
00015 
00016 namespace Sirikata{
00017 namespace JS{
00018 
00019 class EmersonScript;
00020 
00021 typedef SST::Stream<SpaceObjectReference> SSTStream;
00022 typedef SSTStream::Ptr SSTStreamPtr;
00023 
00024 // NOTE: virtual on Liveness because JSObjectScript also uses it
00025 class EmersonMessagingManager : public virtual Liveness
00026 {
00027 public:
00028     EmersonMessagingManager(ObjectHostContext* ctx);
00029     virtual ~EmersonMessagingManager();
00030 
00031     //EmersonScript must know what to do with messages that we receive.
00032     /*
00033       Payload should be able to be parsed into JS::Proctocol::JSMessage.  If it
00034       can be, and deserialization is successful, processes the scripting
00035       message. (via deserializeMsgAndDispatch.)
00036      */
00037     virtual bool handleScriptCommRead(const SpaceObjectReference& src, const SpaceObjectReference& dst, const std::string& payload) = 0;
00038 
00039 
00040     bool sendScriptCommMessageReliable(const SpaceObjectReference& sender, const SpaceObjectReference& receiver, const String& msg);
00041     bool sendScriptCommMessageReliable(
00042         const SpaceObjectReference& sender, const SpaceObjectReference& receiver,
00043         const String& msg, int8 retriesSameStream,int8 retriesNewStream,
00044         bool isRetry=false);
00045 
00046 
00047     void presenceConnected(const SpaceObjectReference& connPresSporef);
00048     void presenceDisconnected(const SpaceObjectReference& disconnPresSporef);
00049 
00050 private:
00051     // Possibly save the new stream to mStreams for later use. Since both sides
00052     // might initiate, we always save the stream initiated by the object with
00053     // smaller if we identify a conflict.
00054     void setupNewStream(SSTStreamPtr sstStream, bool closePrevious = false);
00055     // Get a saved stream for the given destination object, or NULL if one isn't
00056     // available.
00057     SSTStreamPtr getStream(const SpaceObjectReference& pres, const SpaceObjectReference& remote);
00058 
00059     // "Destroy" (i.e. discard reference to) all streams owned by an object
00060     void clearStreams(const SpaceObjectReference& pres);
00061 
00062     //reading helpers
00063     void createScriptCommListenerStreamCB(Liveness::Token alive, const SpaceObjectReference& toListenFrom, int err, SSTStreamPtr sstStream);
00064     void handleIncomingSubstream(Liveness::Token alive, int err, SSTStreamPtr streamPtr);
00065     void handleScriptCommStreamRead(Liveness::Token alive, SSTStreamPtr sstptr, String* prevdata, uint8* buffer, int length);
00066 
00067     // Only put a few parameters in here to avoid copying lots of stuff, we only
00068     // need to get < 8 parameters for bind to work on all platforms
00069     struct CommWriteStreamConnectedCBRetryData {
00070         int8 retriesSameStream;
00071         int8 retriesNewStream;
00072         bool isRetry;
00073     };
00074     //writing helper
00075     void scriptCommWriteStreamConnectedCB(
00076         Liveness::Token alive, const String& msg,
00077         const SpaceObjectReference& sender, const SpaceObjectReference& receiver,
00078         int err, SSTStreamPtr streamPtr, CommWriteStreamConnectedCBRetryData retryData);
00079 
00080     // Writes a message to a *substream* of the given stream
00081     void writeMessage(
00082         Liveness::Token alive, SSTStreamPtr streamPtr,
00083         const String& msg, const SpaceObjectReference& sender,
00084         const SpaceObjectReference& receiver, int8 retriesSameStream,
00085         int8 retriesNewStream);
00086 
00087     void writeMessageSubstream(
00088         Liveness::Token alive, int err, SSTStreamPtr subStreamPtr,
00089         const String& msg, const SpaceObjectReference& sender,
00090         const SpaceObjectReference& receiver, int8 retriesSameStream,
00091         int8 retriesNewStream);
00092 
00093     void writeData(Liveness::Token alive, SSTStreamPtr streamPtr, const String& msg, const SpaceObjectReference& sender, const SpaceObjectReference& receiver);
00094 
00095     void removeStream(
00096         const SpaceObjectReference& sender, const SpaceObjectReference& receiver);
00097 
00098 
00099     ObjectHostContext* mMainContext;
00100 
00101     //map of existing presences.  value doesn't matter, just want a quick way of
00102     //checking if particular presences are connected.
00103     std::map<SpaceObjectReference, bool> allPres;
00104 
00105     // Streams to be reused for sending messages
00106     typedef std::tr1::unordered_map<SpaceObjectReference, SSTStreamPtr, SpaceObjectReference::Hasher> StreamMap;
00107     typedef std::tr1::unordered_map<SpaceObjectReference, StreamMap, SpaceObjectReference::Hasher> PresenceStreamMap;
00108     PresenceStreamMap mStreams;
00109 };
00110 
00111 } //end namespace js
00112 } //end namespace sirikata
00113 
00114 #endif