# roadstop_base.h

Go to the documentation of this file.

    00001 /* $Id: roadstop_base.h 18809 2010-01-15 16:41:15Z rubidium $ */
    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 #include "direction_type.h"
    00019 #include "vehicle_type.h"
    00020
    00021 typedef Pool<RoadStop, RoadStopID, 32, 64000> RoadStopPool;
    00022 extern RoadStopPool _roadstop_pool;
    00023
    00025 struct RoadStop : RoadStopPool::PoolItem<&_roadstop_pool> {
    00026   enum RoadStopStatusFlags {
    00027     RSSFB_BAY0_FREE  = 0,
    00028     RSSFB_BAY1_FREE  = 1,
    00029     RSSFB_BAY_COUNT  = 2,
    00030     RSSFB_BASE_ENTRY = 6,
    00031     RSSFB_ENTRY_BUSY = 7,
    00032   };
    00033
    00035   struct Entry {
    00036   private:
    00037     int length;
    00038     int occupied;
    00039
    00040   public:
    00041     friend struct RoadStop;
    00042
    00044     Entry() : length(0), occupied(0) {}
    00045
    00050     FORCEINLINE int GetLength() const
    00051     {
    00052       return this->length;
    00053     }
    00054
    00059     FORCEINLINE int GetOccupied() const
    00060     {
    00061       return this->occupied;
    00062     }
    00063
    00064     void Leave(const RoadVehicle *rv);
    00065     void Enter(const RoadVehicle *rv);
    00066     void CheckIntegrity(const RoadStop *rs) const;
    00067     void Rebuild(const RoadStop *rs, int side = -1);
    00068   };
    00069
    00070   TileIndex       xy;
    00071   byte            status;
    00072   struct RoadStop *next;
    00073
    00075   FORCEINLINE RoadStop(TileIndex tile = INVALID_TILE) :
    00076     xy(tile),
    00077     status((1 << RSSFB_BAY_COUNT) - 1)
    00078   { }
    00079
    00080   ~RoadStop();
    00081
    00086   FORCEINLINE bool HasFreeBay() const
    00087   {
    00088     return GB(this->status, 0, RSSFB_BAY_COUNT) != 0;
    00089   }
    00090
    00096   FORCEINLINE bool IsFreeBay(uint nr) const
    00097   {
    00098     assert(nr < RSSFB_BAY_COUNT);
    00099     return HasBit(this->status, nr);
    00100   }
    00101
    00106   FORCEINLINE bool IsEntranceBusy() const
    00107   {
    00108     return HasBit(this->status, RSSFB_ENTRY_BUSY);
    00109   }
    00110
    00115   FORCEINLINE void SetEntranceBusy(bool busy)
    00116   {
    00117     SB(this->status, RSSFB_ENTRY_BUSY, 1, busy);
    00118   }
    00119
    00125   FORCEINLINE const Entry *GetEntry(DiagDirection dir) const
    00126   {
    00127     return HasBit((int)dir, 1) ? this->west : this->east;
    00128   }
    00129
    00135   FORCEINLINE Entry *GetEntry(DiagDirection dir)
    00136   {
    00137     return HasBit((int)dir, 1) ? this->west : this->east;
    00138   }
    00139
    00140   void MakeDriveThrough();
    00141   void ClearDriveThrough();
    00142
    00143   void Leave(RoadVehicle *rv);
    00144   bool Enter(RoadVehicle *rv);
    00145
    00146   RoadStop *GetNextRoadStop(const struct RoadVehicle *v) const;
    00147
    00148   static RoadStop *GetByTile(TileIndex tile, RoadStopType type);
    00149
    00150   static bool IsDriveThroughRoadStopContinuation(TileIndex rs, TileIndex next);
    00151
    00152 private:
    00153   Entry *east;
    00154   Entry *west;
    00155
    00161   FORCEINLINE uint AllocateBay()
    00162   {
    00163     assert(this->HasFreeBay());
    00164
    00165     /* Find the first free bay. If the bit is set, the bay is free. */
    00166     uint bay_nr = 0;
    00167     while (!HasBit(this->status, bay_nr)) bay_nr++;
    00168
    00169     ClrBit(this->status, bay_nr);
    00170     return bay_nr;
    00171   }
    00172
    00177   FORCEINLINE void AllocateDriveThroughBay(uint nr)
    00178   {
    00179     assert(nr < RSSFB_BAY_COUNT);
    00180     ClrBit(this->status, nr);
    00181   }
    00182
    00187   FORCEINLINE void FreeBay(uint nr)
    00188   {
    00189     assert(nr < RSSFB_BAY_COUNT);
    00190     SetBit(this->status, nr);
    00191   }
    00192 };
    00193
    00194 #define FOR_ALL_ROADSTOPS_FROM(var, start) FOR_ALL_ITEMS_FROM(RoadStop, roadstop_index, var, start)
    00195 #define FOR_ALL_ROADSTOPS(var) FOR_ALL_ROADSTOPS_FROM(var, 0)
    00196
    00197 #endif /* ROADSTOP_BASE_H */