Avoid some inefficiencies when handling ItemStack(Metadata)

This commit is contained in:
sfan5 2024-12-31 01:26:08 +01:00
parent d884a1624f
commit a2058f7f3a
7 changed files with 37 additions and 51 deletions

@ -874,7 +874,6 @@ void Hud::drawSelectionMesh()
{ {
if (m_mode == HIGHLIGHT_NONE || (m_mode == HIGHLIGHT_HALO && !m_selection_mesh)) if (m_mode == HIGHLIGHT_NONE || (m_mode == HIGHLIGHT_HALO && !m_selection_mesh))
return; return;
const video::SMaterial oldmaterial = driver->getMaterial2D();
driver->setMaterial(m_selection_material); driver->setMaterial(m_selection_material);
const core::matrix4 oldtransform = driver->getTransform(video::ETS_WORLD); const core::matrix4 oldtransform = driver->getTransform(video::ETS_WORLD);
@ -910,7 +909,6 @@ void Hud::drawSelectionMesh()
driver->drawMeshBuffer(buf); driver->drawMeshBuffer(buf);
} }
} }
driver->setMaterial(oldmaterial);
driver->setTransform(video::ETS_WORLD, oldtransform); driver->setTransform(video::ETS_WORLD, oldtransform);
} }
@ -935,17 +933,11 @@ void Hud::drawBlockBounds()
return; return;
} }
video::SMaterial old_material = driver->getMaterial2D();
driver->setMaterial(m_block_bounds_material); driver->setMaterial(m_block_bounds_material);
u16 mesh_chunk_size = std::max<u16>(1, g_settings->getU16("client_mesh_chunk")); u16 mesh_chunk_size = std::max<u16>(1, g_settings->getU16("client_mesh_chunk"));
v3s16 pos = player->getStandingNodePos(); v3s16 block_pos = getContainerPos(player->getStandingNodePos(), MAP_BLOCKSIZE);
v3s16 block_pos(
floorf((float) pos.X / MAP_BLOCKSIZE),
floorf((float) pos.Y / MAP_BLOCKSIZE),
floorf((float) pos.Z / MAP_BLOCKSIZE)
);
v3f cam_offset = intToFloat(client->getCamera()->getOffset(), BS); v3f cam_offset = intToFloat(client->getCamera()->getOffset(), BS);
@ -988,8 +980,6 @@ void Hud::drawBlockBounds()
choose_color(block_pos.Y, block_pos.Z) choose_color(block_pos.Y, block_pos.Z)
); );
} }
driver->setMaterial(old_material);
} }
void Hud::updateSelectionMesh(const v3s16 &camera_offset) void Hud::updateSelectionMesh(const v3s16 &camera_offset)

@ -85,8 +85,8 @@ void GUIInventoryList::draw()
v2s32 p((i % m_geom.X) * m_slot_spacing.X, v2s32 p((i % m_geom.X) * m_slot_spacing.X,
(i / m_geom.X) * m_slot_spacing.Y); (i / m_geom.X) * m_slot_spacing.Y);
core::rect<s32> rect = imgrect + base_pos + p; core::rect<s32> rect = imgrect + base_pos + p;
ItemStack item = ilist->getItem(item_i); const ItemStack &orig_item = ilist->getItem(item_i);
ItemStack orig_item = item; ItemStack item = orig_item;
bool selected = selected_item bool selected = selected_item
&& m_invmgr->getInventory(selected_item->inventoryloc) == inv && m_invmgr->getInventory(selected_item->inventoryloc) == inv

