Changeset - r26100:e30b0b8187b5
[Not reviewed]
master
0 9 0
Michael Lutz - 3 years ago 2021-10-28 22:56:07
michi@icosahedron.de
Codechange: Use lambdas instead of CommandContainer to manage station picker commands.
9 files changed with 110 insertions and 84 deletions:
0 comments (0 inline, 0 general)
src/airport_gui.cpp
Show inline comments
 
@@ -26,7 +26,9 @@
 
#include "hotkeys.h"
 
#include "vehicle_func.h"
 
#include "gui.h"
 
#include "command_func.h"
 
#include "airport_cmd.h"
 
#include "station_cmd.h"
 

	
 
#include "widgets/airport_widget.h"
 

	
 
@@ -61,8 +63,19 @@ static void PlaceAirport(TileIndex tile)
 

	
 
	uint32 p1 = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index)->GetIndex();
 
	p1 |= _selected_airport_layout << 8;
 
	CommandContainer cmdcont = { tile, p1, p2, CMD_BUILD_AIRPORT, STR_ERROR_CAN_T_BUILD_AIRPORT_HERE, CcBuildAirport, "" };
 
	ShowSelectStationIfNeeded(cmdcont, TileArea(tile, _thd.size.x / TILE_SIZE, _thd.size.y / TILE_SIZE));
 

	
 
	auto proc = [=](bool test, StationID to_join) -> bool {
 
		if (test) {
 
			return DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_AIRPORT)), CMD_BUILD_AIRPORT, tile, p1, p2).Succeeded();
 
		} else {
 
			uint32 p2_final = p2;
 
			if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join);
 

	
 
			return DoCommandP(CMD_BUILD_AIRPORT, STR_ERROR_CAN_T_BUILD_AIRPORT_HERE, CcBuildAirport, tile, p1, p2_final);
 
		}
 
	};
 

	
 
	ShowSelectStationIfNeeded(TileArea(tile, _thd.size.x / TILE_SIZE, _thd.size.y / TILE_SIZE), proc);
 
}
 

	
 
/** Airport build toolbar window handler. */
src/command.cpp
Show inline comments
 
@@ -163,20 +163,6 @@ bool IsCommandAllowedWhilePaused(Command
 

	
 

	
 
static int _docommand_recursive = 0;
 

	
 
/**
 
 * Shorthand for calling the long DoCommand with a container.
 
 *
 
 * @param container Container with (almost) all information
 
 * @param flags Flags for the command and how to execute the command
 
 * @see CommandProc
 
 * @return the cost
 
 */
 
CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags)
 
{
 
	return DoCommand(flags, container->cmd, container->tile, container->p1, container->p2, container->text);
 
}
 

	
 
/*!
 
 * This function executes a given command with the parameters from the #CommandProc parameter list.
 
 * Depending on the flags parameter it execute or test a command.
 
@@ -327,18 +313,6 @@ static bool DoCommandP(Commands cmd, Str
 
}
 

	
 
/**
 
 * Shortcut for the long DoCommandP when having a container with the data.
 
 * @param container the container with information.
 
 * @param my_cmd indicator if the command is from a company or server (to display error messages for a user)
 
 * @param network_command execute the command without sending it on the network
 
 * @return true if the command succeeded, else false
 
 */
 
bool DoCommandP(const CommandContainer *container, bool my_cmd, bool network_command)
 
{
 
	return DoCommandP(container->cmd, container->err_msg, container->callback, my_cmd, network_command, container->tile, container->p1, container->p2, container->text);
 
}
 

	
 
/**
 
 * Shortcut for the long DoCommandP when not using a callback or error message.
 
 * @param cmd The command to execute (a CMD_* value)
 
 * @param tile The tile to perform a command on (see #CommandProc)
src/command_func.h
Show inline comments
 
@@ -37,13 +37,11 @@ static const CommandCost CMD_ERROR = Com
 
typedef std::vector<byte> CommandDataBuffer;
 

	
 
CommandCost DoCommand(DoCommandFlag flags, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {});
 
CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags);
 

	
 
bool DoCommandP(Commands cmd, StringID err_message, CommandCallback *callback, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {});
 
bool DoCommandP(Commands cmd, StringID err_message, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {});
 
bool DoCommandP(Commands cmd, CommandCallback *callback, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {});
 
bool DoCommandP(Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text = {});
 
bool DoCommandP(const CommandContainer *container, bool my_cmd = true, bool network_command = false);
 

	
 
bool InjectNetworkCommand(Commands cmd, StringID err_message, CommandCallback *callback, bool my_cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text);
 

	
src/command_type.h
Show inline comments
 
@@ -460,17 +460,4 @@ template <Commands Tcmd> struct CommandT
 
 */
 
