예제 #1
0
void HostedObject::iHandleDisconnected(
    const HostedObjectWPtr& weakSelf, const SpaceObjectReference& spaceobj,
    Disconnect::Code cc)
{
    HostedObjectPtr self(weakSelf.lock());
    if ((!self)||self->stopped()) {
        HO_LOG(detailed,"Ignoring disconnection callback after system stop requested.");
        return;
    }

    Mutex::scoped_lock lock(self->notifyMutex);
    self->notify(&SessionEventListener::onDisconnected, self, spaceobj);

    // Only invoke disconnectFromSpace if we weren't already aware of the
    // disconnection, i.e. if the disconnect was due to the space and we haven't
    // cleaned up yet.
    if (cc == Disconnect::Forced)
        self->disconnectFromSpace(spaceobj.space(), spaceobj.object());
    if (cc == Disconnect::LoginDenied) {
        assert(self->mPresenceData.find(spaceobj)==self->mPresenceData.end());
        self->mObjectHost->unregisterHostedObject(spaceobj, self.get());
        if (--self->mNumOutstandingConnections==0&&self->mDestroyWhenConnected) {
            self->mDestroyWhenConnected=false;
            self->destroy(true);
        }
    }
}
예제 #2
0
void LocationService::newSession(ObjectSession* session) {
    using std::tr1::placeholders::_1;
    using std::tr1::placeholders::_2;

    SST::Stream<SpaceObjectReference>::Ptr strm = session->getStream();

    SST::Connection<SpaceObjectReference>::Ptr conn = strm->connection().lock();
    assert(conn);

    SpaceObjectReference sourceObject = conn->remoteEndPoint().endPoint;

    // Datagram updates
    conn->registerReadDatagramCallback( OBJECT_PORT_LOCATION,
        std::tr1::bind(
            &LocationService::handleLocationUpdateDatagram, this,
            sourceObject.object().getAsUUID(),
            std::tr1::placeholders::_1,std::tr1::placeholders::_2
        )
    );

    // SST updates
    strm->listenSubstream(OBJECT_PORT_LOCATION,
        std::tr1::bind(
            &LocationService::handleLocationUpdateSubstream, this,
            sourceObject.object().getAsUUID(),
            std::tr1::placeholders::_1,std::tr1::placeholders::_2
        )
    );

}
예제 #3
0
ProxyObjectPtr ObjectHostProxyManager::getProxyObject(const SpaceObjectReference &id) const {
    if (id.space() == mSpaceID) {
        ProxyMap::const_iterator iter = mProxyMap.find(id.object());
        if (iter != mProxyMap.end()) {
            return (*iter).second.obj;
        }
    }
    return ProxyObjectPtr();
}
예제 #4
0
ProxyObjectPtr ProxyManager::getProxyObject(const SpaceObjectReference &id) const {
    PROXYMAN_SERIALIZED();

    assert(id.space() == mID.space());

    ProxyMap::const_iterator iter = mProxyMap.find(id.object());
    if (iter != mProxyMap.end())
        return (*iter).second.ptr;

    return ProxyObjectPtr();
}
예제 #5
0
void ObjectHost::wrappedStreamCreatedCallback(HostedObjectWPtr ho_weak, const SpaceObjectReference& sporef, SessionManager::ConnectionEvent after, StreamCreatedCallback cb) {
    if (mQueryProcessor != NULL) {
        HostedObjectPtr ho(ho_weak);
        if (ho) {
            SSTStreamPtr strm = getSpaceStream(sporef.space(), sporef.object());
            // This had better be OK here since we're just getting the callback
            assert(strm);
            mQueryProcessor->presenceConnectedStream(ho, sporef, strm);
        }
    }
    cb(sporef, after);
}
예제 #6
0
void HostedObject::handleLocationUpdate(const SpaceObjectReference& observer, const LocUpdate& lu) {
    ProxyManagerPtr proxy_manager = this->getProxyManager(observer.space(), observer.object());
    if (!proxy_manager) {
        HO_LOG(warn,"Hosted Object received a message for a presence without a proxy manager.");
        return;
    }

    SpaceObjectReference observed(observer.space(), ObjectReference(lu.object()));
    ProxyObjectPtr proxy_obj = proxy_manager->getProxyObject(observed);
    assert(proxy_obj);

    this->processLocationUpdate( observer, proxy_obj, lu);
}
예제 #7
0
SharedResourcePtr GraphicsResourceManager::getResourceEntity(const SpaceObjectReference &id, GraphicsEntity *graphicsEntity)
{
  WeakResourcePtr curWeakPtr = getResource(id.toString());
  SharedResourcePtr curSharedPtr = curWeakPtr.lock();
  if (curSharedPtr)
    return curSharedPtr;
  else {
    curSharedPtr = GraphicsResource::construct<GraphicsResourceEntity>(id, graphicsEntity);
    mIDResourceMap[id.toString()] = curSharedPtr;
    mEntities.insert(curSharedPtr.get());

    return curSharedPtr;
  }
}
예제 #8
0
void OrphanLocUpdateManager::addOrphanUpdate(const SpaceObjectReference& observed, const Sirikata::Protocol::Loc::LocationUpdate& update) {
    assert( ObjectReference(update.object()) == observed.object() );
    UpdateInfoList& info_list = mUpdates[observed];
    info_list.push_back(
        UpdateInfoPtr(new UpdateInfo(observed, new Sirikata::Protocol::Loc::LocationUpdate(update), mContext->simTime() + mTimeout))
    );
}
예제 #9
0
void ObjectHostProxyManager::destroyViewedObject(const SpaceObjectReference &newObj, QueryTracker*viewer) {
    ProxyMap::iterator iter = mProxyMap.find(newObj.object());
    if (iter != mProxyMap.end()) {
        std::tr1::unordered_multiset<QueryTracker*>::iterator viewiter;
        viewiter = iter->second.viewers.find(viewer);
        iter->second.viewers.erase(viewiter);
        viewiter = iter->second.viewers.find(viewer);
        if (viewiter == iter->second.viewers.end()) {
            iter->second.obj->destroy();
            notify(&ProxyCreationListener::onDestroyProxy,iter->second.obj);
            mProxyMap.erase(iter);
        }
    }
}
예제 #10
0
void HostedObject::handleStreamCreated(const HostedObjectWPtr& weakSelf, const SpaceObjectReference& spaceobj, SessionManager::ConnectionEvent after, PresenceToken token) {
    HO_LOG(detailed,"Handling new SST stream from space server for " << spaceobj);
    HostedObjectPtr self(weakSelf.lock());
    if (!self)
        return;

    Mutex::scoped_lock lock(self->notifyMutex);
    HO_LOG(detailed,"Notifying of connected object " << spaceobj.object() << " to space " << spaceobj.space());
    if (after == SessionManager::Connected) {
        self->notify(&SessionEventListener::onConnected, self, spaceobj, token);
        if (--self->mNumOutstandingConnections==0&&self->mDestroyWhenConnected) {
            self->mDestroyWhenConnected=false;
            self->destroy(true);
        }

    } else if (after == SessionManager::Migrated)
        self->notify(&SessionEventListener::onMigrated, self, spaceobj, token);
}
예제 #11
0
    void invokeOrphanUpdates(ObjectHost* oh, const QuerierIDType& observer, const SpaceObjectReference& proximateID, ListenerType* listener) {
        ObjectUpdateMap::iterator it = mUpdates.find(proximateID);
        if (it == mUpdates.end()) return;

        const UpdateInfoList& info_list = it->second;
        for(UpdateInfoList::const_iterator info_it = info_list.begin(); info_it != info_list.end(); info_it++) {
            if ((*info_it)->value != NULL) {
                LocProtocolLocUpdate llu( *((*info_it)->value), oh, proximateID.space() );
                listener->onOrphanLocUpdate( observer, llu );
            }
            else if ((*info_it)->opd != NULL) {
                PresencePropertiesLocUpdate plu( (*info_it)->object.object(), *((*info_it)->opd) );
                listener->onOrphanLocUpdate( observer, plu );
            }
        }

        // Once we've notified of these we can get rid of them -- if they
        // need the info again they should re-register it with
        // addUpdateFromExisting before cleaning up the object.
        mUpdates.erase(it);
    }