@ -88,12 +88,11 @@ void ItemStackMetadata::deSerialize(std::istream &is)
void ItemStackMetadata::updateToolCapabilities() void ItemStackMetadata::updateToolCapabilities()
{ {
if (contains(TOOLCAP_KEY)) { if (contains(TOOLCAP_KEY)) {
toolcaps_overridden = true;
toolcaps_override = ToolCapabilities(); toolcaps_override = ToolCapabilities();
std::istringstream is(getString(TOOLCAP_KEY)); std::istringstream is(getString(TOOLCAP_KEY));
toolcaps_override.deserializeJson(is); toolcaps_override->deserializeJson(is);
} else { } else {
toolcaps_overridden = false; toolcaps_override = std::nullopt;
} }
} }

@ -15,8 +15,7 @@ class IItemDefManager;
class ItemStackMetadata : public SimpleMetadata class ItemStackMetadata : public SimpleMetadata
{ {
public: public:
ItemStackMetadata(): ItemStackMetadata()
toolcaps_overridden(false)
{} {}
// Overrides // Overrides
@ -29,7 +28,7 @@ public:
const ToolCapabilities &getToolCapabilities( const ToolCapabilities &getToolCapabilities(
const ToolCapabilities &default_caps) const 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); void setToolCapabilities(const ToolCapabilities &caps);
@ -40,7 +39,6 @@ public:
return wear_bar_override; return wear_bar_override;
} }
void setWearBarParams(const WearBarParams &params); void setWearBarParams(const WearBarParams &params);
void clearWearBarParams(); void clearWearBarParams();
@ -48,7 +46,6 @@ private:
void updateToolCapabilities(); void updateToolCapabilities();
void updateWearBarParams(); void updateWearBarParams();
bool toolcaps_overridden; std::optional<ToolCapabilities> toolcaps_override;
ToolCapabilities toolcaps_override;
std::optional<WearBarParams> wear_bar_override; std::optional<WearBarParams> wear_bar_override;
}; };

@ -1594,7 +1594,7 @@ ToolCapabilities read_tool_capabilities(
// key at index -2 and value at index -1 // key at index -2 and value at index -1
int rating = luaL_checkinteger(L, -2); int rating = luaL_checkinteger(L, -2);
float time = luaL_checknumber(L, -1); float time = luaL_checknumber(L, -1);
groupcap.times[rating] = time; groupcap.times.emplace_back(rating, time);
// removes value, keeps key for next iteration // removes value, keeps key for next iteration
lua_pop(L, 1); lua_pop(L, 1);
} }

