(svn r26893) -Feature: ScriptStationList_Cargo for sorting cargo by from and via
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
#include "../../stdafx.h"
|
||||
#include "script_stationlist.hpp"
|
||||
#include "script_vehicle.hpp"
|
||||
#include "script_cargo.hpp"
|
||||
#include "../../station_base.h"
|
||||
#include "../../vehicle_base.h"
|
||||
|
||||
@@ -35,3 +36,240 @@ ScriptStationList_Vehicle::ScriptStationList_Vehicle(VehicleID vehicle_id)
|
||||
if (o->IsType(OT_GOTO_STATION)) this->AddItem(o->GetDestination());
|
||||
}
|
||||
}
|
||||
|
||||
ScriptStationList_Cargo::ScriptStationList_Cargo(ScriptStationList_Cargo::CargoMode mode,
|
||||
ScriptStationList_Cargo::CargoSelector selector, StationID station_id, CargoID cargo,
|
||||
StationID other_station)
|
||||
{
|
||||
switch(mode) {
|
||||
case CM_WAITING:
|
||||
ScriptStationList_CargoWaiting(selector, station_id, cargo, other_station).SwapList(this);
|
||||
break;
|
||||
case CM_PLANNED:
|
||||
ScriptStationList_CargoPlanned(selector, station_id, cargo, other_station).SwapList(this);
|
||||
break;
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
ScriptStationList_CargoWaiting::ScriptStationList_CargoWaiting(
|
||||
ScriptStationList_Cargo::CargoSelector selector, StationID station_id, CargoID cargo,
|
||||
StationID other_station)
|
||||
{
|
||||
switch(selector) {
|
||||
case CS_BY_FROM:
|
||||
ScriptStationList_CargoWaitingByFrom(station_id, cargo).SwapList(this);
|
||||
break;
|
||||
case CS_VIA_BY_FROM:
|
||||
ScriptStationList_CargoWaitingViaByFrom(station_id, cargo, other_station).SwapList(this);
|
||||
break;
|
||||
case CS_BY_VIA:
|
||||
ScriptStationList_CargoWaitingByVia(station_id, cargo).SwapList(this);
|
||||
break;
|
||||
case CS_FROM_BY_VIA:
|
||||
ScriptStationList_CargoWaitingFromByVia(station_id, cargo, other_station).SwapList(this);
|
||||
break;
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
ScriptStationList_CargoPlanned::ScriptStationList_CargoPlanned(
|
||||
ScriptStationList_Cargo::CargoSelector selector, StationID station_id, CargoID cargo,
|
||||
StationID other_station)
|
||||
{
|
||||
switch(selector) {
|
||||
case CS_BY_FROM:
|
||||
ScriptStationList_CargoPlannedByFrom(station_id, cargo).SwapList(this);
|
||||
break;
|
||||
case CS_VIA_BY_FROM:
|
||||
ScriptStationList_CargoPlannedViaByFrom(station_id, cargo, other_station).SwapList(this);
|
||||
break;
|
||||
case CS_BY_VIA:
|
||||
ScriptStationList_CargoPlannedByVia(station_id, cargo).SwapList(this);
|
||||
break;
|
||||
case CS_FROM_BY_VIA:
|
||||
ScriptStationList_CargoPlannedFromByVia(station_id, cargo, other_station).SwapList(this);
|
||||
break;
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
class CargoCollector {
|
||||
public:
|
||||
CargoCollector(ScriptStationList_Cargo *parent, StationID station_id, CargoID cargo,
|
||||
StationID other);
|
||||
~CargoCollector() ;
|
||||
|
||||
template<ScriptStationList_Cargo::CargoSelector Tselector>
|
||||
void Update(StationID from, StationID via, uint amount);
|
||||
const GoodsEntry *GE() const { return ge; }
|
||||
|
||||
private:
|
||||
void SetValue();
|
||||
|
||||
ScriptStationList_Cargo *list;
|
||||
const GoodsEntry *ge;
|
||||
StationID other_station;
|
||||
|
||||
StationID last_key;
|
||||
uint amount;
|
||||
};
|
||||
|
||||
CargoCollector::CargoCollector(ScriptStationList_Cargo *parent,
|
||||
StationID station_id, CargoID cargo, StationID other) :
|
||||
list(parent), ge(NULL), other_station(other), last_key(INVALID_STATION), amount(0)
|
||||
{
|
||||
if (!ScriptStation::IsValidStation(station_id)) return;
|
||||
if (!ScriptCargo::IsValidCargo(cargo)) return;
|
||||
this->ge = &(Station::Get(station_id)->goods[cargo]);
|
||||
}
|
||||
|
||||
CargoCollector::~CargoCollector()
|
||||
{
|
||||
this->SetValue();
|
||||
}
|
||||
|
||||
void CargoCollector::SetValue()
|
||||
{
|
||||
if (this->amount > 0) {
|
||||
if (this->list->HasItem(this->last_key)) {
|
||||
this->list->SetValue(this->last_key,
|
||||
this->list->GetValue(this->last_key) + this->amount);
|
||||
} else {
|
||||
this->list->AddItem(this->last_key, this->amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<ScriptStationList_Cargo::CargoSelector Tselector>
|
||||
void CargoCollector::Update(StationID from, StationID via, uint amount)
|
||||
{
|
||||
StationID key = INVALID_STATION;
|
||||
switch (Tselector) {
|
||||
case ScriptStationList_Cargo::CS_VIA_BY_FROM:
|
||||
if (via != this->other_station) return;
|
||||
/* fall through */
|
||||
case ScriptStationList_Cargo::CS_BY_FROM:
|
||||
key = from;
|
||||
break;
|
||||
case ScriptStationList_Cargo::CS_FROM_BY_VIA:
|
||||
if (from != this->other_station) return;
|
||||
/* fall through */
|
||||
case ScriptStationList_Cargo::CS_BY_VIA:
|
||||
key = via;
|
||||
break;
|
||||
}
|
||||
if (key == this->last_key) {
|
||||
this->amount += amount;
|
||||
} else {
|
||||
this->SetValue();
|
||||
this->amount = amount;
|
||||
this->last_key = key;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<ScriptStationList_Cargo::CargoSelector Tselector>
|
||||
void ScriptStationList_CargoWaiting::Add(StationID station_id, CargoID cargo, StationID other_station)
|
||||
{
|
||||
CargoCollector collector(this, station_id, cargo, other_station);
|
||||
if (collector.GE() == NULL) return;
|
||||
|
||||
StationCargoList::ConstIterator iter = collector.GE()->cargo.Packets()->begin();
|
||||
StationCargoList::ConstIterator end = collector.GE()->cargo.Packets()->end();
|
||||
for (; iter != end; ++iter) {
|
||||
collector.Update<Tselector>((*iter)->SourceStation(), iter.GetKey(), (*iter)->Count());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<ScriptStationList_Cargo::CargoSelector Tselector>
|
||||
void ScriptStationList_CargoPlanned::Add(StationID station_id, CargoID cargo, StationID other_station)
|
||||
{
|
||||
CargoCollector collector(this, station_id, cargo, other_station);
|
||||
if (collector.GE() == NULL) return;
|
||||
|
||||
FlowStatMap::const_iterator iter = collector.GE()->flows.begin();
|
||||
FlowStatMap::const_iterator end = collector.GE()->flows.end();
|
||||
for (; iter != end; ++iter) {
|
||||
const FlowStat::SharesMap *shares = iter->second.GetShares();
|
||||
uint prev = 0;
|
||||
for (FlowStat::SharesMap::const_iterator flow_iter = shares->begin();
|
||||
flow_iter != shares->end(); ++flow_iter) {
|
||||
collector.Update<Tselector>(iter->first, flow_iter->second, flow_iter->first - prev);
|
||||
prev = flow_iter->first;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ScriptStationList_CargoWaitingByFrom::ScriptStationList_CargoWaitingByFrom(StationID station_id,
|
||||
CargoID cargo)
|
||||
{
|
||||
this->Add<CS_BY_FROM>(station_id, cargo);
|
||||
}
|
||||
|
||||
ScriptStationList_CargoWaitingViaByFrom::ScriptStationList_CargoWaitingViaByFrom(
|
||||
StationID station_id, CargoID cargo, StationID via)
|
||||
{
|
||||
CargoCollector collector(this, station_id, cargo, via);
|
||||
if (collector.GE() == NULL) return;
|
||||
|
||||
std::pair<StationCargoList::ConstIterator, StationCargoList::ConstIterator> range =
|
||||
collector.GE()->cargo.Packets()->equal_range(via);
|
||||
for (StationCargoList::ConstIterator iter = range.first; iter != range.second; ++iter) {
|
||||
collector.Update<CS_VIA_BY_FROM>((*iter)->SourceStation(), iter.GetKey(), (*iter)->Count());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ScriptStationList_CargoWaitingByVia::ScriptStationList_CargoWaitingByVia(StationID station_id,
|
||||
CargoID cargo)
|
||||
{
|
||||
this->Add<CS_BY_VIA>(station_id, cargo);
|
||||
}
|
||||
|
||||
ScriptStationList_CargoWaitingFromByVia::ScriptStationList_CargoWaitingFromByVia(
|
||||
StationID station_id, CargoID cargo, StationID from)
|
||||
{
|
||||
this->Add<CS_FROM_BY_VIA>(station_id, cargo, from);
|
||||
}
|
||||
|
||||
ScriptStationList_CargoPlannedByFrom::ScriptStationList_CargoPlannedByFrom(StationID station_id,
|
||||
CargoID cargo)
|
||||
{
|
||||
this->Add<CS_BY_FROM>(station_id, cargo);
|
||||
}
|
||||
|
||||
ScriptStationList_CargoPlannedViaByFrom::ScriptStationList_CargoPlannedViaByFrom(
|
||||
StationID station_id, CargoID cargo, StationID via)
|
||||
{
|
||||
this->Add<CS_VIA_BY_FROM>(station_id, cargo, via);
|
||||
}
|
||||
|
||||
|
||||
ScriptStationList_CargoPlannedByVia::ScriptStationList_CargoPlannedByVia(StationID station_id,
|
||||
CargoID cargo)
|
||||
{
|
||||
this->Add<CS_BY_VIA>(station_id, cargo);
|
||||
}
|
||||
|
||||
|
||||
ScriptStationList_CargoPlannedFromByVia::ScriptStationList_CargoPlannedFromByVia(
|
||||
StationID station_id, CargoID cargo, StationID from)
|
||||
{
|
||||
CargoCollector collector(this, station_id, cargo, from);
|
||||
if (collector.GE() == NULL) return;
|
||||
|
||||
FlowStatMap::const_iterator iter = collector.GE()->flows.find(from);
|
||||
if (iter == collector.GE()->flows.end()) return;
|
||||
const FlowStat::SharesMap *shares = iter->second.GetShares();
|
||||
uint prev = 0;
|
||||
for (FlowStat::SharesMap::const_iterator flow_iter = shares->begin();
|
||||
flow_iter != shares->end(); ++flow_iter) {
|
||||
collector.Update<CS_FROM_BY_VIA>(iter->first, flow_iter->second, flow_iter->first - prev);
|
||||
prev = flow_iter->first;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user