void HostedObject::updateLocUpdateRequest(const SpaceID& space, const ObjectReference& oref, const TimedMotionVector3f* const loc, const TimedMotionQuaternion* const orient, const BoundingSphere3f* const bounds, const String* const mesh, const String* const phy) { if (stopped()) { HO_LOG(detailed,"Ignoring loc update request after system stop."); return; } { // Scope this lock since sendLocUpdateRequest will acquire // lock itself Mutex::scoped_lock locker(presenceDataMutex); assert(mPresenceData.find(SpaceObjectReference(space, oref)) != mPresenceData.end()); PerPresenceData& pd = *(mPresenceData.find(SpaceObjectReference(space, oref)))->second; // These set values directly, the epoch/seqno values will be // updated when the request is sent if (loc != NULL) { pd.requestLoc->setLocation(*loc); pd.updateFields |= PerPresenceData::LOC_FIELD_LOC; } if (orient != NULL) { pd.requestLoc->setOrientation(*orient); pd.updateFields |= PerPresenceData::LOC_FIELD_ORIENTATION; } if (bounds != NULL) { pd.requestLoc->setBounds(*bounds); pd.updateFields |= PerPresenceData::LOC_FIELD_BOUNDS; } if (mesh != NULL) { pd.requestLoc->setMesh(Transfer::URI(*mesh)); pd.updateFields |= PerPresenceData::LOC_FIELD_MESH; } if (phy != NULL) { pd.requestLoc->setPhysics(*phy); pd.updateFields |= PerPresenceData::LOC_FIELD_PHYSICS; } // Cancel the re-request timer if it was active pd.rerequestTimer->cancel(); } sendLocUpdateRequest(space, oref); }
void HostedObject::handleConnected(const HostedObjectWPtr& weakSelf, ObjectHost* parentOH, const SpaceID& space, const ObjectReference& obj, ObjectHost::ConnectionInfo info) { HostedObjectPtr self(weakSelf.lock()); if ((!self)||self->stopped()) { HO_LOG(detailed,"Ignoring connection success after system stop requested."); parentOH->context()->mainStrand->post( std::tr1::bind(&HostedObject::disconnectDeadPresence, parentOH, space, obj), "HostedObject::disconnectDeadPresence" ); return; } if (info.server == NullServerID) { HO_LOG(warning,"Earlier failure to connect object:" << obj << " to space " << space); return; } BaseDatagramLayerPtr baseDatagramLayer (self->mContext->sstConnMgr()->createDatagramLayer( SpaceObjectReference(space, obj), self->mContext, self->mDelegateODPService ) ); // We have to manually do what mContext->mainStrand->wrap( ... ) should be // doing because it can't handle > 5 arguments. self->mContext->mainStrand->post( std::tr1::bind(&HostedObject::handleConnectedIndirect, weakSelf, parentOH, space, obj, info, baseDatagramLayer), "HostedObject::handleConnectedIndirect" ); }
//returns all the spaceobjrefs associated with all presences of this object. //They are returned in ss. void HostedObject::getSpaceObjRefs(SpaceObjRefVec& ss) const { Mutex::scoped_lock lock( const_cast<Mutex&>(presenceDataMutex) ); PresenceDataMap::const_iterator smapIter; for (smapIter = mPresenceData.begin(); smapIter != mPresenceData.end(); ++smapIter) ss.push_back(SpaceObjectReference(smapIter->second->space,smapIter->second->object)); }
//use this function to request the object host to send a disconnect message //to space for object void ObjectHost::disconnectObject(const SpaceID& space, const ObjectReference& oref) { SpaceSessionManagerMap::iterator iter = mSessionManagers.find(space); if (iter == mSessionManagers.end()) return; iter->second->disconnect(SpaceObjectReference(space,oref)); }
SpaceObjectReference PerPresenceData::id() const { if (! validSpaceObjRef) { std::cout<<"\n\nERROR should have set which space earlier\n\n"; assert(false); } return SpaceObjectReference(space, object); }
//runs through all object references held by this particular object host proxy //manager and returns them in vecotr form. void ProxyManager::getAllObjectReferences(std::vector<SpaceObjectReference>& allObjReferences) const { PROXYMAN_SERIALIZED(); ProxyMap::const_iterator iter; SpaceID space = mID.space(); for (iter = mProxyMap.begin(); iter != mProxyMap.end(); ++iter) { if (iter->second.ptr) allObjReferences.push_back(SpaceObjectReference(space, iter->first)); } }
String HostedObject::requestQuery(const SpaceID& space, const ObjectReference& oref) { Mutex::scoped_lock lock(presenceDataMutex); PresenceDataMap::iterator iter = mPresenceData.find(SpaceObjectReference(space,oref)); if (iter == mPresenceData.end()) { SILOG(cppoh, error, "Error in cppoh, requesting solid angle for presence that doesn't exist in your presence map. Returning max solid angle instead."); static String empty_query(""); return empty_query; } return iter->second->query; }
ProxyObjectPtr HostedObject::getProxy(const SpaceID& space, const ObjectReference& oref) { ProxyManagerPtr proxy_manager = getProxyManager(space,oref); if (proxy_manager == nullManPtr) { SILOG(oh,info, "[HO] In getProxy of HostedObject, have no proxy manager associated with "<<space<<"-"<<oref); return nullPtr; } ProxyObjectPtr proxy_obj = proxy_manager->getProxyObject(SpaceObjectReference(space,oref)); return proxy_obj; }
void HostedObject::disconnectDeadPresence(ObjectHost* parentOH, const SpaceID& space, const ObjectReference& obj) { // We can get connection callbacks from the session manager after we have // already been stopped/destroyed since the script can kill things at any // time. However, we need to make sure we clean these up properly, // disconnecting the presence so a) it doesn't hang around in the space and // b) so that we can clean up the HostedObject locally/don't keep garbage in // the SessionManager. // The cleanup is mostly like we were disconnecting normally. The NULL value // passed to unregisterHostedObject indicates that we no longer have the // pointer because the object using the ID has been stopped. parentOH->disconnectObject(space,obj); parentOH->unregisterHostedObject(SpaceObjectReference(space,obj), NULL); return; }
void ObjectHost::wrappedConnectedCallback(HostedObjectWPtr ho_weak, const SpaceID& space, const ObjectReference& obj, const SessionManager::ConnectionInfo& ci, ConnectedCallback cb) { if (mQueryProcessor != NULL) { HostedObjectPtr ho(ho_weak); if (ho) mQueryProcessor->presenceConnected(ho, SpaceObjectReference(space, obj)); } ConnectionInfo info; info.server = ci.server; info.loc = ci.loc; info.orient = ci.orient; info.bnds = ci.bounds; info.mesh = ci.mesh; info.physics = ci.physics; info.query = ci.query; cb(space, obj, info); }
bool decodeSporef(v8::Handle<v8::Value> toDecode, SpaceObjectReference& sporef, String& errorMessage) { String sporefStr; bool strDecode = decodeString(toDecode,sporefStr,errorMessage); if (! strDecode ) return false; try { sporef = SpaceObjectReference(sporefStr); } catch (std::invalid_argument& ia) { std::cout<<"\n\nDEBUG: This is sporef string: "<<sporefStr<<"\n\n"; errorMessage += " Could not convert string to sporef when decoding sporef."; return false; } return true; }
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) ); } }
PortID DelegateService::unusedODPPort(const SpaceID& space, const ObjectReference& objref) { return unusedODPPort(SpaceObjectReference(space, objref)); }
Port* DelegateService::bindODPPort(const SpaceID& space, const ObjectReference& objref) { return bindODPPort(SpaceObjectReference(space, objref)); }