Sirikata
liboh/include/sirikata/oh/ObjectHost.hpp
Go to the documentation of this file.
00001 /*  Sirikata liboh -- Object Host
00002  *  ObjectHost.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_OBJECT_HOST_HPP_
00034 #define _SIRIKATA_OBJECT_HOST_HPP_
00035 
00036 #include <sirikata/oh/Platform.hpp>
00037 #include <sirikata/core/util/Platform.hpp>
00038 #include <sirikata/oh/ObjectHostContext.hpp>
00039 #include <sirikata/core/util/SpaceObjectReference.hpp>
00040 #include <sirikata/core/network/Address.hpp>
00041 #include <sirikata/core/util/ListenerProvider.hpp>
00042 #include <sirikata/core/service/Service.hpp>
00043 #include <sirikata/oh/SessionManager.hpp>
00044 #include <sirikata/core/ohdp/Service.hpp>
00045 #include <sirikata/oh/SpaceNodeSession.hpp>
00046 #include <sirikata/oh/ObjectNodeSession.hpp>
00047 
00048 #include <sirikata/core/command/Commander.hpp>
00049 
00050 #include <sirikata/core/transfer/TransferPool.hpp>
00051 #include <sirikata/core/transfer/TransferMediator.hpp>
00052 
00053 namespace Sirikata {
00054 class ProxyManager;
00055 class PluginManager;
00056 class SpaceConnection;
00057 class ConnectionEventListener;
00058 class ObjectScriptManager;
00059 
00060 class ServerIDMap;
00061 
00062 class HostedObject;
00063 typedef std::tr1::weak_ptr<HostedObject> HostedObjectWPtr;
00064 typedef std::tr1::shared_ptr<HostedObject> HostedObjectPtr;
00065 
00066 typedef Provider< ConnectionEventListener* > ConnectionEventProvider;
00067 
00068 namespace OH {
00069 class Storage;
00070 class PersistedObjectSet;
00071 class ObjectQueryProcessor;
00072 }
00073 
00074 class SIRIKATA_OH_EXPORT ObjectHost
00075     : public ConnectionEventProvider,
00076       public Service,
00077       public OHDP::Service,
00078       public SpaceNodeSessionManager, private SpaceNodeSessionListener,
00079       public ObjectNodeSessionProvider
00080 {
00081 
00082     ObjectHostContext* mContext;
00083 
00084     typedef std::tr1::unordered_map<SpaceID,SessionManager*,SpaceID::Hasher> SpaceSessionManagerMap;
00085 
00086     typedef std::tr1::unordered_map<SpaceObjectReference, HostedObjectPtr, SpaceObjectReference::Hasher> HostedObjectMap;
00087     // Save weak references by ID so we can look up objects, but don't force
00088     // them to stay alive.
00089     typedef std::tr1::unordered_map<UUID, HostedObjectWPtr, UUID::Hasher> InternalIDHostedObjectMap;
00090 
00091     OH::Storage* mStorage;
00092     OH::PersistedObjectSet* mPersistentSet;
00093     OH::ObjectQueryProcessor* mQueryProcessor;
00094 
00095     SpaceSessionManagerMap mSessionManagers;
00096 
00097     uint32 mActiveHostedObjects;
00098     HostedObjectMap mHostedObjects;
00099     InternalIDHostedObjectMap mHostedObjectsByID;
00100 
00101     typedef std::tr1::unordered_map<String, ObjectScriptManager*> ScriptManagerMap;
00102     ScriptManagerMap mScriptManagers;
00103 
00104     std::tr1::shared_ptr<Transfer::TransferPool> mTransferPool;
00105     Transfer::TransferMediator *mTransferMediator;
00106 
00107     std::tr1::unordered_map<String,OptionSet*> mSpaceConnectionProtocolOptions;
00109     std::map<std::string, std::string > mSimOptions;
00110     typedef std::tr1::function<void(const SpaceID&, const ObjectReference&, ServerID, const TimedMotionVector3f&, const TimedMotionQuaternion&, const BoundingSphere3f&, const String&, const String&)> SessionConnectedCallback;
00111 
00112 public:
00113     String getSimOptions(const String&);
00114     struct ConnectionInfo {
00115         ServerID server;
00116         TimedMotionVector3f loc;
00117         TimedMotionQuaternion orient;
00118         BoundingSphere3f bnds;
00119         String mesh;
00120         String physics;
00121         String query;
00122     };
00123 
00124     typedef std::tr1::function<void(const SpaceID&, const ObjectReference&, ServerID)> SessionCallback;
00125     // Callback indicating that a connection to the server was made and it is available for sessions
00126     typedef std::tr1::function<void(const SpaceID&, const ObjectReference&, ConnectionInfo)> ConnectedCallback;
00127     // Callback indicating that a connection is being migrated to a new server.  This occurs as soon
00128     // as the object host starts the transition and no additional notification is given since, for all
00129     // intents and purposes this is the point at which the transition happens
00130     typedef std::tr1::function<void(const SpaceID&, const ObjectReference&, ServerID)> MigratedCallback;
00131     typedef std::tr1::function<void(const SpaceObjectReference&, SessionManager::ConnectionEvent after)> StreamCreatedCallback;
00132     // Notifies the ObjectHost of object connection that was closed, including a
00133     // reason.
00134     typedef std::tr1::function<void(const SpaceObjectReference&, Disconnect::Code)> DisconnectedCallback;
00135 
00141     ObjectHost(ObjectHostContext* ctx, Network::IOService*ioServ, const String&options);
00143     ~ObjectHost();
00144 
00145     ObjectHostContext* context() const { return mContext; }
00146 
00156     virtual HostedObjectPtr createObject(const UUID &_id, const String& script_type, const String& script_opts, const String& script_contents);
00164     virtual HostedObjectPtr createObject(const String& script_type, const String& script_opts, const String& script_contents);
00165 
00166     virtual const String& defaultScriptType() const = 0;
00167     virtual const String& defaultScriptOptions() const = 0;
00168     virtual const String& defaultScriptContents() const = 0;
00169 
00170     // Space API - Provide info for ObjectHost to communicate with spaces
00171     void addServerIDMap(const SpaceID& space_id, ServerIDMap* sidmap);
00172 
00173     // Get and set the storage backend to use for persistent object storage.
00174     void setStorage(OH::Storage* storage) { mStorage = storage; }
00175     OH::Storage* getStorage() { return mStorage; }
00176 
00177     // Get and set the storage backend to use for the set of persistent objects.
00178     void setPersistentSet(OH::PersistedObjectSet* persistentset) { mPersistentSet = persistentset; }
00179     OH::PersistedObjectSet* getPersistedObjectSet() { return mPersistentSet; }
00180 
00181     // Get and set the storage backend to use for queries.
00182     void setQueryProcessor(OH::ObjectQueryProcessor* proc) { mQueryProcessor = proc; }
00183     OH::ObjectQueryProcessor* getQueryProcessor() { return mQueryProcessor; }
00184 
00185     std::tr1::shared_ptr<Transfer::TransferPool> getTransferPool() { return mTransferPool; }
00186 
00187     // Primary HostedObject API
00188 
00193     bool connect(
00194         HostedObjectPtr ho, // requestor, or can be NULL
00195         const SpaceObjectReference& sporef, const SpaceID& space,
00196         const TimedMotionVector3f& loc,
00197         const TimedMotionQuaternion& orient,
00198         const BoundingSphere3f& bnds,
00199         const String& mesh,
00200         const String& physics,
00201         const String& query,
00202         const String& zernike,
00203         ConnectedCallback connected_cb,
00204         MigratedCallback migrated_cb, StreamCreatedCallback stream_created_cb,
00205         DisconnectedCallback disconnected_cb
00206     );
00207 
00211     void disconnectObject(const SpaceID& space, const ObjectReference& oref);
00212 
00216     Duration serverTimeOffset(const SpaceID& space) const;
00220     Duration clientTimeOffset(const SpaceID& space) const;
00221 
00226     Time spaceTime(const SpaceID& space, const Time& t) const;
00228     Time currentSpaceTime(const SpaceID& space) const;
00233     Time localTime(const SpaceID& space, const Time& t) const;
00235     Time currentLocalTime() const;
00236 
00238     bool send(SpaceObjectReference& sporefsrc, const SpaceID& space, const ObjectMessagePort src_port, const UUID& dest, const ObjectMessagePort dest_port, const std::string& payload);
00239     bool send(SpaceObjectReference& sporefsrc, const SpaceID& space, const ObjectMessagePort src_port, const UUID& dest, const ObjectMessagePort dest_port, MemoryReference payload);
00240 
00241 
00242 
00243 
00248     void registerHostedObject(const SpaceObjectReference &sporef_uuid, const HostedObjectPtr& obj);
00250     void unregisterHostedObject(const SpaceObjectReference& sporef_uuid, HostedObject *obj);
00251     /* Notify the ObjectHost that . Only called by HostedObject. */
00252     void hostedObjectDestroyed(const UUID& objid);
00253 
00258     HostedObjectPtr getHostedObject(const SpaceObjectReference &id) const;
00260     HostedObjectPtr getHostedObject(const UUID &id) const;
00261 
00263     typedef SST::Stream<SpaceObjectReference> SSTStream;
00264     typedef SSTStream::Ptr SSTStreamPtr;
00265     SSTStreamPtr getSpaceStream(const SpaceID& space, const ObjectReference& internalID);
00266 
00267     // Service Interface
00268     virtual void start();
00269     virtual void stop();
00270 
00271     // OHDP::Service Interface
00272     virtual OHDP::Port* bindOHDPPort(const SpaceID& space, const OHDP::NodeID& node, OHDP::PortID port);
00273     virtual OHDP::Port* bindOHDPPort(const SpaceID& space, const OHDP::NodeID& node);
00274     virtual OHDP::PortID unusedOHDPPort(const SpaceID& space, const OHDP::NodeID& node);
00275     virtual void registerDefaultOHDPHandler(const MessageHandler& cb);
00276 
00277     // The object host will instantiate script managers and pass them user
00278     // specified flags.  These can then be reused by calling this method to get
00279     // at them.
00280     ObjectScriptManager* getScriptManager(const String& id);
00281 
00282   private:
00283 
00284     // SpaceNodeSessionListener Interface -- forwards on to real listeners
00285     virtual void onSpaceNodeSession(const OHDP::SpaceNodeID& id, OHDPSST::Stream::Ptr sn_stream) { fireSpaceNodeSession(id, sn_stream); }
00286     virtual void onSpaceNodeSessionEnded(const OHDP::SpaceNodeID& id) { fireSpaceNodeSessionEnded(id); }
00287 
00288     // Session Management Implementation
00289     void handleObjectConnected(const SpaceObjectReference& sporef_internalID, ServerID server);
00290     void handleObjectMigrated(const SpaceObjectReference& sporef_internalID, ServerID from, ServerID to);
00291     void handleObjectMessage(const SpaceObjectReference& sporef_internalID, const SpaceID& space, Sirikata::Protocol::Object::ObjectMessage* msg);
00292     void handleObjectDisconnected(const SpaceObjectReference& sporef_internalID, Disconnect::Code);
00293 
00294     // Wrappers so we can forward events to interested parties. For Connected
00295     // callback, also allows us to convert ConnectionInfo.
00296     void wrappedConnectedCallback(HostedObjectWPtr ho_weak, const SpaceID& space, const ObjectReference& obj, const SessionManager::ConnectionInfo& ci, ConnectedCallback cb);
00297     void wrappedStreamCreatedCallback(HostedObjectWPtr ho_weak, const SpaceObjectReference& sporef, SessionManager::ConnectionEvent after, StreamCreatedCallback cb);
00298     void wrappedDisconnectedCallback(HostedObjectWPtr ho_weak, const SpaceObjectReference& sporef, Disconnect::Code cause, DisconnectedCallback);
00299 
00300 
00301     // Commands
00302     void commandListObjects(const Command::Command& cmd, Command::Commander* cmdr, Command::CommandID cmdid);
00303     void commandCreateObject(const Command::Command& cmd, Command::Commander* cmdr, Command::CommandID cmdid);
00304     void commandDestroyObject(const Command::Command& cmd, Command::Commander* cmdr, Command::CommandID cmdid);
00305     void commandObjectPresences(const Command::Command& cmd, Command::Commander* cmdr, Command::CommandID cmdid);
00306     // Helper that gets the object a command is operating on. Returns errors for
00307     // you and a NULL pointer on failure.
00308     HostedObjectPtr getCommandObject(const Command::Command& cmd, Command::Commander* cmdr, Command::CommandID cmdid);
00309 
00310     // Checks serialization of access to SessionManagers
00311     Sirikata::SerializationCheck mSessionSerialization;
00312 
00313     void handleDefaultOHDPMessageHandler(const OHDP::Endpoint& src, const OHDP::Endpoint& dst, MemoryReference payload);
00314 
00315     OHDP::MessageHandler mDefaultOHDPMessageHandler;
00316 }; // class ObjectHost
00317 
00318 } // namespace Sirikata
00319 
00320 #endif //_SIRIKATA_OBJECT_HOST_HPP