Sirikata
|
00001 /* Sirikata liboh -- Object Host 00002 * HostedObject.hpp 00003 * 00004 * Copyright (c) 2009, Patrick 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 #ifndef _SIRIKATA_HOSTED_OBJECT_HPP_ 00033 #define _SIRIKATA_HOSTED_OBJECT_HPP_ 00034 00035 #include <sirikata/core/util/SpaceObjectReference.hpp> 00036 #include <sirikata/proxyobject/ProxyObject.hpp> 00037 #include <sirikata/proxyobject/VWObject.hpp> 00038 #include <sirikata/core/util/Platform.hpp> 00039 #include <sirikata/core/odp/DelegateService.hpp> 00040 #include <sirikata/oh/ObjectScriptManager.hpp> 00041 00042 #include <utility> 00043 00044 #include <sirikata/core/network/ObjectMessage.hpp> 00045 #include <sirikata/core/odp/SST.hpp> 00046 00047 #include <sirikata/core/transfer/URI.hpp> 00048 00049 #include <sirikata/oh/ObjectHost.hpp> 00050 #include <sirikata/oh/SimulationFactory.hpp> 00051 00052 //here 00053 #include <sirikata/core/util/Platform.hpp> 00054 00055 #include <sirikata/core/service/Service.hpp> 00056 #include <sirikata/core/util/Timer.hpp> 00057 #include <sirikata/core/service/Context.hpp> 00058 00059 #include <sirikata/core/network/Message.hpp> 00060 00061 #include <boost/lexical_cast.hpp> 00062 #include <boost/asio.hpp> //htons, ntohs 00063 00064 00065 #include <sirikata/core/transfer/TransferData.hpp> 00066 #include <sirikata/core/transfer/RemoteFileMetadata.hpp> 00067 #include <sirikata/core/transfer/TransferPool.hpp> 00068 #include <sirikata/core/transfer/TransferMediator.hpp> 00069 00070 namespace Sirikata { 00071 00072 class LocUpdate; 00073 00074 namespace Protocol { 00075 namespace Loc { 00076 class LocationUpdate; 00077 class BulkLocationUpdate; 00078 } 00079 namespace Prox { 00080 class ProximityUpdate; 00081 } 00082 } 00083 00084 class ProxyObject; 00085 class ProxyObject; 00086 struct LightInfo; 00087 typedef std::tr1::shared_ptr<ProxyObject> ProxyObjectPtr; 00088 00089 class ObjectScript; 00090 class HostedObject; 00091 class PerPresenceData; 00092 typedef std::tr1::weak_ptr<HostedObject> HostedObjectWPtr; 00093 typedef std::tr1::shared_ptr<HostedObject> HostedObjectPtr; 00094 00095 00096 class SIRIKATA_OH_EXPORT HostedObject 00097 : public VWObject, 00098 public Service 00099 { 00100 private: 00101 struct PrivateCallbacks; 00102 00103 typedef struct OHConnectInfo{ 00104 public: 00105 SpaceID spaceID; 00106 Location startingLocation; 00107 BoundingSphere3f meshBounds; 00108 String mesh; 00109 String physics; 00110 String query; 00111 ObjectReference orefID; 00112 int64 token; 00113 String zernike; 00114 } OHConnectInfo; 00115 typedef std::tr1::shared_ptr<OHConnectInfo> OHConnectInfoPtr; 00116 00117 protected: 00118 00119 ObjectHostContext* mContext; 00120 const UUID mID; 00121 00122 ObjectHost *mObjectHost; 00123 ObjectScript *mObjectScript; 00124 typedef std::map<SpaceObjectReference, PerPresenceData*> PresenceDataMap; 00125 PresenceDataMap mPresenceData; 00126 00127 bool destroyed; 00128 00129 ODP::DelegateService* mDelegateODPService; 00130 00131 typedef boost::mutex Mutex; 00132 Mutex presenceDataMutex; 00133 Mutex notifyMutex; 00134 00135 friend class ::Sirikata::SelfWeakPtr<VWObject>; 00136 friend class PerPresenceData; 00137 AtomicValue<int> mNumOutstandingConnections; 00138 bool mDestroyWhenConnected; 00139 00140 public: 00141 typedef SST::EndPoint<SpaceObjectReference> EndPointType; 00142 typedef SST::BaseDatagramLayer<SpaceObjectReference> BaseDatagramLayerType; 00143 typedef BaseDatagramLayerType::Ptr BaseDatagramLayerPtr; 00144 typedef SST::Connection<SpaceObjectReference> SSTConnection; 00145 typedef SSTConnection::Ptr SSTConnectionPtr; 00146 typedef SST::Stream<SpaceObjectReference> SSTStream; 00147 typedef SSTStream::Ptr SSTStreamPtr; 00148 00150 virtual ~HostedObject(); 00151 00156 const UUID& id() const; 00157 00158 // Sirikata::Service interface 00159 virtual void start(); 00160 virtual void stop(); 00161 00162 bool stopped() const; 00163 00170 typedef std::vector<SpaceObjectReference> SpaceObjRefVec; 00171 void getSpaceObjRefs(SpaceObjRefVec& ss) const; 00172 00173 ObjectHostContext* context() { return mContext; } 00174 const ObjectHostContext* context() const { return mContext; } 00175 00177 Time spaceTime(const SpaceID& space, const Time& t); 00179 Time currentSpaceTime(const SpaceID& space); 00181 Time localTime(const SpaceID& space, const Time& t); 00183 Time currentLocalTime(); 00184 00186 void initializeScript(const String& script_type, const String& args, const String& script); 00187 00191 void destroy(bool need_self = true); 00195 ObjectHost *getObjectHost()const {return mObjectHost;} 00196 00198 ProxyObjectPtr getProxy(const SpaceID& space, const ObjectReference& oref); 00199 00200 Simulation* runSimulation( 00201 const SpaceObjectReference& sporef, const String& simName, 00202 Network::IOStrandPtr simStrand); 00203 00204 void killSimulation( 00205 const SpaceObjectReference& sporef, const String& simName); 00206 00207 virtual ProxyManagerPtr getProxyManager(const SpaceID& space,const ObjectReference& oref); 00208 00209 typedef int64 PresenceToken; 00210 const static PresenceToken DEFAULT_PRESENCE_TOKEN = -1; 00211 00228 bool connect( 00229 const SpaceID&spaceID, 00230 const Location&startingLocation, 00231 const BoundingSphere3f &meshBounds, 00232 const String& mesh, 00233 const String& physics, 00234 const String& query, 00235 const ObjectReference& orefID = ObjectReference::null(), 00236 PresenceToken token = DEFAULT_PRESENCE_TOKEN); 00237 00238 00239 void objectHostConnectIndirect(OHConnectInfoPtr oci) { 00240 bool ret = objectHostConnect(oci->spaceID, oci->startingLocation, oci->meshBounds, 00241 oci->mesh, oci->physics, oci->query, oci->zernike, 00242 oci->orefID, oci->token); 00243 } 00244 00245 00246 00247 bool objectHostConnect( 00248 const SpaceID spaceID, 00249 const Location startingLocation, 00250 const BoundingSphere3f meshBounds, 00251 const String mesh, 00252 const String physics, 00253 const String query, 00254 const String zernike, 00255 const ObjectReference orefID, 00256 PresenceToken token = DEFAULT_PRESENCE_TOKEN); 00257 00258 bool downloadZernikeDescriptor(OHConnectInfoPtr ocip, uint8 n_retry=0); 00259 00260 void metadataDownloaded( 00261 OHConnectInfoPtr ocip, 00262 uint8 retryCount, 00263 std::tr1::shared_ptr<Transfer::MetadataRequest> request, 00264 std::tr1::shared_ptr<Transfer::RemoteFileMetadata> response); 00265 00266 00268 void disconnectFromSpace(const SpaceID &spaceID, const ObjectReference& oref); 00269 00272 void receiveMessage(const SpaceID& space, const Protocol::Object::ObjectMessage* msg); 00273 00274 00275 HostedObjectPtr getSharedPtr() { 00276 return std::tr1::static_pointer_cast<HostedObject>(this->VWObject::getSharedPtr()); 00277 } 00278 HostedObjectWPtr getWeakPtr() { 00279 return std::tr1::static_pointer_cast<HostedObject>(this->VWObject::getSharedPtr()); 00280 } 00281 00282 // Identification 00283 virtual ProxyManagerPtr presence(const SpaceObjectReference& sor); 00284 virtual SequencedPresencePropertiesPtr presenceRequestedLocation(const SpaceObjectReference& sor); 00285 virtual uint64 presenceLatestEpoch(const SpaceObjectReference& sor); 00286 00287 virtual ProxyObjectPtr self(const SpaceObjectReference& sor); 00288 00289 // ODP::Service Interface 00290 virtual ODP::Port* bindODPPort(const SpaceID& space, const ObjectReference& objref, ODP::PortID port); 00291 virtual ODP::Port* bindODPPort(const SpaceObjectReference& sor, ODP::PortID port); 00292 virtual ODP::Port* bindODPPort(const SpaceID& space, const ObjectReference& objref); 00293 virtual ODP::Port* bindODPPort(const SpaceObjectReference& sor); 00294 virtual ODP::PortID unusedODPPort(const SpaceID& space, const ObjectReference& objref); 00295 virtual ODP::PortID unusedODPPort(const SpaceObjectReference& sor); 00296 virtual void registerDefaultODPHandler(const ODP::Service::MessageHandler& cb); 00297 00298 // Access to SST for this object 00299 ODPSST::Stream::Ptr getSpaceStream(const SpaceObjectReference& sor); 00300 00301 // Movement Interface 00302 //note: location update services both position and velocity 00303 00304 virtual void requestLocationUpdate(const SpaceID& space, const ObjectReference& oref,const TimedMotionVector3f& loc); 00305 virtual void requestOrientationUpdate(const SpaceID& space, const ObjectReference& oref, const TimedMotionQuaternion& orient); 00306 virtual void requestBoundsUpdate(const SpaceID& space, const ObjectReference& oref, const BoundingSphere3f& bounds); 00307 virtual void requestMeshUpdate(const SpaceID& space, const ObjectReference& oref, const String& mesh); 00308 virtual void requestPhysicsUpdate(const SpaceID& space, const ObjectReference& oref, const String& phy); 00309 00310 virtual void requestQueryUpdate(const SpaceID& space, const ObjectReference& oref, const String& new_query); 00311 // Shortcut for requestQueryUpdate("") 00312 virtual void requestQueryRemoval(const SpaceID& space, const ObjectReference& oref); 00313 virtual String requestQuery(const SpaceID& space, const ObjectReference& oref); 00314 00315 00316 // ObjectQuerier Interface 00317 void handleProximityUpdate(const SpaceObjectReference& spaceobj, const Sirikata::Protocol::Prox::ProximityUpdate& update); 00318 void handleLocationUpdate(const SpaceObjectReference& spaceobj, const LocUpdate& lu); 00319 00320 00321 00322 // Commands 00323 void commandPresences( 00324 const Command::Command& cmd, Command::Commander* cmdr, Command::CommandID cmdid); 00325 00326 private: 00328 00334 HostedObject(ObjectHostContext* ctx, ObjectHost*parent, const UUID &_id); 00335 00336 // Because IOStrand->wrap() can't handle > 5 parameters (because the 00337 // underlying boost impementation doesnt), we need to handle wrapping 00338 // connection callbacks manually. 00339 00340 void iHandleDisconnected( 00341 const HostedObjectWPtr& weakSelf, const SpaceObjectReference& spaceobj, 00342 Disconnect::Code cc); 00343 00344 static void handleConnected(const HostedObjectWPtr &weakSelf, ObjectHost* parentOH, const SpaceID& space, const ObjectReference& obj, ObjectHost::ConnectionInfo info); 00345 static void handleConnectedIndirect(const HostedObjectWPtr &weakSelf, ObjectHost* parentOH, const SpaceID& space, const ObjectReference& obj, ObjectHost::ConnectionInfo info, const BaseDatagramLayerPtr&); 00346 00347 // static bool handleEntityCreateMessage(const HostedObjectWPtr &weakSelf, const ODP::Endpoint& src, const ODP::Endpoint& dst, MemoryReference bodyData); 00348 static void handleMigrated(const HostedObjectWPtr &weakSelf, const SpaceID& space, const ObjectReference& obj, ServerID server); 00349 static void handleStreamCreated(const HostedObjectWPtr &weakSelf, const SpaceObjectReference& spaceobj, SessionManager::ConnectionEvent after, PresenceToken token); 00350 static void handleDisconnected(const HostedObjectWPtr &weakSelf, const SpaceObjectReference& spaceobj, Disconnect::Code cc); 00351 00352 // Helper that disconnects presences that were completed after the 00353 // HostedObject was stopped/destroyed. Only invoke indirectly (via posting) 00354 // since we don't want to muck with the connection within the connection 00355 // callback. 00356 static void disconnectDeadPresence(ObjectHost* parentOH, const SpaceID& space, const ObjectReference& obj); 00357 00358 ODP::DelegatePort* createDelegateODPPort(ODP::DelegateService* parentService, const SpaceObjectReference& spaceobj, ODP::PortID port); 00359 bool delegateODPPortSend(const ODP::Endpoint& source_ep, const ODP::Endpoint& dest_ep, MemoryReference payload); 00360 00361 00362 // Handlers for core space-managed updates 00363 void processLocationUpdate(const SpaceObjectReference& sporef, ProxyObjectPtr proxy_obj, const LocUpdate& update); 00364 void processLocationUpdate( 00365 const SpaceID& space, ProxyObjectPtr proxy_obj, bool predictive, 00366 TimedMotionVector3f* loc, uint64 loc_seqno, 00367 TimedMotionQuaternion* orient, uint64 orient_seqno, 00368 AggregateBoundingInfo* bounds, uint64 bounds_seqno, 00369 String* mesh, uint64 mesh_seqno, 00370 String* phy, uint64 phy_seqno 00371 ); 00372 00373 // Helper for creating the correct type of proxy 00374 ProxyObjectPtr createProxy(const SpaceObjectReference& objref, const SpaceObjectReference& owner_objref, const Transfer::URI& meshuri, TimedMotionVector3f& tmv, TimedMotionQuaternion& tmvq, const AggregateBoundingInfo& bounds, const String& physics, const String& query, bool isAggregate, uint64 seqNo); 00375 00376 // Helper for constructing and sending location update 00377 void updateLocUpdateRequest(const SpaceID& space, const ObjectReference& oref, const TimedMotionVector3f* const loc, const TimedMotionQuaternion* const orient, const BoundingSphere3f* const bounds, const String* const mesh, const String* const phy); 00378 void sendLocUpdateRequest(const SpaceID& space, const ObjectReference& oref); 00379 00380 }; 00381 00382 } 00383 00384 #endif