void AlwaysLocationUpdatePolicy::tryCreateChildStream(SSTStreamPtr parent_stream, std::string* msg, int count) {
    parent_stream->createChildStream(
        std::tr1::bind(&AlwaysLocationUpdatePolicy::locSubstreamCallback, this, _1, _2, parent_stream, msg, count+1),
        (void*)msg->data(), msg->size(),
        OBJECT_PORT_LOCATION, OBJECT_PORT_LOCATION
    );
}
Exemplo n.º 2
0
void HostedObject::sendLocUpdateRequest(const SpaceID& space, const ObjectReference& oref) {
    // Up here to avoid recursive lock
    ProxyObjectPtr self_proxy = getProxy(space, oref);

    Mutex::scoped_lock locker(presenceDataMutex);
    assert(mPresenceData.find(SpaceObjectReference(space, oref)) != mPresenceData.end());
    PerPresenceData& pd = *(mPresenceData.find(SpaceObjectReference(space, oref)))->second;

    if (!self_proxy)
    {
        HO_LOG(warn,"Requesting sendLocUpdateRequest for missing self proxy.  Doing nothing.");
        return;
    }

    assert(pd.updateFields != PerPresenceData::LOC_FIELD_NONE);
    // Generate and send an update to Loc
    Protocol::Loc::Container container;
    Protocol::Loc::ILocationUpdateRequest loc_request = container.mutable_update_request();
    uint64 epoch = pd.requestEpoch++;
    loc_request.set_epoch(epoch);
    if (pd.updateFields & PerPresenceData::LOC_FIELD_LOC) {
        Protocol::ITimedMotionVector requested_loc = loc_request.mutable_location();
        requested_loc.set_t( spaceTime(space, pd.requestLoc->location().updateTime()) );
        requested_loc.set_position(pd.requestLoc->location().position());
        requested_loc.set_velocity(pd.requestLoc->location().velocity());
        // Save value but bump the epoch
        pd.requestLoc->setLocation(pd.requestLoc->location(), epoch);
    }
    if (pd.updateFields & PerPresenceData::LOC_FIELD_ORIENTATION) {
        Protocol::ITimedMotionQuaternion requested_orient = loc_request.mutable_orientation();
        requested_orient.set_t( spaceTime(space, pd.requestLoc->orientation().updateTime()) );
        //Normalize positions, which only make sense as unit quaternions.
        requested_orient.set_position(pd.requestLoc->orientation().position().normal());
        requested_orient.set_velocity(pd.requestLoc->orientation().velocity());
        // Save value but bump the epoch
        pd.requestLoc->setOrientation(pd.requestLoc->orientation(), epoch);
    }
    if (pd.updateFields & PerPresenceData::LOC_FIELD_BOUNDS) {
        loc_request.set_bounds(pd.requestLoc->bounds());
        // Save value but bump the epoch
        pd.requestLoc->setBounds(pd.requestLoc->bounds(), epoch);
    }
    if (pd.updateFields & PerPresenceData::LOC_FIELD_MESH) {
        loc_request.set_mesh(pd.requestLoc->mesh().toString());
        // Save value but bump the epoch
        pd.requestLoc->setMesh(pd.requestLoc->mesh(), epoch);
    }
    if (pd.updateFields & PerPresenceData::LOC_FIELD_PHYSICS) {
        loc_request.set_physics(pd.requestLoc->physics());
        // Save value but bump the epoch
        pd.requestLoc->setPhysics(pd.requestLoc->physics(), epoch);
    }

    std::string payload = serializePBJMessage(container);


    bool send_succeeded = false;
    SSTStreamPtr spaceStream = mObjectHost->getSpaceStream(space, oref);
    if (spaceStream) {
        spaceStream->createChildStream(
            std::tr1::bind(discardChildStream, _1, _2),
            (void*)payload.data(), payload.size(),
            OBJECT_PORT_LOCATION, OBJECT_PORT_LOCATION
        );
        send_succeeded = true;
    }

    if (send_succeeded) {
        pd.updateFields = PerPresenceData::LOC_FIELD_NONE;
    }
    else {
        // Set up retry timer. Just rerun this method, but add no new
        // update fields.
        pd.rerequestTimer->wait(
            Duration::milliseconds((int64)10),
            std::tr1::bind(&HostedObject::sendLocUpdateRequest, this, space, oref)
        );
    }
}