action::error move::check_validity() const { // Used to deal with multiple return paths. class arrow_texture_setter { public: arrow_texture_setter(const move *target, move::ARROW_TEXTURE current_texture, move::ARROW_TEXTURE setting_texture): target(target), current_texture(current_texture), setting_texture(setting_texture) {} ~arrow_texture_setter() { if(current_texture!=setting_texture) { target->set_arrow_texture(setting_texture); } } void set_texture(move::ARROW_TEXTURE texture) { setting_texture=texture; } private: const move *target; move::ARROW_TEXTURE current_texture, setting_texture; }; arrow_texture_setter setter(this, arrow_texture_, ARROW_TEXTURE_INVALID); if(!(get_source_hex().valid() && get_dest_hex().valid())) { return INVALID_LOCATION; } //Check that the unit still exists in the source hex unit_map::iterator unit_it; unit_it = resources::units->find(get_source_hex()); if(unit_it == resources::units->end()) { return NO_UNIT; } //check if the unit in the source hex has the same unit id as before, //i.e. that it's the same unit if(unit_id_ != unit_it->id() || unit_underlying_id_ != unit_it->underlying_id()) { return UNIT_CHANGED; } //If the path has at least two hexes (it can have less with the attack subclass), ensure destination hex is free if(get_route().steps.size() >= 2 && get_visible_unit(get_dest_hex(),resources::teams->at(viewer_team())) != NULL) { return LOCATION_OCCUPIED; } //check that the path is good if(get_source_hex() != get_dest_hex()) { //skip zero-hex move used by attack subclass // Mark the plain route to see if the move can still be done in one turn, // which is always the case for planned moves pathfind::marked_route checked_route = pathfind::mark_route(get_route().route); if(checked_route.marks[checked_route.steps.back()].turns != 1) { return TOO_FAR; } } // The move is valid, so correct the setter. setter.set_texture(ARROW_TEXTURE_VALID); return OK; }
void do_pgr_dijkstraVia( pgr_edge_t* data_edges, size_t total_edges, int64_t* via_vidsArr, size_t size_via_vidsArr, bool directed, bool strict, bool U_turn_on_edge, Routes_t** return_tuples, size_t* return_count, char** log_msg, char** notice_msg, char** err_msg) { std::ostringstream log; std::ostringstream err; std::ostringstream notice; try { pgassert(total_edges != 0); pgassert(!(*log_msg)); pgassert(!(*notice_msg)); pgassert(!(*err_msg)); pgassert(!(*return_tuples)); pgassert(*return_count == 0); graphType gType = directed? DIRECTED: UNDIRECTED; std::deque< Path >paths; log << "\nInserting vertices into a c++ vector structure"; std::vector< int64_t > via_vertices( via_vidsArr, via_vidsArr + size_via_vidsArr); if (directed) { log << "\nWorking with directed Graph"; pgrouting::DirectedGraph digraph(gType); digraph.insert_edges(data_edges, total_edges); pgr_dijkstraViaVertex( digraph, via_vertices, paths, strict, U_turn_on_edge, log); } else { log << "\nWorking with Undirected Graph"; pgrouting::UndirectedGraph undigraph(gType); undigraph.insert_edges(data_edges, total_edges); pgr_dijkstraViaVertex( undigraph, via_vertices, paths, strict, U_turn_on_edge, log); } size_t count(count_tuples(paths)); if (count == 0) { (*return_tuples) = NULL; (*return_count) = 0; notice << "No paths found"; *log_msg = pgr_msg(notice.str().c_str()); return; } // get the space required to store all the paths (*return_tuples) = pgr_alloc(count, (*return_tuples)); log << "\nConverting a set of paths into the tuples"; (*return_count) = (get_route(return_tuples, paths)); (*return_tuples)[count - 1].edge = -2; *log_msg = log.str().empty()? *log_msg : pgr_msg(log.str().c_str()); *notice_msg = notice.str().empty()? *notice_msg : pgr_msg(notice.str().c_str()); } catch (AssertFailedException &except) { (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << except.what(); *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } catch (std::exception &except) { (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << except.what(); *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } catch(...) { (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << "Caught unknown exception!"; *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } }
int main(int argc, char** argv) { if (argc > 1 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h"))) usage(0); int32 mode = RTM_LIST; if (argc > 1) { if (!strcmp(argv[1], "delete") || !strcmp(argv[1], "del") || !strcmp(argv[1], "-d")) { // delete route if (argc < 3) usage(1); mode = RTM_DELETE; } else if (!strcmp(argv[1], "add") || !strcmp(argv[1], "-a")) { // add route if (argc < 3) usage(1); mode = RTM_ADD; } else if (!strcmp(argv[1], "get")) { // get route for destination if (argc < 3) usage(1); mode = RTM_GET; } } int32 i = 2; int32 interfaceIndex = i; bool familySpecified = false; int32 familyIndex = 0; const char *interface = NULL; BNetworkAddress destination; BNetworkAddress mask; BNetworkAddress gateway; bool defaultRoute = false; route_entry route; memset(&route, 0, sizeof(route_entry)); while (i < argc && i < 5) { // try to parse address family if (i <= 3 && familySpecified == false && get_address_family(argv[i], familyIndex)) { familySpecified = true; if (i == 2) interfaceIndex = -1; } if (!strcmp(argv[i], "default")) { defaultRoute = true; route.flags = RTF_DEFAULT; i++; break; } else if (parse_address(familyIndex, argv[i], destination)) { i++; break; } i++; } if (!defaultRoute && destination.IsEmpty() && mode != RTM_LIST) usage(1); if (i == 3) interfaceIndex = -1; if (interfaceIndex != -1 && interfaceIndex < argc) interface = argv[interfaceIndex]; if (i < argc && parse_address(familyIndex, argv[i], mask)) i++; // parse options and flags while (i < argc) { if (!strcmp(argv[i], "gw") || !strcmp(argv[i], "gateway")) { if (!parse_address(familyIndex, argv[i + 1], gateway)) { fprintf(stderr, "%s: Option 'gw' needs valid address " "parameter\n", kProgramName); exit(1); } i++; } else if (!strcmp(argv[i], "nm") || !strcmp(argv[i], "netmask")) { if (!mask.IsEmpty()) { fprintf(stderr, "%s: Netmask or prefix length is specified " "twice\n", kProgramName); exit(1); } if (!parse_address(familyIndex, argv[i + 1], mask)) { fprintf(stderr, "%s: Option 'netmask' needs valid address " "parameter\n", kProgramName); exit(1); } i++; } else if (!strcmp(argv[i], "plen") || !strcmp(argv[i], "prefixlen") || !strcmp(argv[i], "prefix-length")) { if (!mask.IsEmpty()) { fprintf(stderr, "%s: Netmask or prefix length is specified " "twice\n", kProgramName); exit(1); } if (!prefix_length_to_mask(familyIndex, argv[i + 1], mask)) { fprintf(stderr, "%s: Option 'prefixlen' is invalid for this " "address family\n", kProgramName); exit(1); } i++; } else if (!strcmp(argv[i], "mtu")) { route.mtu = argv[i + 1] ? strtol(argv[i + 1], NULL, 0) : 0; if (route.mtu <= 500) { fprintf(stderr, "%s: Option 'mtu' exptected valid max transfer " "unit size\n", kProgramName); exit(1); } i++; } else if (!strcmp(argv[i], "host")) { route.flags |= RTF_HOST; } else if (!strcmp(argv[i], "local")) { route.flags |= RTF_LOCAL; } else if (!strcmp(argv[i], "reject")) { route.flags |= RTF_REJECT; } else usage(1); i++; } if (!destination.IsEmpty()) route.destination = (sockaddr*)destination; if (!mask.IsEmpty()) route.mask = (sockaddr*)mask; if (!gateway.IsEmpty()) { route.gateway = (sockaddr*)gateway; route.flags |= RTF_GATEWAY; } // we need a socket to talk to the networking stack int socket = ::socket(kFamilies[familyIndex].family, SOCK_DGRAM, 0); if (socket < 0) { fprintf(stderr, "%s: The requested address family is not available.\n", kProgramName); return 1; } switch (mode) { case RTM_ADD: if (interface == NULL) { fprintf(stderr, "%s: You need to specify an interface when " "adding a route.\n", kProgramName); usage(1); } add_route(socket, interface, route); break; case RTM_DELETE: if (interface == NULL) { fprintf(stderr, "%s: You need to specify an interface when " "removing a route.\n", kProgramName); usage(1); } delete_route(socket, interface, route); break; case RTM_LIST: if (familySpecified) list_routes(socket, interface, route); else { for (int32 i = 0; kFamilies[i].family >= 0; i++) { int socket = ::socket(kFamilies[i].family, SOCK_DGRAM, 0); if (socket < 0) continue; list_routes(socket, interface, route); close(socket); } } break; case RTM_GET: get_route(socket, route); break; } close(socket); return 0; }
// CREATE OR REPLACE FUNCTION pgr_dijkstraViaVertices(sql text, vertices anyarray, directed boolean default true, void do_pgr_dijkstraViaVertex( pgr_edge_t *data_edges, size_t total_tuples, int64_t *via_vidsArr, size_t size_via_vidsArr, bool directed, bool strict, bool U_turn_on_edge, Routes_t **return_tuples, size_t *return_count, char ** err_msg){ std::ostringstream log; try { if (total_tuples == 1) { log << "Requiered: more than one tuple\n"; (*return_tuples) = NULL; (*return_count) = 0; *err_msg = strdup(log.str().c_str()); return; } graphType gType = directed? DIRECTED: UNDIRECTED; const auto initial_size = total_tuples; std::deque< Path >paths; log << "Inserting vertices into a c++ vector structure\n"; std::vector< int64_t > via_vertices(via_vidsArr, via_vidsArr + size_via_vidsArr); if (directed) { log << "Working with directed Graph\n"; Pgr_base_graph< DirectedGraph > digraph(gType, initial_size); digraph.graph_insert_data(data_edges, total_tuples); pgr_dijkstraViaVertex(digraph, via_vertices, paths, strict, U_turn_on_edge, log); } else { log << "Working with Undirected Graph\n"; Pgr_base_graph< UndirectedGraph > undigraph(gType, initial_size); undigraph.graph_insert_data(data_edges, total_tuples); pgr_dijkstraViaVertex(undigraph, via_vertices, paths, strict, U_turn_on_edge, log); } size_t count(count_tuples(paths)); if (count == 0) { (*return_tuples) = NULL; (*return_count) = 0; log << "No paths found between Starting and any of the Ending vertices\n"; *err_msg = strdup(log.str().c_str()); return; } // get the space required to store all the paths (*return_tuples) = get_memory(count, (*return_tuples)); log << "Converting a set of paths into the tuples\n"; (*return_count) = (get_route(return_tuples, paths)); (*return_tuples)[count - 1].edge = -2; #ifndef DEBUG *err_msg = strdup("OK"); #else *err_msg = strdup(log.str().c_str()); #endif } catch ( ... ) { log << "Caught unknown expection!\n"; *err_msg = strdup(log.str().c_str()); } }