src/cargopacket.h
changeset 7506 e52d89f5c7c1
child 7587 353e9434475c
equal deleted inserted replaced
7505:94a7391e0377 7506:e52d89f5c7c1
       
     1 /* $Id$ */
       
     2 
       
     3 /** @file cargotype.h */
       
     4 
       
     5 #ifndef CARGOPACKET_H
       
     6 #define CARGOPACKET_H
       
     7 
       
     8 #include <list>
       
     9 
       
    10 /**
       
    11  * Container for cargo from the same location and time
       
    12  */
       
    13 struct CargoPacket {
       
    14 	bool touched;
       
    15 
       
    16 	typedef uint32 ID;      ///< Type for cargopacket identifiers
       
    17 
       
    18 	ID index;               ///< The unique index of this packet
       
    19 
       
    20 	StationID source;       ///< The station where the cargo came from first
       
    21 	TileIndex source_xy;    ///< The origin of the cargo (first station in feeder chain)
       
    22 	TileIndex loaded_at_xy; ///< Location where this cargo has been loaded into the vehicle
       
    23 
       
    24 	uint16 count;           ///< The amount of cargo in this packet
       
    25 	byte days_in_transit;   ///< Amount of days this packet has been in transit
       
    26 	Money feeder_share;     ///< Value of feeder pickup to be paid for on delivery of cargo
       
    27 	bool paid_for;          ///< Have we been paid for this cargo packet?
       
    28 
       
    29 	/**
       
    30 	 * Creates a new cargo packet
       
    31 	 * @param source the source of the packet
       
    32 	 * @param count  the number of cargo entities to put in this packet
       
    33 	 * @pre count != 0 || source == INVALID_STATION
       
    34 	 */
       
    35 	CargoPacket(StationID source = INVALID_STATION, uint16 count = 0);
       
    36 
       
    37 	/** Destroy the packet */
       
    38 	~CargoPacket();
       
    39 
       
    40 
       
    41 	/**
       
    42 	 * Is this a valid cargo packet ?
       
    43 	 * @return true if and only it is valid
       
    44 	 */
       
    45 	bool IsValid() const { return this->count != 0; }
       
    46 
       
    47 	/**
       
    48 	 * Checks whether the cargo packet is from (exactly) the same source
       
    49 	 * in time and location.
       
    50 	 * @param cp the cargo packet to compare to
       
    51 	 * @return true if and only if days_in_transit and source_xy are equal
       
    52 	 */
       
    53 	bool SameSource(CargoPacket *cp);
       
    54 
       
    55 
       
    56 	/* normal new/delete operators. Used when building/removing station */
       
    57 	void* operator new (size_t size);
       
    58 	void operator delete(void *p);
       
    59 
       
    60 	/* new/delete operators accepting station index. Used when loading station from savegame. */
       
    61 	void* operator new (size_t size, CargoPacket::ID cp_idx);
       
    62 	void operator delete(void *p, CargoPacket::ID cp_idx);
       
    63 
       
    64 private:
       
    65 	/**
       
    66 	 * Allocate the raw memory for this cargo packet
       
    67 	 * @return the allocated memory
       
    68 	 */
       
    69 	static CargoPacket *AllocateRaw();
       
    70 };
       
    71 
       
    72 /** We want to use a pool */
       
    73 DECLARE_OLD_POOL(CargoPacket, CargoPacket, 10, 1000)
       
    74 
       
    75 /**
       
    76  * Iterate over all _valid_ cargo packets from the given start
       
    77  * @param cp    the variable used as "iterator"
       
    78  * @param start the cargo packet ID of the first packet to iterate over
       
    79  */
       
    80 #define FOR_ALL_CARGOPACKETS_FROM(cp, start) for (cp = GetCargoPacket(start); cp != NULL; cp = (cp->index + 1U < GetCargoPacketPoolSize()) ? GetCargoPacket(cp->index + 1U) : NULL) if (cp->IsValid())
       
    81 
       
    82 /**
       
    83  * Iterate over all _valid_ cargo packets from the begin of the pool
       
    84  * @param cp    the variable used as "iterator"
       
    85  */
       
    86 #define FOR_ALL_CARGOPACKETS(cp) FOR_ALL_CARGOPACKETS_FROM(cp, 0)
       
    87 
       
    88 /**
       
    89  * Simple collection class for a list of cargo packets
       
    90  */
       
    91 class CargoList {
       
    92 public:
       
    93 	/** List of cargo packets */
       
    94 	typedef std::list<CargoPacket *> List;
       
    95 
       
    96 	/** Kind of actions that could be done with packets on move */
       
    97 	enum MoveToAction {
       
    98 		MTA_FINAL_DELIVERY, ///< "Deliver" the packet to the final destination, i.e. destroy the packet
       
    99 		MTA_CARGO_LOAD,     ///< Load the packet onto a vehicle, i.e. set the last loaded station ID
       
   100 		MTA_OTHER           ///< "Just" move the packet to another cargo list
       
   101 	};
       
   102 
       
   103 private:
       
   104 	List packets;         ///< The cargo packets in this list
       
   105 
       
   106 	bool empty;           ///< Cache for whether this list is empty or not
       
   107 	uint count;           ///< Cache for the number of cargo entities
       
   108 	bool unpaid_cargo;    ///< Cache for the unpaid cargo
       
   109 	Money feeder_share;   ///< Cache for the feeder share
       
   110 	StationID source;     ///< Cache for the source of the packet
       
   111 	uint days_in_transit; ///< Cache for the number of days in transit
       
   112 
       
   113 public:
       
   114 	/**
       
   115 	 * Needed for an ugly hack:
       
   116 	 *  - vehicles and stations need to store cargo lists, so they use CargoList as container
       
   117 	 *  - this internals of the container should be protected, e.g. private (or protected) by C++
       
   118 	 *  - for saving/loading we need to pass pointer to objects
       
   119 	 *  -> so *if* the pointer to the cargo list is the same as the pointer to the packet list
       
   120 	 *     encapsulated in the CargoList, we can just pass the CargoList as "offset".
       
   121 	 *     Normally we would then just add the offset of the packets variable within the cargo list
       
   122 	 *     but that is not possible because the variable is private. Furthermore we are not sure
       
   123 	 *     that this works on all platforms, we need to check whether the offset is actually 0.
       
   124 	 *     This cannot be done compile time, because the variable is private. So we need to write
       
   125 	 *     a function that does actually check the offset runtime and call it somewhere where it
       
   126 	 *     is always called but it should not be called often.
       
   127 	 */
       
   128 	static void AssertOnWrongPacketOffset();
       
   129 
       
   130 	/** Create the cargo list */
       
   131 	CargoList() { this->InvalidateCache(); }
       
   132 	/** And destroy it ("frees" all cargo packets) */
       
   133 	~CargoList();
       
   134 
       
   135 	/**
       
   136 	 * Returns a pointer to the cargo packet list (so you can iterate over it etc).
       
   137 	 * @return pointer to the packet list
       
   138 	 */
       
   139 	const CargoList::List *Packets() const;
       
   140 
       
   141 	/**
       
   142 	 * Ages the all cargo in this list
       
   143 	 */
       
   144 	void AgeCargo();
       
   145 
       
   146 	/**
       
   147 	 * Checks whether this list is empty
       
   148 	 * @return true if and only if the list is empty
       
   149 	 */
       
   150 	bool Empty() const;
       
   151 
       
   152 	/**
       
   153 	 * Returns the number of cargo entities in this list
       
   154 	 * @return the before mentioned number
       
   155 	 */
       
   156 	uint Count() const;
       
   157 
       
   158 	/**
       
   159 	 * Is there some cargo that has not been paid for?
       
   160 	 * @return true if and only if there is such a cargo
       
   161 	 */
       
   162 	bool UnpaidCargo() const;
       
   163 
       
   164 	/**
       
   165 	 * Returns total sum of the feeder share for all packets
       
   166 	 * @return the before mentioned number
       
   167 	 */
       
   168 	Money FeederShare() const;
       
   169 
       
   170 	/**
       
   171 	 * Returns source of the first cargo packet in this list
       
   172 	 * @return the before mentioned source
       
   173 	 */
       
   174 	StationID Source() const;
       
   175 
       
   176 	/**
       
   177 	 * Returns average number of days in transit for a cargo entity
       
   178 	 * @return the before mentioned number
       
   179 	 */
       
   180 	uint DaysInTransit() const;
       
   181 
       
   182 
       
   183 	/**
       
   184 	 * Appends the given cargo packet
       
   185 	 * @warning After appending this packet may not exist anymore!
       
   186 	 * @note Do not use the cargo packet anymore after it has been appended to this CargoList!
       
   187 	 * @param cp the cargo packet to add
       
   188 	 * @pre cp != NULL
       
   189 	 */
       
   190 	void Append(CargoPacket *cp);
       
   191 
       
   192 	/**
       
   193 	 * Truncates the cargo in this list to the given amount. It leaves the
       
   194 	 * first count cargo entities and removes the rest.
       
   195 	 * @param count the maximum amount of entities to be in the list after the command
       
   196 	 */
       
   197 	void Truncate(uint count);
       
   198 
       
   199 	/**
       
   200 	 * Moves the given amount of cargo to another list.
       
   201 	 * Depending on the value of mta the side effects of this function differ:
       
   202 	 *  - MTA_FINAL_DELIVERY: destroys the packets that do not originate from a specific station
       
   203 	 *  - MTA_CARGO_LOAD:     sets the loaded_at_xy value of the moved packets
       
   204 	 *  - MTA_OTHER:          just move without side effects
       
   205 	 * @param dest  the destination to move the cargo to
       
   206 	 * @param count the amount of cargo entities to move
       
   207 	 * @param mta   how to handle the moving (side effects)
       
   208 	 * @param data  Depending on mta the data of this variable differs:
       
   209 	 *              - MTA_FINAL_DELIVERY - station ID of packet's origin not to remove
       
   210 	 *              - MTA_CARGO_LOAD     - station's tile index of load
       
   211 	 *              - MTA_OTHER          - unused
       
   212 	 * @param mta == MTA_FINAL_DELIVERY || dest != NULL
       
   213 	 * @return true if there are still packets that might be moved from this cargo list
       
   214 	 */
       
   215 	bool MoveTo(CargoList *dest, uint count, CargoList::MoveToAction mta = MTA_OTHER, uint data = 0);
       
   216 
       
   217 	/** Invalidates the cached data and rebuild it */
       
   218 	void InvalidateCache();
       
   219 };
       
   220 
       
   221 #endif /* CARGOPACKET_H */