예제 #12
0
ProxyObjectPtr HostedObject::createProxy(const SpaceObjectReference& objref, const SpaceObjectReference& owner_objref, const Transfer::URI& meshuri, TimedMotionVector3f& tmv, TimedMotionQuaternion& tmq, const BoundingSphere3f& bs, const String& phy, const String& query, bool isAggregate, uint64 seqNo)
{
    ProxyManagerPtr proxy_manager = getProxyManager(owner_objref.space(), owner_objref.object());
    Mutex::scoped_lock lock(presenceDataMutex);
    if (!proxy_manager)
    {
        mPresenceData.insert(
            PresenceDataMap::value_type(
                owner_objref,
                new PerPresenceData(getSharedPtr(), owner_objref.space(),owner_objref.object(), BaseDatagramLayerPtr(), query)
            )
        );
        proxy_manager = getProxyManager(owner_objref.space(), owner_objref.object());
    }

    ProxyObjectPtr proxy_obj = proxy_manager->createObject(objref, tmv, tmq, bs, meshuri, phy,
                                                           isAggregate, seqNo);

    return proxy_obj;
}
void ManualObjectQueryProcessor::registerOrUpdateObjectQuery(const SpaceObjectReference& sporef) {
    // Get query info
    ObjectStateMap::iterator it = mObjectState.find(sporef);
    assert(it != mObjectState.end());
    ObjectState& state = it->second;
    HostedObjectPtr ho = state.who.lock();
    assert( ho && !state.query.empty() && state.node != OHDP::NodeID::null() );

    // Get the appropriate handler
    QueryHandlerMap::iterator handler_it = mObjectQueryHandlers.find(OHDP::SpaceNodeID(sporef.space(), state.node));
    assert(handler_it != mObjectQueryHandlers.end());
    ObjectQueryHandlerPtr handler = handler_it->second;

    // And register
    handler->updateQuery(ho, sporef, state.query);
    state.registered = true;
}
예제 #14
0
ProxyObjectPtr ProxyManager::createObject(
    const SpaceObjectReference& id,
    const TimedMotionVector3f& tmv, const TimedMotionQuaternion& tmq, const AggregateBoundingInfo& bs,
    const Transfer::URI& meshuri, const String& phy, bool isAggregate, uint64 seqNo
)
{
    PROXYMAN_SERIALIZED();

    ProxyObjectPtr newObj;
    // Try to reuse an existing object, even if we only have a valid
    // weak pointer to it.
    assert(id.space() == mID.space());
    ProxyMap::iterator iter = mProxyMap.find(id.object());
    if (iter != mProxyMap.end()) {
        // From strong ref
        newObj = iter->second.ptr;
        if (!newObj) {
            // From weak ref
            newObj = iter->second.wptr.lock();

            // And either update the strong ref or clear out the entry
            // if its not even valid anymore.
            if (newObj)
                iter->second.ptr = newObj;
            else
                mProxyMap.erase(iter);
        }
    }

    // If we couldn't get a valid existing copy, create and insert a
    // new one.
    if (!newObj) {
        newObj = ProxyObject::construct(getSharedPtr(), id);
        std::pair<ProxyMap::iterator, bool> result = mProxyMap.insert(
            ProxyMap::value_type(
                newObj->getObjectReference().object(),
                ProxyData(newObj)
            )
        );
        iter = result.first;
    }

    assert(newObj);
    assert(newObj->getObjectReference() == id);
    assert(newObj->getOwner().get() == this);

    // This makes things simpler elsewhere: For new objects, we ensure
    // all the values are set properly so that when the notification
    // happens below, the proxy passed to listeners (for
    // onCreateProxy) will be completely setup, making it valid for
    // use. We don't need this for old ProxyObjects since they were
    // already initialized. The seqNo of 0 only updates something if it wasn't
    // set yet.
    newObj->setLocation(tmv, 0);
    newObj->setOrientation(tmq, 0);
    newObj->setBounds(bs, 0);
    if(meshuri)
        newObj->setMesh(meshuri, 0);
    if(phy.size() > 0)
        newObj->setPhysics(phy, 0);
    newObj->setIsAggregate(isAggregate, 0);

    // Notification of the proxy will have already occured, but
    // updates via, e.g., PositionListener or MeshListener, will go
    // out here, so the potentially invalid initial data automatically
    // filled when the object was created by createObject() shouldn't
    // matter.
    newObj->setLocation(tmv, seqNo);
    newObj->setOrientation(tmq, seqNo);
    newObj->setBounds(bs, seqNo);
    if(meshuri)
        newObj->setMesh(meshuri, seqNo);
    if(phy.size() > 0)
        newObj->setPhysics(phy, seqNo);
    newObj->setIsAggregate(isAggregate, seqNo);

    // Notification has to happen either way
    notify(&ProxyCreationListener::onCreateProxy, newObj);

    return newObj;
}
예제 #15
0
void ObjectHost::handleObjectConnected(const SpaceObjectReference& sporef_objid, ServerID server) {
    ObjectNodeSessionProvider::notify(&ObjectNodeSessionListener::onObjectNodeSession, sporef_objid.space(), sporef_objid.object(), OHDP::NodeID(server));
}
예제 #16
0
void ObjectHost::handleObjectMigrated(const SpaceObjectReference& sporef_objid, ServerID from, ServerID to) {
    ObjectNodeSessionProvider::notify(&ObjectNodeSessionListener::onObjectNodeSession, sporef_objid.space(), sporef_objid.object(), OHDP::NodeID(to));
}
예제 #17
0
 void PerPresenceData::populateSpaceObjRef(const SpaceObjectReference& sporef)
 {
     validSpaceObjRef = true;
     space   = sporef.space();
     object  = sporef.object();
 }