@ -47,7 +47,7 @@ void ToolGroupCap::fromJson(const Json::Value &json)
for (Json::ArrayIndex i = 0; i < size; ++i) { for (Json::ArrayIndex i = 0; i < size; ++i) {
if (times_object[i].isDouble()) 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++) { for(u32 i = 0; i < times_size; i++) {
int level = readS16(is); int level = readS16(is);
float time = readF32(is); float time = readF32(is);
cap.times[level] = time; cap.times.emplace_back(level, time);
} }
groupcaps[name] = cap; groupcaps[name] = cap;
} }
@ -272,21 +272,11 @@ std::optional<WearBarParams> WearBarParams::deserializeJson(std::istream &is)
return WearBarParams(colorStops, blend); return WearBarParams(colorStops, blend);
} }
video::SColor WearBarParams::getWearBarColor(f32 durabilityPercent) { video::SColor WearBarParams::getWearBarColor(f32 durabilityPercent)
{
if (colorStops.empty()) if (colorStops.empty())
return video::SColor(); 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); auto upper = colorStops.upper_bound(durabilityPercent);
if (upper == colorStops.end()) // durability is >= the highest defined color stop 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 if (upper == colorStops.begin()) // durability is <= the lowest defined color stop
return upper->second; return upper->second;
// between two values, interpolate
auto lower = std::prev(upper); auto lower = std::prev(upper);
f32 lower_bound = lower->first; f32 lower_bound = lower->first;
video::SColor lower_color = lower->second; video::SColor lower_color = lower->second;

@ -12,26 +12,33 @@
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <vector>
#include <map> #include <map>
#include <unordered_map>
#include <optional> #include <optional>
struct ItemDefinition; struct ItemDefinition;
class IItemDefManager; class IItemDefManager;
/*
* NOTE: these structs intentionally use vector<pair<>> 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 struct ToolGroupCap
{ {
std::unordered_map<int, float> times; std::vector<std::pair<int, float>> times;
int maxlevel = 1; int maxlevel = 1;
int uses = 20; int uses = 20;
ToolGroupCap() = default; ToolGroupCap() = default;
std::optional<float> getTime(int rating) const { std::optional<float> getTime(int rating) const {
auto i = times.find(rating); for (auto &it : times) {
if (i == times.end()) if (it.first == rating)
return std::nullopt; return it.second;
return i->second; }
return std::nullopt;
} }
void toJson(Json::Value &object) const; void toJson(Json::Value &object) const;
@ -39,16 +46,16 @@ struct ToolGroupCap
}; };
typedef std::unordered_map<std::string, struct ToolGroupCap> ToolGCMap; typedef std::map<std::string, ToolGroupCap> ToolGCMap;
typedef std::unordered_map<std::string, s16> DamageGroup; typedef std::map<std::string, s16> DamageGroup;
struct ToolCapabilities struct ToolCapabilities
{ {
float full_punch_interval; float full_punch_interval;
int max_drop_level; int max_drop_level;
int punch_attack_uses;
ToolGCMap groupcaps; ToolGCMap groupcaps;
DamageGroup damageGroups; DamageGroup damageGroups;
int punch_attack_uses;
ToolCapabilities( ToolCapabilities(
float full_punch_interval_ = 1.4f, float full_punch_interval_ = 1.4f,
@ -59,9 +66,9 @@ struct ToolCapabilities
): ):
full_punch_interval(full_punch_interval_), full_punch_interval(full_punch_interval_),
max_drop_level(max_drop_level_), max_drop_level(max_drop_level_),
punch_attack_uses(punch_attack_uses_),
groupcaps(groupcaps_), groupcaps(groupcaps_),
damageGroups(damageGroups_), damageGroups(damageGroups_)
punch_attack_uses(punch_attack_uses_)
{} {}
void serialize(std::ostream &os, u16 version) const; void serialize(std::ostream &os, u16 version) const;
@ -76,17 +83,18 @@ private:
struct WearBarParams struct WearBarParams
{ {
std::map<f32, video::SColor> colorStops;
enum BlendMode : u8 { enum BlendMode : u8 {
BLEND_MODE_CONSTANT, BLEND_MODE_CONSTANT,
BLEND_MODE_LINEAR, BLEND_MODE_LINEAR,
BlendMode_END // Dummy for validity check BlendMode_END // Dummy for validity check
}; };
constexpr const static EnumString es_BlendMode[3] = { constexpr const static EnumString es_BlendMode[3] = {
{WearBarParams::BLEND_MODE_CONSTANT, "constant"}, {BLEND_MODE_CONSTANT, "constant"},
{WearBarParams::BLEND_MODE_LINEAR, "linear"}, {BLEND_MODE_LINEAR, "linear"},
{0, nullptr} {0, nullptr}
}; };
std::map<f32, video::SColor> colorStops;
BlendMode blend; BlendMode blend;
WearBarParams(const std::map<f32, video::SColor> &colorStops, BlendMode blend): WearBarParams(const std::map<f32, video::SColor> &colorStops, BlendMode blend):
@ -102,6 +110,7 @@ struct WearBarParams
static WearBarParams deserialize(std::istream &is); static WearBarParams deserialize(std::istream &is);
void serializeJson(std::ostream &os) const; void serializeJson(std::ostream &os) const;
static std::optional<WearBarParams> deserializeJson(std::istream &is); static std::optional<WearBarParams> deserializeJson(std::istream &is);
video::SColor getWearBarColor(f32 durabilityPercent); video::SColor getWearBarColor(f32 durabilityPercent);
}; };