Sirikata
space/src/MigrationMonitor.hpp
Go to the documentation of this file.
00001 /*  Sirikata
00002  *  MigrationMonitor.hpp
00003  *
00004  *  Copyright (c) 2009, 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_MIGRATION_MONITOR_HPP_
00034 #define _SIRIKATA_MIGRATION_MONITOR_HPP_
00035 
00036 #include <sirikata/core/util/Platform.hpp>
00037 #include <sirikata/space/LocationService.hpp>
00038 #include <sirikata/space/CoordinateSegmentation.hpp>
00039 
00040 #include <boost/multi_index_container.hpp>
00041 #include <boost/multi_index/member.hpp>
00042 #include <boost/multi_index/ordered_index.hpp>
00043 
00044 namespace Sirikata {
00045 
00051 class MigrationMonitor : public LocationServiceListener, public CoordinateSegmentation::Listener {
00052 public:
00053     typedef std::tr1::function<void(const UUID&)> MigrationCallback;
00054 
00062     MigrationMonitor(SpaceContext* ctx, LocationService* locservice, CoordinateSegmentation* cseg, MigrationCallback cb);
00063     ~MigrationMonitor();
00064 
00065     // Indicates whether the given position is on this server, useful to check if object should be
00066     // permitted to join this server.
00067     bool onThisServer(const Vector3f& pos) const;
00068 
00069 private:
00070 
00072   virtual void localObjectAdded(const UUID& uuid, bool agg, const TimedMotionVector3f& loc, const TimedMotionQuaternion& orient, const AggregateBoundingInfo& bounds, const String& mesh, const String& physics, const String& zernike);
00073     virtual void localObjectRemoved(const UUID& uuid, bool agg);
00074     virtual void localLocationUpdated(const UUID& uuid, bool agg, const TimedMotionVector3f& newval);
00075 
00076     // Handlers for location events we care about.  These are handled in our internal strand
00077     void handleLocalObjectAdded(const UUID& uuid, const TimedMotionVector3f& loc, const AggregateBoundingInfo& bounds);
00078     void handleLocalObjectRemoved(const UUID& uuid);
00079     void handleLocalLocationUpdated(const UUID& uuid, const TimedMotionVector3f& newval);
00080 
00082     virtual void updatedSegmentation(CoordinateSegmentation* cseg, const std::vector<SegmentationInfo>& new_segmentation);
00083     void handleUpdatedSegmentation(CoordinateSegmentation* cseg, const std::vector<SegmentationInfo>& new_segmentation);
00084 
00085     // Given our current information, sets up the next timeout, cancelling any outstanding timeouts.
00086     // This is conservative -- it will only replace the timer if the earliest event time changed
00087     void waitForNextEvent();
00088 
00089     // Service the migration monitor, return a set of objects for which migrations should be started
00090     void service();
00091 
00092     bool inRegion(const Vector3f& pos) const;
00093 
00094     Time computeNextEventTime(const UUID& obj, const TimedMotionVector3f& newloc);
00095 
00096     SpaceContext* mContext;
00097     LocationService* mLocService;
00098     CoordinateSegmentation* mCSeg;
00099     BoundingBoxList mBoundingRegions;
00100 
00101     struct ObjectInfo {
00102         ObjectInfo(UUID id, Time next)
00103          : objid(id),
00104            nextEvent(next)
00105         {}
00106 
00107         UUID objid;
00108         Time nextEvent;
00109     };
00110 
00111 
00112     // Tags used by ObjectInfoSet
00113     struct objid {};
00114     struct nextevent {};
00115 
00116     typedef boost::multi_index_container<
00117         ObjectInfo,
00118         boost::multi_index::indexed_by<
00119             boost::multi_index::ordered_unique< boost::multi_index::tag<objid>, BOOST_MULTI_INDEX_MEMBER(ObjectInfo,UUID,objid) >,
00120             boost::multi_index::ordered_non_unique< boost::multi_index::tag<nextevent>, BOOST_MULTI_INDEX_MEMBER(ObjectInfo,Time,nextEvent) >
00121         >
00122     > ObjectInfoSet;
00123     typedef ObjectInfoSet::index<objid>::type ObjectInfoByID;
00124     typedef ObjectInfoSet::index<nextevent>::type ObjectInfoByNextEvent;
00125 
00126     static void changeNextEventTime(ObjectInfo& objinfo, const Time& newt);
00127 
00128     ObjectInfoSet mObjectInfo;
00129 
00130     Network::IOStrand* mStrand;
00131     Network::IOTimerPtr mTimer;
00132 
00133     Time mMinEventTime;
00134 
00135     MigrationCallback mCB;
00136 };
00137 
00138 } // namespace Sirikata
00139 
00140 #endif //_SIRIKATA_MIGRATION_MONITOR_HPP_