# roadstop_base.h

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 #ifndef ROADSTOP_BASE_H
    00013 #define ROADSTOP_BASE_H
    00014
    00015 #include "station_type.h"
    00016 #include "core/pool_type.hpp"
    00017 #include "core/bitmath_func.hpp"
    00018
    00019 typedef Pool<RoadStop, RoadStopID, 32, 64000> RoadStopPool;
    00020 extern RoadStopPool _roadstop_pool;
    00021
    00023 struct RoadStop : RoadStopPool::PoolItem<&_roadstop_pool> {
    00024   enum RoadStopStatusFlags {
    00025     RSSFB_BAY0_FREE  = 0,
    00026     RSSFB_BAY1_FREE  = 1,
    00027     RSSFB_BAY_COUNT  = 2,
    00028     RSSFB_BASE_ENTRY = 6,
    00029     RSSFB_ENTRY_BUSY = 7,
    00030   };
    00031
    00033   struct Entry {
    00034   private:
    00035     int length;
    00036     int occupied;
    00037
    00038   public:
    00039     friend struct RoadStop;
    00040
    00042     Entry() : length(0), occupied(0) {}
    00043
    00048     FORCEINLINE int GetLength() const
    00049     {
    00050       return this->length;
    00051     }
    00052
    00057     FORCEINLINE int GetOccupied() const
    00058     {
    00059       return this->occupied;
    00060     }
    00061
    00062     void Leave(const RoadVehicle *rv);
    00063     void Enter(const RoadVehicle *rv);
    00064     void CheckIntegrity(const RoadStop *rs) const;
    00065     void Rebuild(const RoadStop *rs, int side = -1);
    00066   };
    00067
    00068   TileIndex       xy;
    00069   byte            status;
    00070   struct RoadStop *next;
    00071
    00073   FORCEINLINE RoadStop(TileIndex tile = INVALID_TILE) :
    00074     xy(tile),
    00075     status((1 << RSSFB_BAY_COUNT) - 1)
    00076   { }
    00077
    00078   ~RoadStop();
    00079
    00084   FORCEINLINE bool HasFreeBay() const
    00085   {
    00086     return GB(this->status, 0, RSSFB_BAY_COUNT) != 0;
    00087   }
    00088
    00094   FORCEINLINE bool IsFreeBay(uint nr) const
    00095   {
    00096     assert(nr < RSSFB_BAY_COUNT);
    00097     return HasBit(this->status, nr);
    00098   }
    00099
    00104   FORCEINLINE bool IsEntranceBusy() const
    00105   {
    00106     return HasBit(this->status, RSSFB_ENTRY_BUSY);
    00107   }
    00108
    00113   FORCEINLINE void SetEntranceBusy(bool busy)
    00114   {
    00115     SB(this->status, RSSFB_ENTRY_BUSY, 1, busy);
    00116   }
    00117
    00123   FORCEINLINE const Entry *GetEntry(DiagDirection dir) const
    00124   {
    00125     return HasBit((int)dir, 1) ? this->west : this->east;
    00126   }
    00127
    00133   FORCEINLINE Entry *GetEntry(DiagDirection dir)
    00134   {
    00135     return HasBit((int)dir, 1) ? this->west : this->east;
    00136   }
    00137
    00138   void MakeDriveThrough();
    00139   void ClearDriveThrough();
    00140
    00141   void Leave(RoadVehicle *rv);
    00142   bool Enter(RoadVehicle *rv);
    00143
    00144   RoadStop *GetNextRoadStop(const struct RoadVehicle *v) const;
    00145
    00146   static RoadStop *GetByTile(TileIndex tile, RoadStopType type);
    00147
    00148   static bool IsDriveThroughRoadStopContinuation(TileIndex rs, TileIndex next);
    00149
    00150 private:
    00151   Entry *east;
    00152   Entry *west;
    00153
    00159   FORCEINLINE uint AllocateBay()
    00160   {
    00161     assert(this->HasFreeBay());
    00162
    00163     /* Find the first free bay. If the bit is set, the bay is free. */
    00164     uint bay_nr = 0;
    00165     while (!HasBit(this->status, bay_nr)) bay_nr++;
    00166
    00167     ClrBit(this->status, bay_nr);
    00168     return bay_nr;
    00169   }
    00170
    00175   FORCEINLINE void AllocateDriveThroughBay(uint nr)
    00176   {
    00177     assert(nr < RSSFB_BAY_COUNT);
    00178     ClrBit(this->status, nr);
    00179   }
    00180
    00185   FORCEINLINE void FreeBay(uint nr)
    00186   {
    00187     assert(nr < RSSFB_BAY_COUNT);
    00188     SetBit(this->status, nr);
    00189   }
    00190 };
    00191
    00192 #define FOR_ALL_ROADSTOPS_FROM(var, start) FOR_ALL_ITEMS_FROM(RoadStop, roadstop_index, var, start)
    00193 #define FOR_ALL_ROADSTOPS(var) FOR_ALL_ROADSTOPS_FROM(var, 0)
    00194
    00195 #endif /* ROADSTOP_BASE_H */