Sirikata
libspace/include/sirikata/space/ObjectSessionManager.hpp
Go to the documentation of this file.
00001 /*  Sirikata
00002  *  ObjectSessionManager.hpp
00003  *
00004  *  Copyright (c) 2010, Ewen Cheslack-Postava
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions are
00009  *  met:
00010  *  * Redistributions of source code must retain the above copyright
00011  *    notice, this list of conditions and the following disclaimer.
00012  *  * Redistributions in binary form must reproduce the above copyright
00013  *    notice, this list of conditions and the following disclaimer in
00014  *    the documentation and/or other materials provided with the
00015  *    distribution.
00016  *  * Neither the name of Sirikata nor the names of its contributors may
00017  *    be used to endorse or promote products derived from this software
00018  *    without specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00021  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00022  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00023  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
00024  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00025  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00026  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00027  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00028  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00029  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  */
00032 
00033 #ifndef _SIRIKATA_SPACE_OBJECT_SESSION_MANAGER_HPP_
00034 #define _SIRIKATA_SPACE_OBJECT_SESSION_MANAGER_HPP_
00035 
00036 #include <sirikata/space/Platform.hpp>
00037 #include <sirikata/core/odp/SST.hpp>
00038 #include <sirikata/core/util/ListenerProvider.hpp>
00039 #include <sirikata/space/SpaceContext.hpp>
00040 
00041 namespace Sirikata {
00042 
00043 class ObjectSessionManager;
00044 
00051 class SIRIKATA_SPACE_EXPORT ObjectSession {
00052   public:
00053     typedef ODPSST::Stream SSTStream;
00054     typedef SSTStream::Ptr SSTStreamPtr;
00055 
00056     ObjectSession(const ObjectReference& objid)
00057         : mID(objid),
00058         mSSTStream(), // set later by ObjectSessionManager
00059         mSeqNo(new SeqNo())
00060     {}
00061     ~ObjectSession()
00062     {
00063         // Force closure, there's no way to get data to the object anymore...
00064         if (mSSTStream) mSSTStream->close(true);
00065     }
00066 
00067     const ObjectReference& id() const { return mID; }
00068 
00069     SSTStreamPtr getStream() const { return mSSTStream; }
00070 
00071     SeqNoPtr getSeqNoPtr() const { return mSeqNo; }
00072 
00073   private:
00074     friend class ObjectSessionManager;
00075 
00076     ObjectReference mID;
00077     SSTStreamPtr mSSTStream;
00078     // We still use SeqNoPtrs to deal with thread safety -- the seqno
00079     // is own
00080     SeqNoPtr mSeqNo;
00081 };
00082 
00083 class SIRIKATA_SPACE_EXPORT ObjectSessionListener {
00084   public:
00085     virtual void newSession(ObjectSession* session) {}
00086     virtual void sessionClosed(ObjectSession* session) {}
00087     virtual ~ObjectSessionListener() {}
00088 };
00089 
00090 class SIRIKATA_SPACE_EXPORT ObjectSessionManager : public Provider<ObjectSessionListener*> {
00091   public:
00092     ObjectSessionManager(SpaceContext* ctx) {
00093         ctx->mObjectSessionManager = this;
00094     }
00095     virtual ~ObjectSessionManager() {}
00096 
00097     // Owner interface -- adds and removes sessions. Adding is split
00098     // into two steps. The first adds the session, making it
00099     // accessible for services that don't need streams. The second
00100     // completes it
00101     void addSession(ObjectSession* session) {
00102         mObjectSessions[session->id()] = session;
00103     }
00104     void completeSession(ObjectReference& obj, ObjectSession::SSTStreamPtr s) {
00105         ObjectSession* session = mObjectSessions[obj];
00106         session->mSSTStream = s;
00107         notify(&ObjectSessionListener::newSession, session);
00108     }
00109     void removeSession(const ObjectReference& obj) {
00110         ObjectSessionMap::iterator session_it = mObjectSessions.find(obj);
00111         if (session_it != mObjectSessions.end()) {
00112             notify(&ObjectSessionListener::sessionClosed, session_it->second);
00113             delete session_it->second;
00114             mObjectSessions.erase(session_it);
00115         }
00116     }
00117 
00118     // User interface
00119 
00120     ObjectSession* getSession(const ObjectReference& objid) const {
00121         ObjectSessionMap::const_iterator it = mObjectSessions.find(objid);
00122         if (it == mObjectSessions.end()) return NULL;
00123         return it->second;
00124     }
00125 
00126   private:
00127     typedef std::tr1::unordered_map<ObjectReference, ObjectSession*, ObjectReference::Hasher> ObjectSessionMap;
00128     ObjectSessionMap mObjectSessions;
00129 };
00130 
00131 } // namespace Sirikata
00132 
00133 #endif //_SIRIKATA_SPACE_OBJECT_SESSION_MANAGER_HPP_