typedef void CommandCallback(const CommandCost &result, Commands cmd, TileIndex tile, uint32 p1, uint32 p2, const std::string &text);
 

	
 
/**
 
 * Structure for buffering the build command when selecting a station to join.
 
 */
 
struct CommandContainer {
 
	TileIndex tile;                  ///< tile command being executed on.
 
	uint32 p1;                       ///< parameter p1.
 
	uint32 p2;                       ///< parameter p2.
 
	Commands cmd;                    ///< command being executed.
 
	StringID err_msg;                ///< string ID of error message to use.
 
	CommandCallback *callback;       ///< any callback function executed upon successful completion of the command.
 
	std::string text;                ///< possible text sent for name changes etc.
 
};
 

	
 
#endif /* COMMAND_TYPE_H */
src/dock_gui.cpp
Show inline comments
 
@@ -27,6 +27,7 @@
 
#include "zoom_func.h"
 
#include "tunnelbridge_cmd.h"
 
#include "dock_cmd.h"
 
#include "station_cmd.h"
 

	
 
#include "widgets/dock_widget.h"
 

	
 
@@ -205,16 +206,25 @@ struct BuildDocksToolbarWindow : Window 
 
				break;
 

	
 
			case WID_DT_STATION: { // Build station button
 
				uint32 p2 = (uint32)INVALID_STATION << 16; // no station to join
 

	
 
				/* tile is always the land tile, so need to evaluate _thd.pos */
 
				CommandContainer cmdcont = { tile, _ctrl_pressed, p2, CMD_BUILD_DOCK, STR_ERROR_CAN_T_BUILD_DOCK_HERE, CcBuildDocks, "" };
 

	
 
				/* Determine the watery part of the dock. */
 
				DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile));
 
				TileIndex tile_to = (dir != INVALID_DIAGDIR ? TileAddByDiagDir(tile, ReverseDiagDir(dir)) : tile);
 

	
 
				ShowSelectStationIfNeeded(cmdcont, TileArea(tile, tile_to));
 
				uint32 p1 = _ctrl_pressed;
 
				uint32 p2 = (uint32)INVALID_STATION << 16; // no station to join
 

	
 
				auto proc = [=](bool test, StationID to_join) -> bool {
 
					if (test) {
 
						return DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_DOCK)), CMD_BUILD_DOCK, tile, p1, p2).Succeeded();
 
					} else {
 
						uint32 p2_final = p2;
 
						if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join);
 

	
 
						return DoCommandP(CMD_BUILD_DOCK, STR_ERROR_CAN_T_BUILD_DOCK_HERE, CcBuildDocks, tile, p1, p2_final);
 
					}
 
				};
 

	
 
				ShowSelectStationIfNeeded(TileArea(tile, tile_to), proc);
 
				break;
 
			}
 

	
src/rail_gui.cpp
Show inline comments
 
@@ -36,6 +36,8 @@
 
#include "sortlist_type.h"
 
#include "stringfilter_type.h"
 
#include "string_func.h"
 
#include "station_cmd.h"
 
#include "waypoint_cmd.h"
 

	
 
#include "station_map.h"
 
#include "tunnelbridge_map.h"
 
@@ -198,8 +200,18 @@ static void PlaceRail_Station(TileIndex 
 
		int h = _settings_client.gui.station_platlength;
 
		if (!_railstation.orientation) Swap(w, h);
 

	
 
		CommandContainer cmdcont = { tile, p1, p2, CMD_BUILD_RAIL_STATION, STR_ERROR_CAN_T_BUILD_RAILROAD_STATION, CcStation, "" };
 
		ShowSelectStationIfNeeded(cmdcont, TileArea(tile, w, h));
 
		auto proc = [=](bool test, StationID to_join) -> bool {
 
			if (test) {
 
				return DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_RAIL_STATION)), CMD_BUILD_RAIL_STATION, tile, p1, p2).Succeeded();
 
			} else {
 
				uint32 p2_final = p2;
 
				if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join);
 

	
 
				return DoCommandP(CMD_BUILD_RAIL_STATION, STR_ERROR_CAN_T_BUILD_RAILROAD_STATION, CcStation, tile, p1, p2_final);
 
			}
 
		};
 

	
 
		ShowSelectStationIfNeeded(TileArea(tile, w, h), proc);
 
	}
 
}
 

	
 