예제 #18
0
void HostedObject::processLocationUpdate(const SpaceObjectReference& sporef, ProxyObjectPtr proxy_obj, const LocUpdate& update) {
    TimedMotionVector3f loc;
    TimedMotionQuaternion orient;
    BoundingSphere3f bounds;
    String mesh;
    String phy;

    TimedMotionVector3f* locptr = NULL;
    uint64 location_seqno = update.location_seqno();
    TimedMotionQuaternion* orientptr = NULL;
    uint64 orient_seqno = update.orientation_seqno();
    BoundingSphere3f* boundsptr = NULL;
    uint64 bounds_seqno = update.bounds_seqno();
    String* meshptr = NULL;
    uint64 mesh_seqno = update.mesh_seqno();
    String* phyptr = NULL;
    uint64 phy_seqno = update.physics_seqno();

    if (update.has_epoch()) {
        // Check if this object is our own presence and update our epoch info if
        // it is.
        Mutex::scoped_lock locker(presenceDataMutex);
        PresenceDataMap::iterator pres_it = mPresenceData.find(sporef);
        if (pres_it != mPresenceData.end()) {
            PerPresenceData* pd = pres_it->second;
            pd->latestReportedEpoch = std::max(pd->latestReportedEpoch, update.epoch());
        }
    }

    if (update.has_location()) {
        loc = update.locationWithLocalTime(this, sporef.space());

        CONTEXT_OHTRACE(objectLoc,
            sporef.object().getAsUUID(),
            //getUUID(),
            update.object().getAsUUID(),
            loc
        );

        locptr = &loc;
    }

    if (update.has_orientation()) {
        orient = update.orientationWithLocalTime(this, sporef.space());
        orientptr = &orient;
    }

    if (update.has_bounds()) {
        bounds = update.bounds();
        boundsptr = &bounds;
    }

    if (update.has_mesh()) {
        mesh = update.mesh();
        meshptr = &mesh;
    }

    if (update.has_physics()) {
        phy = update.physics();
        phyptr = &phy;
    }
    processLocationUpdate(
        sporef.space(), proxy_obj, false,
        locptr, location_seqno, orientptr, orient_seqno,
        boundsptr, bounds_seqno, meshptr, mesh_seqno, phyptr, phy_seqno
    );
}
예제 #19
0
std::string CameraEntity::ogreCameraName(const SpaceObjectReference&ref) {
    return "Camera:"+ref.toString();
}
예제 #20
0
 size_t operator() (const SpaceObjectReference&uuid) const {
     return uuid.hash();
 }
