From a2058f7f3a2d2c95c6b6effdf161e326c8d2f35c Mon Sep 17 00:00:00 2001 From: sfan5 Date: Tue, 31 Dec 2024 01:26:08 +0100 Subject: [PATCH] Avoid some inefficiencies when handling ItemStack(Metadata) --- src/client/hud.cpp | 12 +---------- src/gui/guiInventoryList.cpp | 4 ++-- src/itemstackmetadata.cpp | 5 ++--- src/itemstackmetadata.h | 9 +++----- src/script/common/c_content.cpp | 2 +- src/tool.cpp | 19 +++++------------ src/tool.h | 37 ++++++++++++++++++++------------- 7 files changed, 37 insertions(+), 51 deletions(-) diff --git a/src/client/hud.cpp b/src/client/hud.cpp index 0aa847cb7..e0b4e83fc 100644 --- a/src/client/hud.cpp +++ b/src/client/hud.cpp @@ -874,7 +874,6 @@ void Hud::drawSelectionMesh() { if (m_mode == HIGHLIGHT_NONE || (m_mode == HIGHLIGHT_HALO && !m_selection_mesh)) return; - const video::SMaterial oldmaterial = driver->getMaterial2D(); driver->setMaterial(m_selection_material); const core::matrix4 oldtransform = driver->getTransform(video::ETS_WORLD); @@ -910,7 +909,6 @@ void Hud::drawSelectionMesh() driver->drawMeshBuffer(buf); } } - driver->setMaterial(oldmaterial); driver->setTransform(video::ETS_WORLD, oldtransform); } @@ -935,17 +933,11 @@ void Hud::drawBlockBounds() return; } - video::SMaterial old_material = driver->getMaterial2D(); driver->setMaterial(m_block_bounds_material); u16 mesh_chunk_size = std::max(1, g_settings->getU16("client_mesh_chunk")); - v3s16 pos = player->getStandingNodePos(); - v3s16 block_pos( - floorf((float) pos.X / MAP_BLOCKSIZE), - floorf((float) pos.Y / MAP_BLOCKSIZE), - floorf((float) pos.Z / MAP_BLOCKSIZE) - ); + v3s16 block_pos = getContainerPos(player->getStandingNodePos(), MAP_BLOCKSIZE); v3f cam_offset = intToFloat(client->getCamera()->getOffset(), BS); @@ -988,8 +980,6 @@ void Hud::drawBlockBounds() choose_color(block_pos.Y, block_pos.Z) ); } - - driver->setMaterial(old_material); } void Hud::updateSelectionMesh(const v3s16 &camera_offset) diff --git a/src/gui/guiInventoryList.cpp b/src/gui/guiInventoryList.cpp index 28d482994..3b839c7af 100644 --- a/src/gui/guiInventoryList.cpp +++ b/src/gui/guiInventoryList.cpp @@ -85,8 +85,8 @@ void GUIInventoryList::draw() v2s32 p((i % m_geom.X) * m_slot_spacing.X, (i / m_geom.X) * m_slot_spacing.Y); core::rect rect = imgrect + base_pos + p; - ItemStack item = ilist->getItem(item_i); - ItemStack orig_item = item; + const ItemStack &orig_item = ilist->getItem(item_i); + ItemStack item = orig_item; bool selected = selected_item && m_invmgr->getInventory(selected_item->inventoryloc) == inv diff --git a/src/itemstackmetadata.cpp b/src/itemstackmetadata.cpp index 9262a784d..a75f1ae29 100644 --- a/src/itemstackmetadata.cpp +++ b/src/itemstackmetadata.cpp @@ -88,12 +88,11 @@ void ItemStackMetadata::deSerialize(std::istream &is) void ItemStackMetadata::updateToolCapabilities() { if (contains(TOOLCAP_KEY)) { - toolcaps_overridden = true; toolcaps_override = ToolCapabilities(); std::istringstream is(getString(TOOLCAP_KEY)); - toolcaps_override.deserializeJson(is); + toolcaps_override->deserializeJson(is); } else { - toolcaps_overridden = false; + toolcaps_override = std::nullopt; } } diff --git a/src/itemstackmetadata.h b/src/itemstackmetadata.h index c49e812ba..c3eda83ed 100644 --- a/src/itemstackmetadata.h +++ b/src/itemstackmetadata.h @@ -15,8 +15,7 @@ class IItemDefManager; class ItemStackMetadata : public SimpleMetadata { public: - ItemStackMetadata(): - toolcaps_overridden(false) + ItemStackMetadata() {} // Overrides @@ -29,7 +28,7 @@ public: const ToolCapabilities &getToolCapabilities( const ToolCapabilities &default_caps) const { - return toolcaps_overridden ? toolcaps_override : default_caps; + return toolcaps_override.has_value() ? *toolcaps_override : default_caps; } void setToolCapabilities(const ToolCapabilities &caps); @@ -40,7 +39,6 @@ public: return wear_bar_override; } - void setWearBarParams(const WearBarParams ¶ms); void clearWearBarParams(); @@ -48,7 +46,6 @@ private: void updateToolCapabilities(); void updateWearBarParams(); - bool toolcaps_overridden; - ToolCapabilities toolcaps_override; + std::optional toolcaps_override; std::optional wear_bar_override; }; diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 5f000acd8..e343d50db 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -1594,7 +1594,7 @@ ToolCapabilities read_tool_capabilities( // key at index -2 and value at index -1 int rating = luaL_checkinteger(L, -2); float time = luaL_checknumber(L, -1); - groupcap.times[rating] = time; + groupcap.times.emplace_back(rating, time); // removes value, keeps key for next iteration lua_pop(L, 1); } diff --git a/src/tool.cpp b/src/tool.cpp index 7f32e63d4..43b3ebe25 100644 --- a/src/tool.cpp +++ b/src/tool.cpp @@ -47,7 +47,7 @@ void ToolGroupCap::fromJson(const Json::Value &json) for (Json::ArrayIndex i = 0; i < size; ++i) { if (times_object[i].isDouble()) - times[i] = times_object[i].asFloat(); + times.emplace_back(i, times_object[i].asFloat()); } } @@ -106,7 +106,7 @@ void ToolCapabilities::deSerialize(std::istream &is) for(u32 i = 0; i < times_size; i++) { int level = readS16(is); float time = readF32(is); - cap.times[level] = time; + cap.times.emplace_back(level, time); } groupcaps[name] = cap; } @@ -272,21 +272,11 @@ std::optional WearBarParams::deserializeJson(std::istream &is) return WearBarParams(colorStops, blend); } -video::SColor WearBarParams::getWearBarColor(f32 durabilityPercent) { +video::SColor WearBarParams::getWearBarColor(f32 durabilityPercent) +{ if (colorStops.empty()) return video::SColor(); - /* - * Strategy: - * Find upper bound of durabilityPercent - * - * if it == stops.end() -> return last color in the map - * if it == stops.begin() -> return first color in the map - * - * else: - * lower_bound = it - 1 - * interpolate/do constant - */ auto upper = colorStops.upper_bound(durabilityPercent); if (upper == colorStops.end()) // durability is >= the highest defined color stop @@ -295,6 +285,7 @@ video::SColor WearBarParams::getWearBarColor(f32 durabilityPercent) { if (upper == colorStops.begin()) // durability is <= the lowest defined color stop return upper->second; + // between two values, interpolate auto lower = std::prev(upper); f32 lower_bound = lower->first; video::SColor lower_color = lower->second; diff --git a/src/tool.h b/src/tool.h index b2e8c7ae5..62b374d91 100644 --- a/src/tool.h +++ b/src/tool.h @@ -12,26 +12,33 @@ #include #include +#include #include -#include #include struct ItemDefinition; class IItemDefManager; +/* + * NOTE: these structs intentionally use vector> or map<> over unordered_map<> + * to avoid blowing up the structure sizes. Also because the linear "dumb" approach + * works better if you have just a handful of items. + */ + struct ToolGroupCap { - std::unordered_map times; + std::vector> times; int maxlevel = 1; int uses = 20; ToolGroupCap() = default; std::optional getTime(int rating) const { - auto i = times.find(rating); - if (i == times.end()) - return std::nullopt; - return i->second; + for (auto &it : times) { + if (it.first == rating) + return it.second; + } + return std::nullopt; } void toJson(Json::Value &object) const; @@ -39,16 +46,16 @@ struct ToolGroupCap }; -typedef std::unordered_map ToolGCMap; -typedef std::unordered_map DamageGroup; +typedef std::map ToolGCMap; +typedef std::map DamageGroup; struct ToolCapabilities { float full_punch_interval; int max_drop_level; + int punch_attack_uses; ToolGCMap groupcaps; DamageGroup damageGroups; - int punch_attack_uses; ToolCapabilities( float full_punch_interval_ = 1.4f, @@ -59,9 +66,9 @@ struct ToolCapabilities ): full_punch_interval(full_punch_interval_), max_drop_level(max_drop_level_), + punch_attack_uses(punch_attack_uses_), groupcaps(groupcaps_), - damageGroups(damageGroups_), - punch_attack_uses(punch_attack_uses_) + damageGroups(damageGroups_) {} void serialize(std::ostream &os, u16 version) const; @@ -76,17 +83,18 @@ private: struct WearBarParams { - std::map colorStops; enum BlendMode : u8 { BLEND_MODE_CONSTANT, BLEND_MODE_LINEAR, BlendMode_END // Dummy for validity check }; constexpr const static EnumString es_BlendMode[3] = { - {WearBarParams::BLEND_MODE_CONSTANT, "constant"}, - {WearBarParams::BLEND_MODE_LINEAR, "linear"}, + {BLEND_MODE_CONSTANT, "constant"}, + {BLEND_MODE_LINEAR, "linear"}, {0, nullptr} }; + + std::map colorStops; BlendMode blend; WearBarParams(const std::map &colorStops, BlendMode blend): @@ -102,6 +110,7 @@ struct WearBarParams static WearBarParams deserialize(std::istream &is); void serializeJson(std::ostream &os) const; static std::optional deserializeJson(std::istream &is); + video::SColor getWearBarColor(f32 durabilityPercent); };