aboutsummaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
authorSmallJoker <SmallJoker@users.noreply.github.com>2019-06-10 13:01:07 +0200
committerGitHub <noreply@github.com>2019-06-10 13:01:07 +0200
commite2f8f4da83206d551f9acebd14d574ea37ca214a (patch)
tree0a2a4f63b59db1a511c781c617b5e80f608723e5 /src/client
parente40be619f2a30c7a4d5042d922f0fe57539411d5 (diff)
downloadminetest-e2f8f4da83206d551f9acebd14d574ea37ca214a.tar.gz
minetest-e2f8f4da83206d551f9acebd14d574ea37ca214a.tar.bz2
minetest-e2f8f4da83206d551f9acebd14d574ea37ca214a.zip
Formspecs: Close on metadata removal (#8348)
Formspecs will now close as soon the formspec string in the node metadata turns invalid.
Diffstat (limited to 'src/client')
-rw-r--r--src/client/game.cpp91
-rw-r--r--src/client/gameui.cpp12
-rw-r--r--src/client/gameui.h16
3 files changed, 80 insertions, 39 deletions
diff --git a/src/client/game.cpp b/src/client/game.cpp
index 8c0433283..a29b35746 100644
--- a/src/client/game.cpp
+++ b/src/client/game.cpp
@@ -827,10 +827,6 @@ private:
ChatBackend *chat_backend = nullptr;
- GUIFormSpecMenu *current_formspec = nullptr;
- //default: "". If other than "", empty show_formspec packets will only close the formspec when the formname matches
- std::string cur_formname;
-
EventManager *eventmgr = nullptr;
QuicktuneShortcutter *quicktune = nullptr;
bool registration_confirmation_shown = false;
@@ -1143,8 +1139,9 @@ void Game::shutdown()
driver->setRenderTarget(irr::video::ERT_STEREO_BOTH_BUFFERS);
}
#endif
- if (current_formspec)
- current_formspec->quitMenu();
+ auto formspec = m_game_ui->getFormspecGUI();
+ if (formspec)
+ formspec->quitMenu();
showOverlayMessage(N_("Shutting down..."), 0, 0, false);
@@ -1163,10 +1160,7 @@ void Game::shutdown()
g_menumgr.deletingMenu(g_menumgr.m_stack.front());
}
- if (current_formspec) {
- current_formspec->drop();
- current_formspec = NULL;
- }
+ m_game_ui->deleteFormspec();
chat_backend->addMessage(L"", L"# Disconnected.");
chat_backend->addMessage(L"", L"");
@@ -1853,8 +1847,9 @@ void Game::processUserInput(f32 dtime)
input->step(dtime);
#ifdef __ANDROID__
- if (current_formspec != NULL)
- current_formspec->getAndroidUIInput();
+ auto formspec = m_game_ui->getFormspecGUI();
+ if (formspec)
+ formspec->getAndroidUIInput();
else
handleAndroidChatInput();
#endif
@@ -2050,10 +2045,11 @@ void Game::openInventory()
if (!client->moddingEnabled()
|| !client->getScript()->on_inventory_open(fs_src->m_client->getInventory(inventoryloc))) {
TextDest *txt_dst = new TextDestPlayerInventory(client);
- GUIFormSpecMenu::create(current_formspec, client, &input->joystick, fs_src,
+ auto *&formspec = m_game_ui->updateFormspec("");
+ GUIFormSpecMenu::create(formspec, client, &input->joystick, fs_src,
txt_dst, client->getFormspecPrepend());
- cur_formname = "";
- current_formspec->setFormSpec(fs_src->getForm(), inventoryloc);
+
+ formspec->setFormSpec(fs_src->getForm(), inventoryloc);
}
}
@@ -2581,9 +2577,10 @@ void Game::handleClientEvent_Deathscreen(ClientEvent *event, CameraOrientation *
void Game::handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation *cam)
{
if (event->show_formspec.formspec->empty()) {
- if (current_formspec && (event->show_formspec.formname->empty()
- || *(event->show_formspec.formname) == cur_formname)) {
- current_formspec->quitMenu();
+ auto formspec = m_game_ui->getFormspecGUI();
+ if (formspec && (event->show_formspec.formname->empty()
+ || *(event->show_formspec.formname) == m_game_ui->getFormspecName())) {
+ formspec->quitMenu();
}
} else {
FormspecFormSource *fs_src =
@@ -2591,9 +2588,9 @@ void Game::handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation
TextDestPlayerInventory *txt_dst =
new TextDestPlayerInventory(client, *(event->show_formspec.formname));
- GUIFormSpecMenu::create(current_formspec, client, &input->joystick,
+ auto *&formspec = m_game_ui->updateFormspec(*(event->show_formspec.formname));
+ GUIFormSpecMenu::create(formspec, client, &input->joystick,
fs_src, txt_dst, client->getFormspecPrepend());
- cur_formname = *(event->show_formspec.formname);
}
delete event->show_formspec.formspec;
@@ -2605,7 +2602,7 @@ void Game::handleClientEvent_ShowLocalFormSpec(ClientEvent *event, CameraOrienta
FormspecFormSource *fs_src = new FormspecFormSource(*event->show_formspec.formspec);
LocalFormspecHandler *txt_dst =
new LocalFormspecHandler(*event->show_formspec.formname, client);
- GUIFormSpecMenu::create(current_formspec, client, &input->joystick,
+ GUIFormSpecMenu::create(m_game_ui->getFormspecGUI(), client, &input->joystick,
fs_src, txt_dst, client->getFormspecPrepend());
delete event->show_formspec.formspec;
@@ -3272,11 +3269,11 @@ void Game::handlePointingAtNode(const PointedThing &pointed,
&client->getEnv().getClientMap(), nodepos);
TextDest *txt_dst = new TextDestNodeMetadata(nodepos, client);
- GUIFormSpecMenu::create(current_formspec, client, &input->joystick, fs_src,
+ auto *&formspec = m_game_ui->updateFormspec("");
+ GUIFormSpecMenu::create(formspec, client, &input->joystick, fs_src,
txt_dst, client->getFormspecPrepend());
- cur_formname.clear();
- current_formspec->setFormSpec(meta->getString("formspec"), inventoryloc);
+ formspec->setFormSpec(meta->getString("formspec"), inventoryloc);
} else {
// Report right click to server
@@ -3844,14 +3841,28 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
1. Delete formspec menu reference if menu was removed
2. Else, make sure formspec menu is on top
*/
- if (current_formspec) {
- if (current_formspec->getReferenceCount() == 1) {
- current_formspec->drop();
- current_formspec = NULL;
- } else if (isMenuActive()) {
- guiroot->bringToFront(current_formspec);
+ auto formspec = m_game_ui->getFormspecGUI();
+ do { // breakable. only runs for one iteration
+ if (!formspec)
+ break;
+
+ if (formspec->getReferenceCount() == 1) {
+ m_game_ui->deleteFormspec();
+ break;
}
- }
+
+ auto &loc = formspec->getFormspecLocation();
+ if (loc.type == InventoryLocation::NODEMETA) {
+ NodeMetadata *meta = client->getEnv().getClientMap().getNodeMetadata(loc.p);
+ if (!meta || meta->getString("formspec").empty()) {
+ formspec->quitMenu();
+ break;
+ }
+ }
+
+ if (isMenuActive())
+ guiroot->bringToFront(formspec);
+ } while (false);
/*
Drawing begins
@@ -4048,7 +4059,7 @@ void Game::extendedResourceCleanup()
void Game::showDeathFormspec()
{
- static std::string formspec =
+ static std::string formspec_str =
std::string(FORMSPEC_VERSION_STRING) +
SIZE_TAG
"bgcolor[#320000b4;true]"
@@ -4059,12 +4070,13 @@ void Game::showDeathFormspec()
/* Create menu */
/* Note: FormspecFormSource and LocalFormspecHandler *
* are deleted by guiFormSpecMenu */
- FormspecFormSource *fs_src = new FormspecFormSource(formspec);
+ FormspecFormSource *fs_src = new FormspecFormSource(formspec_str);
LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_DEATH_SCREEN", client);
- GUIFormSpecMenu::create(current_formspec, client, &input->joystick, fs_src,
- txt_dst, client->getFormspecPrepend());
- current_formspec->setFocus("btn_respawn");
+ auto *&formspec = m_game_ui->getFormspecGUI();
+ GUIFormSpecMenu::create(formspec, client, &input->joystick,
+ fs_src, txt_dst, client->getFormspecPrepend());
+ formspec->setFocus("btn_respawn");
}
#define GET_KEY_NAME(KEY) gettext(getKeySetting(#KEY).name())
@@ -4188,10 +4200,11 @@ void Game::showPauseMenu()
FormspecFormSource *fs_src = new FormspecFormSource(os.str());
LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_PAUSE_MENU");
- GUIFormSpecMenu::create(current_formspec, client, &input->joystick,
+ auto *&formspec = m_game_ui->getFormspecGUI();
+ GUIFormSpecMenu::create(formspec, client, &input->joystick,
fs_src, txt_dst, client->getFormspecPrepend());
- current_formspec->setFocus("btn_continue");
- current_formspec->doPause = true;
+ formspec->setFocus("btn_continue");
+ formspec->doPause = true;
}
/****************************************************************************/
diff --git a/src/client/gameui.cpp b/src/client/gameui.cpp
index 5533cd119..f3c3fefb6 100644
--- a/src/client/gameui.cpp
+++ b/src/client/gameui.cpp
@@ -302,3 +302,15 @@ void GameUI::toggleProfiler()
showTranslatedStatusText("Profiler hidden");
}
}
+
+
+void GameUI::deleteFormspec()
+{
+ if (m_formspec)
+ m_formspec->quitMenu();
+
+ delete m_formspec;
+ m_formspec = nullptr;
+
+ m_formname.clear();
+}
diff --git a/src/client/gameui.h b/src/client/gameui.h
index b6b54562a..8d20870d7 100644
--- a/src/client/gameui.h
+++ b/src/client/gameui.h
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#pragma once
#include <IGUIEnvironment.h>
+#include "gui/guiFormSpecMenu.h"
#include "util/enriched_string.h"
#include "util/pointedthing.h"
#include "game.h"
@@ -88,6 +89,16 @@ public:
void toggleHud();
void toggleProfiler();
+ GUIFormSpecMenu *&updateFormspec(const std::string &formname)
+ {
+ m_formname = formname;
+ return m_formspec;
+ }
+
+ const std::string &getFormspecName() { return m_formname; }
+ GUIFormSpecMenu *&getFormspecGUI() { return m_formspec; }
+ void deleteFormspec();
+
private:
Flags m_flags;
@@ -107,4 +118,9 @@ private:
gui::IGUIStaticText *m_guitext_profiler = nullptr; // Profiler text
u8 m_profiler_current_page = 0;
const u8 m_profiler_max_page = 3;
+
+ // Default: "". If other than "": Empty show_formspec packets will only
+ // close the formspec when the formname matches
+ std::string m_formname;
+ GUIFormSpecMenu *m_formspec = nullptr;
};