Sirikata
|
00001 /* Sirikata 00002 * CBRLocationServiceCache.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 libprox 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_CBR_LOCATION_SERVICE_CACHE_HPP_ 00034 #define _SIRIKATA_CBR_LOCATION_SERVICE_CACHE_HPP_ 00035 00036 #include <sirikata/pintoloc/ExtendedLocationServiceCache.hpp> 00037 #include <prox/base/LocationServiceCache.hpp> 00038 #include <prox/base/ZernikeDescriptor.hpp> 00039 #include <sirikata/space/LocationService.hpp> 00040 #include <boost/thread.hpp> 00041 00042 namespace Sirikata { 00043 00044 /* Implementation of LocationServiceCache which serves Prox libraries; 00045 * works by listening for updates from our LocationService. Note that 00046 * CBR should only be using the LocationServiceListener methods in normal 00047 * operation -- all other threads are to be used by libprox classes and 00048 * will only be accessed in the proximity thread. Therefore, most of the 00049 * work happens in the proximity thread, with the callbacks just storing 00050 * information to be picked up in the next iteration. 00051 */ 00052 class CBRLocationServiceCache : 00053 public ExtendedLocationServiceCache, 00054 public LocationServiceListener 00055 { 00056 public: 00057 typedef Prox::LocationUpdateListener<ObjectProxSimulationTraits> LocationUpdateListener; 00058 00063 CBRLocationServiceCache(Network::IOStrand* strand, LocationService* locservice, bool replicas); 00064 virtual ~CBRLocationServiceCache(); 00065 00066 /* LocationServiceCache members. */ 00067 virtual void addPlaceholderImposter( 00068 const ObjectID& id, 00069 const Vector3f& center_offset, 00070 const float32 center_bounds_radius, 00071 const float32 max_size, 00072 const String& zernike, 00073 const String& mesh 00074 ); 00075 virtual Iterator startTracking(const ObjectID& id); 00076 virtual void stopTracking(const Iterator& id); 00077 virtual bool startRefcountTracking(const ObjectID& id); 00078 virtual void stopRefcountTracking(const ObjectID& id); 00079 00080 // ExtendLocationServiceCache 00081 virtual bool tracking(const ObjectID& id); 00082 00083 virtual TimedMotionVector3f location(const Iterator& id); 00084 virtual Vector3f centerOffset(const Iterator& id); 00085 virtual float32 centerBoundsRadius(const Iterator& id); 00086 virtual float32 maxSize(const Iterator& id); 00087 virtual bool isLocal(const Iterator& id); 00088 Prox::ZernikeDescriptor& zernikeDescriptor(const Iterator& id); 00089 String mesh(const Iterator& id); 00090 00091 virtual const ObjectReference& iteratorID(const Iterator& id); 00092 00093 virtual void addUpdateListener(LocationUpdateListener* listener); 00094 virtual void removeUpdateListener(LocationUpdateListener* listener); 00095 00096 // ExtendLocationServiceCache 00097 // We also provide accessors by ID for Proximity generate results. 00098 TimedMotionVector3f location(const ObjectID& id); 00099 TimedMotionQuaternion orientation(const ObjectID& id); 00100 AggregateBoundingInfo bounds(const ObjectID& id); 00101 Transfer::URI mesh(const ObjectID& id); 00102 String physics(const ObjectID& id); 00103 virtual bool aggregate(const ObjectID& id) { return isAggregate(id); } 00104 00105 const bool isAggregate(const ObjectID& id); 00106 00107 00108 /* LocationServiceListener members. */ 00109 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); 00110 virtual void localObjectRemoved(const UUID& uuid, bool agg); 00111 virtual void localLocationUpdated(const UUID& uuid, bool agg, const TimedMotionVector3f& newval); 00112 virtual void localOrientationUpdated(const UUID& uuid, bool agg, const TimedMotionQuaternion& newval); 00113 virtual void localBoundsUpdated(const UUID& uuid, bool agg, const AggregateBoundingInfo& newval); 00114 virtual void localMeshUpdated(const UUID& uuid, bool agg, const String& newval); 00115 virtual void localPhysicsUpdated(const UUID& uuid, bool agg, const String& newval); 00116 virtual void replicaObjectAdded(const UUID& uuid, const TimedMotionVector3f& loc, const TimedMotionQuaternion& orient, const AggregateBoundingInfo& bounds, const String& mesh, const String& physics, const String& zernike); 00117 virtual void replicaObjectRemoved(const UUID& uuid); 00118 virtual void replicaLocationUpdated(const UUID& uuid, const TimedMotionVector3f& newval); 00119 virtual void replicaOrientationUpdated(const UUID& uuid, const TimedMotionQuaternion& newval); 00120 virtual void replicaBoundsUpdated(const UUID& uuid, const AggregateBoundingInfo& newval); 00121 virtual void replicaMeshUpdated(const UUID& uuid, const String& newval); 00122 virtual void replicaPhysicsUpdated(const UUID& uuid, const String& newval); 00123 00124 private: 00125 // Object data is only accessed in the prox thread (by libprox 00126 // and by this class when updates are passed by the main thread). 00127 // Therefore, this data does *NOT* need to be locked for access. 00128 struct ObjectData { 00129 TimedMotionVector3f location; 00130 TimedMotionQuaternion orientation; 00131 AggregateBoundingInfo bounds; 00132 // Whether the object is local or a replica 00133 bool isLocal; 00134 String mesh; 00135 String physics; 00136 Prox::ZernikeDescriptor zernike; 00137 bool exists; // Exists, i.e. xObjectRemoved hasn't been called 00138 int16 tracking; // Ref count to support multiple users 00139 bool isAggregate; 00140 }; 00141 00142 00143 // These generate and queue up updates from the main thread 00144 void objectAdded(const UUID& uuid, bool islocal, bool agg, const TimedMotionVector3f& loc, const TimedMotionQuaternion& orient, const AggregateBoundingInfo& bounds, const String& mesh, const String& physics, const String& zernike); 00145 void objectRemoved(const UUID& uuid, bool agg); 00146 void locationUpdated(const UUID& uuid, bool agg, const TimedMotionVector3f& newval); 00147 void orientationUpdated(const UUID& uuid, bool agg, const TimedMotionQuaternion& newval); 00148 void boundsUpdated(const UUID& uuid, bool agg, const AggregateBoundingInfo& newval); 00149 void meshUpdated(const UUID& uuid, bool agg, const String& newval); 00150 void physicsUpdated(const UUID& uuid, bool agg, const String& newval); 00151 00152 // These do the actual work for the LocationServiceListener methods. Local versions always 00153 // call these, replica versions only call them if replica tracking is 00154 // on. Although we now have to lock in these, we put them on the strand 00155 // instead of processing directly in the methods above so that they don't 00156 // block any other work. 00157 void processObjectAdded(const ObjectReference& uuid, ObjectData data); 00158 void processObjectRemoved(const ObjectReference& uuid, bool agg); 00159 void processLocationUpdated(const ObjectReference& uuid, bool agg, const TimedMotionVector3f& newval); 00160 void processOrientationUpdated(const ObjectReference& uuid, bool agg, const TimedMotionQuaternion& newval); 00161 void processBoundsUpdated(const ObjectReference& uuid, bool agg, const AggregateBoundingInfo& newval); 00162 void processMeshUpdated(const ObjectReference& uuid, bool agg, const String& newval); 00163 void processPhysicsUpdated(const ObjectReference& uuid, bool agg, const String& newval); 00164 00165 00166 CBRLocationServiceCache(); 00167 00168 typedef boost::recursive_mutex Mutex; 00169 typedef boost::lock_guard<Mutex> Lock; 00170 // Separate listener list and rest of data. Some callbacks to listeners can 00171 // be expensive and we don't want to lock during these (e.g. connections 00172 // causing insertions with lots of operations and other changes during the 00173 // insertion). 00174 Mutex mListenerMutex; 00175 Mutex mDataMutex; 00176 00177 Network::IOStrand* mStrand; 00178 LocationService* mLoc; 00179 00180 typedef std::set<LocationUpdateListener*> ListenerSet; 00181 ListenerSet mListeners; 00182 00183 typedef std::tr1::unordered_map<ObjectReference, ObjectData, ObjectReference::Hasher> ObjectDataMap; 00184 ObjectDataMap mObjects; 00185 bool mWithReplicas; 00186 00187 bool tryRemoveObject(ObjectDataMap::iterator& obj_it); 00188 00189 // Data contained in our Iterators. We maintain both the UUID and the 00190 // iterator because the iterator can become invalidated due to ordering of 00191 // events in the prox thread. 00192 struct IteratorData { 00193 IteratorData(const ObjectReference& _objid, ObjectDataMap::iterator _it) 00194 : objid(_objid), it(_it) {} 00195 00196 const ObjectReference objid; 00197 ObjectDataMap::iterator it; 00198 }; 00199 00200 }; 00201 00202 } // namespace Sirikata 00203 00204 #endif //_SIRIKATA_CBR_LOCATION_SERVICE_CACHE_HPP_