Page 1 of 1

[SOLVE]Problem with listening event

Posted: Fri Jan 02, 2009 11:20 pm
by ayboangelus
Hi all, i have a problem, when my listening event is running, it crash.

I have this code:

Code: Select all

char character::draw()
{
    cEventReceiver eventReceiver;
    device->setEventReceiver(&eventReceiver);
    return 0;
}
and my listening event:

Code: Select all

#ifndef EVENEMENT_H_INCLUDED
#define EVENEMENT_H_INCLUDED

#include <irrlicht.h>
#include <iostream>

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

enum
{
        GUI_ID_VAL1,
        GUI_ID_VAL2,
        GUI_ID_VAL3
};

class cEventReceiver : public IEventReceiver
{
public:

	cEventReceiver() {}

        virtual bool OnEvent(const SEvent& event)
        {
                if (event.EventType == EET_GUI_EVENT)
                {
                        s32 id = event.GUIEvent.Caller->getID();
                        IGUIEnvironment* env = device->getGUIEnvironment();

                        if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED)
                        {
                                if (id == GUI_ID_VAL1 || id == GUI_ID_VAL2 || id == GUI_ID_VAL3)
                                { IDChar = IDperso; }
                        }
                }
                return false;
        }

private:
        int IDChar,IDperso;
        IrrlichtDevice *device;

};
#endif // EVENEMENT_H_INCLUDED
Thanks for your help.[/quote]

Re: Problem with listening event

Posted: Fri Jan 02, 2009 11:31 pm
by Seven
I will take a crack at this one....

Code: Select all

char character::draw()
{
    cEventReceiver eventReceiver;
    device->setEventReceiver(&eventReceiver);
    return 0;
}
it appears that you are creating an eventreceiver every time you draw the character? so if you are running 30 frames per second, you are creating an event receiver and setting it to the device 30 times per second? That doesnt seem right :)


Code: Select all

class cEventReceiver : public IEventReceiver
{
public:

	cEventReceiver() {}

        virtual bool OnEvent(const SEvent& event)
        {
                if (event.EventType == EET_GUI_EVENT)
                {
                        s32 id = event.GUIEvent.Caller->getID();
                        IGUIEnvironment* env = device->getGUIEnvironment();

                        if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED)
                        {
                                if (id == GUI_ID_VAL1 || id == GUI_ID_VAL2 || id == GUI_ID_VAL3)
                                { IDChar = IDperso; }
                        }
                }
                return false;
        }

private:
        int IDChar,IDperso;
        IrrlichtDevice *device;

};
where do you set device to something valid?


I highly recommend that you get one of the tutorials off of the website to see how all of this is done.

Posted: Fri Jan 02, 2009 11:44 pm
by ayboangelus
I have try it, and get another but no succeed that's why i post there.

Need help for understand better.

Posted: Sat Jan 03, 2009 12:03 am
by Seven
post all of your main.cpp file code for us to look at

Posted: Sat Jan 03, 2009 12:50 am
by vitek
He's already showed you the problem. You just didn't notice it...

Code: Select all

char character::draw() 
{ 
    cEventReceiver eventReceiver; 
    device->setEventReceiver(&eventReceiver); 
    return 0; 
} 
The problem is that he passes a pointer to his event receiver to the device, and then his event receiver goes out of scope and is destroyed. The device then attempts to send events to this defunct event receiver. Boom.

Posted: Sat Jan 03, 2009 1:21 am
by Seven
and he does it in the draw function every frame. he also tries to use an undefined private device inside the receiver. in the end, it looks like the entire code is a malfunction so again I must suggest that he go back to compiling the tutorials and learning from them.

Posted: Sat Jan 03, 2009 9:49 am
by ayboangelus
i succed to make an exemple like tuto but when i put it in my code, it crash :(

if you want that's is the new code:

character.h

Code: Select all

#ifndef CHARACTER_H
#define CHARACTER_H
#include "Login.h"
#include <irrlicht.h>

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace gui;

struct SAppContext
{
        IrrlichtDevice *device;
};

// Define some values that we'll use to identify individual GUI controls.
enum
{
        GUI_ID_VAL1,
        GUI_ID_VAL2,
        GUI_ID_VAL3
};
class MyEventReceiver : public IEventReceiver
{
public:
        MyEventReceiver(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();

                        if(event.GUIEvent.EventType == EGET_BUTTON_CLICKED)
                        {
                                if (id == GUI_ID_VAL1 || id == GUI_ID_VAL2 || id == GUI_ID_VAL3)
                                {
                                IDChar = 11;
                                stringw temp = L" ";
                                temp += IDChar;
                                env->addStaticText(temp.c_str(),rect<s32>(380,700,670,750),false);
                                }
                                        return true;
                        }
                        return false;
                }

                return false;
        }

private:
        int IDChar, IDperso;
        SAppContext & Context;
};