@@ -724,8 +736,18 @@ struct BuildRailToolbarWindow : Window {
 
							uint32 p1 = _cur_railtype | (select_method == VPM_X_LIMITED ? AXIS_X : AXIS_Y) << 6 | ta.w << 8 | ta.h << 16 | _ctrl_pressed << 24;
 
							uint32 p2 = STAT_CLASS_WAYP | _cur_waypoint_type << 8 | INVALID_STATION << 16;
 

	
 
							CommandContainer cmdcont = { ta.tile, p1, p2, CMD_BUILD_RAIL_WAYPOINT, STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT, CcPlaySound_CONSTRUCTION_RAIL, "" };
 
							ShowSelectWaypointIfNeeded(cmdcont, ta);
 
							auto proc = [=](bool test, StationID to_join) -> bool {
 
								if (test) {
 
									return DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_RAIL_WAYPOINT)), CMD_BUILD_RAIL_WAYPOINT, ta.tile, p1, p2).Succeeded();
 
								} else {
 
									uint32 p2_final = p2;
 
									if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join);
 

	
 
									return DoCommandP(CMD_BUILD_RAIL_WAYPOINT, STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT, CcPlaySound_CONSTRUCTION_RAIL, ta.tile, p1, p2_final);
 
								}
 
							};
 

	
 
							ShowSelectWaypointIfNeeded(ta, proc);
 
						}
 
					}
 
					break;
 
@@ -883,8 +905,18 @@ static void HandleStationPlacement(TileI
 
	uint32 p1 = _cur_railtype | _railstation.orientation << 6 | numtracks << 8 | platlength << 16 | _ctrl_pressed << 24;
 
	uint32 p2 = _railstation.station_class | _railstation.station_type << 8 | INVALID_STATION << 16;
 

	
 
	CommandContainer cmdcont = { ta.tile, p1, p2, CMD_BUILD_RAIL_STATION, STR_ERROR_CAN_T_BUILD_RAILROAD_STATION, CcStation, "" };
 
	ShowSelectStationIfNeeded(cmdcont, ta);
 
	auto proc = [=](bool test, StationID to_join) -> bool {
 
		if (test) {
 
			return DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_RAIL_STATION)), CMD_BUILD_RAIL_STATION, ta.tile, p1, p2).Succeeded();
 
		} else {
 
			uint32 p2_final = p2;
 
			if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join);
 

	
 
			return DoCommandP(CMD_BUILD_RAIL_STATION, STR_ERROR_CAN_T_BUILD_RAILROAD_STATION, CcStation, ta.tile, p1, p2_final);
 
		}
 
	};
 

	
 
	ShowSelectStationIfNeeded(ta, proc);
 
}
 

	
 
/** Enum referring to the Hotkeys in the build rail station window */
src/road_gui.cpp
Show inline comments
 
@@ -31,6 +31,7 @@
 
#include "strings_func.h"
 
#include "core/geometry_func.hpp"
 
#include "date_func.h"
 
#include "station_cmd.h"
 

	
 
#include "widgets/road_widget.h"
 

	
 
@@ -179,12 +180,14 @@ void CcRoadStop(const CommandCost &resul
 
 * @param p2 bit 0: 0 For bus stops, 1 for truck stops.
 
 *           bit 2: Allow stations directly adjacent to other stations.
 
 *           bit 5..10: The roadtypes.
 
 * @param cmd Command to use.
 
 * @param err_msg Error message to show.
 
 * @see CcRoadStop()
 
 */
 
static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, Commands cmd, StringID err_msg)
 
static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, StringID err_msg)
 
