Beispiel #1
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);
}
Beispiel #2
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);
        }
    }
}
Beispiel #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();
}
Beispiel #4
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;
}
Beispiel #5
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();
}
Beispiel #6
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);
}
    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);
    }
Beispiel #8
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()
        );
    }

}
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;
}
Beispiel #10
0
Endpoint::Endpoint(const SpaceObjectReference& space_obj, const PortID& port)
 : mSpace(space_obj.space()),
   mObject(space_obj.object()),
   mPort(port)
{
}
Beispiel #11
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;
}
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;
}
Beispiel #13
0
 void PerPresenceData::populateSpaceObjRef(const SpaceObjectReference& sporef)
 {
     validSpaceObjRef = true;
     space   = sporef.space();
     object  = sporef.object();
 }
Beispiel #14
0
void ObjectHost::handleObjectConnected(const SpaceObjectReference& sporef_objid, ServerID server) {
    ObjectNodeSessionProvider::notify(&ObjectNodeSessionListener::onObjectNodeSession, sporef_objid.space(), sporef_objid.object(), OHDP::NodeID(server));
}
 bool operator==(const SpaceObjectReference& rhs) const {
     return space()==rhs.space()&&object()==rhs.object();
 }
 bool operator<(const SpaceObjectReference& rhs) const {
     if (space()==rhs.space()) return object()<rhs.object();
     return space()<rhs.space();
 }
Beispiel #17
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));
}
Beispiel #18
0
ProxyManagerPtr HostedObject::presence(const SpaceObjectReference& sor)
{
    return getProxyManager(sor.space(), sor.object());
}
Beispiel #19
0
 /** Initializes the proxy.  This performs initalizations that
  *  call virtual methods that cannot be called during construction.
  *  This should *always* be called immediately after construction.
  */
 void initialize(Sirikata::Graphics::OgreSystem *sys, const SpaceObjectReference& ref) {
   mSpace=ref.space();
   mEntity = sys->getEntity(ref);
 }
Beispiel #20
0
void ObjectHost::handleObjectDisconnected(const SpaceObjectReference& sporef_objid, Disconnect::Code) {
    ObjectNodeSessionProvider::notify(&ObjectNodeSessionListener::onObjectNodeSession, sporef_objid.space(), sporef_objid.object(), OHDP::NodeID::null());
}
Beispiel #21
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
    );
}
Beispiel #22
0
ODPSST::Stream::Ptr HostedObject::getSpaceStream(const SpaceObjectReference& sor) {
    return mObjectHost->getSpaceStream(sor.space(), sor.object());
}
Beispiel #23
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);
}