class character
{
    public:
        character(IrrlichtDevice* Device);
        ~character();
        char draw();
        int IDChar, IDperso;
        int fonction() { return IDChar; }

    private:
        IrrlichtDevice* device;
        IVideoDriver *driver;
        ISceneManager *scenegraph;
        IGUIEnvironment *env;
        IGUIImage *img;
        IAnimatedMesh* modele;
        IAnimatedMeshSceneNode* Nmodele;
        IAnimatedMesh* modele2;
        IAnimatedMeshSceneNode* Nmodele2;
        IGUIEnvironment *gui;
};
#endif
character.cpp

Code: Select all

#include "character.h"
#include <iostream>
#include <fstream>

character::character(IrrlichtDevice* Device)
{
    device = Device;
    driver = device->getVideoDriver ();
    scenegraph = device->getSceneManager ();
    gui = scenegraph->getGUIEnvironment();
    env = device->getGUIEnvironment();

	scenegraph->addCameraSceneNode (0, core::vector3df (0,0,0), core::vector3df (50,0,0));

    IGUIImage *img = env->addImage(rect<s32>(0,0,1024,768));
    img->setImage(driver->getTexture("media/cadre.jpg"));

    int IDperso = 11;

    // Perso 1
    modele2 = scenegraph->getMesh("persos/11.x");
    Nmodele2 = scenegraph->addAnimatedMeshSceneNode(modele2);
    Nmodele2->setPosition(core::vector3df(150,-30,70));
    Nmodele2->setRotation(core::vector3df(0,80,0));
    Nmodele2->setMaterialFlag(video::EMF_LIGHTING, false);
    Nmodele2->setFrameLoop(0,0);
    Nmodele2->setMaterialTexture( 0, driver->getTexture("persos/dwarf.jpg") );

    // Perso 2
    modele = scenegraph->getMesh("persos/test/player.x");
    Nmodele = scenegraph->addAnimatedMeshSceneNode(modele);
    Nmodele->setPosition(core::vector3df(10.5,0.5,-0.5));
    Nmodele->setRotation(core::vector3df(0,-90,0));
    Nmodele->setMaterialFlag(video::EMF_LIGHTING, false);

    env->addButton(core::rect<s32>(190,600,330,650), 0, GUI_ID_VAL1, L"Selection");
    env->addButton(core::rect<s32>(460,600,600,650), 0, GUI_ID_VAL2, L"Selection");
    env->addButton(core::rect<s32>(740,600,880,650), 0, GUI_ID_VAL3, L"Selection");
    IGUIStaticText* choixperso = env->addStaticText(L"Choix du personnage",rect<s32>(380,700,670,750),false);

    SAppContext context;
    context.device = device;
    MyEventReceiver receiver(context);
    device->setEventReceiver(&receiver);
}
character::~character()
{
    scenegraph->clear();
    env->clear();
    gui->clear();
    driver->removeAllTextures();
}
char character::draw()
{
}

Thanks for your help. It do like i want on a classic program but when i want introduce it in mine, big crash without compiler error.

help me please :(

Posted: Sat Jan 03, 2009 6:12 pm
by vitek
Your code here has the same exact problem that it did before...

Code: Select all

character::character(IrrlichtDevice* Device) 
{
    // ...

    SAppContext context; 
    context.device = device; 
    MyEventReceiver receiver(context); 
    device->setEventReceiver(&receiver);
}
The MyEventReceiver object is created on the stack. When the function returns, the object is destroyed automatically. Since you've given the device a pointer to the event receiver, the device will send messages to the event receiver, but by the time an event is processed by the device, the receiver has already been destroyed.

You either need to declare the event receiver at a scope where it will not be deallocated until after the event receiver is dropped, or you need to allocate it on the heap.

Another thing to consider. You've put this code into the character constructor. If you create the receiver on the heap and you create multiple characters, you will leak the previous receiver.

Travis

Posted: Sat Jan 03, 2009 11:31 pm
by ayboangelus
Problem solve, have modify party of code and work well now, thanks for all