Changeset - r13022:11b36960dd16
[Not reviewed]
master
0 6 0
rubidium - 15 years ago 2009-09-13 17:47:07
rubidium@openttd.org
(svn r17530) -Codechange: use QSortT instead of qsort for sorting EngineIDs
6 files changed with 56 insertions and 62 deletions:
0 comments (0 inline, 0 general)
src/autoreplace_gui.cpp
Show inline comments
 
@@ -55,17 +55,15 @@ enum ReplaceVehicleWindowWidgets {
 
	RVW_WIDGET_TRAIN_FLUFF_LEFT,
 
	RVW_WIDGET_TRAIN_RAILTYPE_DROPDOWN,
 
	RVW_WIDGET_TRAIN_FLUFF_RIGHT,
 
	RVW_WIDGET_TRAIN_WAGONREMOVE_TOGGLE,
 
};
 

	
 
static int CDECL EngineNumberSorter(const void *a, const void *b)
 
static int CDECL EngineNumberSorter(const EngineID *a, const EngineID *b)
 
{
 
	const EngineID va = *(const EngineID*)a;
 
	const EngineID vb = *(const EngineID*)b;
 
	int r = ListPositionOfEngine(va) - ListPositionOfEngine(vb);
 
	int r = ListPositionOfEngine(*a) - ListPositionOfEngine(*b);
 

	
 
	return r;
 
}
 

	
 
/** Rebuild the left autoreplace list if an engine is removed or added
 
 * @param e Engine to check if it is removed or added
src/build_vehicle_gui.cpp
Show inline comments
 
@@ -111,39 +111,37 @@ enum {
 

	
 
static bool _internal_sort_order; // descending/ascending
 
static byte _last_sort_criteria[]    = {0, 0, 0, 0};
 
static bool _last_sort_order[]       = {false, false, false, false};
 
static byte _last_filter_criteria[]  = {0, 0, 0, 0};
 

	
 
static int CDECL EngineNumberSorter(const void *a, const void *b)
 
static int CDECL EngineNumberSorter(const EngineID *a, const EngineID *b)
 
{
 
	const EngineID va = *(const EngineID*)a;
 
	const EngineID vb = *(const EngineID*)b;
 
	int r = ListPositionOfEngine(va) - ListPositionOfEngine(vb);
 
	int r = ListPositionOfEngine(*a) - ListPositionOfEngine(*b);
 

	
 
	return _internal_sort_order ? -r : r;
 
}
 

	
 
static int CDECL EngineIntroDateSorter(const void *a, const void *b)
 
static int CDECL EngineIntroDateSorter(const EngineID *a, const EngineID *b)
 
{
 
	const int va = Engine::Get(*(const EngineID*)a)->intro_date;
 
	const int vb = Engine::Get(*(const EngineID*)b)->intro_date;
 
	const int va = Engine::Get(*a)->intro_date;
 
	const int vb = Engine::Get(*b)->intro_date;
 
	const int r = va - vb;
 

	
 
	/* Use EngineID to sort instead since we want consistent sorting */
 
	if (r == 0) return EngineNumberSorter(a, b);
 
	return _internal_sort_order ? -r : r;
 
}
 

	
 
static int CDECL EngineNameSorter(const void *a, const void *b)
 
static int CDECL EngineNameSorter(const EngineID *a, const EngineID *b)
 
