mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-09 23:50:25 +00:00
(svn r18776) -Codechange: Use SmallVector to collect refit options.
This commit is contained in:
parent
3ebec78900
commit
d5fa74369a
@ -222,37 +222,43 @@ byte GetBestFittingSubType(Vehicle *v_from, Vehicle *v_for)
|
|||||||
return ret_refit_cyc;
|
return ret_refit_cyc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Option to refit a vehicle chain */
|
||||||
struct RefitOption {
|
struct RefitOption {
|
||||||
CargoID cargo;
|
CargoID cargo; ///< Cargo to refit to
|
||||||
byte subtype;
|
byte subtype; ///< Subcargo to use
|
||||||
uint16 value;
|
uint16 value; ///< GRF-local String to display for the cargo
|
||||||
EngineID engine;
|
EngineID engine; ///< Engine for which to resolve #value
|
||||||
|
|
||||||
|
FORCEINLINE bool operator != (const RefitOption &other) const
|
||||||
|
{
|
||||||
|
return other.cargo != this->cargo || other.subtype != this->subtype;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RefitList {
|
typedef SmallVector<RefitOption, 32> RefitList;
|
||||||
uint num_lines; ///< Number of #items.
|
|
||||||
RefitOption *items;
|
|
||||||
};
|
|
||||||
|
|
||||||
static RefitList *BuildRefitList(const Vehicle *v)
|
/**
|
||||||
|
* Collects all (cargo, subcargo) refit-options of a vehicle chain
|
||||||
|
* @param v front vehicle
|
||||||
|
* @param refit_list container to store result
|
||||||
|
*/
|
||||||
|
static void BuildRefitList(const Vehicle *v, RefitList *refit_list)
|
||||||
{
|
{
|
||||||
uint max_lines = 256;
|
refit_list->Clear();
|
||||||
RefitOption *refit = CallocT<RefitOption>(max_lines);
|
|
||||||
RefitList *list = CallocT<RefitList>(1);
|
|
||||||
Vehicle *u = const_cast<Vehicle *>(v);
|
Vehicle *u = const_cast<Vehicle *>(v);
|
||||||
uint num_lines = 0;
|
|
||||||
uint i;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
const Engine *e = Engine::Get(u->engine_type);
|
const Engine *e = Engine::Get(u->engine_type);
|
||||||
uint32 cmask = e->info.refit_mask;
|
uint32 cmask = e->info.refit_mask;
|
||||||
byte callback_mask = e->info.callback_mask;
|
byte callback_mask = e->info.callback_mask;
|
||||||
|
|
||||||
/* Skip this engine if it has no capacity */
|
/* Skip this engine if it does not carry anything */
|
||||||
if (u->cargo_cap == 0) continue;
|
if (!e->CanCarryCargo()) continue;
|
||||||
|
|
||||||
/* Loop through all cargos in the refit mask */
|
/* Loop through all cargos in the refit mask */
|
||||||
for (CargoID cid = 0; cid < NUM_CARGO && num_lines < max_lines; cid++) {
|
const CargoSpec *cs;
|
||||||
|
FOR_ALL_CARGOSPECS(cs) {
|
||||||
|
CargoID cid = cs->Index();
|
||||||
/* Skip cargo type if it's not listed */
|
/* Skip cargo type if it's not listed */
|
||||||
if (!HasBit(cmask, cid)) continue;
|
if (!HasBit(cmask, cid)) continue;
|
||||||
|
|
||||||
@ -265,32 +271,23 @@ static RefitList *BuildRefitList(const Vehicle *v)
|
|||||||
|
|
||||||
u->cargo_type = cid;
|
u->cargo_type = cid;
|
||||||
|
|
||||||
for (uint refit_cyc = 0; refit_cyc < MAX_REFIT_CYCLE && num_lines < max_lines; refit_cyc++) {
|
for (uint refit_cyc = 0; refit_cyc < MAX_REFIT_CYCLE; refit_cyc++) {
|
||||||
bool duplicate = false;
|
|
||||||
uint16 callback;
|
|
||||||
|
|
||||||
u->cargo_subtype = refit_cyc;
|
u->cargo_subtype = refit_cyc;
|
||||||
|
|
||||||
/* Make sure we don't pick up anything cached. */
|
/* Make sure we don't pick up anything cached. */
|
||||||
u->First()->InvalidateNewGRFCache();
|
u->First()->InvalidateNewGRFCache();
|
||||||
u->InvalidateNewGRFCache();
|
u->InvalidateNewGRFCache();
|
||||||
callback = GetVehicleCallback(CBID_VEHICLE_CARGO_SUFFIX, 0, 0, u->engine_type, u);
|
uint16 callback = GetVehicleCallback(CBID_VEHICLE_CARGO_SUFFIX, 0, 0, u->engine_type, u);
|
||||||
|
|
||||||
if (callback == 0xFF) callback = CALLBACK_FAILED;
|
if (callback == 0xFF) callback = CALLBACK_FAILED;
|
||||||
if (refit_cyc != 0 && callback == CALLBACK_FAILED) break;
|
if (refit_cyc != 0 && callback == CALLBACK_FAILED) break;
|
||||||
|
|
||||||
/* Check if this cargo and subtype combination are listed */
|
RefitOption option;
|
||||||
for (i = 0; i < num_lines && !duplicate; i++) {
|
option.cargo = cid;
|
||||||
if (refit[i].cargo == cid && refit[i].value == callback) duplicate = true;
|
option.subtype = refit_cyc;
|
||||||
}
|
option.value = callback;
|
||||||
|
option.engine = u->engine_type;
|
||||||
if (duplicate) continue;
|
refit_list->Include(option);
|
||||||
|
|
||||||
refit[num_lines].cargo = cid;
|
|
||||||
refit[num_lines].subtype = refit_cyc;
|
|
||||||
refit[num_lines].value = callback;
|
|
||||||
refit[num_lines].engine = u->engine_type;
|
|
||||||
num_lines++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset the vehicle's cargo type */
|
/* Reset the vehicle's cargo type */
|
||||||
@ -302,27 +299,15 @@ static RefitList *BuildRefitList(const Vehicle *v)
|
|||||||
u->InvalidateNewGRFCache();
|
u->InvalidateNewGRFCache();
|
||||||
} else {
|
} else {
|
||||||
/* No cargo suffix callback -- use no subtype */
|
/* No cargo suffix callback -- use no subtype */
|
||||||
bool duplicate = false;
|
RefitOption option;
|
||||||
|
option.cargo = cid;
|
||||||
for (i = 0; i < num_lines && !duplicate; i++) {
|
option.subtype = 0;
|
||||||
if (refit[i].cargo == cid && refit[i].value == CALLBACK_FAILED) duplicate = true;
|
option.value = CALLBACK_FAILED;
|
||||||
}
|
option.engine = INVALID_ENGINE;
|
||||||
|
refit_list->Include(option);
|
||||||
if (!duplicate) {
|
|
||||||
refit[num_lines].cargo = cid;
|
|
||||||
refit[num_lines].subtype = 0;
|
|
||||||
refit[num_lines].value = CALLBACK_FAILED;
|
|
||||||
refit[num_lines].engine = INVALID_ENGINE;
|
|
||||||
num_lines++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} while ((v->type == VEH_TRAIN || v->type == VEH_ROAD) && (u = u->Next()) != NULL);
|
||||||
} while ((v->type == VEH_TRAIN || v->type == VEH_ROAD) && (u = u->Next()) != NULL && num_lines < max_lines);
|
|
||||||
|
|
||||||
list->num_lines = num_lines;
|
|
||||||
list->items = refit;
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Draw the list of available refit options for a consist and highlight the selected refit option (if any).
|
/** Draw the list of available refit options for a consist and highlight the selected refit option (if any).
|
||||||
@ -333,13 +318,13 @@ static RefitList *BuildRefitList(const Vehicle *v)
|
|||||||
* @param delta Step height in caller window
|
* @param delta Step height in caller window
|
||||||
* @param r Rectangle of the matrix widget.
|
* @param r Rectangle of the matrix widget.
|
||||||
*/
|
*/
|
||||||
static void DrawVehicleRefitWindow(const RefitList *list, int sel, uint pos, uint rows, uint delta, const Rect &r)
|
static void DrawVehicleRefitWindow(const RefitList &list, int sel, uint pos, uint rows, uint delta, const Rect &r)
|
||||||
{
|
{
|
||||||
uint y = r.top + WD_MATRIX_TOP;
|
uint y = r.top + WD_MATRIX_TOP;
|
||||||
/* Draw the list, and find the selected cargo (by its position in list) */
|
/* Draw the list, and find the selected cargo (by its position in list) */
|
||||||
for (uint i = pos; i < pos + rows && i < list->num_lines; i++) {
|
for (uint i = pos; i < pos + rows && i < list.Length(); i++) {
|
||||||
TextColour colour = (sel == (int)i) ? TC_WHITE : TC_BLACK;
|
TextColour colour = (sel == (int)i) ? TC_WHITE : TC_BLACK;
|
||||||
RefitOption *refit = &list->items[i];
|
const RefitOption *refit = &list[i];
|
||||||
|
|
||||||
/* Get the cargo name */
|
/* Get the cargo name */
|
||||||
SetDParam(0, CargoSpec::Get(refit->cargo)->name);
|
SetDParam(0, CargoSpec::Get(refit->cargo)->name);
|
||||||
@ -370,7 +355,7 @@ enum VehicleRefitWidgets {
|
|||||||
struct RefitWindow : public Window {
|
struct RefitWindow : public Window {
|
||||||
int sel; ///< Index in refit options, \c -1 if nothing is selected.
|
int sel; ///< Index in refit options, \c -1 if nothing is selected.
|
||||||
RefitOption *cargo; ///< Refit option selected by \v sel.
|
RefitOption *cargo; ///< Refit option selected by \v sel.
|
||||||
RefitList *list; ///< List of cargo types available for refitting.
|
RefitList list; ///< List of cargo types available for refitting.
|
||||||
uint length; ///< For trains, the number of vehicles.
|
uint length; ///< For trains, the number of vehicles.
|
||||||
VehicleOrderID order; ///< If not #INVALID_VEH_ORDER_ID, selection is part of a refit order (rather than execute directly).
|
VehicleOrderID order; ///< If not #INVALID_VEH_ORDER_ID, selection is part of a refit order (rather than execute directly).
|
||||||
|
|
||||||
@ -389,15 +374,9 @@ struct RefitWindow : public Window {
|
|||||||
|
|
||||||
this->order = order;
|
this->order = order;
|
||||||
this->sel = -1;
|
this->sel = -1;
|
||||||
this->list = BuildRefitList(v);
|
BuildRefitList(v, &this->list);
|
||||||
if (v->type == VEH_TRAIN) this->length = CountVehiclesInChain(v);
|
if (v->type == VEH_TRAIN) this->length = CountVehiclesInChain(v);
|
||||||
this->vscroll.SetCount(this->list->num_lines);
|
this->vscroll.SetCount(this->list.Length());
|
||||||
}
|
|
||||||
|
|
||||||
~RefitWindow()
|
|
||||||
{
|
|
||||||
free(this->list->items);
|
|
||||||
free(this->list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnPaint()
|
virtual void OnPaint()
|
||||||
@ -409,16 +388,14 @@ struct RefitWindow : public Window {
|
|||||||
|
|
||||||
if (length != this->length) {
|
if (length != this->length) {
|
||||||
/* Consist length has changed, so rebuild the refit list */
|
/* Consist length has changed, so rebuild the refit list */
|
||||||
free(this->list->items);
|
BuildRefitList(v, &this->list);
|
||||||
free(this->list);
|
|
||||||
this->list = BuildRefitList(v);
|
|
||||||
this->length = length;
|
this->length = length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->vscroll.SetCount(this->list->num_lines);
|
this->vscroll.SetCount(this->list.Length());
|
||||||
|
|
||||||
this->cargo = (this->sel >= 0 && this->sel < (int)this->list->num_lines) ? &this->list->items[this->sel] : NULL;
|
this->cargo = (this->sel >= 0 && this->sel < (int)this->list.Length()) ? &this->list[this->sel] : NULL;
|
||||||
this->DrawWidgets();
|
this->DrawWidgets();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user