/** * Shift all dates (join dates and edge annotations) of link graphs and link * graph jobs by the number of days given. * @param interval Number of days to be added or subtracted. */ void LinkGraphSchedule::ShiftDates(int interval) { LinkGraph *lg; FOR_ALL_LINK_GRAPHS(lg) lg->ShiftDates(interval); LinkGraphJob *lgj; FOR_ALL_LINK_GRAPH_JOBS(lgj) lgj->ShiftJoinDate(interval); }
bool TypeGraphManager::fullyConnected(vector<XY> agentLocs) { LinkGraph a = LinkGraph(agentLocs, edges); for (size_t i = 0; i < agentLocs.size(); i++) { for (size_t j = 0; j < agentLocs.size(); j++) { if (i == j) continue; list<int> path = a.astar(i, j); if (path.size() == 1) return false; } } return true; }
/** * Load all link graphs. */ static void Load_LGRP() { int index; while ((index = SlIterateArray()) != -1) { if (!LinkGraph::CanAllocateItem()) { /* Impossible as they have been present in previous game. */ NOT_REACHED(); } LinkGraph *lg = new (index) LinkGraph(); SlObject(lg, GetLinkGraphDesc()); lg->Init(_num_nodes); SaveLoad_LinkGraph(*lg); } }
// ****************************************************************************************** // Build the robot links connection graph and then check for links with no geomotry // ****************************************************************************************** void computeConnectionGraph(const robot_model::LinkModel *start_link, LinkGraph &link_graph) { link_graph.clear(); // make sure the edges structure is clear // Recurively build adj list of link connections computeConnectionGraphRec(start_link, link_graph); // Repeatidly check for links with no geometry and remove them, then re-check until no more removals are detected bool update = true; // track if a no geometry link was found while (update) { update = false; // default // Check if each edge has a shape for (LinkGraph::const_iterator edge_it = link_graph.begin() ; edge_it != link_graph.end() ; ++edge_it) { if (edge_it->first->getShapes().empty()) // link in adjList "link_graph" does not have shape, remove! { // Temporary list for connected links std::vector<const robot_model::LinkModel*> temp_list; // Copy link's parent and child links to temp_list for (std::set<const robot_model::LinkModel*>::const_iterator adj_it = edge_it->second.begin(); adj_it != edge_it->second.end(); ++adj_it) { temp_list.push_back(*adj_it); } // Make all preceeding and succeeding links to the no-shape link fully connected // so that they don't collision check with themselves for (std::size_t i = 0 ; i < temp_list.size() ; ++i) { for (std::size_t j = i + 1 ; j < temp_list.size() ; ++j) { // for each LinkModel in temp_list, find its location in the link_graph structure and insert the rest // of the links into its unique set. // if the LinkModel is not already in the set, update is set to true so that we keep searching if (link_graph[temp_list[i]].insert(temp_list[j]).second) update = true; if (link_graph[temp_list[j]].insert(temp_list[i]).second) update = true; } } } } } //ROS_INFO("Generated connection graph with %d links", int(link_graph.size())); }
// ****************************************************************************************** // Disable collision checking for adjacent links, or adjacent with no geometry links between them // ****************************************************************************************** unsigned int disableAdjacentLinks(planning_scene::PlanningScene &scene, LinkGraph &link_graph, LinkPairMap &link_pairs) { int num_disabled = 0; for (LinkGraph::const_iterator link_graph_it = link_graph.begin() ; link_graph_it != link_graph.end() ; ++link_graph_it) { // disable all connected links to current link by looping through them for (std::set<const robot_model::LinkModel*>::const_iterator adj_it = link_graph_it->second.begin(); adj_it != link_graph_it->second.end(); ++adj_it) { //ROS_INFO("Disabled %s to %s", link_graph_it->first->getName().c_str(), (*adj_it)->getName().c_str() ); // Check if either of the links have no geometry. If so, do not add (are we sure?) if ( !link_graph_it->first->getShapes().empty() && !(*adj_it)->getShapes().empty() ) // both links have geometry { num_disabled += setLinkPair( link_graph_it->first->getName(), (*adj_it)->getName(), ADJACENT, link_pairs ); // disable link checking in the collision matrix scene.getAllowedCollisionMatrixNonConst().setEntry( link_graph_it->first->getName(), (*adj_it)->getName(), true); } } } //ROS_INFO("Disabled %d adjancent link pairs from collision checking", num_disabled); return num_disabled; }
/** * Spawn the threads for running link graph calculations. * Has to be done after loading as the cargo classes might have changed. */ void AfterLoadLinkGraphs() { if (IsSavegameVersionBefore(191)) { LinkGraph *lg; FOR_ALL_LINK_GRAPHS(lg) { for (NodeID node_id = 0; node_id < lg->Size(); ++node_id) { (*lg)[node_id].UpdateLocation(Station::Get((*lg)[node_id].Station())->xy); } } LinkGraphJob *lgj; FOR_ALL_LINK_GRAPH_JOBS(lgj) { lg = &(const_cast<LinkGraph &>(lgj->Graph())); for (NodeID node_id = 0; node_id < lg->Size(); ++node_id) { (*lg)[node_id].UpdateLocation(Station::Get((*lg)[node_id].Station())->xy); } } }
/** * Start the next job in the schedule. */ void LinkGraphSchedule::SpawnNext() { if (this->schedule.empty()) return; LinkGraph *next = this->schedule.front(); LinkGraph *first = next; while (next->Size() < 2) { this->schedule.splice(this->schedule.end(), this->schedule, this->schedule.begin()); next = this->schedule.front(); if (next == first) return; } assert(next == LinkGraph::Get(next->index)); this->schedule.pop_front(); if (LinkGraphJob::CanAllocateItem()) { LinkGraphJob *job = new LinkGraphJob(*next); job->SpawnThread(); this->running.push_back(job); } else { NOT_REACHED(); } }
/** * Runs various procedures that have to be done yearly */ static void OnNewYear() { CompaniesYearlyLoop(); VehiclesYearlyLoop(); TownsYearlyLoop(); InvalidateWindowClassesData(WC_BUILD_STATION); #ifdef ENABLE_NETWORK if (_network_server) NetworkServerYearlyLoop(); #endif /* ENABLE_NETWORK */ if (_cur_year == _settings_client.gui.semaphore_build_before) ResetSignalVariant(); /* check if we reached end of the game */ if (_cur_year == ORIGINAL_END_YEAR) { ShowEndGameChart(); /* check if we reached the maximum year, decrement dates by a year */ } else if (_cur_year == MAX_YEAR + 1) { Vehicle *v; int days_this_year; _cur_year--; days_this_year = IsLeapYear(_cur_year) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR; _date -= days_this_year; FOR_ALL_VEHICLES(v) v->date_of_last_service -= days_this_year; LinkGraph *lg; FOR_ALL_LINK_GRAPHS(lg) lg->ShiftDates(-days_this_year); #ifdef ENABLE_NETWORK /* Because the _date wraps here, and text-messages expire by game-days, we have to clean out * all of them if the date is set back, else those messages will hang for ever */ NetworkInitChatMessage(); #endif /* ENABLE_NETWORK */ } if (_settings_client.gui.auto_euro) CheckSwitchToEuro(); }
/** * Save/load a link graph. * @param comp Link graph to be saved or loaded. */ void SaveLoad_LinkGraph(LinkGraph &lg) { uint size = lg.Size(); for (NodeID from = 0; from < size; ++from) { Node *node = &lg.nodes[from]; SlObject(node, _node_desc); if (IsSavegameVersionBefore(191)) { /* We used to save the full matrix ... */ for (NodeID to = 0; to < size; ++to) { SlObject(&lg.edges[from][to], _edge_desc); } } else { /* ... but as that wasted a lot of space we save a sparse matrix now. */ for (NodeID to = from; to != INVALID_NODE; to = lg.edges[from][to].next_edge) { SlObject(&lg.edges[from][to], _edge_desc); } } } }
/** * Clean up a station by clearing vehicle orders, invalidating windows and * removing link stats. * Aircraft-Hangar orders need special treatment here, as the hangars are * actually part of a station (tiletype is STATION), but the order type * is OT_GOTO_DEPOT. */ Station::~Station() { if (CleaningPool()) { for (CargoID c = 0; c < NUM_CARGO; c++) { this->goods[c].cargo.OnCleanPool(); } return; } while (!this->loading_vehicles.empty()) { this->loading_vehicles.front()->LeaveStation(); } Aircraft *a; FOR_ALL_AIRCRAFT(a) { if (!a->IsNormalAircraft()) continue; if (a->targetairport == this->index) a->targetairport = INVALID_STATION; } for (CargoID c = 0; c < NUM_CARGO; ++c) { LinkGraph *lg = LinkGraph::GetIfValid(this->goods[c].link_graph); if (lg == NULL) continue; for (NodeID node = 0; node < lg->Size(); ++node) { Station *st = Station::Get((*lg)[node].Station()); st->goods[c].flows.erase(this->index); if ((*lg)[node][this->goods[c].node].LastUpdate() != INVALID_DATE) { st->goods[c].flows.DeleteFlows(this->index); RerouteCargo(st, c, this->index, st->index); } } lg->RemoveNode(this->goods[c].node); if (lg->Size() == 0) { LinkGraphSchedule::instance.Unqueue(lg); delete lg; } } Vehicle *v; FOR_ALL_VEHICLES(v) { /* Forget about this station if this station is removed */ if (v->last_station_visited == this->index) { v->last_station_visited = INVALID_STATION; } if (v->last_loading_station == this->index) { v->last_loading_station = INVALID_STATION; } } /* Clear the persistent storage. */ delete this->airport.psa; if (this->owner == OWNER_NONE) { /* Invalidate all in case of oil rigs. */ InvalidateWindowClassesData(WC_STATION_LIST, 0); } else { InvalidateWindowData(WC_STATION_LIST, this->owner, 0); } if (Overlays::Instance()->HasStation(Station::Get(this->index))) { Overlays::Instance()->ToggleStation(Station::Get(this->index)); }; DeleteWindowById(WC_STATION_VIEW, index); /* Now delete all orders that go to the station */ RemoveOrderFromAllVehicles(OT_GOTO_STATION, this->index); /* Remove all news items */ DeleteStationNews(this->index); for (CargoID c = 0; c < NUM_CARGO; c++) { this->goods[c].cargo.Truncate(); } CargoPacket::InvalidateAllFrom(this->index); }