roadstop_base.h

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