{
 
	TileArea ta(start_tile, end_tile);
 
	uint32 p1 = (uint32)(ta.w | ta.h << 8);
 

	
 
	uint8 ddir = _road_station_picker_orientation;
 
	SB(p2, 16, 16, INVALID_STATION); // no station to join
 

	
 
@@ -194,9 +197,18 @@ static void PlaceRoadStop(TileIndex star
 
	}
 
	p2 |= ddir << 3; // Set the DiagDirecion into p2 bits 3 and 4.
 

	
 
	TileArea ta(start_tile, end_tile);
 
	CommandContainer cmdcont = { ta.tile, (uint32)(ta.w | ta.h << 8), p2, cmd, err_msg, CcRoadStop, "" };
 
	ShowSelectStationIfNeeded(cmdcont, ta);
 
	auto proc = [=](bool test, StationID to_join) -> bool {
 
		if (test) {
 
			return DoCommand(CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_ROAD_STOP)), CMD_BUILD_ROAD_STOP, ta.tile, p1, p2).Succeeded();
 
		} else {
 
			uint32 p2_final = p2;
 
			if (to_join != INVALID_STATION) SB(p2_final, 16, 16, to_join);
 

	
 
			return DoCommandP(CMD_BUILD_ROAD_STOP, err_msg, CcRoadStop, ta.tile, p1, p2_final);
 
		}
 
	};
 

	
 
	ShowSelectStationIfNeeded(ta, proc);
 
}
 

	
 
/**
 
@@ -684,7 +696,7 @@ struct BuildRoadToolbarWindow : Window {
 
							TileArea ta(start_tile, end_tile);
 
							DoCommandP(CMD_REMOVE_ROAD_STOP, this->rti->strings.err_remove_station[ROADSTOP_BUS], CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_BUS);
 
						} else {
 
							PlaceRoadStop(start_tile, end_tile, _cur_roadtype << 5 | (_ctrl_pressed << 2) | ROADSTOP_BUS, CMD_BUILD_ROAD_STOP, this->rti->strings.err_build_station[ROADSTOP_BUS]);
 
							PlaceRoadStop(start_tile, end_tile, _cur_roadtype << 5 | (_ctrl_pressed << 2) | ROADSTOP_BUS, this->rti->strings.err_build_station[ROADSTOP_BUS]);
 
						}
 
					}
 
					break;
 
@@ -696,7 +708,7 @@ struct BuildRoadToolbarWindow : Window {
 
							TileArea ta(start_tile, end_tile);
 
							DoCommandP(CMD_REMOVE_ROAD_STOP, this->rti->strings.err_remove_station[ROADSTOP_TRUCK], CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_TRUCK);
 
						} else {
 
							PlaceRoadStop(start_tile, end_tile, _cur_roadtype << 5 | (_ctrl_pressed << 2) | ROADSTOP_TRUCK, CMD_BUILD_ROAD_STOP, this->rti->strings.err_build_station[ROADSTOP_TRUCK]);
 
							PlaceRoadStop(start_tile, end_tile, _cur_roadtype << 5 | (_ctrl_pressed << 2) | ROADSTOP_TRUCK, this->rti->strings.err_build_station[ROADSTOP_TRUCK]);
 
						}
 
					}
 
					break;
src/station_gui.cpp
Show inline comments
 
@@ -2264,13 +2264,13 @@ static const NWidgetPart _nested_select_
 
 */
 
template <class T>
 
struct SelectStationWindow : Window {
 
	CommandContainer select_station_cmd; ///< Command to build new station
 
	StationPickerCmdProc select_station_proc;
 
	TileArea area; ///< Location of new station
 
	Scrollbar *vscroll;
 

	
 
	SelectStationWindow(WindowDesc *desc, const CommandContainer &cmd, TileArea ta) :
 
	SelectStationWindow(WindowDesc *desc, TileArea ta, StationPickerCmdProc&& proc) :
 
		Window(desc),
 
		select_station_cmd(cmd),
 
		select_station_proc(std::move(proc)),
 
		area(ta)
 
