示例#1
0
文件: move.cpp 项目: gaconkzk/wesnoth
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());
    }
}
示例#3
0
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;
}
示例#4
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());
    }
}