Ejemplo n.º 1
0
void LocationService::handleLocationUpdateSubstreamRead(const UUID& source, SSTStreamPtr s, std::stringstream* prevdata, uint8* buffer, int length) {
    prevdata->write((const char*)buffer, length);
    String payload(prevdata->str());
    if (locationUpdate(source, (void*)payload.c_str(), payload.size())) {
        // FIXME we should be getting a callback on stream close instead of
        // relying on this parsing as an indicator
        delete prevdata;
        // Clear out callback so we aren't responsible for any remaining
        // references to s, and close the stream
        s->registerReadCallback(0);
        s->close(false);
    }
}
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
    );
}
Ejemplo n.º 3
0
void LocationService::handleLocationUpdateSubstream(const UUID& source, int err, SSTStreamPtr s) {
    s->registerReadCallback(
        std::tr1::bind(
            &LocationService::handleLocationUpdateSubstreamRead, this,
            source, s, new std::stringstream(),
            std::tr1::placeholders::_1,std::tr1::placeholders::_2
        )
    );
}
void AlwaysLocationUpdatePolicy::locSubstreamCallback(int x, SSTStreamPtr substream, SSTStreamPtr parent_stream, std::string* msg, int count) {
    // If we got it, the data got sent and we can drop the stream
    if (substream) {
        delete msg;
        substream->close(false);
        return;
    }

    // If we didn't get it and we haven't retried too many times, try
    // again. Otherwise, report error and give up.
    if (count < 5) {
        tryCreateChildStream(parent_stream, msg, count);
    }
    else {
        SILOG(always_loc,error,"Failed multiple times to open loc update substream.");
        delete msg;
    }
}
Ejemplo n.º 5
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)
        );
    }
}