{
 
	static EngineID last_engine[2] = { INVALID_ENGINE, INVALID_ENGINE };
 
	static char     last_name[2][64] = { "\0", "\0" };
 

	
 
	const EngineID va = *(const EngineID*)a;
 
	const EngineID vb = *(const EngineID*)b;
 
	const EngineID va = *a;
 
	const EngineID vb = *b;
 

	
 
	if (va != last_engine[0]) {
 
		last_engine[0] = va;
 
		SetDParam(0, va);
 
		GetString(last_name[0], STR_ENGINE_NAME, lastof(last_name[0]));
 
	}
 
@@ -158,72 +156,72 @@ static int CDECL EngineNameSorter(const 
 

	
 
	/* Use EngineID to sort instead since we want consistent sorting */
 
	if (r == 0) return EngineNumberSorter(a, b);
 
	return _internal_sort_order ? -r : r;
 
}
 

	
 
static int CDECL EngineReliabilitySorter(const void *a, const void *b)
 
static int CDECL EngineReliabilitySorter(const EngineID *a, const EngineID *b)
 
{
 
	const int va = Engine::Get(*(const EngineID*)a)->reliability;
 
	const int vb = Engine::Get(*(const EngineID*)b)->reliability;
 
	const int va = Engine::Get(*a)->reliability;
 
	const int vb = Engine::Get(*b)->reliability;
 
	const int r = va - vb;
 

	
 
	/* Use EngineID to sort instead since we want consistent sorting */
 
	if (r == 0) return EngineNumberSorter(a, b);
 
	return _internal_sort_order ? -r : r;
 
}
 

	
 
static int CDECL EngineCostSorter(const void *a, const void *b)
 
static int CDECL EngineCostSorter(const EngineID *a, const EngineID *b)
 
{
 
	Money va = Engine::Get(*(const EngineID*)a)->GetCost();
 
	Money vb = Engine::Get(*(const EngineID*)b)->GetCost();
 
	Money va = Engine::Get(*a)->GetCost();
 
	Money vb = Engine::Get(*b)->GetCost();
 
	int r = ClampToI32(va - vb);
 

	
 
	/* Use EngineID to sort instead since we want consistent sorting */
 
	if (r == 0) return EngineNumberSorter(a, b);
 
	return _internal_sort_order ? -r : r;
 
}
 

	
 
static int CDECL EngineSpeedSorter(const void *a, const void *b)
 
static int CDECL EngineSpeedSorter(const EngineID *a, const EngineID *b)
 
{
 
	int va = Engine::Get(*(const EngineID*)a)->GetDisplayMaxSpeed();
 
	int vb = Engine::Get(*(const EngineID*)b)->GetDisplayMaxSpeed();
 
	int va = Engine::Get(*a)->GetDisplayMaxSpeed();
 
	int vb = Engine::Get(*b)->GetDisplayMaxSpeed();
 
	int r = va - vb;
 

	
 
	/* Use EngineID to sort instead since we want consistent sorting */
 
	if (r == 0) return EngineNumberSorter(a, b);
 
	return _internal_sort_order ? -r : r;
 
}
 

	
 
static int CDECL EnginePowerSorter(const void *a, const void *b)
 
static int CDECL EnginePowerSorter(const EngineID *a, const EngineID *b)
 
{
 
	int va = Engine::Get(*(const EngineID*)a)->GetPower();
 
	int vb = Engine::Get(*(const EngineID*)b)->GetPower();
 
	int va = Engine::Get(*a)->GetPower();
 
	int vb = Engine::Get(*b)->GetPower();
 
	int r = va - vb;
 

	
 
	/* Use EngineID to sort instead since we want consistent sorting */
 
	if (r == 0) return EngineNumberSorter(a, b);
 
	return _internal_sort_order ? -r : r;
 
}
 

	
 
static int CDECL EngineRunningCostSorter(const void *a, const void *b)
 
static int CDECL EngineRunningCostSorter(const EngineID *a, const EngineID *b)
 
{
 
	Money va = Engine::Get(*(const EngineID*)a)->GetRunningCost();
 
	Money vb = Engine::Get(*(const EngineID*)b)->GetRunningCost();
 
	Money va = Engine::Get(*a)->GetRunningCost();
 
	Money vb = Engine::Get(*b)->GetRunningCost();
 
	int r = ClampToI32(va - vb);
 

	
 
	/* Use EngineID to sort instead since we want consistent sorting */
 
	if (r == 0) return EngineNumberSorter(a, b);
 
	return _internal_sort_order ? -r : r;
 
}
 

	
 
/* Train sorting functions */
 
static int CDECL TrainEnginePowerVsRunningCostSorter(const void *a, const void *b)
 
static int CDECL TrainEnginePowerVsRunningCostSorter(const EngineID *a, const EngineID *b)
 
{
 
	const Engine *e_a = Engine::Get(*(const EngineID*)a);
 
	const Engine *e_b = Engine::Get(*(const EngineID*)b);
 
	const Engine *e_a = Engine::Get(*a);
 
	const Engine *e_b = Engine::Get(*b);
 

	
 
	/* Here we are using a few tricks to get the right sort.
 
	 * We want power/running cost, but since we usually got higher running cost than power and we store the result in an int,
 
	 * we will actually calculate cunning cost/power (to make it more than 1).
 
	 * Because of this, the return value have to be reversed as well and we return b - a instead of a - b.
 
	 * Another thing is that both power and running costs should be doubled for multiheaded engines.
 
@@ -234,80 +232,78 @@ static int CDECL TrainEnginePowerVsRunni
 

	
 
	/* Use EngineID to sort instead since we want consistent sorting */
 
	if (r == 0) return EngineNumberSorter(a, b);
 
	return _internal_sort_order ? -r : r;
 
}
 

	
 
static int CDECL TrainEngineCapacitySorter(const void *a, const void *b)
 
static int CDECL TrainEngineCapacitySorter(const EngineID *a, const EngineID *b)
 
{
 
	const RailVehicleInfo *rvi_a = RailVehInfo(*(const EngineID*)a);
 
	const RailVehicleInfo *rvi_b = RailVehInfo(*(const EngineID*)b);
 
	const RailVehicleInfo *rvi_a = RailVehInfo(*a);
 
	const RailVehicleInfo *rvi_b = RailVehInfo(*b);
 

	
 
	int va = GetTotalCapacityOfArticulatedParts(*(const EngineID*)a, VEH_TRAIN) * (rvi_a->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1);
 
	int vb = GetTotalCapacityOfArticulatedParts(*(const EngineID*)b, VEH_TRAIN) * (rvi_b->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1);
 
	int va = GetTotalCapacityOfArticulatedParts(*a, VEH_TRAIN) * (rvi_a->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1);
 
	int vb = GetTotalCapacityOfArticulatedParts(*b, VEH_TRAIN) * (rvi_b->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1);
 
	int r = va - vb;
 

	
 
	/* Use EngineID to sort instead since we want consistent sorting */
 
	if (r == 0) return EngineNumberSorter(a, b);
 
	return _internal_sort_order ? -r : r;
 
}
 

	
 
static int CDECL TrainEnginesThenWagonsSorter(const void *a, const void *b)
 
static int CDECL TrainEnginesThenWagonsSorter(const EngineID *a, const EngineID *b)
 
{
 
	EngineID va = *(const EngineID*)a;
 
	EngineID vb = *(const EngineID*)b;
 
	int val_a = (RailVehInfo(va)->railveh_type == RAILVEH_WAGON ? 1 : 0);
 
	int val_b = (RailVehInfo(vb)->railveh_type == RAILVEH_WAGON ? 1 : 0);
 
	int val_a = (RailVehInfo(*a)->railveh_type == RAILVEH_WAGON ? 1 : 0);
 
	int val_b = (RailVehInfo(*b)->railveh_type == RAILVEH_WAGON ? 1 : 0);
 
	int r = val_a - val_b;
 

	
 
	/* Use EngineID to sort instead since we want consistent sorting */
 
	if (r == 0) return EngineNumberSorter(a, b);
 
	return _internal_sort_order ? -r : r;
 
}
 

	
 
/* Road vehicle sorting functions */
 
static int CDECL RoadVehEngineCapacitySorter(const void *a, const void *b)
 
static int CDECL RoadVehEngineCapacitySorter(const EngineID *a, const EngineID *b)
 
{
 
	int va = GetTotalCapacityOfArticulatedParts(*(const EngineID*)a, VEH_ROAD);
 
	int vb = GetTotalCapacityOfArticulatedParts(*(const EngineID*)b, VEH_ROAD);
 
	int va = GetTotalCapacityOfArticulatedParts(*a, VEH_ROAD);
 
	int vb = GetTotalCapacityOfArticulatedParts(*b, VEH_ROAD);
 
	int r = va - vb;
 

	
 
	/* Use EngineID to sort instead since we want consistent sorting */
 
	if (r == 0) return EngineNumberSorter(a, b);
 
	return _internal_sort_order ? -r : r;
 
}
 

	
 
/* Ship vehicle sorting functions */
 
static int CDECL ShipEngineCapacitySorter(const void *a, const void *b)
 
static int CDECL ShipEngineCapacitySorter(const EngineID *a, const EngineID *b)
 
{
 
	const Engine *e_a = Engine::Get(*(const EngineID*)a);
 
	const Engine *e_b = Engine::Get(*(const EngineID*)b);
 
	const Engine *e_a = Engine::Get(*a);
 
	const Engine *e_b = Engine::Get(*b);
 

	
 
	int va = e_a->GetDisplayDefaultCapacity();
 
	int vb = e_b->GetDisplayDefaultCapacity();
 
	int r = va - vb;
 

	
 
	/* Use EngineID to sort instead since we want consistent sorting */
 
	if (r == 0) return EngineNumberSorter(a, b);
 
	return _internal_sort_order ? -r : r;
 
}
 

	
 
/* Aircraft sorting functions */
 
static int CDECL AircraftEngineCargoSorter(const void *a, const void *b)
 
static int CDECL AircraftEngineCargoSorter(const EngineID *a, const EngineID *b)
 
{
 
	const Engine *e_a = Engine::Get(*(const EngineID*)a);
 
	const Engine *e_b = Engine::Get(*(const EngineID*)b);
 
	const Engine *e_a = Engine::Get(*a);
 
	const Engine *e_b = Engine::Get(*b);
 

	
 
	int va = e_a->GetDisplayDefaultCapacity();
 
	int vb = e_b->GetDisplayDefaultCapacity();
 
	int r = va - vb;
 

	
 
	if (r == 0) {
 
		/* The planes has the same passenger capacity. Check mail capacity instead */
 
		va = AircraftVehInfo(*(const EngineID*)a)->mail_capacity;
 
		vb = AircraftVehInfo(*(const EngineID*)b)->mail_capacity;
 
		va = AircraftVehInfo(*a)->mail_capacity;
 
		vb = AircraftVehInfo(*b)->mail_capacity;
 
		r = va - vb;
 

	
 
		if (r == 0) {
 
			/* Use EngineID to sort instead since we want consistent sorting */
 
			return EngineNumberSorter(a, b);
 
		}
src/core/sort_func.hpp
Show inline comments
 
@@ -16,13 +16,12 @@
 
#include "math_func.hpp"
 
#include "mem_func.hpp"
 

	
 
/**
 
 * Type safe qsort()
 
 *
 
 * @todo replace the normal qsort with this one
 
 * @note Use this sort for irregular sorted data.
 
 *
 
 * @param base Pointer to the first element of the array to be sorted.
 
 * @param num Number of elements in the array pointed by base.
 
 * @param comparator Function that compares two elements.
 
 * @param desc Sort descending.
src/engine_gui.cpp
Show inline comments
 
@@ -20,12 +20,13 @@
 
#include "strings_func.h"
 
#include "engine_gui.h"
 
#include "articulated_vehicles.h"
 
#include "vehicle_func.h"
 
#include "company_func.h"
 
#include "rail.h"
 
#include "core/sort_func.hpp"
 

	
 
#include "table/strings.h"
 
#include "table/sprites.h"
 

	
 
/** Return the category of an engine.
 
 * @param engine Engine to examine.
 
@@ -260,23 +261,23 @@ void DrawVehicleEngine(int x, int y, Eng
 
			break;
 

	
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 
/** Sort all items using qsort() and given 'CompareItems' function
 
/** Sort all items using quick sort and given 'CompareItems' function
 
 * @param el list to be sorted
 
 * @param compare function for evaluation of the quicksort
 
 */
 
void EngList_Sort(GUIEngineList *el, EngList_SortTypeFunction compare)
 
{
 
	uint size = el->Length();
 
	/* out-of-bounds access at the next line for size == 0 (even with operator[] at some systems)
 
	 * generally, do not sort if there are less than 2 items */
 
	if (size < 2) return;
 
	qsort(el->Begin(), size, sizeof(*el->Begin()), compare); // MorphOS doesn't know vector::at(int) ...
 
	QSortT(el->Begin(), size, compare);
 
}
 

	
 
/** Sort selected range of items (on indices @ <begin, begin+num_items-1>)
 
 * @param el list to be sorted
 
 * @param compare function for evaluation of the quicksort
 
 * @param begin start of sorting
 
@@ -284,9 +285,9 @@ void EngList_Sort(GUIEngineList *el, Eng
 
 */
 
void EngList_SortPartial(GUIEngineList *el, EngList_SortTypeFunction compare, uint begin, uint num_items)
 
{
 
	if (num_items < 2) return;
 
	assert(begin < el->Length());
 
	assert(begin + num_items <= el->Length());
 
	qsort(el->Get(begin), num_items, sizeof(*el->Begin()), compare);
 
	QSortT(el->Get(begin), num_items, compare);
 
}
 

	
src/engine_gui.h
Show inline comments
 
@@ -13,15 +13,15 @@
 
#define ENGINE_GUI_H
 

	
 
#include "sortlist_type.h"
 

	
 
typedef GUIList<EngineID, CargoID> GUIEngineList;
 

	
 
typedef int CDECL EngList_SortTypeFunction(const void*, const void*); ///< argument type for EngList_Sort()
 
void EngList_Sort(GUIEngineList *el, EngList_SortTypeFunction compare);  ///< qsort of the engine list
 
void EngList_SortPartial(GUIEngineList *el, EngList_SortTypeFunction compare, uint begin, uint num_items); ///< qsort of specified portion of the engine list
 
typedef int CDECL EngList_SortTypeFunction(const EngineID*, const EngineID*); ///< argument type for EngList_Sort()
 
void EngList_Sort(GUIEngineList *el, EngList_SortTypeFunction compare);  ///< sort of the engine list
 
void EngList_SortPartial(GUIEngineList *el, EngList_SortTypeFunction compare, uint begin, uint num_items); ///< sort of specified portion of the engine list
 

	
 
StringID GetEngineCategoryName(EngineID engine);
 
StringID GetEngineInfoString(EngineID engine);
 
void DrawVehicleEngine(int x, int y, EngineID engine, SpriteID pal);
 

	
 
#endif /* ENGINE_GUI_H */
src/sortlist_type.h
Show inline comments
 
@@ -22,13 +22,13 @@
 
/** Flags of the sort list. */
 
enum SortListFlags {
 
	VL_NONE       = 0,      ///< no sort
 
	VL_DESC       = 1 << 0, ///< sort descending or ascending
 
	VL_RESORT     = 1 << 1, ///< instruct the code to resort the list in the next loop
 
	VL_REBUILD    = 1 << 2, ///< rebuild the sort list
 
	VL_FIRST_SORT = 1 << 3, ///< sort with qsort first
 
	VL_FIRST_SORT = 1 << 3, ///< sort with quick sort first
 
	VL_FILTER     = 1 << 4, ///< filter disabled/enabled
 
	VL_END        = 1 << 5,
 
};
 
DECLARE_ENUM_AS_BIT_SET(SortListFlags);
 

	
 
/** Data structure describing how to show the list (what sort direction and criterium). */
 
@@ -243,13 +243,13 @@ public:
 

	
 
		if (this->IsSortable()) MemReverseT(this->data, this->items);
 
	}
 

	
 
	/**
 
	 * Sort the list.
 
	 *  For the first sorting we use qsort since it is
 
	 *  For the first sorting we use quick sort since it is
 
	 *  faster for irregular sorted data. After that we
 
	 *  use gsort.
 
	 *
 
	 * @param compare The function to compare two list items
 
	 * @return true if the list sequence has been altered
 
	 * */
0 comments (0 inline, 0 general)