Sirikata
|
00001 /* Sirikata 00002 * ObjectSegmentation.hpp 00003 * 00004 * Copyright (c) 2010, Daniel Reiter Horn 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_OBJECT_SEGMENTATION_HPP_ 00034 #define _SIRIKATA_OBJECT_SEGMENTATION_HPP_ 00035 00036 #include <sirikata/space/SpaceContext.hpp> 00037 #include <sirikata/space/ServerMessage.hpp> 00038 #include <sirikata/space/CoordinateSegmentation.hpp> 00039 #include <sirikata/core/service/Service.hpp> 00040 #include <sirikata/core/util/Factory.hpp> 00041 00042 #include <sirikata/core/queue/ThreadSafeQueueWithNotification.hpp> 00043 #include "Protocol_OSeg.pbj.hpp" 00044 00045 namespace Sirikata 00046 { 00047 00048 class OSegCache; 00049 00050 class OSegEntry { 00051 protected: 00052 uint32 mServer; 00053 float mRadius; 00054 public: 00055 explicit OSegEntry() 00056 : mServer(NullServerID), mRadius(0) 00057 {} 00058 OSegEntry(uint32 server, float radius) { 00059 mServer=server; 00060 mRadius=radius; 00061 } 00062 static OSegEntry null() { 00063 return OSegEntry(NullServerID,0); 00064 } 00065 bool isNull() const { 00066 return mServer==NullServerID&&mRadius==0; 00067 } 00068 bool notNull() const { 00069 return !isNull(); 00070 } 00071 uint32 server() const{ 00072 return mServer; 00073 } 00074 float radius () const{ 00075 return mRadius; 00076 } 00077 void setServer(uint32 server) 00078 { 00079 mServer = server; 00080 } 00081 void setRadius(float radius) 00082 { 00083 mRadius = radius; 00084 } 00085 }; 00086 00087 /* Listener interface for OSeg events. 00088 * 00089 * Note that these are likely to be called from another thread, so 00090 * the implementing class must ensure they are thread safe. 00091 */ 00092 class OSegLookupListener { 00093 public: 00094 virtual ~OSegLookupListener() {} 00095 00096 virtual void osegLookupCompleted(const UUID& id, const OSegEntry& dest) = 0; 00097 }; // class OSegLookupListener 00098 00099 00101 class OSegWriteListener { 00102 public: 00103 virtual ~OSegWriteListener() {} 00104 00105 00106 enum OSegAddNewStatus 00107 { 00108 SUCCESS, 00109 OBJ_ALREADY_REGISTERED, 00110 UNKNOWN_ERROR 00111 }; 00112 00113 virtual void osegAddNewFinished(const UUID& id, OSegAddNewStatus) = 0; 00114 virtual void osegMigrationAcknowledged(const UUID& id) = 0; 00115 }; // class OSegMembershipListener 00116 00117 00118 00119 00120 class SIRIKATA_SPACE_EXPORT ObjectSegmentation : public Service, public MessageRecipient 00121 { 00122 protected: 00123 SpaceContext* mContext; 00124 bool mStopping; 00125 OSegLookupListener* mLookupListener; 00126 OSegWriteListener* mWriteListener; 00127 Network::IOStrand* oStrand; 00128 00129 Router<Message*>* mOSegServerMessageService; 00130 // This queue handles outgoing migration ack messages, getting them safely 00131 // into the outgoing queue. Implementations only need to call queueMigAck() 00132 // from any other thread to get messages sent. 00133 Sirikata::ThreadSafeQueueWithNotification<Message*> mMigAckMessages; 00134 Message* mFrontMigAck; 00135 void queueMigAck(const Sirikata::Protocol::OSeg::MigrateMessageAcknowledge& msg); 00136 void trySendMigAcks(); 00137 void handleNewMigAckMessages(); 00138 00139 // MessageRecipient Interface 00140 virtual void receiveMessage(Message* msg); 00141 00142 // These handlers for server-to-server messages need to be provided by 00143 // implementations. Note that these are *not* thread safe! You may need to 00144 // shift processing into your own thread/strand. 00145 virtual void handleMigrateMessageAck(const Sirikata::Protocol::OSeg::MigrateMessageAcknowledge& msg) = 0; 00146 virtual void handleUpdateOSegMessage(const Sirikata::Protocol::OSeg::UpdateOSegMessage& update_oseg_msg) = 0; 00147 00148 public: 00149 ObjectSegmentation(SpaceContext* ctx, Network::IOStrand* o_strand); 00150 virtual ~ObjectSegmentation(); 00151 00152 virtual void start() { 00153 } 00154 00155 virtual void stop() { 00156 mStopping = true; 00157 } 00158 00159 void setLookupListener(OSegLookupListener* listener) { 00160 mLookupListener = listener; 00161 } 00162 00163 void setWriteListener(OSegWriteListener* listener) { 00164 mWriteListener = listener; 00165 } 00166 00167 00168 virtual OSegEntry lookup(const UUID& obj_id) = 0; 00169 virtual OSegEntry cacheLookup(const UUID& obj_id) = 0; 00170 virtual void migrateObject(const UUID& obj_id, const OSegEntry& new_server_id) = 0; 00171 virtual void addNewObject(const UUID& obj_id, float radius) = 0; 00172 virtual void addMigratedObject(const UUID& obj_id, float radius, ServerID idServerAckTo, bool) = 0; 00173 virtual void removeObject(const UUID& obj_id) = 0; 00174 virtual bool clearToMigrate(const UUID& obj_id) = 0; 00175 00176 virtual int getPushback() 00177 { 00178 return 0; 00179 } 00180 00181 }; 00182 00183 class SIRIKATA_SPACE_EXPORT OSegFactory 00184 : public AutoSingleton<OSegFactory>, 00185 public Factory5<ObjectSegmentation*, SpaceContext*, Network::IOStrand*, CoordinateSegmentation*, OSegCache*, const String &> 00186 { 00187 public: 00188 static OSegFactory& getSingleton(); 00189 static void destroy(); 00190 }; // class OSegFactory 00191 00192 } // namespace Sirikata 00193 00194 #include <sirikata/space/OSegCache.hpp> 00195 00196 #endif