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) ); } }
Time ObjectHost::currentSpaceTime(const SpaceID& space) { return spaceTime(space, mContext->simTime()); }