Problem with GUI tutorial snippets

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
brianempson
Posts: 14
Joined: Sun Apr 24, 2011 4:10 am

Problem with GUI tutorial snippets

Post by brianempson »

Hello, I am new to the engine and just started fiddling with some different things. I was messing around with the GUI functions, specifically using an EventReceiver to capture GUI commands, it worked before, but I changed something (don't remember what) and now I get "Runtime Error, pure virtual function!" upon execution.

Here is the conditional path that leads to the error, pressing ` causes a runtime error.

Code: Select all

				if (keyboard.getKey() == '`')
				{
					if (show_console == 0)
					{
						show_console = 1;
						IGUIScrollBar* con_scroll = guienv->addScrollBar(true,rect<s32>(400, 50, 410, 350), 0, GUI_ID_CONSOLE_SCROLL);
						con_scroll->setMax(500);
						con_scroll->setPos(0);
						IGUIListBox* con_win = guienv->addListBox(rect<s32>(50, 50, 400, 350));
						IGUIEditBox* con_edit = guienv->addEditBox(L"Commands go here.", rect<s32>(50, 350, 400, 360));
						guienv->hasFocus(con_edit);
						SAppContext context;
				        context.device = device;
						context.counter = 0;
						context.listbox = con_win;
						// Then create the event receiver, giving it that context structure.
						GuiEvent guirecv(context);
						// And tell the device to use our custom event receiver.
						device->setEventReceiver(&guirecv);
					}
					else
					{
						show_console = 0;
						camera->setInputReceiverEnabled(true);
						device->getCursorControl()->setVisible(false);
						//device->setEventReceiver(&keyboard);
					}
				}
Removing this line "fixes" it, but I don't get the functionality I want (a working receiver):

Code: Select all

device->setEventReceiver(&guirecv);
Here is the actual receiver code:

Code: Select all


#ifndef GUI_H
#define GUI_H

#include "polybius.h"


class GuiEvent : public IEventReceiver
{
public:
        GuiEvent(SAppContext & context) : Context(context) { }

        virtual bool OnEvent(const SEvent& event)
        {
                if (event.EventType == EET_GUI_EVENT)
                {
                        s32 id = event.GUIEvent.Caller->getID();
                        IGUIEnvironment* env = Context.device->getGUIEnvironment();
                        switch(event.GUIEvent.EventType)
                        {
							case EGET_SCROLL_BAR_CHANGED:
                                if (id == GUI_ID_CONSOLE_SCROLL)
                                {
                                        s32 pos = ((IGUIScrollBar*)event.GUIEvent.Caller)->getPos();
                                        
                                        for (u32 i=0; i<EGDC_COUNT ; ++i)
                                        {
                                                SColor col = env->getSkin()->getColor((EGUI_DEFAULT_COLOR)i);
                                                col.setAlpha(pos);
                                                env->getSkin()->setColor((EGUI_DEFAULT_COLOR)i, col);
                                        }
                                        
                                }
                                break;
							case EGET_EDITBOX_ENTER:
								if (id == GUI_ID_CONSOLE_EDIT)
								{
								//	Context.console_command = ((IGUIEditBox*)event.GUIEvent.Caller)->getText();
								//	Context.device->getLogger()->log(Context.console_command.c_str());
								}
								break;
                        default:
                                break;
                        }
                }

                return false;
        }

private:
        SAppContext & Context;
};

#endif
Here is the header, polybius.h:

Code: Select all

#ifndef POLYBIUS_H
#define POLYBIUS_H

//Header for all engine functions
#include <irrlicht.h>
#include <vector>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

#define VERSION .1a

class KeyboardEvent; //Forward declarations
class ConsoleEvent;

// Declare a structure to hold some context for the event receiver so that it
// has it available inside its OnEvent() method.
struct SAppContext
{
        IrrlichtDevice *device;
        s32             counter;
        IGUIListBox*    listbox;
//		stringw console_command;
};

// Define some values that we'll use to identify individual GUI controls.
enum
{
        //GUI_ID_QUIT_BUTTON = 101,
        //GUI_ID_NEW_WINDOW_BUTTON,
        //GUI_ID_FILE_OPEN_BUTTON,
        GUI_ID_CONSOLE_SCROLL,
		GUI_ID_CONSOLE_EDIT
};

#endif
I put breakpoints at every line on the receiver code, the program jumps to it, hits the constructor and then dies after it hits the problem line. My programming is pretty sloppy and I'm not versed in virtual functions, could anyone help me out?
[/code]
CuteAlien
Admin
Posts: 9718
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

You set your event-receiver to a local variable. Local variables are created on the stack and destroyed as soon as the scope ends (the scope ends on the } bracket). So when you pass a pointer to that variable to Irrlicht then Irrlicht will use an event-receiver which is already destroyed in memory the next line.

So either use a scope which exist longer (for example global, or in your main() function) or create your event-receiver on the heap instead (using new/delete for your objects).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Post Reply