Sirikata
liboh/include/sirikata/oh/HostedObject.hpp
Go to the documentation of this file.
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