From 829e724a2c28c9162f738821b1da5a4eb5400ebb Mon Sep 17 00:00:00 2001 From: Dmitry Date: Mon, 29 Jul 2019 23:11:49 +0300 Subject: [PATCH] Minor fixes. --- include/crlib/cr-array.h | 36 +++++++++++++++----- include/crlib/cr-binheap.h | 50 ++++++++++++++++----------- include/crlib/cr-http.h | 4 +-- include/crlib/cr-string.h | 4 +-- include/crlib/cr-twin.h | 8 ----- include/crlib/cr-ulz.h | 4 +-- include/yapb.h | 70 ++++++++++++++++++++++---------------- source/graph.cpp | 10 +++--- source/manager.cpp | 38 ++++++++++----------- 9 files changed, 127 insertions(+), 97 deletions(-) diff --git a/include/crlib/cr-array.h b/include/crlib/cr-array.h index e522ae2..a0e44b9 100644 --- a/include/crlib/cr-array.h +++ b/include/crlib/cr-array.h @@ -14,23 +14,29 @@ #include #include +#include + // policy to reserve memory CR_DECLARE_SCOPED_ENUM (ReservePolicy, - MultipleByTwo, - PlusOne + Mutiple, + Single, ); CR_NAMESPACE_BEGIN // simple array class like std::vector -template class Array : public DenyCopying { +template class Array : public DenyCopying { public: T *m_data = nullptr; size_t m_capacity = 0; size_t m_length = 0; public: - explicit Array () = default; + explicit Array () { + if (fix (S > 0)) { + reserve (S); + } + } Array (const size_t amount) { reserve (amount); @@ -44,6 +50,12 @@ public: rhs.reset (); } + Array (std::initializer_list list) { + for (const auto &elem : list) { + push (elem); + } + } + ~Array () { destroy (); } @@ -79,9 +91,9 @@ public: if (m_length + amount < m_capacity) { return true; } - auto capacity = m_capacity ? m_capacity : 8; + auto capacity = m_capacity ? m_capacity : 12; - if (cr::fix (R == ReservePolicy::MultipleByTwo)) { + if (cr::fix (R == ReservePolicy::Mutiple)) { while (m_length + amount > capacity) { capacity *= 2; } @@ -110,10 +122,10 @@ public: if (!ensure (amount)) { return false; } - size_t pushLength = amount - m_length; + size_t resizeLength = amount - m_length; - for (size_t i = 0; i < pushLength; ++i) { - push (T ()); + while (resizeLength--) { + emplace (); } } return true; @@ -193,6 +205,9 @@ public: if (index + count > m_capacity) { return false; } + for (size_t i = m_length; i < m_length + count; i++) { + alloc.destruct (&m_data[i]); + } m_length -= count; for (size_t i = index; i < m_length; ++i) { @@ -386,5 +401,8 @@ public: } }; +// small array (with minimal reserve policy, something like fixed array, but still able to grow, by default allocates 64 elements) +template using SmallArray = Array ; + CR_NAMESPACE_END diff --git a/include/crlib/cr-binheap.h b/include/crlib/cr-binheap.h index d3c2767..f1fb7e6 100644 --- a/include/crlib/cr-binheap.h +++ b/include/crlib/cr-binheap.h @@ -84,35 +84,39 @@ public: private: void percolateUp (size_t index) { while (index != 0) { - size_t parent = this->parent (index); + size_t parentIndex = parent (index); - if (m_data[parent] <= m_data[index]) { + if (m_data[parentIndex] > m_data[index]) { + cr::swap (m_data[index], m_data[parentIndex]); + index = parentIndex; + } + else { break; } - cr::swap (m_data[index], m_data[parent]); - index = parent; } } void percolateDown (size_t index) { - while (this->left (index) < m_data.length ()) { - size_t best = this->left (index); + while (hasLeft (index)) { + size_t bestIndex = left (index); - if (this->right (index) < m_data.length ()) { - size_t right_index = this->right (index); + if (hasRight (index)) { + size_t rightIndex = right (index); - if (m_data[right_index] < m_data[best]) { - best = right_index; + if (m_data[rightIndex] < m_data[bestIndex]) { + bestIndex = rightIndex; } } - if (m_data[index] <= m_data[best]) { + if (m_data[index] > m_data[bestIndex]) { + cr::swap (m_data[index], m_data[bestIndex]); + + index = bestIndex; + bestIndex = left (index); + } + else { break; } - cr::swap (m_data[index], m_data[best]); - - index = best; - best = this->left (index); } } @@ -125,16 +129,24 @@ private: } private: + static constexpr size_t parent (size_t index) { + return (index - 1) / 2; + } + static constexpr size_t left (size_t index) { - return index << 1 | 1; + return (index * 2) + 1; } static constexpr size_t right (size_t index) { - return ++index << 1; + return (index * 2) + 2; } - static constexpr size_t parent (size_t index) { - return --index >> 1; + bool hasLeft (size_t index) const { + return left (index) < m_data.length (); + } + + bool hasRight (size_t index) const { + return right (index) < m_data.length (); } }; diff --git a/include/crlib/cr-http.h b/include/crlib/cr-http.h index 1c20711..55f7677 100644 --- a/include/crlib/cr-http.h +++ b/include/crlib/cr-http.h @@ -275,7 +275,7 @@ public: return false; } - Array buffer (m_chunkSize); + SmallArray buffer (m_chunkSize); m_code = parseResponseHeader (buffer.data ()); if (m_code != HttpClientResult::OK) { @@ -379,7 +379,7 @@ public: return false; } - Array buffer (m_chunkSize); + SmallArray buffer (m_chunkSize); int32 length = 0; for (;;) { diff --git a/include/crlib/cr-string.h b/include/crlib/cr-string.h index 2764d42..9fbaf4f 100644 --- a/include/crlib/cr-string.h +++ b/include/crlib/cr-string.h @@ -266,7 +266,7 @@ public: template String &assignf (const char *fmt, Args ...args) { const size_t size = snprintf (nullptr, 0, fmt, args...); - Array buffer (size + 1); + SmallArray buffer (size + 1); snprintf (buffer.data (), size + 1, fmt, cr::forward (args)...); return assign (buffer.data ()); @@ -278,7 +278,7 @@ public: } const size_t size = snprintf (nullptr, 0, fmt, args...) + length (); - Array buffer (size + 1); + SmallArray buffer (size + 1); snprintf (buffer.data (), size + 1, fmt, cr::forward (args)...); return append (buffer.data ()); diff --git a/include/crlib/cr-twin.h b/include/crlib/cr-twin.h index 1b3f8ae..ff53dd8 100644 --- a/include/crlib/cr-twin.h +++ b/include/crlib/cr-twin.h @@ -50,17 +50,9 @@ public: return a.second < b.second; } - friend bool operator <= (const Twin &a, const Twin &b) { - return a.second <= b.second; - } - friend bool operator > (const Twin &a, const Twin &b) { return b.second < a.second; } - - friend bool operator >= (const Twin &a, const Twin &b) { - return b.second <= a.second; - } }; // creating pairs diff --git a/include/crlib/cr-ulz.h b/include/crlib/cr-ulz.h index 5b3cb80..6e7233c 100644 --- a/include/crlib/cr-ulz.h +++ b/include/crlib/cr-ulz.h @@ -37,8 +37,8 @@ private: private: - Array m_hashTable; - Array m_prevTable; + SmallArray m_hashTable; + SmallArray m_prevTable; public: ULZ () { diff --git a/include/yapb.h b/include/yapb.h index a8dc029..45071a0 100644 --- a/include/yapb.h +++ b/include/yapb.h @@ -1296,10 +1296,11 @@ private: Array m_activeGrenades; // holds currently active grenades on the map Array m_intrestingEntities; // holds currently intresting entities on the map - Array m_creationTab; // bot creation tab - Array m_filters; // task filters - Array m_bots; // all available bots + SmallArray m_creationTab; // bot creation tab + SmallArray m_filters; // task filters + SmallArray m_bots; // all available bots + edict_t *m_killerEntity; // killer entity for bots protected: @@ -1389,7 +1390,7 @@ public: } // get the list of filters - Array &getFilters () { + SmallArray &getFilters () { return m_filters; } @@ -1552,11 +1553,11 @@ private: IntArray m_rescuePoints; IntArray m_visitedGoals; - Array m_buckets[kMaxBucketsInsidePos][kMaxBucketsInsidePos][kMaxBucketsInsidePos]; - Array m_matrix; - Array m_practice; - Array m_paths; - Array m_vistable; + SmallArray m_buckets[kMaxBucketsInsidePos][kMaxBucketsInsidePos][kMaxBucketsInsidePos]; + SmallArray m_matrix; + SmallArray m_practice; + SmallArray m_paths; + SmallArray m_vistable; String m_tempStrings; edict_t *m_editor; @@ -1595,8 +1596,8 @@ public: bool saveGraphData (); bool loadGraphData (); - template bool saveStorage (const String &ext, const String &name, StorageOption options, StorageVersion version, const Array &data, uint8 *blob); - template bool loadStorage (const String &ext, const String &name, StorageOption options, StorageVersion version, Array &data, uint8 *blob, int32 *outOptions); + template bool saveStorage (const String &ext, const String &name, StorageOption options, StorageVersion version, const SmallArray &data, uint8 *blob); + template bool loadStorage (const String &ext, const String &name, StorageOption options, StorageVersion version, SmallArray &data, uint8 *blob, int32 *outOptions); void saveOldFormat (); void initGraph (); @@ -1641,7 +1642,7 @@ public: Bucket locateBucket (const Vector &pos); IntArray searchRadius (float radius, const Vector &origin, int maxCount = -1); - const Array &getNodesInBucket (const Vector &pos); + const SmallArray &getNodesInBucket (const Vector &pos); public: int getHighestDamageForTeam (int team) const { @@ -1719,19 +1720,18 @@ private: Array m_botNames; Array m_replies; - Array m_weapons; - Array m_weaponProps; + SmallArray m_weapons; + SmallArray m_weaponProps; StringArray m_logos; StringArray m_avatars; // default tables for personality weapon preferences, overridden by general.cfg - int m_normalWeaponPrefs[kNumWeapons] = { 0, 2, 1, 4, 5, 6, 3, 12, 10, 24, 25, 13, 11, 8, 7, 22, 23, 18, 21, 17, 19, 15, 17, 9, 14, 16 }; - int m_rusherWeaponPrefs[kNumWeapons] = { 0, 2, 1, 4, 5, 6, 3, 24, 19, 22, 23, 20, 21, 10, 12, 13, 7, 8, 11, 9, 18, 17, 19, 25, 15, 16 }; - int m_carefulWeaponPrefs[kNumWeapons] = { 0, 2, 1, 4, 25, 6, 3, 7, 8, 12, 10, 13, 11, 9, 24, 18, 14, 17, 16, 15, 19, 20, 21, 22, 23, 5 }; - int m_grenadeBuyPrecent[kNumWeapons - 23] = { 95, 85, 60 }; - int m_botBuyEconomyTable[kNumWeapons - 15] = { 1900, 2100, 2100, 4000, 6000, 7000, 16000, 1200, 800, 1000, 3000 }; - int *m_weaponPrefs[3] = { m_normalWeaponPrefs, m_rusherWeaponPrefs, m_carefulWeaponPrefs }; + SmallArray m_normalWeaponPrefs = { 0, 2, 1, 4, 5, 6, 3, 12, 10, 24, 25, 13, 11, 8, 7, 22, 23, 18, 21, 17, 19, 15, 17, 9, 14, 16 }; + SmallArray m_rusherWeaponPrefs = { 0, 2, 1, 4, 5, 6, 3, 24, 19, 22, 23, 20, 21, 10, 12, 13, 7, 8, 11, 9, 18, 17, 19, 25, 15, 16 }; + SmallArray m_carefulWeaponPrefs = { 0, 2, 1, 4, 25, 6, 3, 7, 8, 12, 10, 13, 11, 9, 24, 18, 14, 17, 16, 15, 19, 20, 21, 22, 23, 5 }; + SmallArray m_botBuyEconomyTable = { 1900, 2100, 2100, 4000, 6000, 7000, 16000, 1200, 800, 1000, 3000 }; + SmallArray m_grenadeBuyPrecent = { 95, 85, 60 }; public: BotConfig (); @@ -1822,7 +1822,7 @@ public: } // get's the weapon info data - Array &getWeapons () { + SmallArray &getWeapons () { return m_weapons; } @@ -1842,13 +1842,23 @@ public: } // get's weapon preferences for personality - int *getWeaponPrefs (int personality) const { - return m_weaponPrefs[personality]; + int32 *getWeaponPrefs (int personality) const { + switch (personality) { + case Personality::Normal: + default: + return m_normalWeaponPrefs.data (); + + case Personality::Rusher: + return m_rusherWeaponPrefs.data (); + + case Personality::Careful: + return m_carefulWeaponPrefs.data (); + } } // get economics value - int *getEconLimit () { - return m_botBuyEconomyTable; + int32 *getEconLimit () { + return m_botBuyEconomyTable.data (); } // get's grenade buy percents @@ -1881,8 +1891,8 @@ private: float m_welcomeReceiveTime; StringArray m_sentences; - Array m_clients; - Array > m_tags; + SmallArray m_clients; + SmallArray > m_tags; public: BotUtils (); @@ -1966,12 +1976,12 @@ public: } // get array of clients - Array &getClients () { + SmallArray &getClients () { return m_clients; } // get clients as const-reference - const Array &getClients () const { + const SmallArray &getClients () const { return m_clients; } @@ -2146,7 +2156,7 @@ public: m_args.clear (); for (int i = 0; i < engfuncs.pfnCmd_Argc (); i++) { - m_args.push (engfuncs.pfnCmd_Argv (i)); + m_args.emplace (engfuncs.pfnCmd_Argv (i)); } } diff --git a/source/graph.cpp b/source/graph.cpp index 195ed05..e297405 100644 --- a/source/graph.cpp +++ b/source/graph.cpp @@ -1357,7 +1357,7 @@ bool BotGraph::convertOldFormat () { return true; } -template bool BotGraph::saveStorage (const String &ext, const String &name, StorageOption options, StorageVersion version, const Array &data, uint8 *blob) { +template bool BotGraph::saveStorage (const String &ext, const String &name, StorageOption options, StorageVersion version, const SmallArray &data, uint8 *blob) { bool isGraph = (ext == "graph"); String filename; @@ -1387,7 +1387,7 @@ template bool BotGraph::saveStorage (const String &ext, const Strin ULZ lz; size_t rawLength = data.length () * sizeof (U); - Array compressed (rawLength + sizeof (uint8) * ULZ::Excess); + SmallArray compressed (rawLength + sizeof (uint8) * ULZ::Excess); // try to compress auto compressedLength = lz.compress (reinterpret_cast (data.data ()), rawLength, reinterpret_cast (compressed.data ())); @@ -1421,7 +1421,7 @@ template bool BotGraph::saveStorage (const String &ext, const Strin return true; } -template bool BotGraph::loadStorage (const String &ext, const String &name, StorageOption options, StorageVersion version, Array &data, uint8 *blob, int32 *outOptions) { +template bool BotGraph::loadStorage (const String &ext, const String &name, StorageOption options, StorageVersion version, SmallArray &data, uint8 *blob, int32 *outOptions) { String filename; filename.assignf ("%s.%s", game.getMapName (), ext.chars ()).lowercase (); @@ -1552,7 +1552,7 @@ template bool BotGraph::loadStorage (const String &ext, const Strin if ((hdr.options & options) != options) { return bailout ("Incorrect storage format for %s (filename: '%s').", name.chars (), filename.chars ()); } - Array compressed (hdr.compressed + sizeof (uint8) * ULZ::Excess); + SmallArray compressed (hdr.compressed + sizeof (uint8) * ULZ::Excess); // graph is not resized upon load if (isGraph) { @@ -2741,7 +2741,7 @@ BotGraph::Bucket BotGraph::locateBucket (const Vector &pos) { }; } -const Array &BotGraph::getNodesInBucket (const Vector &pos) { +const SmallArray &BotGraph::getNodesInBucket (const Vector &pos) { const auto &bucket = locateBucket (pos); return m_buckets[bucket.x][bucket.y][bucket.z]; } diff --git a/source/manager.cpp b/source/manager.cpp index 23b577e..1afc0ae 100644 --- a/source/manager.cpp +++ b/source/manager.cpp @@ -1660,13 +1660,16 @@ void BotConfig::loadNamesConfig () { void BotConfig::loadWeaponsConfig () { setupMemoryFiles (); - auto addWeaponEntries = [] (Array &weapons, size_t max, bool as, const String &name, const StringArray &data) { - if (data.length () != max) { - logger.error ("%s entry in weapons config is not valid or malformed.", name.chars ()); + auto addWeaponEntries = [] (SmallArray &weapons, bool as, const String &name, const StringArray &data) { + + // we're have null terminator element in weapons array... + if (data.length () + 1 != weapons.length ()) { + logger.error ("%s entry in weapons config is not valid or malformed (%d/%d).", name.chars (), data.length (), weapons.length ()); + return; } - for (size_t i = 0; i < max; ++i) { + for (size_t i = 0; i < data.length (); ++i) { if (as) { weapons[i].teamAS = data[i].int_ (); } @@ -1676,13 +1679,13 @@ void BotConfig::loadWeaponsConfig () { } }; - auto addIntEntries = [] (int *to, size_t max, const String &name, const StringArray &data) { - if (data.length () != max) { - logger.error ("%s entry in weapons config is not valid or malformed.", name.chars ()); + auto addIntEntries = [] (SmallArray &to, const String &name, const StringArray &data) { + if (data.length () != to.length ()) { + logger.error ("%s entry in weapons config is not valid or malformed (%d/%d).", name.chars (), data.length (), to.length ()); return; } - for (size_t i = 0; i < max; ++i) { + for (size_t i = 0; i < to.length (); ++i) { to[i] = data[i].int_ (); } }; @@ -1709,35 +1712,30 @@ void BotConfig::loadWeaponsConfig () { auto splitted = pair[1].split (","); if (pair[0].startsWith ("MapStandard")) { - addWeaponEntries (m_weapons, kNumWeapons, false, pair[0], splitted); + addWeaponEntries (m_weapons, false, pair[0], splitted); } else if (pair[0].startsWith ("MapAS")) { - addWeaponEntries (m_weapons, kNumWeapons, true, pair[0], splitted); + addWeaponEntries (m_weapons, true, pair[0], splitted); } else if (pair[0].startsWith ("GrenadePercent")) { - addIntEntries (m_grenadeBuyPrecent, 3, pair[0], splitted); + addIntEntries (m_grenadeBuyPrecent, pair[0], splitted); } else if (pair[0].startsWith ("Economics")) { - addIntEntries (m_botBuyEconomyTable, 11, pair[0], splitted); + addIntEntries (m_botBuyEconomyTable, pair[0], splitted); } else if (pair[0].startsWith ("PersonalityNormal")) { - addIntEntries (m_normalWeaponPrefs, kNumWeapons, pair[0], splitted); + addIntEntries (m_normalWeaponPrefs, pair[0], splitted); } else if (pair[0].startsWith ("PersonalityRusher")) { - addIntEntries (m_rusherWeaponPrefs, kNumWeapons, pair[0], splitted); + addIntEntries (m_rusherWeaponPrefs, pair[0], splitted); } else if (pair[0].startsWith ("PersonalityCareful")) { - addIntEntries (m_carefulWeaponPrefs, kNumWeapons, pair[0], splitted); + addIntEntries (m_carefulWeaponPrefs, pair[0], splitted); } } file.close (); } - - // set personality weapon pointers here - m_weaponPrefs[Personality::Normal] = reinterpret_cast (&m_normalWeaponPrefs); - m_weaponPrefs[Personality::Rusher] = reinterpret_cast (&m_rusherWeaponPrefs); - m_weaponPrefs[Personality::Careful] = reinterpret_cast (&m_carefulWeaponPrefs); } void BotConfig::loadChatterConfig () {