From 829a2c201ddb9727b159729595f6c16dab059d93 Mon Sep 17 00:00:00 2001 From: rubidium Date: Fri, 13 May 2011 18:04:10 +0000 Subject: [PATCH] (svn r22449) [1.1] -Backport from trunk: - Feature: [NewGRF] Allow to filter by town of the current industry when using industry variable 0x68 [FS#4591] (r22434) - Change: Improve the speed of YAPF by tweaking hash tables size (r22351, r22350, r22348) --- projects/openttd_vs100.vcxproj | 1 + projects/openttd_vs100.vcxproj.filters | 3 +++ projects/openttd_vs80.vcproj | 4 ++++ projects/openttd_vs90.vcproj | 4 ++++ source.list | 1 + src/misc/hashtable.hpp | 13 ++++------- src/newgrf_industries.cpp | 18 +++++++++++---- src/pathfinder/yapf/yapf_node.hpp | 17 -------------- src/pathfinder/yapf/yapf_node_rail.hpp | 4 ++-- src/pathfinder/yapf/yapf_node_road.hpp | 4 ++-- src/pathfinder/yapf/yapf_node_ship.hpp | 32 ++++++++++++++++++++++++++ src/pathfinder/yapf/yapf_ship.cpp | 1 + 12 files changed, 68 insertions(+), 34 deletions(-) create mode 100644 src/pathfinder/yapf/yapf_node_ship.hpp diff --git a/projects/openttd_vs100.vcxproj b/projects/openttd_vs100.vcxproj index edfda19459..fc708d54bd 100644 --- a/projects/openttd_vs100.vcxproj +++ b/projects/openttd_vs100.vcxproj @@ -1074,6 +1074,7 @@ + diff --git a/projects/openttd_vs100.vcxproj.filters b/projects/openttd_vs100.vcxproj.filters index 5e009c2088..05c0e40e87 100644 --- a/projects/openttd_vs100.vcxproj.filters +++ b/projects/openttd_vs100.vcxproj.filters @@ -2442,6 +2442,9 @@ YAPF + + YAPF + YAPF diff --git a/projects/openttd_vs80.vcproj b/projects/openttd_vs80.vcproj index 8b531142ae..34ad35501d 100644 --- a/projects/openttd_vs80.vcproj +++ b/projects/openttd_vs80.vcproj @@ -3662,6 +3662,10 @@ RelativePath=".\..\src\pathfinder\yapf\yapf_node_road.hpp" > + + diff --git a/projects/openttd_vs90.vcproj b/projects/openttd_vs90.vcproj index 4df272e64f..e9a52b2463 100644 --- a/projects/openttd_vs90.vcproj +++ b/projects/openttd_vs90.vcproj @@ -3659,6 +3659,10 @@ RelativePath=".\..\src\pathfinder\yapf\yapf_node_road.hpp" > + + diff --git a/source.list b/source.list index 3370af3cfd..723573fc1e 100644 --- a/source.list +++ b/source.list @@ -875,6 +875,7 @@ pathfinder/yapf/yapf_destrail.hpp pathfinder/yapf/yapf_node.hpp pathfinder/yapf/yapf_node_rail.hpp pathfinder/yapf/yapf_node_road.hpp +pathfinder/yapf/yapf_node_ship.hpp pathfinder/yapf/yapf_rail.cpp pathfinder/yapf/yapf_road.cpp pathfinder/yapf/yapf_ship.cpp diff --git a/src/misc/hashtable.hpp b/src/misc/hashtable.hpp index 46ef7ca478..d4b3eae8d6 100644 --- a/src/misc/hashtable.hpp +++ b/src/misc/hashtable.hpp @@ -145,20 +145,15 @@ protected: */ typedef CHashTableSlotT Slot; - Slot *m_slots; // here we store our data (array of blobs) - int m_num_items; // item counter + Slot m_slots[Tcapacity]; // here we store our data (array of blobs) + int m_num_items; // item counter public: /* default constructor */ - FORCEINLINE CHashTableT() + FORCEINLINE CHashTableT() : m_num_items(0) { - /* construct all slots */ - m_slots = new Slot[Tcapacity]; - m_num_items = 0; } - ~CHashTableT() {delete [] m_slots; m_num_items = 0; m_slots = NULL;} - protected: /** static helper - return hash for the given key modulo number of slots */ FORCEINLINE static int CalcHash(const Tkey& key) @@ -180,7 +175,7 @@ public: FORCEINLINE int Count() const {return m_num_items;} /** simple clear - forget all items - used by CSegmentCostCacheT.Flush() */ - FORCEINLINE void Clear() const {for (int i = 0; i < Tcapacity; i++) m_slots[i].Clear();} + FORCEINLINE void Clear() {for (int i = 0; i < Tcapacity; i++) m_slots[i].Clear();} /** const item search */ const Titem_ *Find(const Tkey& key) const diff --git a/src/newgrf_industries.cpp b/src/newgrf_industries.cpp index de051ad241..70cd0a2c15 100644 --- a/src/newgrf_industries.cpp +++ b/src/newgrf_industries.cpp @@ -106,10 +106,11 @@ static uint32 GetClosestIndustry(TileIndex tile, IndustryType type, const Indust * function. * @param param_setID parameter given to the callback, which is the set id, or the local id, in our terminology * @param layout_filter on what layout do we filter? + * @param town_filter Do we filter on the same town as the current industry? * @param current Industry for which the inquiry is made * @return the formatted answer to the callback : rr(reserved) cc(count) dddd(manhattan distance of closest sister) */ -static uint32 GetCountAndDistanceOfClosestInstance(byte param_setID, byte layout_filter, const Industry *current) +static uint32 GetCountAndDistanceOfClosestInstance(byte param_setID, byte layout_filter, bool town_filter, const Industry *current) { uint32 GrfID = GetRegister(0x100); ///< Get the GRFID of the definition to look for in register 100h IndustryType ind_index; @@ -135,7 +136,7 @@ static uint32 GetCountAndDistanceOfClosestInstance(byte param_setID, byte layout /* If the industry type is invalid, there is none and the closest is far away. */ if (ind_index >= NUM_INDUSTRYTYPES) return 0 | 0xFFFF; - if (layout_filter == 0) { + if (layout_filter == 0 && !town_filter) { /* If the filter is 0, it could be because none was specified as well as being really a 0. * In either case, just do the regular var67 */ closest_dist = GetClosestIndustry(current->location.tile, ind_index, current); @@ -145,7 +146,7 @@ static uint32 GetCountAndDistanceOfClosestInstance(byte param_setID, byte layout * Unfortunately, we have to do it manually */ const Industry *i; FOR_ALL_INDUSTRIES(i) { - if (i->type == ind_index && i != current && i->selected_layout == layout_filter) { + if (i->type == ind_index && i != current && (i->selected_layout == layout_filter || layout_filter == 0) && (!town_filter || i->town == current->town)) { closest_dist = min(closest_dist, DistanceManhattan(current->location.tile, i->location.tile)); count++; } @@ -264,7 +265,16 @@ uint32 IndustryGetVariable(const ResolverObject *object, byte variable, byte par /* Count of industry, distance of closest instance * 68 is the same as 67, but with a filtering on selected layout */ case 0x67: - case 0x68: return GetCountAndDistanceOfClosestInstance(parameter, variable == 0x68 ? GB(GetRegister(0x101), 0, 8) : 0, industry); + case 0x68: { + byte layout_filter = 0; + bool town_filter = false; + if (variable == 0x68) { + uint32 reg = GetRegister(0x101); + layout_filter = GB(reg, 0, 8); + town_filter = HasBit(reg, 8); + } + return GetCountAndDistanceOfClosestInstance(parameter, layout_filter, town_filter, industry); + } /* Get a variable from the persistent storage */ case 0x7C: return industry->psa.Get(parameter); diff --git a/src/pathfinder/yapf/yapf_node.hpp b/src/pathfinder/yapf/yapf_node.hpp index 0ed3748e57..0eb9802deb 100644 --- a/src/pathfinder/yapf/yapf_node.hpp +++ b/src/pathfinder/yapf/yapf_node.hpp @@ -81,21 +81,4 @@ struct CYapfNodeT { } }; -/** Yapf Node for ships */ -template -struct CYapfShipNodeT - : CYapfNodeT > -{ - -}; - -/* now define two major node types (that differ by key type) */ -typedef CYapfShipNodeT CYapfShipNodeExitDir; -typedef CYapfShipNodeT CYapfShipNodeTrackDir; - -/* Default NodeList types */ -typedef CNodeList_HashTableT CShipNodeListExitDir; -typedef CNodeList_HashTableT CShipNodeListTrackDir; - - #endif /* YAPF_NODE_HPP */ diff --git a/src/pathfinder/yapf/yapf_node_rail.hpp b/src/pathfinder/yapf/yapf_node_rail.hpp index 31149ec7c4..275133bd8a 100644 --- a/src/pathfinder/yapf/yapf_node_rail.hpp +++ b/src/pathfinder/yapf/yapf_node_rail.hpp @@ -291,7 +291,7 @@ typedef CYapfRailNodeT CYapfRailNodeExitDir; typedef CYapfRailNodeT CYapfRailNodeTrackDir; /* Default NodeList types */ -typedef CNodeList_HashTableT CRailNodeListExitDir; -typedef CNodeList_HashTableT CRailNodeListTrackDir; +typedef CNodeList_HashTableT CRailNodeListExitDir; +typedef CNodeList_HashTableT CRailNodeListTrackDir; #endif /* YAPF_NODE_RAIL_HPP */ diff --git a/src/pathfinder/yapf/yapf_node_road.hpp b/src/pathfinder/yapf/yapf_node_road.hpp index d93ece9ec3..5cc2d55398 100644 --- a/src/pathfinder/yapf/yapf_node_road.hpp +++ b/src/pathfinder/yapf/yapf_node_road.hpp @@ -35,7 +35,7 @@ typedef CYapfRoadNodeT CYapfRoadNodeExitDir; typedef CYapfRoadNodeT CYapfRoadNodeTrackDir; /* Default NodeList types */ -typedef CNodeList_HashTableT CRoadNodeListExitDir; -typedef CNodeList_HashTableT CRoadNodeListTrackDir; +typedef CNodeList_HashTableT CRoadNodeListExitDir; +typedef CNodeList_HashTableT CRoadNodeListTrackDir; #endif /* YAPF_NODE_ROAD_HPP */ diff --git a/src/pathfinder/yapf/yapf_node_ship.hpp b/src/pathfinder/yapf/yapf_node_ship.hpp new file mode 100644 index 0000000000..7a1358af68 --- /dev/null +++ b/src/pathfinder/yapf/yapf_node_ship.hpp @@ -0,0 +1,32 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * 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. + * 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. + * 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 . + */ + +/** @file yapf_node_ship.hpp Node tailored for ship pathfinding. */ + +#ifndef YAPF_NODE_SHIP_HPP +#define YAPF_NODE_SHIP_HPP + +/** Yapf Node for ships */ +template +struct CYapfShipNodeT + : CYapfNodeT > +{ + +}; + +/* now define two major node types (that differ by key type) */ +typedef CYapfShipNodeT CYapfShipNodeExitDir; +typedef CYapfShipNodeT CYapfShipNodeTrackDir; + +/* Default NodeList types */ +typedef CNodeList_HashTableT CShipNodeListExitDir; +typedef CNodeList_HashTableT CShipNodeListTrackDir; + + +#endif /* YAPF_NODE_SHIP_HPP */ diff --git a/src/pathfinder/yapf/yapf_ship.cpp b/src/pathfinder/yapf/yapf_ship.cpp index 51fc849440..69f1ce2c55 100644 --- a/src/pathfinder/yapf/yapf_ship.cpp +++ b/src/pathfinder/yapf/yapf_ship.cpp @@ -13,6 +13,7 @@ #include "../../ship.h" #include "yapf.hpp" +#include "yapf_node_ship.hpp" /** Node Follower module of YAPF for ships */ template