fix: stabilize block item registration and display

Store item names as owned strings in ItemManager, set block type
property for block items, validate item kind before placement, and
handle items without textures gracefully in inventory UI.
This commit is contained in:
2026-08-04 16:58:57 +08:00
parent 8af30e159d
commit 1514338144
8 changed files with 46 additions and 30 deletions

View File

@@ -40,6 +40,7 @@ private:
static inline IDMap m_id_map;
static inline bool is_init = false;
static inline CrossPlaneMap m_cross_plane_map;
static void set_up_cross_plane_map();
static void set_up_cross_plane_map(
const std::vector<std::pair<bool, BlockType>>& types);
};
} // namespace Cubed

View File

@@ -25,7 +25,7 @@ private:
using acc = ItemMap::accessor;
using cacc = ItemMap::const_accessor;
using IDMap = tbb::concurrent_hash_map<std::string_view, ItemID>;
using IDMap = tbb::concurrent_hash_map<std::string, ItemID>;
using BlockToIDMap = tbb::concurrent_hash_map<BlockType, ItemID>;
void add(const std::filesystem::path& path);

View File

@@ -47,7 +47,7 @@ private:
void load_block_status(unsigned status_id);
void load_block_texture(unsigned block_id);
void load_item_texture();
void init_item_texture();
void load_cross_plane_texture(unsigned id);
const Texture* load_image_texture(const std::string& path);
void load_pbr_texture(unsigned id);

View File

@@ -5,6 +5,7 @@
#include "Cubed/tools/log.hpp"
#include "Cubed/tools/toml.utils.hpp"
#include <algorithm>
#include <filesystem>
namespace fs = std::filesystem;
@@ -122,7 +123,7 @@ float BlockManager::roughness(BlockType id) {
void BlockManager::init() {
fs::path data_path{block_data_dir};
std::vector<std::pair<bool, BlockType>> types;
for (auto entry : fs::recursive_directory_iterator(data_path)) {
if (!entry.is_regular_file()) {
continue;
@@ -169,9 +170,12 @@ void BlockManager::init() {
if (!m_datas.emplace(static_cast<BlockType>(*id), std::move(data))) {
Logger::error("Block Type {} already exist!", *id);
}
m_id_map.emplace(*name, static_cast<BlockType>(*id));
types.emplace_back(*is_cross_plane, static_cast<BlockType>(*id));
}
set_up_cross_plane_map();
std::sort(types.begin(), types.end(),
[](const auto& a, const auto& b) { return a.second < b.second; });
set_up_cross_plane_map(types);
is_init = true;
}
@@ -197,11 +201,12 @@ BlockType BlockManager::id_from_name(const std::string& name) {
return 0;
}
void BlockManager::set_up_cross_plane_map() {
void BlockManager::set_up_cross_plane_map(
const std::vector<std::pair<bool, BlockType>>& types) {
unsigned cur_id = 0;
for (const auto& [id, data] : m_datas) {
if (data.is_cross_plane) {
m_cross_plane_map.emplace(data.id, cur_id);
for (auto id : types) {
if (id.first) {
m_cross_plane_map.emplace(id.second, cur_id);
cur_id++;
}

View File

@@ -79,6 +79,7 @@ void ItemManager::add(const std::filesystem::path& path) {
if (a->second.kind == ItemKind::BLOCK) {
BlockType b = BlockManager::id_from_name(a->second.name);
m_block_to_id_map.emplace(b, a->first);
a->second.property = b;
}
} else {
@@ -91,7 +92,7 @@ const ItemData& ItemManager::get_item_data(std::string_view key) const {
{
IDMap::const_accessor cacc;
if (m_id_map.find(cacc, key)) {
if (m_id_map.find(cacc, std::string(key))) {
id = cacc->second;
} else {
Logger::error("Can't Find key {} in id map", key);

View File

@@ -408,6 +408,7 @@ void LocalPlayer::place_block(float dt) {
}
if (m_mouse_state.right) {
auto& data = ItemManager::get(m_hotbar[m_selected_hotbar].id);
if (data.kind == ItemKind::BLOCK) {
auto* t = std::get_if<BlockType>(&data.property);
ASSERT(t);
auto type = *t;
@@ -423,6 +424,7 @@ void LocalPlayer::place_block(float dt) {
}
}
}
}
}
int LocalPlayer::selected_hotbar() const { return m_selected_hotbar; }

View File

@@ -122,9 +122,13 @@ void TextureManager::load_block_texture(unsigned id) {
}
}
void TextureManager::load_item_texture() {
void TextureManager::init_item_texture() {
for (ItemID i = 0; i < ItemManager::size(); ++i) {
auto& item = ItemManager::get(i);
if (item.path.empty()) {
m_item_textures.try_emplace(item.id, nullptr);
continue;
}
auto data = Tools::load_image_data(item.path);
std::unique_ptr<Texture> texture =
std::make_unique<Texture>(TextureType::TEXTURE_2D);
@@ -279,6 +283,7 @@ void TextureManager::init_texture() {
Logger::info("Map Init Success");
init_block();
init_item_texture();
init_block_status();
init_ui();
init_skin();

View File

@@ -1,12 +1,11 @@
#include "Cubed/ui/inventory_ui.hpp"
#include "Cubed/app.hpp"
#include "Cubed/gameplay/block_manager.hpp"
#include "Cubed/gameplay/item_manager.hpp"
#include "Cubed/scene/scene_manager.hpp"
#include "Cubed/scene/world_scene.hpp"
#include "Cubed/ui/column_layout.hpp"
#include "Cubed/ui/image.hpp"
namespace Cubed {
InventoryUI::InventoryUI(WorldScene& scene) : m_scene(scene) {}
@@ -22,12 +21,15 @@ void InventoryUI::init() {
column.set_anchor(Anchor::CENTER);
column.set_child_anchor(ColumnLayoutAnchor::LEFT);
auto& item_textures = texture_manager.get_item_textures();
auto sum = item_textures.size();
{
auto& row_layout = column.add_child<RowLayout>();
auto row = &row_layout;
size_t i = 0;
for (auto& [id, texture] : item_textures) {
if (id == 0) {
continue;
}
if (i % 10 == 0) {
auto& r = column.add_child<RowLayout>();
row = &r;
@@ -40,8 +42,6 @@ void InventoryUI::init() {
m_slots.emplace_back(&slot);
++i;
}
for (size_t i = 1; i < sum; ++i) {
}
}
{
auto& label = back->add_child<Label>();
@@ -97,10 +97,12 @@ void InventoryUI::update(float dt) {
void InventoryUI::update_item_info() {
auto show_item_info = [this](ItemSlot* slot) {
if (slot && !m_selected_image->has_texture()) {
auto type = slot->id();
if (type != 0) {
m_item_info->set_text(BlockManager::local_name(type))
.set_visible(true);
auto& data = ItemManager::get(type);
m_item_info->set_text(data.name).set_visible(true);
return true;
}
}