Sirikata
|
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_