# cargoaction.cpp

Go to the documentation of this file.

    00001 /* $Id$ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
    00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
    00008  */
    00009
    00012 #include "stdafx.h"
    00013 #include "economy_base.h"
    00014 #include "cargoaction.h"
    00015 #include "station_base.h"
    00016
    00023 template<class Tsource, class Tdest>
    00024 CargoPacket *CargoMovement<Tsource, Tdest>::Preprocess(CargoPacket *cp)
    00025 {
    00026   if (this->max_move < cp->Count()) {
    00027     cp = cp->Split(this->max_move);
    00028     this->max_move = 0;
    00029   } else {
    00030     this->max_move -= cp->Count();
    00031   }
    00032   return cp;
    00033 }
    00034
    00041 template<class Tsource>
    00042 uint CargoRemoval<Tsource>::Preprocess(CargoPacket *cp)
    00043 {
    00044   if (this->max_move >= cp->Count()) {
    00045     this->max_move -= cp->Count();
    00046     return cp->Count();
    00047   } else {
    00048     uint ret = this->max_move;
    00049     this->max_move = 0;
    00050     return ret;
    00051   }
    00052 }
    00053
    00060 template<class Tsource>
    00061 bool CargoRemoval<Tsource>::Postprocess(CargoPacket *cp, uint remove)
    00062 {
    00063   if (remove == cp->Count()) {
    00064     delete cp;
    00065     return true;
    00066   } else {
    00067     cp->Reduce(remove);
    00068     return false;
    00069   }
    00070 }
    00071
    00078 template<>
    00079 bool CargoRemoval<StationCargoList>::operator()(CargoPacket *cp)
    00080 {
    00081   uint remove = this->Preprocess(cp);
    00082   this->source->RemoveFromCache(cp, remove);
    00083   return this->Postprocess(cp, remove);
    00084 }
    00085
    00092 template<>
    00093 bool CargoRemoval<VehicleCargoList>::operator()(CargoPacket *cp)
    00094 {
    00095   uint remove = this->Preprocess(cp);
    00096   this->source->RemoveFromMeta(cp, VehicleCargoList::MTA_KEEP, remove);
    00097   return this->Postprocess(cp, remove);
    00098 }
    00099
    00106 bool CargoDelivery::operator()(CargoPacket *cp)
    00107 {
    00108   uint remove = this->Preprocess(cp);
    00109   this->source->RemoveFromMeta(cp, VehicleCargoList::MTA_DELIVER, remove);
    00110   this->payment->PayFinalDelivery(cp, remove);
    00111   return this->Postprocess(cp, remove);
    00112 }
    00113
    00119 bool CargoLoad::operator()(CargoPacket *cp)
    00120 {
    00121   CargoPacket *cp_new = this->Preprocess(cp);
    00122   if (cp_new == NULL) return false;
    00123   cp_new->SetLoadPlace(this->load_place);
    00124   this->source->RemoveFromCache(cp_new, cp_new->Count());
    00125   this->destination->Append(cp_new, VehicleCargoList::MTA_KEEP);
    00126   return cp_new == cp;
    00127 }
    00128
    00134 bool CargoReservation::operator()(CargoPacket *cp)
    00135 {
    00136   CargoPacket *cp_new = this->Preprocess(cp);
    00137   if (cp_new == NULL) return false;
    00138   cp_new->SetLoadPlace(this->load_place);
    00139   this->source->reserved_count += cp_new->Count();
    00140   this->source->RemoveFromCache(cp_new, cp_new->Count());
    00141   this->destination->Append(cp_new, VehicleCargoList::MTA_LOAD);
    00142   return cp_new == cp;
    00143 }
    00144
    00150 bool CargoReturn::operator()(CargoPacket *cp)
    00151 {
    00152   CargoPacket *cp_new = this->Preprocess(cp);
    00153   if (cp_new == NULL) cp_new = cp;
    00154   assert(cp_new->Count() <= this->destination->reserved_count);
    00155   this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_LOAD, cp_new->Count());
    00156   this->destination->reserved_count -= cp_new->Count();
    00157   this->destination->Append(cp_new, this->next);
    00158   return cp_new == cp;
    00159 }
    00160
    00166 bool CargoTransfer::operator()(CargoPacket *cp)
    00167 {
    00168   CargoPacket *cp_new = this->Preprocess(cp);
    00169   if (cp_new == NULL) return false;
    00170   this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_TRANSFER, cp_new->Count());
    00171   cp_new->AddFeederShare(this->payment->PayTransfer(cp_new, cp_new->Count()));
    00172   this->destination->Append(cp_new, cp_new->NextStation());
    00173   return cp_new == cp;
    00174 }
    00175
    00181 bool CargoShift::operator()(CargoPacket *cp)
    00182 {
    00183   CargoPacket *cp_new = this->Preprocess(cp);
    00184   if (cp_new == NULL) cp_new = cp;
    00185   this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_KEEP, cp_new->Count());
    00186   this->destination->Append(cp_new, VehicleCargoList::MTA_KEEP);
    00187   return cp_new == cp;
    00188 }
    00189
    00195 bool CargoReroute::operator()(CargoPacket *cp)
    00196 {
    00197   CargoPacket *cp_new = this->Preprocess(cp);
    00198   if (cp_new == NULL) cp_new = cp;
    00199   StationID next = this->ge->GetVia(cp_new->SourceStation(), this->avoid, this->avoid2);
    00200   assert(next != this->avoid && next != this->avoid2);
    00201   if (this->source != this->destination) {
    00202     this->source->RemoveFromCache(cp_new, cp_new->Count());
    00203     this->destination->AddToCache(cp_new);
    00204   }
    00205
    00206   /* Legal, as insert doesn't invalidate iterators in the MultiMap, however
    00207    * this might insert the packet between range.first and range.second (which might be end())
    00208    * This is why we check for GetKey above to avoid infinite loops. */
    00209   this->destination->packets.Insert(next, cp_new);
    00210   return cp_new == cp;
    00211 }
    00212
    00213 template uint CargoRemoval<VehicleCargoList>::Preprocess(CargoPacket *cp);
    00214 template uint CargoRemoval<StationCargoList>::Preprocess(CargoPacket *cp);
    00215 template bool CargoRemoval<VehicleCargoList>::Postprocess(CargoPacket *cp, uint remove);
    00216 template bool CargoRemoval<StationCargoList>::Postprocess(CargoPacket *cp, uint remove);