void LLCacheName::dump() { for (Cache::iterator iter = impl.mCache.begin(), end = impl.mCache.end(); iter != end; iter++) { LLCacheNameEntry* entry = iter->second; if (entry->mIsGroup) { llinfos << iter->first << " = (group) " << entry->mGroupName << " @ " << entry->mCreateTime << llendl; } else { llinfos << iter->first << " = " << buildFullName(entry->mFirstName, entry->mLastName) << " @ " << entry->mCreateTime << llendl; } } }
BOOL LLCacheName::getFullName(const LLUUID& id, std::string& fullname) { std::string first_name, last_name; BOOL res = impl.getName(id, first_name, last_name); fullname = buildFullName(first_name, last_name); return res; }
bool LLCacheName::importFile(std::istream& istr) { LLSD data; if(LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(data, istr)) { return false; } // We'll expire entries more than a week old U32 now = (U32)time(NULL); const U32 SECS_PER_DAY = 60 * 60 * 24; U32 delete_before_time = now - (7 * SECS_PER_DAY); // iterate over the agents S32 count = 0; LLSD agents = data[AGENTS]; LLSD::map_iterator iter = agents.beginMap(); LLSD::map_iterator end = agents.endMap(); for( ; iter != end; ++iter) { LLUUID id((*iter).first); LLSD agent = (*iter).second; U32 ctime = (U32)agent[CTIME].asInteger(); if(ctime < delete_before_time) continue; LLCacheNameEntry* entry = new LLCacheNameEntry(); entry->mIsGroup = false; entry->mCreateTime = ctime; entry->mFirstName = agent[FIRST].asString(); entry->mLastName = agent[LAST].asString(); impl.mCache[id] = entry; std::string fullname = buildFullName(entry->mFirstName, entry->mLastName); impl.mReverseCache[fullname] = id; ++count; } llinfos << "LLCacheName loaded " << count << " agent names" << llendl; count = 0; LLSD groups = data[GROUPS]; iter = groups.beginMap(); end = groups.endMap(); for( ; iter != end; ++iter) { LLUUID id((*iter).first); LLSD group = (*iter).second; U32 ctime = (U32)group[CTIME].asInteger(); if(ctime < delete_before_time) continue; LLCacheNameEntry* entry = new LLCacheNameEntry(); entry->mIsGroup = true; entry->mCreateTime = ctime; entry->mGroupName = group[NAME].asString(); impl.mCache[id] = entry; impl.mReverseCache[entry->mGroupName] = id; ++count; } llinfos << "LLCacheName loaded " << count << " group names" << llendl; return true; }
// This is a little bit kludgy. LLCacheNameCallback is a slot instead of a function pointer. // The reason it is a slot is so that the legacy get() function below can bind an old callback // and pass it as a slot. The reason it isn't a boost::function is so that trackable behavior // doesn't get lost. As a result, we have to bind the slot to a signal to call it, even when // we call it immediately. -Steve // NOTE: Even though passing first and last name is a bit of extra overhead, it eliminates the // potential need for any parsing should any code need to handle first and last name independently. boost::signals2::connection LLCacheName::get(const LLUUID& id, bool is_group, const LLCacheNameCallback& callback) { boost::signals2::connection res; if(id.isNull()) { LLCacheNameSignal signal; signal.connect(callback); signal(id, sCacheName["nobody"], is_group); return res; } LLCacheNameEntry* entry = get_ptr_in_map(impl.mCache, id ); if (entry) { LLCacheNameSignal signal; signal.connect(callback); // id found in map therefore we can call the callback immediately. if (entry->mIsGroup) { signal(id, entry->mGroupName, entry->mIsGroup); } else { std::string fullname = buildFullName(entry->mFirstName, entry->mLastName); signal(id, fullname, entry->mIsGroup); } } else { // id not found in map so we must queue the callback call until available. if (!impl.isRequestPending(id)) { if (is_group) { impl.mAskGroupQueue.insert(id); } else { impl.mAskNameQueue.insert(id); } } res = impl.addPending(id, callback); } return res; }
int ModManDecentral::registerAtServer() { voraus::robot_registration logInTemp; logInTemp.request.name = name.name; if (logIn.call(logInTemp)) { robot.state = voraus::Voraus::idle; name.id = logInTemp.response.id; robot.maxTimeWithoutHeartbeat = ros::Duration(logInTemp.response.timeout); central.task_scheduling = logInTemp.response.task_scheduling; central.localisation = logInTemp.response.localisation; central.path_planing = logInTemp.response.path_planing; central.demo = logInTemp.response.demo; } else { robot.state = voraus::Voraus::unregistered; name.id = 0; robot.maxTimeWithoutHeartbeat = ros::Duration(3600); central.task_scheduling = true; central.localisation = true; central.path_planing = true; central.demo = true; } robot.lastHeartbeatWithMyIdCounter = 0; buildFullName(); if (name.id == 0) { ROS_ERROR("%s server unreachable", name.full.c_str()); } else { std::ostringstream temp; temp.str(""); temp << "Module-Config: "; temp << "task_scheduling = " << ((central.task_scheduling) ? "central" : "decentral"); temp << "; localisation = " << ((central.localisation) ? "central" : "decentral"); temp << "; path_planing = " << ((central.path_planing) ? "central" : "decentral"); temp << "; demo = " << ((central.demo) ? "central" : "decentral"); ROS_INFO("%s Connected to server; TimeOut: %.2fs; %s", name.full.c_str(), robot.maxTimeWithoutHeartbeat.toSec(), temp.str().c_str()); } return 0; }
BOOL LLCacheName::getUUID(const std::string& first, const std::string& last, LLUUID& id) { std::string full_name = buildFullName(first, last); return getUUID(full_name, id); }
void initStateEntities(AssetAPI* assetAPI, const char* stateName, std::map<hash_t, Entity>& entities) { LOGF_IF(!assetAPI, "Missing assetAPI"); // Retrieve .entity in scene subfolder char* subfolder = (char*) alloca(sizeof("entities/") + strlen(stateName) + 100); strcpy(subfolder, "entities/"); strcat(subfolder, stateName); auto files = assetAPI->listAssetContent(".entity", subfolder); std::list<Entity> entitiesBuilt; unsigned buildCount = entitiesBuilt.size(); // build all entities (inefficient but only used ~10 times) while (!files.empty()) { bool earlyExit = false; for (auto f=files.begin(); f!=files.end(); ++f) { auto* fullname = buildFullName(stateName, (*f).c_str(), subfolder); const EntityTemplateRef tmpl = theEntityManager.entityTemplateLibrary.load(fullname); const EntityTemplate* t = theEntityManager.entityTemplateLibrary.get(tmpl, false); if (!t->autoCreate) { files.erase(f); earlyExit = true; break; } // Only build if all dependencies have been built bool dependenciesReady = true; std::for_each(t->dependencies.begin(), t->dependencies.end(), [&entitiesBuilt, &dependenciesReady] (hash_t h) -> void { Entity e = theEntityManager.getEntityByName(h); if (e == 0) { if (std::find(entitiesBuilt.begin(), entitiesBuilt.end(), h) == entitiesBuilt.end()) { LOGV(2, "Missing " << INV_HASH(h)); dependenciesReady = false; } } }); if (dependenciesReady) { hash_t h = Murmur::RuntimeHash(fullname); entities[h] = theEntityManager.CreateEntityFromTemplate(fullname); entitiesBuilt.push_back(h); files.erase(f); break; } } if (!earlyExit) { unsigned newCount = entitiesBuilt.size(); if (newCount <= buildCount) { #if SAC_ENABLE_LOG LOGE("Entities built:"); for (auto e: entitiesBuilt) LOGE("\t* " << INV_HASH(e) << ".entity"); LOGE("Entities not-built"); for (auto e: files) { auto* fullname = buildFullName(stateName, (e).c_str(), subfolder); const EntityTemplateRef tmpl = theEntityManager.entityTemplateLibrary.load(fullname); const EntityTemplate* t = theEntityManager.entityTemplateLibrary.get(tmpl, false); std::stringstream d; d << "dependencies="; for (auto dep: t->dependencies) { d << INV_HASH(dep) << " "; } LOGE("\t* " << stateName << '/' << e << ".entity (" << d.str() << ')'); } #endif LOGF("Entities defined for state " << stateName << " have circular dependencies (" << entitiesBuilt.size() << " built and " << files.size() << " not built)"); } buildCount = newCount; } } }