예제 #21
0
void ObjectHost::handleObjectDisconnected(const SpaceObjectReference& sporef_objid, Disconnect::Code) {
    ObjectNodeSessionProvider::notify(&ObjectNodeSessionListener::onObjectNodeSession, sporef_objid.space(), sporef_objid.object(), OHDP::NodeID::null());
}
예제 #22
0
ProxyManagerPtr HostedObject::presence(const SpaceObjectReference& sor)
{
    return getProxyManager(sor.space(), sor.object());
}
예제 #23
0
void ObjectHost::registerHostedObject(const SpaceObjectReference &sporef_uuid, const HostedObjectPtr& obj)
{
    HostedObjectMap::iterator iter = mHostedObjects.find(sporef_uuid);
    if (iter != mHostedObjects.end()) {
        SILOG(oh,error,"Two objects having the same internal name in the mHostedObjects map on connect"<<sporef_uuid.toString());
    }
    mHostedObjects[sporef_uuid]=obj;
}
예제 #24
0
void HostedObject::handleProximityUpdate(const SpaceObjectReference& spaceobj, const Sirikata::Protocol::Prox::ProximityUpdate& update) {
    HostedObject* self = this;
    SpaceID space = spaceobj.space();

    ProxyManagerPtr proxy_manager = self->getProxyManager(spaceobj.space(),spaceobj.object());
    if (!proxy_manager) {
        HO_LOG(warn,"Hosted Object received a message for a presence without a proxy manager.");
        return;
    }

    for(int32 aidx = 0; aidx < update.addition_size(); aidx++) {
        Sirikata::Protocol::Prox::ObjectAddition addition = update.addition(aidx);
        ProxProtocolLocUpdate add(addition);

        SpaceObjectReference proximateID(spaceobj.space(), add.object());

        TimedMotionVector3f loc(add.locationWithLocalTime(this, spaceobj.space()));

        CONTEXT_OHTRACE(prox,
            spaceobj.object().getAsUUID(),
            //getUUID(),
            addition.object(),
            true,
            loc
        );

        TimedMotionQuaternion orient(add.orientationWithLocalTime(this, spaceobj.space()));
        BoundingSphere3f bnds = add.bounds();
        String mesh = add.meshOrDefault();
        String phy = add.physicsOrDefault();
        bool isAggregate =
          (addition.type() == Sirikata::Protocol::Prox::ObjectAddition::Aggregate) ?
            true : false;

        ProxyObjectPtr proxy_obj = proxy_manager->getProxyObject(proximateID);
        if (!proxy_obj) {
            Transfer::URI meshuri;
            if (addition.has_mesh()) meshuri = Transfer::URI(addition.mesh());


            // FIXME use weak_ptr instead of raw
            uint64 proxyAddSeqNo = add.location_seqno();
            assert( add.location_seqno() == add.orientation_seqno() &&
                 add.location_seqno() == add.bounds_seqno() &&
                add.location_seqno() == add.mesh_seqno() &&
                add.location_seqno() == add.physics_seqno());
            proxy_obj = self->createProxy(proximateID, spaceobj, meshuri, loc, orient, bnds, phy, "",
                                          isAggregate, proxyAddSeqNo);
        }
        else {
            // We need to handle optional values properly -- they
            // shouldn't get overwritten.
            String* mesh_ptr = (addition.has_mesh() ? &mesh : NULL);
            String* phy_ptr = (addition.has_physics() ? &phy : NULL);

            self->processLocationUpdate(space, proxy_obj, false,
                &loc, add.location_seqno(),
                &orient, add.orientation_seqno(),
                &bnds, add.bounds_seqno(),
                mesh_ptr, add.mesh_seqno(),
                phy_ptr, add.physics_seqno()
            );
        }

        // Always mark the object as valid (either revalidated, or just
        // valid for the first time)
        if (proxy_obj) proxy_obj->validate();

        //tells the object script that something that was close has come
        //into view
        if(self->mObjectScript)
            self->mObjectScript->notifyProximate(proxy_obj,spaceobj);
    }

    for(int32 ridx = 0; ridx < update.removal_size(); ridx++) {
        Sirikata::Protocol::Prox::ObjectRemoval removal = update.removal(ridx);

        SpaceObjectReference removed_obj_ref(spaceobj.space(),
            ObjectReference(removal.object()));

        bool permanent = (removal.has_type() && (removal.type() == Sirikata::Protocol::Prox::ObjectRemoval::Permanent));

        if (removed_obj_ref == spaceobj) {
            // We want to ignore removal of ourself -- we should
            // always be in our result set, and we don't want to
            // delete our own proxy.

            SILOG(oh,detailed,"Ignoring self removal from proximity results.");
        }
        else {
            ProxyObjectPtr proxy_obj = proxy_manager->getProxyObject(removed_obj_ref);

            if (proxy_obj) {
                // NOTE: We *don't* reset the proxy object
                // here. Resetting it puts the seqnos back at 0,
                // but if we get an addition while still on this
                // space server, we actually want the old ones to
                // stay in place, in case of unordered prox/loc
                // updates. Resetting only happens when we move
                // across space servers (see handleMigrated).
                proxy_manager->destroyObject(proxy_obj);

                if (self->mObjectScript)
                    self->mObjectScript->notifyProximateGone(proxy_obj,spaceobj);

                proxy_obj->invalidate(permanent);
            }
        }

        CONTEXT_OHTRACE(prox,
            spaceobj.object().getAsUUID(),
            //getUUID(),
            removal.object(),
            false,
            TimedMotionVector3f()
        );
    }

}
예제 #25
0
void ObjectHost::unregisterHostedObject(const SpaceObjectReference& sporef_uuid, HostedObject* key_obj)
{
    HostedObjectMap::iterator iter = mHostedObjects.find(sporef_uuid);
    if (iter != mHostedObjects.end()) {
        HostedObjectPtr obj (iter->second);
        // The NULL case covers the possibility that the connection finishes
        // after the HostedObject requests destruction and stops paying
        // attention to connection events
        if (key_obj == NULL || obj.get()==key_obj)
            mHostedObjects.erase(iter);
        else
            SILOG(oh,error,"Two objects having the same internal name in the mHostedObjects map on disconnect "<<sporef_uuid.toString());
    }
}
void ManualObjectQueryProcessor::unregisterObjectQuery(const SpaceObjectReference& sporef) {
    // Get query info
    ObjectStateMap::iterator it = mObjectState.find(sporef);
    assert(it != mObjectState.end());
    ObjectState& state = it->second;
    HostedObjectPtr ho = state.who.lock();
    // unregisterObjectQuery can happen due to disconnection where we
    // want to preserve the query info, so we can't assert an empty
    // query like we assert a non-empty one in registerOrUpdateObjectQuery
    assert( ho && state.node != OHDP::NodeID::null() );

    // Get the appropriate handler
    QueryHandlerMap::iterator handler_it = mObjectQueryHandlers.find(OHDP::SpaceNodeID(sporef.space(), state.node));
    assert(handler_it != mObjectQueryHandlers.end());
    ObjectQueryHandlerPtr handler = handler_it->second;

    // And unregister
    handler->removeQuery(ho, sporef);
    state.registered = false;
}
예제 #27
0
Endpoint::Endpoint(const SpaceObjectReference& space_obj, const PortID& port)
 : mSpace(space_obj.space()),
   mObject(space_obj.object()),
   mPort(port)
{
}
예제 #28
0
 bool operator==(const SpaceObjectReference& rhs) const {
     return space()==rhs.space()&&object()==rhs.object();
 }
예제 #29
0
 bool operator<(const SpaceObjectReference& rhs) const {
     if (space()==rhs.space()) return object()<rhs.object();
     return space()<rhs.space();
 }
예제 #30
0
ODPSST::Stream::Ptr HostedObject::getSpaceStream(const SpaceObjectReference& sor) {
    return mObjectHost->getSpaceStream(sor.space(), sor.object());
}