Skip to content

Commit 127f354

Browse files
sapiersapier
sapier
authored and
sapier
committedApr 22, 2014
Fix formspec replacement handling for in game formspecs
1 parent e7ef4f0 commit 127f354

File tree

4 files changed

+125
-123
lines changed

4 files changed

+125
-123
lines changed
 

‎src/game.cpp

+86-104
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,16 @@ struct TextDestPlayerInventory : public TextDest
122122
struct LocalFormspecHandler : public TextDest
123123
{
124124
LocalFormspecHandler();
125-
LocalFormspecHandler(std::string formname) {
125+
LocalFormspecHandler(std::string formname) :
126+
m_client(0)
127+
{
126128
m_formname = formname;
127129
}
128130

129-
LocalFormspecHandler(std::string formname,Client *client) {
131+
LocalFormspecHandler(std::string formname, Client *client) :
132+
m_client(client)
133+
{
130134
m_formname = formname;
131-
m_client = client;
132135
}
133136

134137
void gotText(std::wstring message) {
@@ -167,25 +170,27 @@ struct LocalFormspecHandler : public TextDest
167170
}
168171
}
169172
if (m_formname == "MT_CHAT_MENU") {
173+
assert(m_client != 0);
170174
if ((fields.find("btn_send") != fields.end()) ||
171175
(fields.find("quit") != fields.end())) {
172176
if (fields.find("f_text") != fields.end()) {
173-
if (m_client != 0) {
174-
m_client->typeChatMessage(narrow_to_wide(fields["f_text"]));
175-
}
176-
else {
177-
errorstream << "LocalFormspecHandler::gotText received chat message but m_client is NULL" << std::endl;
178-
}
177+
m_client->typeChatMessage(narrow_to_wide(fields["f_text"]));
179178
}
180179
return;
181180
}
182181
}
183182

184183
if (m_formname == "MT_DEATH_SCREEN") {
184+
assert(m_client != 0);
185185
if ((fields.find("btn_respawn") != fields.end())) {
186186
m_client->sendRespawn();
187187
return;
188188
}
189+
190+
if (fields.find("quit") != fields.end()) {
191+
m_client->sendRespawn();
192+
return;
193+
}
189194
}
190195

191196
errorstream << "LocalFormspecHandler::gotText unhandled >" << m_formname << "< event" << std::endl;
@@ -963,34 +968,47 @@ bool nodePlacementPrediction(Client &client,
963968
return false;
964969
}
965970

966-
static void show_chat_menu(FormspecFormSource* current_formspec,
967-
TextDest* current_textdest, IWritableTextureSource* tsrc,
968-
IrrlichtDevice * device, Client* client, std::string text)
971+
static inline void create_formspec_menu(GUIFormSpecMenu** cur_formspec,
972+
InventoryManager *invmgr, IGameDef *gamedef,
973+
IWritableTextureSource* tsrc, IrrlichtDevice * device,
974+
IFormSource* fs_src, TextDest* txt_dest
975+
) {
976+
977+
if (*cur_formspec == 0) {
978+
*cur_formspec = new GUIFormSpecMenu(device, guiroot, -1, &g_menumgr,
979+
invmgr, gamedef, tsrc, fs_src, txt_dest, cur_formspec );
980+
(*cur_formspec)->doPause = false;
981+
(*cur_formspec)->drop();
982+
}
983+
else {
984+
(*cur_formspec)->setFormSource(fs_src);
985+
(*cur_formspec)->setTextDest(txt_dest);
986+
}
987+
}
988+
989+
static void show_chat_menu(GUIFormSpecMenu** cur_formspec,
990+
InventoryManager *invmgr, IGameDef *gamedef,
991+
IWritableTextureSource* tsrc, IrrlichtDevice * device,
992+
Client* client, std::string text)
969993
{
970994
std::string formspec =
971995
"size[11,5.5,true]"
972996
"field[3,2.35;6,0.5;f_text;;" + text + "]"
973-
"button_exit[4,3;3,0.5;btn_send;" + wide_to_narrow(wstrgettext("Proceed")) + "]"
997+
"button_exit[4,3;3,0.5;btn_send;" + wide_to_narrow(wstrgettext("Proceed")) + "]"
974998
;
975999

9761000
/* Create menu */
9771001
/* Note: FormspecFormSource and LocalFormspecHandler
9781002
* are deleted by guiFormSpecMenu */
979-
current_formspec = new FormspecFormSource(formspec,&current_formspec);
980-
current_textdest = new LocalFormspecHandler("MT_CHAT_MENU",client);
981-
GUIFormSpecMenu *menu =
982-
new GUIFormSpecMenu(device, guiroot, -1,
983-
&g_menumgr,
984-
NULL, NULL, tsrc);
985-
menu->doPause = false;
986-
menu->setFormSource(current_formspec);
987-
menu->setTextDest(current_textdest);
988-
menu->drop();
1003+
FormspecFormSource* fs_src = new FormspecFormSource(formspec);
1004+
LocalFormspecHandler* txt_dst = new LocalFormspecHandler("MT_CHAT_MENU", client);
1005+
1006+
create_formspec_menu(cur_formspec, invmgr, gamedef, tsrc, device, fs_src, txt_dst);
9891007
}
9901008

991-
static void show_deathscreen(FormspecFormSource* current_formspec,
992-
TextDest* current_textdest, IWritableTextureSource* tsrc,
993-
IrrlichtDevice * device, Client* client)
1009+
static void show_deathscreen(GUIFormSpecMenu** cur_formspec,
1010+
InventoryManager *invmgr, IGameDef *gamedef,
1011+
IWritableTextureSource* tsrc, IrrlichtDevice * device, Client* client)
9941012
{
9951013
std::string formspec =
9961014
std::string("") +
@@ -1003,24 +1021,18 @@ static void show_deathscreen(FormspecFormSource* current_formspec,
10031021
/* Create menu */
10041022
/* Note: FormspecFormSource and LocalFormspecHandler
10051023
* are deleted by guiFormSpecMenu */
1006-
current_formspec = new FormspecFormSource(formspec,&current_formspec);
1007-
current_textdest = new LocalFormspecHandler("MT_DEATH_SCREEN",client);
1008-
GUIFormSpecMenu *menu =
1009-
new GUIFormSpecMenu(device, guiroot, -1,
1010-
&g_menumgr,
1011-
NULL, NULL, tsrc);
1012-
menu->doPause = false;
1013-
menu->setFormSource(current_formspec);
1014-
menu->setTextDest(current_textdest);
1015-
menu->drop();
1024+
FormspecFormSource* fs_src = new FormspecFormSource(formspec);
1025+
LocalFormspecHandler* txt_dst = new LocalFormspecHandler("MT_DEATH_SCREEN", client);
1026+
1027+
create_formspec_menu(cur_formspec, invmgr, gamedef, tsrc, device, fs_src, txt_dst);
10161028
}
10171029

10181030
/******************************************************************************/
1019-
static void show_pause_menu(FormspecFormSource* current_formspec,
1020-
TextDest* current_textdest, IWritableTextureSource* tsrc,
1021-
IrrlichtDevice * device, bool singleplayermode)
1031+
static void show_pause_menu(GUIFormSpecMenu** cur_formspec,
1032+
InventoryManager *invmgr, IGameDef *gamedef,
1033+
IWritableTextureSource* tsrc, IrrlichtDevice * device,
1034+
bool singleplayermode)
10221035
{
1023-
10241036
std::string control_text = wide_to_narrow(wstrgettext("Default Controls:\n"
10251037
"- WASD: move\n"
10261038
"- Space: jump/climb\n"
@@ -1046,7 +1058,7 @@ static void show_pause_menu(FormspecFormSource* current_formspec,
10461058
<< wide_to_narrow(wstrgettext("Change Password")) << "]";
10471059
}
10481060

1049-
os << "button_exit[4," << (ypos++) << ";3,0.5;btn_sound;"
1061+
os << "button_exit[4," << (ypos++) << ";3,0.5;btn_sound;"
10501062
<< wide_to_narrow(wstrgettext("Sound Volume")) << "]";
10511063
os << "button_exit[4," << (ypos++) << ";3,0.5;btn_exit_menu;"
10521064
<< wide_to_narrow(wstrgettext("Exit to Menu")) << "]";
@@ -1061,14 +1073,10 @@ static void show_pause_menu(FormspecFormSource* current_formspec,
10611073
/* Create menu */
10621074
/* Note: FormspecFormSource and LocalFormspecHandler *
10631075
* are deleted by guiFormSpecMenu */
1064-
current_formspec = new FormspecFormSource(os.str(),&current_formspec);
1065-
current_textdest = new LocalFormspecHandler("MT_PAUSE_MENU");
1066-
GUIFormSpecMenu *menu =
1067-
new GUIFormSpecMenu(device, guiroot, -1, &g_menumgr, NULL, NULL, tsrc);
1068-
menu->doPause = true;
1069-
menu->setFormSource(current_formspec);
1070-
menu->setTextDest(current_textdest);
1071-
menu->drop();
1076+
FormspecFormSource* fs_src = new FormspecFormSource(os.str());
1077+
LocalFormspecHandler* txt_dst = new LocalFormspecHandler("MT_PAUSE_MENU");
1078+
1079+
create_formspec_menu(cur_formspec, invmgr, gamedef, tsrc, device, fs_src, txt_dst);
10721080
}
10731081

10741082
/******************************************************************************/
@@ -1080,8 +1088,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
10801088
const SubgameSpec &gamespec /* Used for local game */,
10811089
bool simple_singleplayer_mode)
10821090
{
1083-
FormspecFormSource* current_formspec = 0;
1084-
TextDest* current_textdest = 0;
1091+
GUIFormSpecMenu* current_formspec = 0;
10851092
video::IVideoDriver* driver = device->getVideoDriver();
10861093
scene::ISceneManager* smgr = device->getSceneManager();
10871094

@@ -1911,34 +1918,29 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
19111918
infostream<<"the_game: "
19121919
<<"Launching inventory"<<std::endl;
19131920

1914-
GUIFormSpecMenu *menu =
1915-
new GUIFormSpecMenu(device, guiroot, -1,
1916-
&g_menumgr,
1917-
&client, gamedef, tsrc);
1921+
PlayerInventoryFormSource* fs_src = new PlayerInventoryFormSource(&client);
1922+
TextDest* txt_dst = new TextDestPlayerInventory(&client);
1923+
1924+
create_formspec_menu(&current_formspec, &client, gamedef, tsrc, device, fs_src, txt_dst);
19181925

19191926
InventoryLocation inventoryloc;
19201927
inventoryloc.setCurrentPlayer();
1921-
1922-
PlayerInventoryFormSource *src = new PlayerInventoryFormSource(&client);
1923-
assert(src);
1924-
menu->doPause = false;
1925-
menu->setFormSpec(src->getForm(), inventoryloc);
1926-
menu->setFormSource(src);
1927-
menu->setTextDest(new TextDestPlayerInventory(&client));
1928-
menu->drop();
1928+
current_formspec->setFormSpec(fs_src->getForm(), inventoryloc);
19291929
}
19301930
else if(input->wasKeyDown(EscapeKey))
19311931
{
1932-
show_pause_menu(current_formspec, current_textdest, tsrc, device,
1932+
show_pause_menu(&current_formspec, &client, gamedef, tsrc, device,
19331933
simple_singleplayer_mode);
19341934
}
19351935
else if(input->wasKeyDown(getKeySetting("keymap_chat")))
19361936
{
1937-
show_chat_menu(current_formspec, current_textdest, tsrc, device, &client,"");
1937+
show_chat_menu(&current_formspec, &client, gamedef, tsrc, device,
1938+
&client,"");
19381939
}
19391940
else if(input->wasKeyDown(getKeySetting("keymap_cmd")))
19401941
{
1941-
show_chat_menu(current_formspec, current_textdest, tsrc, device, &client,"/");
1942+
show_chat_menu(&current_formspec, &client, gamedef, tsrc, device,
1943+
&client,"/");
19421944
}
19431945
else if(input->wasKeyDown(getKeySetting("keymap_console")))
19441946
{
@@ -2396,8 +2398,8 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
23962398
}
23972399
else if(event.type == CE_DEATHSCREEN)
23982400
{
2399-
show_deathscreen(current_formspec, current_textdest,
2400-
tsrc, device, &client);
2401+
show_deathscreen(&current_formspec, &client, gamedef, tsrc,
2402+
device, &client);
24012403

24022404
chat_backend.addMessage(L"", L"You died.");
24032405

@@ -2411,29 +2413,14 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
24112413
}
24122414
else if (event.type == CE_SHOW_FORMSPEC)
24132415
{
2414-
if (current_formspec == 0)
2415-
{
2416-
/* Create menu */
2417-
/* Note: FormspecFormSource and TextDestPlayerInventory
2418-
* are deleted by guiFormSpecMenu */
2419-
current_formspec = new FormspecFormSource(*(event.show_formspec.formspec),&current_formspec);
2420-
current_textdest = new TextDestPlayerInventory(&client,*(event.show_formspec.formname));
2421-
GUIFormSpecMenu *menu =
2422-
new GUIFormSpecMenu(device, guiroot, -1,
2423-
&g_menumgr,
2424-
&client, gamedef, tsrc);
2425-
menu->doPause = false;
2426-
menu->setFormSource(current_formspec);
2427-
menu->setTextDest(current_textdest);
2428-
menu->drop();
2429-
}
2430-
else
2431-
{
2432-
assert(current_textdest != 0);
2433-
/* update menu */
2434-
current_textdest->setFormName(*(event.show_formspec.formname));
2435-
current_formspec->setForm(*(event.show_formspec.formspec));
2436-
}
2416+
FormspecFormSource* fs_src =
2417+
new FormspecFormSource(*(event.show_formspec.formspec));
2418+
TextDestPlayerInventory* txt_dst =
2419+
new TextDestPlayerInventory(&client,*(event.show_formspec.formname));
2420+
2421+
create_formspec_menu(&current_formspec, &client, gamedef,
2422+
tsrc, device, fs_src, txt_dst);
2423+
24372424
delete(event.show_formspec.formspec);
24382425
delete(event.show_formspec.formname);
24392426
}
@@ -2986,19 +2973,14 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
29862973
InventoryLocation inventoryloc;
29872974
inventoryloc.setNodeMeta(nodepos);
29882975

2989-
/* Create menu */
2990-
2991-
GUIFormSpecMenu *menu =
2992-
new GUIFormSpecMenu(device, guiroot, -1,
2993-
&g_menumgr,
2994-
&client, gamedef, tsrc);
2995-
menu->doPause = false;
2996-
menu->setFormSpec(meta->getString("formspec"),
2997-
inventoryloc);
2998-
menu->setFormSource(new NodeMetadataFormSource(
2999-
&client.getEnv().getClientMap(), nodepos));
3000-
menu->setTextDest(new TextDestNodeMetadata(nodepos, &client));
3001-
menu->drop();
2976+
NodeMetadataFormSource* fs_src = new NodeMetadataFormSource(
2977+
&client.getEnv().getClientMap(), nodepos);
2978+
TextDest* txt_dst = new TextDestNodeMetadata(nodepos, &client);
2979+
2980+
create_formspec_menu(&current_formspec, &client, gamedef,
2981+
tsrc, device, fs_src, txt_dst);
2982+
2983+
current_formspec->setFormSpec(meta->getString("formspec"), inventoryloc);
30022984
}
30032985
// Otherwise report right click to server
30042986
else

‎src/guiEngine.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ GUIEngine::GUIEngine( irr::IrrlichtDevice* dev,
166166
rect,false,true,0,-1);
167167

168168
//create formspecsource
169-
m_formspecgui = new FormspecFormSource("",&m_formspecgui);
169+
m_formspecgui = new FormspecFormSource("");
170170

171171
/* Create menu */
172172
m_menu =
@@ -176,12 +176,13 @@ GUIEngine::GUIEngine( irr::IrrlichtDevice* dev,
176176
m_menumanager,
177177
0 /* &client */,
178178
0 /* gamedef */,
179-
m_texture_source);
179+
m_texture_source,
180+
m_formspecgui,
181+
m_buttonhandler,
182+
NULL);
180183

181184
m_menu->allowClose(false);
182185
m_menu->lockSize(true,v2u32(800,600));
183-
m_menu->setFormSource(m_formspecgui);
184-
m_menu->setTextDest(m_buttonhandler);
185186

186187
// Initialize scripting
187188

‎src/guiFormSpecMenu.cpp

+18-6
Original file line numberDiff line numberDiff line change
@@ -68,20 +68,22 @@ with this program; if not, write to the Free Software Foundation, Inc.,
6868
GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev,
6969
gui::IGUIElement* parent, s32 id, IMenuManager *menumgr,
7070
InventoryManager *invmgr, IGameDef *gamedef,
71-
ISimpleTextureSource *tsrc) :
71+
ISimpleTextureSource *tsrc, IFormSource* fsrc, TextDest* tdst,
72+
GUIFormSpecMenu** ext_ptr) :
7273
GUIModalMenu(dev->getGUIEnvironment(), parent, id, menumgr),
7374
m_device(dev),
7475
m_invmgr(invmgr),
7576
m_gamedef(gamedef),
7677
m_tsrc(tsrc),
77-
m_form_src(NULL),
78-
m_text_dst(NULL),
7978
m_selected_item(NULL),
8079
m_selected_amount(0),
8180
m_selected_dragging(false),
8281
m_tooltip_element(NULL),
8382
m_allowclose(true),
84-
m_lock(false)
83+
m_lock(false),
84+
m_form_src(fsrc),
85+
m_text_dst(tdst),
86+
m_ext_ptr(ext_ptr)
8587
{
8688
current_keys_pending.key_down = false;
8789
current_keys_pending.key_up = false;
@@ -95,8 +97,18 @@ GUIFormSpecMenu::~GUIFormSpecMenu()
9597
removeChildren();
9698

9799
delete m_selected_item;
98-
delete m_form_src;
99-
delete m_text_dst;
100+
101+
if (m_form_src != NULL) {
102+
delete m_form_src;
103+
}
104+
if (m_text_dst != NULL) {
105+
delete m_text_dst;
106+
}
107+
108+
if (m_ext_ptr != NULL) {
109+
assert(*m_ext_ptr == this);
110+
*m_ext_ptr = NULL;
111+
}
100112
}
101113

102114
void GUIFormSpecMenu::removeChildren()

‎src/guiFormSpecMenu.h

+16-9
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,10 @@ class GUIFormSpecMenu : public GUIModalMenu
190190
IMenuManager *menumgr,
191191
InventoryManager *invmgr,
192192
IGameDef *gamedef,
193-
ISimpleTextureSource *tsrc
193+
ISimpleTextureSource *tsrc,
194+
IFormSource* fs_src,
195+
TextDest* txt_dst,
196+
GUIFormSpecMenu** ext_ptr
194197
);
195198

196199
~GUIFormSpecMenu();
@@ -206,12 +209,18 @@ class GUIFormSpecMenu : public GUIModalMenu
206209
// form_src is deleted by this GUIFormSpecMenu
207210
void setFormSource(IFormSource *form_src)
208211
{
212+
if (m_form_src != NULL) {
213+
delete m_form_src;
214+
}
209215
m_form_src = form_src;
210216
}
211217

212218
// text_dst is deleted by this GUIFormSpecMenu
213219
void setTextDest(TextDest *text_dst)
214220
{
221+
if (m_text_dst != NULL) {
222+
delete m_text_dst;
223+
}
215224
m_text_dst = text_dst;
216225
}
217226

@@ -268,8 +277,6 @@ class GUIFormSpecMenu : public GUIModalMenu
268277

269278
std::string m_formspec_string;
270279
InventoryLocation m_current_inventory_location;
271-
IFormSource *m_form_src;
272-
TextDest *m_text_dst;
273280

274281
std::vector<ListDrawSpec> m_inventorylists;
275282
std::vector<ImageDrawSpec> m_backgrounds;
@@ -305,6 +312,10 @@ class GUIFormSpecMenu : public GUIModalMenu
305312
video::SColor m_slotbg_h;
306313
video::SColor m_slotbordercolor;
307314
private:
315+
IFormSource* m_form_src;
316+
TextDest* m_text_dst;
317+
GUIFormSpecMenu** m_ext_ptr;
318+
308319
typedef struct {
309320
v2s32 size;
310321
s32 helptext_h;
@@ -360,16 +371,13 @@ class GUIFormSpecMenu : public GUIModalMenu
360371
class FormspecFormSource: public IFormSource
361372
{
362373
public:
363-
FormspecFormSource(std::string formspec,FormspecFormSource** game_formspec)
374+
FormspecFormSource(std::string formspec)
364375
{
365376
m_formspec = formspec;
366-
m_game_formspec = game_formspec;
367377
}
368378

369379
~FormspecFormSource()
370-
{
371-
*m_game_formspec = 0;
372-
}
380+
{}
373381

374382
void setForm(std::string formspec) {
375383
m_formspec = formspec;
@@ -381,7 +389,6 @@ class FormspecFormSource: public IFormSource
381389
}
382390

383391
std::string m_formspec;
384-
FormspecFormSource** m_game_formspec;
385392
};
386393

387394
#endif

0 commit comments

Comments
 (0)
Please sign in to comment.