Skip to content

Commit

Permalink
[InventoryWidget] Avoid reallocating items to prevent Vulkan crash.
Browse files Browse the repository at this point in the history
  • Loading branch information
Unarelith committed Oct 29, 2023
1 parent 699d3bf commit fa79a67
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 27 deletions.
36 changes: 27 additions & 9 deletions source/client/gui/InventoryWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void InventoryWidget::scroll(float scrolling) {
if (offset + size > m_inventory->width() * m_inventory->height())
size = u16(m_inventory->width() * m_inventory->height() - offset);

loadItemWidgets(offset, size, m_lastSearch);
updateItemWidgets(offset, size, m_lastSearch);
}

void InventoryWidget::onEvent(const SDL_Event &event) {
Expand Down Expand Up @@ -87,7 +87,7 @@ void InventoryWidget::update() {

void InventoryWidget::applySearch(const std::string &search) {
if (search != m_lastSearch) {
loadItemWidgets(m_offset, m_size, search);
updateItemWidgets(m_offset, m_size, search);
m_lastSearch = search;
}
}
Expand Down Expand Up @@ -141,7 +141,7 @@ void InventoryWidget::draw(RenderTarget &target, RenderStates states) const {
target.draw(m_selectedItemBackground, states);
}

void InventoryWidget::loadItemWidgets(u16 offset, u16 size, std::string search) {
void InventoryWidget::loadItemWidgets(u16 offset, u16 size) {
m_itemWidgets.clear();

u16 itemCounter = 0;
Expand All @@ -151,18 +151,36 @@ void InventoryWidget::loadItemWidgets(u16 offset, u16 size, std::string search)
if (x >= m_inventory->width() || y >= m_inventory->height())
break;

m_itemWidgets.emplace_back(*m_inventory, x, y, this);

ItemWidget &widget = m_itemWidgets.back();
widget.update();
widget.setPosition((itemCounter % m_inventory->width()) * 18.f, (itemCounter / m_inventory->width()) * 18.f, 0);

itemCounter++;
}
}

void InventoryWidget::updateItemWidgets(u16 offset, u16 size, std::string search)
{
u16 itemCounter = 0;
for (u16 i = 0; itemCounter < size; ++i) {
u16 x = u16((i + offset) % m_inventory->width());
u16 y = u16((i + offset) / m_inventory->width());
if (x >= m_inventory->width() || y >= m_inventory->height())
break;

std::string label = m_inventory->getStack(x, y).item().label();
std::transform(label.begin(), label.end(), label.begin(), [](unsigned char c) { return std::tolower(c); });
std::transform(search.begin(), search.end(), search.begin(), [](unsigned char c) { return std::tolower(c); });
if (search.empty() || label.find(search) != std::string::npos) {
m_itemWidgets.emplace_back(*m_inventory, x, y, this);

ItemWidget &widget = m_itemWidgets.back();
widget.update();
widget.setPosition((itemCounter % m_inventory->width()) * 18.f, (itemCounter / m_inventory->width()) * 18.f, 0);
m_itemWidgets[itemCounter].changeItem(x, y);
m_itemWidgets[itemCounter].update();

itemCounter++;
}
}
}

for (u16 i = itemCounter; i < m_itemWidgets.size(); ++i)
m_itemWidgets[i].disable();
}
3 changes: 2 additions & 1 deletion source/client/gui/InventoryWidget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ class InventoryWidget : public AbstractInventoryWidget {
private:
void draw(RenderTarget &target, RenderStates states) const override;

void loadItemWidgets(u16 offset, u16 size, std::string search = "");
void loadItemWidgets(u16 offset, u16 size);
void updateItemWidgets(u16 offset, u16 size, std::string search = "");

ClientCommandHandler &m_client;

Expand Down
15 changes: 14 additions & 1 deletion source/client/gui/ItemWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,20 @@ ItemWidget::ItemWidget(Inventory &inventory, u16 x, u16 y, Widget *parent)
// m_cube.setRotation(-172, glm::vec3{0.42, -0.2, 1});
}

void ItemWidget::changeItem(u16 x, u16 y) {
m_x = x;
m_y = y;

m_isEnabled = true;
}

void ItemWidget::disable() {
m_isEnabled = false;
}

void ItemWidget::update() {
if (!m_isEnabled) return;

if (stack().item().isBlock()) {
const Block &block = Registry::getInstance().getBlock(stack().item().id());
const BlockState &blockState = block.getState(0); // FIXME: Get state from item stack
Expand Down Expand Up @@ -85,7 +98,7 @@ void ItemWidget::setStack(const std::string &name, u16 amount) {
}

void ItemWidget::draw(RenderTarget &target, RenderStates states) const {
if (stack().amount() == 0) return;
if (!m_isEnabled || stack().amount() == 0) return;

states.transform *= getTransform();

Expand Down
7 changes: 7 additions & 0 deletions source/client/gui/ItemWidget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ class ItemWidget : public Widget {
void update() override;
void updateImage(const BlockState *blockState = nullptr);

void changeItem(u16 x, u16 y);
void disable();

const ItemStack &stack() const { return m_inventory.getStack(m_x, m_y); }
void setStack(const std::string &name, u16 amount = 1);

Expand All @@ -51,6 +54,8 @@ class ItemWidget : public Widget {
bool hasChanged() const { return m_hasChanged; }
void setChanged(bool hasChanged) { m_hasChanged = hasChanged; }

bool isEnabled() const { return m_isEnabled; }

protected:
void draw(RenderTarget &target, RenderStates states) const override;

Expand All @@ -72,6 +77,8 @@ class ItemWidget : public Widget {
bool m_hasChanged = false;

std::string m_oldTexturePack{""};

bool m_isEnabled = true;
};

#endif // ITEMWIDGET_HPP_
30 changes: 17 additions & 13 deletions source/client/gui/MouseItemWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,16 @@ void MouseItemWidget::leftClickBehaviour() {
if (m_currentInventoryWidget && m_currentInventoryWidget->currentItemWidget() && m_currentInventoryWidget->inventory()) {
if (m_currentInventoryWidget->doItemMatchFilter(m_inventory.getStack(0, 0).item())) {
ItemWidget *currentItemWidget = m_currentInventoryWidget->currentItemWidget();
if (!m_currentInventoryWidget->inventory()->isUnlimited())
swapItems(*currentItemWidget, m_currentInventoryWidget->isReadOnly());
else if (getStack().amount() == 0 && currentItemWidget->stack().amount() != 0)
setStack(currentItemWidget->stack().item().stringID(), currentItemWidget->stack().item().maxStackSize());
else
setStack(BLOCK_AIR, 0);
if (currentItemWidget->isEnabled()) {
if (!m_currentInventoryWidget->inventory()->isUnlimited())
swapItems(*currentItemWidget, m_currentInventoryWidget->isReadOnly());
else if (getStack().amount() == 0 && currentItemWidget->stack().amount() != 0)
setStack(currentItemWidget->stack().item().stringID(), currentItemWidget->stack().item().maxStackSize());
else
setStack(BLOCK_AIR, 0);

m_currentInventoryWidget->sendUpdatePacket();
m_currentInventoryWidget->sendUpdatePacket();
}
}
}
}
Expand All @@ -96,10 +98,12 @@ void MouseItemWidget::rightClickBehaviour() {
if (!m_currentInventoryWidget->isReadOnly()) {
if (m_currentInventoryWidget->doItemMatchFilter(m_inventory.getStack(0, 0).item())) {
ItemWidget *currentItemWidget = m_currentInventoryWidget->currentItemWidget();
if (!m_currentInventoryWidget->inventory()->isUnlimited())
putItem(*currentItemWidget);
else if (getStack().amount() == 0 && currentItemWidget->stack().amount() != 0)
setStack(currentItemWidget->stack().item().stringID(), 1);
if (currentItemWidget->isEnabled()) {
if (!m_currentInventoryWidget->inventory()->isUnlimited())
putItem(*currentItemWidget);
else if (getStack().amount() == 0 && currentItemWidget->stack().amount() != 0)
setStack(currentItemWidget->stack().item().stringID(), 1);
}
}

m_currentInventoryWidget->sendUpdatePacket();
Expand All @@ -113,7 +117,7 @@ void MouseItemWidget::startDragging(bool isLeftClickDrag) {
m_draggedStack = getStack();
m_dragOrigin = nullptr;

if (m_currentItemWidget && (m_currentItemWidget->stack().amount() == 0 || m_currentItemWidget->stack().item().stringID() == m_draggedStack.item().stringID())) {
if (m_currentItemWidget && m_currentItemWidget->isEnabled() && (m_currentItemWidget->stack().amount() == 0 || m_currentItemWidget->stack().item().stringID() == m_draggedStack.item().stringID())) {
m_dragOrigin = m_currentItemWidget;
m_draggedSlots[m_currentItemWidget] = m_currentItemWidget->stack();
}
Expand Down Expand Up @@ -173,7 +177,7 @@ void MouseItemWidget::draggingBehaviour(ItemWidget *newItemWidget) {
}

void MouseItemWidget::updateCurrentItem(ItemWidget *currentItemWidget) {
if (currentItemWidget) {
if (currentItemWidget && currentItemWidget->isEnabled()) {
bool doItemMatchFilter = !m_currentInventoryWidget || (m_currentInventoryWidget->doItemMatchFilter(m_draggedStack.item()) && !m_currentInventoryWidget->isReadOnly());
if (m_isDragging && currentItemWidget != m_currentItemWidget && doItemMatchFilter)
draggingBehaviour(currentItemWidget);
Expand Down
6 changes: 3 additions & 3 deletions source/client/gui/MouseItemWidget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,16 @@ class MouseItemWidget : public ItemWidget {
const ItemWidget *currentItemWidget() const { return m_currentItemWidget; }
void updateCurrentItem(ItemWidget *currentItemWidget);

void swapItems(ItemWidget &widget, bool isReadOnly = false);
void putItem(ItemWidget &widget);

void setCurrentInventoryWidget(InventoryWidget *inventoryWidget) { m_currentInventoryWidget = inventoryWidget; }

const ItemStack &getStack() const { return m_inventory.getStack(0, 0); }

private:
void draw(RenderTarget &target, RenderStates states) const override;

void swapItems(ItemWidget &widget, bool isReadOnly = false);
void putItem(ItemWidget &widget);

void updatePosition(s32 x, s32 y);

Inventory m_inventory{1, 1};
Expand Down

0 comments on commit fa79a67

Please sign in to comment.