diff options
author | rubidium <rubidium@openttd.org> | 2007-01-02 19:19:48 +0000 |
---|---|---|
committer | rubidium <rubidium@openttd.org> | 2007-01-02 19:19:48 +0000 |
commit | 66bbf336c6af7353ef0aeed58002c46543b30635 (patch) | |
tree | ad4a63860df2626b22f77e7dac712e958bea54cb /yapf/yapf_costrail.hpp | |
parent | ccc0a3f4dbf58c005b22341ac8874252924690cd (diff) | |
download | openttd-66bbf336c6af7353ef0aeed58002c46543b30635.tar.xz |
(svn r7759) -Merge: makefile rewrite. This merge features:
- A proper ./configure, so everything needs to be configured only once, not for every make.
- Usage of makedepend when available. This greatly reduces the time needed for generating the dependencies.
- A generator for all project files. There is a single file with sources, which is used to generate Makefiles and the project files for MSVC.
- Proper support for OSX universal binaries.
- Object files for non-MSVC compiles are also placed in separate directories, making is faster to switch between debug and release compiles and it does not touch the directory with the source files.
- Functionality to make a bundle of all needed files for for example a nightly or distribution of a binary with all needed GRFs and language files.
Note: as this merge moves almost all files, it is recommended to make a backup of your working copy before updating your working copy.
Diffstat (limited to 'yapf/yapf_costrail.hpp')
-rw-r--r-- | yapf/yapf_costrail.hpp | 381 |
1 files changed, 0 insertions, 381 deletions
diff --git a/yapf/yapf_costrail.hpp b/yapf/yapf_costrail.hpp deleted file mode 100644 index 93062b5c2..000000000 --- a/yapf/yapf_costrail.hpp +++ /dev/null @@ -1,381 +0,0 @@ -/* $Id$ */ - -#ifndef YAPF_COSTRAIL_HPP -#define YAPF_COSTRAIL_HPP - - -template <class Types> -class CYapfCostRailT - : public CYapfCostBase - , public CostRailSettings -{ -public: - typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class) - typedef typename Types::TrackFollower TrackFollower; - typedef typename Types::NodeList::Titem Node; ///< this will be our node type - typedef typename Node::Key Key; ///< key to hash tables - typedef typename Node::CachedData CachedData; - -protected: - int m_max_cost; - CBlobT<int> m_sig_look_ahead_costs; -public: - bool m_stopped_on_first_two_way_signal; -protected: - - static const int s_max_segment_cost = 10000; - - CYapfCostRailT() - : m_max_cost(0) - , m_stopped_on_first_two_way_signal(false) - { - // pre-compute look-ahead penalties into array - int p0 = Yapf().PfGetSettings().rail_look_ahead_signal_p0; - int p1 = Yapf().PfGetSettings().rail_look_ahead_signal_p1; - int p2 = Yapf().PfGetSettings().rail_look_ahead_signal_p2; - int *pen = m_sig_look_ahead_costs.GrowSizeNC(Yapf().PfGetSettings().rail_look_ahead_max_signals); - for (uint i = 0; i < Yapf().PfGetSettings().rail_look_ahead_max_signals; i++) - pen[i] = p0 + i * (p1 + i * p2); - } - - /// to access inherited path finder - Tpf& Yapf() {return *static_cast<Tpf*>(this);} - -public: - FORCEINLINE int SlopeCost(TileIndex tile, Trackdir td) - { - CPerfStart perf_cost(Yapf().m_perf_slope_cost); - if (!stSlopeCost(tile, td)) return 0; - return Yapf().PfGetSettings().rail_slope_penalty; - } - - FORCEINLINE int CurveCost(Trackdir td1, Trackdir td2) - { - int cost = 0; - if (TrackFollower::Allow90degTurns() - && ((TrackdirToTrackdirBits(td2) & (TrackdirBits)TrackdirCrossesTrackdirs(td1)) != 0)) { - // 90-deg curve penalty - cost += Yapf().PfGetSettings().rail_curve90_penalty; - } else if (td2 != NextTrackdir(td1)) { - // 45-deg curve penalty - cost += Yapf().PfGetSettings().rail_curve45_penalty; - } - return cost; - } - - /** return one tile cost. If tile is a tunnel entry, it is moved to the end of tunnel */ - FORCEINLINE int OneTileCost(TileIndex& tile, Trackdir trackdir) - { - int cost = 0; - // set base cost - if (IsDiagonalTrackdir(trackdir)) { - cost += YAPF_TILE_LENGTH; - switch (GetTileType(tile)) { - case MP_STREET: - /* Increase the cost for level crossings */ - if (IsLevelCrossing(tile)) - cost += Yapf().PfGetSettings().rail_crossing_penalty; - break; - - case MP_STATION: - // penalty for passing station tiles - cost += Yapf().PfGetSettings().rail_station_penalty; - break; - - default: - break; - } - } else { - // non-diagonal trackdir - cost = YAPF_TILE_CORNER_LENGTH; - } - return cost; - } - - int SignalCost(Node& n, TileIndex tile, Trackdir trackdir) - { - int cost = 0; - // if there is one-way signal in the opposite direction, then it is not our way - CPerfStart perf_cost(Yapf().m_perf_other_cost); - if (IsTileType(tile, MP_RAILWAY)) { - bool has_signal_against = HasSignalOnTrackdir(tile, ReverseTrackdir(trackdir)); - bool has_signal_along = HasSignalOnTrackdir(tile, trackdir); - if (has_signal_against && !has_signal_along) { - // one-way signal in opposite direction - n.m_segment->flags_u.flags_s.m_end_of_line = true; - } else if (has_signal_along) { - SignalState sig_state = GetSignalStateByTrackdir(tile, trackdir); - // cache the look-ahead polynomial constant only if we didn't pass more signals than the look-ahead limit is - int look_ahead_cost = (n.m_num_signals_passed < m_sig_look_ahead_costs.Size()) ? m_sig_look_ahead_costs.Data()[n.m_num_signals_passed] : 0; - if (sig_state != SIGNAL_STATE_RED) { - // green signal - n.flags_u.flags_s.m_last_signal_was_red = false; - // negative look-ahead red-signal penalties would cause problems later, so use them as positive penalties for green signal - if (look_ahead_cost < 0) { - // add its negation to the cost - cost -= look_ahead_cost; - } - } else { - // we have a red signal in our direction - // was it first signal which is two-way? - if (Yapf().TreatFirstRedTwoWaySignalAsEOL() && n.flags_u.flags_s.m_choice_seen && has_signal_against && n.m_num_signals_passed == 0) { - // yes, the first signal is two-way red signal => DEAD END - n.m_segment->flags_u.flags_s.m_end_of_line = true; - Yapf().m_stopped_on_first_two_way_signal = true; - return -1; - } - SignalType sig_type = GetSignalType(tile); - n.m_last_red_signal_type = sig_type; - n.flags_u.flags_s.m_last_signal_was_red = true; - - // look-ahead signal penalty - if (look_ahead_cost > 0) { - // add the look ahead penalty only if it is positive - cost += look_ahead_cost; - } - - // special signal penalties - if (n.m_num_signals_passed == 0) { - switch (sig_type) { - case SIGTYPE_COMBO: - case SIGTYPE_EXIT: cost += Yapf().PfGetSettings().rail_firstred_exit_penalty; break; // first signal is red pre-signal-exit - case SIGTYPE_NORMAL: - case SIGTYPE_ENTRY: cost += Yapf().PfGetSettings().rail_firstred_penalty; break; - }; - } - } - n.m_num_signals_passed++; - n.m_segment->m_last_signal_tile = tile; - n.m_segment->m_last_signal_td = trackdir; - } - } - return cost; - } - - FORCEINLINE int PlatformLengthPenalty(int platform_length) - { - int cost = 0; - const Vehicle* v = Yapf().GetVehicle(); - assert(v != NULL); - assert(v->type == VEH_Train); - assert(v->u.rail.cached_total_length != 0); - int needed_platform_length = (v->u.rail.cached_total_length + TILE_SIZE - 1) / TILE_SIZE; - if (platform_length > needed_platform_length) { - // apply penalty for longer platform than needed - cost += Yapf().PfGetSettings().rail_longer_platform_penalty; - } else if (needed_platform_length > platform_length) { - // apply penalty for shorter platform than needed - cost += Yapf().PfGetSettings().rail_shorter_platform_penalty; - } - return cost; - } - -public: - FORCEINLINE void SetMaxCost(int max_cost) {m_max_cost = max_cost;} - - /** Called by YAPF to calculate the cost from the origin to the given node. - * Calculates only the cost of given node, adds it to the parent node cost - * and stores the result into Node::m_cost member */ - FORCEINLINE bool PfCalcCost(Node& n) - { - assert(!n.flags_u.flags_s.m_targed_seen); - CPerfStart perf_cost(Yapf().m_perf_cost); - int parent_cost = (n.m_parent != NULL) ? n.m_parent->m_cost : 0; - int first_tile_cost = 0; - int segment_cost = 0; - int extra_cost = 0; - const Vehicle* v = Yapf().GetVehicle(); - - // start at n.m_key.m_tile / n.m_key.m_td and walk to the end of segment - TileIndex prev_tile = (n.m_parent != NULL) ? n.m_parent->GetLastTile() : INVALID_TILE; - Trackdir prev_trackdir = (n.m_parent != NULL) ? n.m_parent->GetLastTrackdir() : INVALID_TRACKDIR; - TileType prev_tile_type = (n.m_parent != NULL) ? GetTileType(n.m_parent->GetLastTile()) : MP_VOID; - - TileIndex tile = n.m_key.m_tile; - Trackdir trackdir = n.m_key.m_td; - TileType tile_type = GetTileType(tile); - - RailType rail_type = GetTileRailType(tile, trackdir); - - bool target_seen = Yapf().PfDetectDestination(tile, trackdir); - - while (true) { - segment_cost += Yapf().OneTileCost(tile, trackdir); - segment_cost += Yapf().CurveCost(prev_trackdir, trackdir); - segment_cost += Yapf().SlopeCost(tile, trackdir); - segment_cost += Yapf().SignalCost(n, tile, trackdir); - if (n.m_segment->flags_u.flags_s.m_end_of_line) { - break; - } - - // finish if we have reached the destination - if (target_seen) { - break; - } - - // finish on first station tile - segment should end here to avoid target skipping - // when cached segments are used - if (tile_type == MP_STATION && prev_tile_type != MP_STATION) { - break; - } - - // finish also on waypoint - same workaround as for first station tile - if (tile_type == MP_RAILWAY && IsRailWaypoint(tile)) { - break; - } - - // if there are no reachable trackdirs on the next tile, we have end of road - TrackFollower F(v, &Yapf().m_perf_ts_cost); - if (!F.Follow(tile, trackdir)) { - // we can't continue? - // n.m_segment->flags_u.flags_s.m_end_of_line = true; - break; - } - - // if there are more trackdirs available & reachable, we are at the end of segment - if (KillFirstBit2x64(F.m_new_td_bits) != 0) { - break; - } - - Trackdir new_td = (Trackdir)FindFirstBit2x64(F.m_new_td_bits); - - { - // end segment if train is about to enter simple loop with no junctions - // so next time it should stop on the next if - if (segment_cost > s_max_segment_cost && IsTileType(F.m_new_tile, MP_RAILWAY)) - break; - - // stop if train is on simple loop with no junctions - if (F.m_new_tile == n.m_key.m_tile && new_td == n.m_key.m_td) - return false; - } - - // if tail type changes, finish segment (cached segment can't contain more rail types) - { - RailType new_rail_type = GetTileRailType(F.m_new_tile, (Trackdir)FindFirstBit2x64(F.m_new_td_bits)); - if (new_rail_type != rail_type) { - break; - } - rail_type = new_rail_type; - } - - // move to the next tile - prev_tile = tile; - prev_trackdir = trackdir; - prev_tile_type = tile_type; - - tile = F.m_new_tile; - trackdir = new_td; - tile_type = GetTileType(tile); - - target_seen = Yapf().PfDetectDestination(tile, trackdir); - - // reversing in depot penalty - if (tile == prev_tile) { - segment_cost += Yapf().PfGetSettings().rail_depot_reverse_penalty; - break; - } - - // if we skipped some tunnel tiles, add their cost - segment_cost += YAPF_TILE_LENGTH * F.m_tiles_skipped; - - // add penalty for skipped station tiles - if (F.m_is_station) - { - if (target_seen) { - // it is our destination station - uint platform_length = F.m_tiles_skipped + 1; - segment_cost += PlatformLengthPenalty(platform_length); - } else { - // station is not our destination station, apply penalty for skipped platform tiles - segment_cost += Yapf().PfGetSettings().rail_station_penalty * F.m_tiles_skipped; - } - } - - // add min/max speed penalties - int min_speed = 0; - int max_speed = F.GetSpeedLimit(&min_speed); - if (max_speed < v->max_speed) - segment_cost += YAPF_TILE_LENGTH * (v->max_speed - max_speed) / v->max_speed; - if (min_speed > v->max_speed) - segment_cost += YAPF_TILE_LENGTH * (min_speed - v->max_speed); - - // finish if we already exceeded the maximum cost - if (m_max_cost > 0 && (parent_cost + first_tile_cost + segment_cost) > m_max_cost) { - return false; - } - - if (first_tile_cost == 0) { - // we just have done first tile - first_tile_cost = segment_cost; - segment_cost = 0; - - // look if we can reuse existing (cached) segment cost - if (n.m_segment->m_cost >= 0) { - // reuse the cached segment cost - break; - } - } - // segment cost was not filled yes, we have not cached it yet - n.SetLastTileTrackdir(tile, trackdir); - - } // while (true) - - if (first_tile_cost == 0) { - // we have just finished first tile - first_tile_cost = segment_cost; - segment_cost = 0; - } - - // do we have cached segment cost? - if (n.m_segment->m_cost >= 0) { - // reuse the cached segment cost - segment_cost = n.m_segment->m_cost; - } else { - // save segment cost - n.m_segment->m_cost = segment_cost; - - // save end of segment back to the node - n.SetLastTileTrackdir(tile, trackdir); - } - - // special costs for the case we have reached our target - if (target_seen) { - n.flags_u.flags_s.m_targed_seen = true; - if (n.flags_u.flags_s.m_last_signal_was_red) { - if (n.m_last_red_signal_type == SIGTYPE_EXIT) { - // last signal was red pre-signal-exit - extra_cost += Yapf().PfGetSettings().rail_lastred_exit_penalty; - } else { - // last signal was red, but not exit - extra_cost += Yapf().PfGetSettings().rail_lastred_penalty; - } - } - } - - // total node cost - n.m_cost = parent_cost + first_tile_cost + segment_cost + extra_cost; - - return !n.m_segment->flags_u.flags_s.m_end_of_line; - } - - FORCEINLINE bool CanUseGlobalCache(Node& n) const - { - return (n.m_parent != NULL) - && (n.m_parent->m_num_signals_passed >= m_sig_look_ahead_costs.Size()); - } - - FORCEINLINE void ConnectNodeToCachedData(Node& n, CachedData& ci) - { - n.m_segment = &ci; - if (n.m_segment->m_cost < 0) { - n.m_segment->m_last_tile = n.m_key.m_tile; - n.m_segment->m_last_td = n.m_key.m_td; - } - } - -}; - - - -#endif /* YAPF_COSTRAIL_HPP */ |