	{
 
		this->CreateNestedTree();
 
@@ -2341,12 +2341,8 @@ struct SelectStationWindow : Window {
 

	
 
		if (distant_join && st_index >= _stations_nearby_list.size()) return;
 

	
 
		/* Insert station to be joined into stored command */
 
		SB(this->select_station_cmd.p2, 16, 16,
 
		   (distant_join ? _stations_nearby_list[st_index] : NEW_STATION));
 

	
 
		/* Execute stored Command */
 
		DoCommandP(&this->select_station_cmd);
 
		this->select_station_proc(false, distant_join ? _stations_nearby_list[st_index] : NEW_STATION);
 

	
 
		/* Close Window; this might cause double frees! */
 
		CloseWindowById(WC_SELECT_STATION, 0);
 
@@ -2412,7 +2408,7 @@ static WindowDesc _select_station_desc(
 
 * @return whether we need to show the station selection window.
 
 */
 
template <class T>
 
static bool StationJoinerNeeded(const CommandContainer &cmd, TileArea ta)
 
static bool StationJoinerNeeded(TileArea ta, const StationPickerCmdProc &proc)
 
{
 
	/* Only show selection if distant join is enabled in the settings */
 
	if (!_settings_game.station.distant_join_stations) return false;
 
@@ -2430,7 +2426,7 @@ static bool StationJoinerNeeded(const Co
 
	if (!_ctrl_pressed) return false;
 

	
 
	/* Now check if we could build there */
 
	if (DoCommand(&cmd, CommandFlagsToDCFlags(GetCommandFlags(cmd.cmd))).Failed()) return false;
 
	if (!proc(true, INVALID_STATION)) return false;
 

	
 
	/* Test for adjacent station or station below selection.
 
	 * If adjacent-stations is disabled and we are building next to a station, do not show the selection window.
 
@@ -2446,32 +2442,32 @@ static bool StationJoinerNeeded(const Co
 
 * @tparam the class to find stations for
 
 */
 
template <class T>
 
void ShowSelectBaseStationIfNeeded(const CommandContainer &cmd, TileArea ta)
 
void ShowSelectBaseStationIfNeeded(TileArea ta, StationPickerCmdProc&& proc)
 
{
 
	if (StationJoinerNeeded<T>(cmd, ta)) {
 
	if (StationJoinerNeeded<T>(ta, proc)) {
 
		if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
 
		new SelectStationWindow<T>(&_select_station_desc, cmd, ta);
 
		new SelectStationWindow<T>(&_select_station_desc, ta, std::move(proc));
 
	} else {
 
		DoCommandP(&cmd);
 
		proc(false, INVALID_STATION);
 
	}
 
}
 

	
 
/**
 
 * Show the station selection window when needed. If not, build the station.
 
 * @param cmd Command to build the station.
 
 * @param ta Area to build the station in
 
 * @param proc Function called to execute the build command.
 
 */
 
void ShowSelectStationIfNeeded(const CommandContainer &cmd, TileArea ta)
 
void ShowSelectStationIfNeeded(TileArea ta, StationPickerCmdProc proc)
 
{
 
	ShowSelectBaseStationIfNeeded<Station>(cmd, ta);
 
	ShowSelectBaseStationIfNeeded<Station>(ta, std::move(proc));
 
}
 

	
 
/**
 
 * Show the waypoint selection window when needed. If not, build the waypoint.
 
 * @param cmd Command to build the waypoint.
 
 * @param ta Area to build the waypoint in
 
 * @param proc Function called to execute the build command.
 
 */
 
void ShowSelectWaypointIfNeeded(const CommandContainer &cmd, TileArea ta)
 
void ShowSelectWaypointIfNeeded(TileArea ta, StationPickerCmdProc proc)
 
{
 
	ShowSelectBaseStationIfNeeded<Waypoint>(cmd, ta);
 
	ShowSelectBaseStationIfNeeded<Waypoint>(ta, std::move(proc));
 
}
src/station_gui.h
Show inline comments
 
@@ -13,6 +13,8 @@
 
#include "command_type.h"
 
#include "tilearea_type.h"
 
#include "window_type.h"
 
#include "station_type.h"
 
#include <functional>
 

	
 

	
 
/** Types of cargo to display for station coverage. */
 
@@ -25,7 +27,9 @@ enum StationCoverageType {
 
int DrawStationCoverageAreaText(int left, int right, int top, StationCoverageType sct, int rad, bool supplies);
 
void CheckRedrawStationCoverage(const Window *w);
 

	
 
void ShowSelectStationIfNeeded(const CommandContainer &cmd, TileArea ta);
 
void ShowSelectWaypointIfNeeded(const CommandContainer &cmd, TileArea ta);
 
using StationPickerCmdProc = std::function<bool(bool test, StationID to_join)>;
 

	
 
void ShowSelectStationIfNeeded(TileArea ta, StationPickerCmdProc proc);
 
void ShowSelectWaypointIfNeeded(TileArea ta, StationPickerCmdProc proc);
 

	
 
#endif /* STATION_GUI_H */
0 comments (0 inline, 0 general)