summaryrefslogtreecommitdiff
path: root/src/cargopacket.cpp
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2013-02-17 14:36:40 +0000
committerrubidium <rubidium@openttd.org>2013-02-17 14:36:40 +0000
commitd6e2a8aa56337af68f2960cf404edf0ac03f405b (patch)
treeaccb17985ebc03652d3c7b42b0dc8c038943a4c3 /src/cargopacket.cpp
parent71bbc130fc3bde400bcf2d46e0d57d974acc83aa (diff)
downloadopenttd-d6e2a8aa56337af68f2960cf404edf0ac03f405b.tar.xz
(svn r25010) -Codechange: Add general framework for cargo actions, i.e. loading, transfering, delivering and such, to contain this logic in a single place instead of spread around (fonsinchen)
Diffstat (limited to 'src/cargopacket.cpp')
-rw-r--r--src/cargopacket.cpp77
1 files changed, 55 insertions, 22 deletions
diff --git a/src/cargopacket.cpp b/src/cargopacket.cpp
index 42643ffa3..842bf0913 100644
--- a/src/cargopacket.cpp
+++ b/src/cargopacket.cpp
@@ -12,6 +12,7 @@
#include "stdafx.h"
#include "core/pool_func.hpp"
#include "economy_base.h"
+#include "cargoaction.h"
/* Initialize the cargopacket-pool */
CargoPacketPool _cargopacket_pool("CargoPacket");
@@ -225,28 +226,7 @@ template <class Tinst>
uint CargoList<Tinst>::Truncate(uint max_move)
{
max_move = min(this->count, max_move);
- uint max_remaining = this->count - max_move;
- for (Iterator it(packets.begin()); it != packets.end(); /* done during loop*/) {
- CargoPacket *cp = *it;
- if (max_remaining == 0) {
- /* Nothing should remain, just remove the packets. */
- it = this->packets.erase(it);
- static_cast<Tinst *>(this)->RemoveFromCache(cp, cp->count);
- delete cp;
- continue;
- }
-
- uint local_count = cp->count;
- if (local_count > max_remaining) {
- uint diff = local_count - max_remaining;
- static_cast<Tinst *>(this)->RemoveFromCache(cp, diff);
- cp->Reduce(diff);
- max_remaining = 0;
- } else {
- max_remaining -= local_count;
- }
- ++it;
- }
+ this->PopCargo(CargoRemoval<Tinst>(static_cast<Tinst *>(this), max_move));
return max_move;
}
@@ -346,6 +326,59 @@ bool CargoList<Tinst>::MoveTo(Tother_inst *dest, uint max_move, MoveToAction mta
return it != packets.end();
}
+/**
+ * Shifts cargo from the front of the packet list and applies some action to it.
+ * @tparam Taction Action class or function to be used. It should define
+ * "bool operator()(CargoPacket *)". If true is returned the
+ * cargo packet will be removed from the list. Otherwise it
+ * will be kept and the loop will be aborted.
+ * @param action Action instance to be applied.
+ */
+template <class Tinst>
+template <class Taction>
+void CargoList<Tinst>::ShiftCargo(Taction action)
+{
+ Iterator it(this->packets.begin());
+ while (it != this->packets.end() && action.MaxMove() > 0) {
+ CargoPacket *cp = *it;
+ if (action(cp)) {
+ it = this->packets.erase(it);
+ } else {
+ break;
+ }
+ }
+}
+
+/**
+ * Pops cargo from the back of the packet list and applies some action to it.
+ * @tparam Taction Action class or function to be used. It should define
+ * "bool operator()(CargoPacket *)". If true is returned the
+ * cargo packet will be removed from the list. Otherwise it
+ * will be kept and the loop will be aborted.
+ * @param action Action instance to be applied.
+ */
+template <class Tinst>
+template <class Taction>
+void CargoList<Tinst>::PopCargo(Taction action)
+{
+ if (this->packets.empty()) return;
+ Iterator it(--(this->packets.end()));
+ Iterator begin(this->packets.begin());
+ while (action.MaxMove() > 0) {
+ CargoPacket *cp = *it;
+ if (action(cp)) {
+ if (it != begin) {
+ this->packets.erase(it--);
+ } else {
+ this->packets.erase(it);
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+}
+
/** Invalidates the cached data and rebuilds it. */
template <class Tinst>
void CargoList<Tinst>::InvalidateCache()