Subscriber problems

For help with anything that CEGUI doesn't offer straight out-of-the-box, e.g.:
- Implementation of new features, such as new Core classes, widgets, WindowRenderers, etc. ...
- Modification of any existing features for specific purposes
- Integration of CEGUI in new engines or frameworks and writing of new plugins (Renderer, Parser, ...) or modules

Moderators: CEGUI MVP, CEGUI Team

User avatar
J_A_X
Quite a regular
Quite a regular
Posts: 72
Joined: Wed Jun 29, 2005 13:18
Contact:

Subscriber problems

Postby J_A_X » Tue Aug 02, 2005 14:07

So I got this code to subscribe an event to a FrameWindow:

Code: Select all

console = (CEGUI::FrameWindow*)GUIWindow::getPtr();    console->subscribeEvent(CEGUI::FrameWindow::EventNamespace+"/"+CEGUI::FrameWindow::EventZOrderChanged,CEGUI::Event::Subscriber(&Console::ConsoleFocus));


I have the following function that's suppose to handle the event:

Code: Select all

void Console::ConsoleFocus(const CEGUI::EventArgs& e){
    const CEGUI::WindowEventArgs& we = (const CEGUI::WindowEventArgs&)e;
    box->activate();
}


Now, when i try to compile, it won't work, it gives me the following error:

d:\mi13685\My Documents\cegui_mk2\include\CEGUIEvent.h(85): error C2064: term does not evaluate to a function taking 1 arguments


So yeah, there seems to be a problem in CEGUIEvent.h for this:

Code: Select all

template <class Functor, typename Ret, typename Args>
class _functorBinder : public SubscriberInterface<Ret,Args>
{
public:
  virtual Ret operator()(Args args) const
  {
    return d_f(args);
  }
  _functorBinder(const Functor& f) : d_f(f) {}
protected:
  Functor d_f;
};


Line 85 is the "return d_f(args)" one. I'm not too sure this is caused by something i've done with my side of the code or if this is a bug of some kind. Whatever it is, I won't let me compile.

User avatar
lindquist
CEGUI Team (Retired)
Posts: 770
Joined: Mon Jan 24, 2005 21:20
Location: Copenhagen, Denmark

Re: Subscriber problems

Postby lindquist » Tue Aug 02, 2005 19:55

the handler callback should return a bool not void

and the is the handler a static function of Console ?

the code

Code: Select all

CEGUI::Event::Subscriber(&Console::ConsoleFocus)

is for a static function (I don't place an ampersand in front of the function)

if it's not static you should do something like this instead:

Code: Select all

CEGUI::Event::Subscriber(Console::ConsoleFocus,pointer_to_instance_of_your_Console_class)

User avatar
J_A_X
Quite a regular
Quite a regular
Posts: 72
Joined: Wed Jun 29, 2005 13:18
Contact:

Re: Subscriber problems

Postby J_A_X » Tue Aug 02, 2005 20:19

*sigh*

you guys need more documentation on event subscribers, i have to look through the coding to try to figure this out, and it ain't helping much...

lindquist, your suggestion did work, it does compile now. I now have this line of code:

Code: Select all

console->subscribeEvent(CEGUI::FrameWindow::EventZOrderChanged,CEGUI::Event::Subscriber(Console::ConsoleFocus,this));


Which compiles and seems to work, but for some reason now, the next window that gets added to root causes an error. I didn't change anything in my coding since and it just plainly crash, when i remove this line of code, all is good.

:cry:

User avatar
lindquist
CEGUI Team (Retired)
Posts: 770
Joined: Mon Jan 24, 2005 21:20
Location: Copenhagen, Denmark

Re: Subscriber problems

Postby lindquist » Tue Aug 02, 2005 20:25

The line above should not cause any trouble. But it's impossible to say anything without more information. CEGUI log / call stack etc...

User avatar
J_A_X
Quite a regular
Quite a regular
Posts: 72
Joined: Wed Jun 29, 2005 13:18
Contact:

Re: Subscriber problems

Postby J_A_X » Tue Aug 02, 2005 20:34

No, its not the line above causing trouble, its what happens afterwards...

I have 2 windows that are being instanciated through classes of my own, console and alertbox.

Console gets instantiated from a layout, then calls the Console::setEvents() function to set all the events (i only have one at the moment, which is the one above).

After its been called from a layout, it is added as a child to root. When that's done, the alertbox layout gets called then added as a child to root, but when it does this action, it returns an error which gets caught by my try-catch and creates an error on screen.

this is the log:
02/08/2005 16:29:21 (InfL2) ---- Beginning loading of GUI layout from '../layouts/Console.layout' ----
02/08/2005 16:29:21 (InfL2) Window 'Console__auto_titlebar__' of type 'TaharezLook/Titlebar' has been created.
02/08/2005 16:29:21 (InfL2) Window 'Console__auto_closebutton__' of type 'TaharezLook/CloseButton' has been created.
02/08/2005 16:29:21 (InfL2) Window 'Console' of type 'TaharezLook/FrameWindow' has been created.
02/08/2005 16:29:21 (InfL2) Window 'ConsoleOutput__auto_vscrollbar____auto_thumb__' of type 'TaharezLook/VerticalScrollbarThumb' has been created.
02/08/2005 16:29:21 (InfL2) Window 'ConsoleOutput__auto_vscrollbar____auto_incbtn__' of type 'TaharezLook/Button' has been created.
02/08/2005 16:29:21 (InfL2) Window 'ConsoleOutput__auto_vscrollbar____auto_decbtn__' of type 'TaharezLook/Button' has been created.
02/08/2005 16:29:21 (InfL2) Window 'ConsoleOutput__auto_vscrollbar__' of type 'TaharezLook/VerticalScrollbar' has been created.
02/08/2005 16:29:21 (InfL2) Window 'ConsoleOutput__auto_hscrollbar____auto_thumb__' of type 'TaharezLook/HorizontalScrollbarThumb' has been created.
02/08/2005 16:29:21 (InfL2) Window 'ConsoleOutput__auto_hscrollbar____auto_incbtn__' of type 'TaharezLook/Button' has been created.
02/08/2005 16:29:21 (InfL2) Window 'ConsoleOutput__auto_hscrollbar____auto_decbtn__' of type 'TaharezLook/Button' has been created.
02/08/2005 16:29:21 (InfL2) Window 'ConsoleOutput__auto_hscrollbar__' of type 'TaharezLook/HorizontalScrollbar' has been created.
02/08/2005 16:29:21 (InfL2) Window 'ConsoleOutput' of type 'TaharezLook/MultiLineEditbox' has been created.
02/08/2005 16:29:21 (InfL2) Window 'ConsoleCommandBox' of type 'TaharezLook/Editbox' has been created.
02/08/2005 16:29:21 (InfL2) Window 'ConsoleSendButton' of type 'TaharezLook/Button' has been created.
02/08/2005 16:29:21 (InfL1) ---- Successfully completed loading of GUI layout from '../layouts/Console.layout' ----
02/08/2005 16:29:21 (InfL2) ---- Beginning loading of GUI layout from '../layouts/AlertBox.layout' ----
02/08/2005 16:29:21 (InfL2) Window 'AlertBox__auto_titlebar__' of type 'TaharezLook/Titlebar' has been created.
02/08/2005 16:29:21 (InfL2) Window 'AlertBox__auto_closebutton__' of type 'TaharezLook/CloseButton' has been created.
02/08/2005 16:29:21 (InfL2) Window 'AlertBox' of type 'TaharezLook/FrameWindow' has been created.
02/08/2005 16:29:21 (InfL1) ---- Successfully completed loading of GUI layout from '../layouts/AlertBox.layout' ----


this is the call stack:
> PCTGUI.exe!GUIWindow::init(CEGUI::String type={...}, CEGUI::String name={...}, CEGUI::String layout={...}, CEGUI::String parent={...}, CEGUI::MetricsMode mode=Absolute, CEGUI::Size size={...}, CEGUI::Vector2 point={...}) Line 49 C++
PCTGUI.exe!Engine::init() Line 76 + 0x133 C++
PCTGUI.exe!WinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, char * lpCmdLine=0x00151f12, int nCmdShow=1) Line 37 + 0xb C++
PCTGUI.exe!WinMainCRTStartup() Line 251 + 0x30 C
kernel32.dll!7c816d4f()
ntdll.dll!7c915b4f()
kernel32.dll!7c8399f3()


There is certainly something funky here...

User avatar
lindquist
CEGUI Team (Retired)
Posts: 770
Joined: Mon Jan 24, 2005 21:20
Location: Copenhagen, Denmark

Re: Subscriber problems

Postby lindquist » Wed Aug 03, 2005 15:17

I'm not sure I quite get your description, and you should really be debugging with a debug build....

User avatar
J_A_X
Quite a regular
Quite a regular
Posts: 72
Joined: Wed Jun 29, 2005 13:18
Contact:

Re: Subscriber problems

Postby J_A_X » Wed Aug 03, 2005 16:53

it is a debug build....

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Re: Subscriber problems

Postby CrazyEddie » Thu Aug 04, 2005 09:15

It would be helpful if you told us the exeption that you're catching ;) Since it does not appear to be a cegui exception, I'm guessing an access violation or some such...

We're also going to have to get deeper than the 'PCTGUI.exe!GUIWindow::init' function. You may have to post some code so we can see specifically what you're doing in there.

Definately sounds like an uninitialised pointer or similar to me.

User avatar
J_A_X
Quite a regular
Quite a regular
Posts: 72
Joined: Wed Jun 29, 2005 13:18
Contact:

Re: Subscriber problems

Postby J_A_X » Thu Aug 04, 2005 13:25

Well, to tell you the truth, I'm not even sure what I'm doing is what I want it to do.

I just want to add some functionality to windows and buttons (mousedown, mouseup,drag,onfocus,etc..) and when it catches these events, i want it to call a specific function for it. There isn't anything about it in the tutorials and its still pretty vague in the forum...

CE: There isn't an error from CEGUI, seems like its doing something its not suppose to and not giving away an error (maybe something you should change because its hard to catch).

After the evensubscriber has been called, when the next AddChildWindow function is called to add another window to the root window, my try-catch catches it and then just gives out and error.

This is the exception given by the output window:

First-chance exception at 0x0056eac9 in PCTGUI.exe: 0xC00000FD: Stack overflow.


It seems to be from inside CEGUI which doesn't let me get into when I'm in debug mode.

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Re: Subscriber problems

Postby CrazyEddie » Fri Aug 05, 2005 07:55

Stack overflows are usually caused by some infinite recursion issue. For example, I have seen this when, from within a 'Sized' handler, the window size is changed again (thus firing the event again, and so on...)

I have not seen the behaviour you describe, so am not sure what it could be at the moment. What is the window type you add in the second AddChildWindow?

User avatar
J_A_X
Quite a regular
Quite a regular
Posts: 72
Joined: Wed Jun 29, 2005 13:18
Contact:

Re: Subscriber problems

Postby J_A_X » Fri Aug 05, 2005 13:35

They're both FrameWindows.

You say its cause of recursion of a handler, but I only have one (the one noted in this thread).

And can one of you please give an example of some sort for basic button functionality? This thing is driving me insane...

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Re: Subscriber problems

Postby CrazyEddie » Fri Aug 05, 2005 18:19

Well I didn't say it definitely was a recursive handler issue, I said that's about the most common cause of a stack overflow with CEGUI.

Basic button functionality - do you mean without using one of the push button classes?

You may have to post your layouts and some code, it's very difficult to help when we basically are coming here and making wild guesses due to lack of info :?

User avatar
J_A_X
Quite a regular
Quite a regular
Posts: 72
Joined: Wed Jun 29, 2005 13:18
Contact:

Re: Subscriber problems

Postby J_A_X » Fri Aug 05, 2005 18:37

Unless you wanna go through 100kb of coding, be my guess, and that's not counting the huge layouts I've made...

The layouts are fine, everything is fine EXCEPT when I placed that line of code in.

Frankly, i don't care about it anymore.

The only think I want are some examples for handlers on some pushbutton functionality. So i can base myself on something and start actually placing some events behind the layout.

thanks

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Re: Subscriber problems

Postby CrazyEddie » Sat Aug 06, 2005 08:03

Ok. Consider the following code, which shows one general approach. There are some additional notes at the bottom of the post.

Code: Select all

class myDemoClass_1
{
public:
    // other methods
    ...

    void assignHandlers();

    //
    // Handler methods
    //
    bool handleQuitButton(const CEGUI::EventArgs& args);
    bool handleShowWindowButton(const CEGUI::EventArgs& args);
    bool handleHideWindowButton(const CEGUI::EventArgs& args);

    ...
};

//
// code
//
void myDemoClass_1::assignHandlers()
{
    using namespace CEGUI;

    // get Window manager to save constantly getting singleton.
    WindowManager& wmgr = WindowManager::getSingleton();

    // find the quit button, and assign its handler
    wmgr.getWindow("mySampleApp/QuitButton")->subscribeEvent(
        PushButton::EventClicked,
        Event::Subscriber(&myDemoClass_1::handleQuitButton, this));

    // find the hide button, and assign its handler
    wmgr.getWindow("mySampleApp/HideButton")->subscribeEvent(
        PushButton::EventClicked,
        Event::Subscriber(&myDemoClass_1::handleHideWindowButton, this));

    // find the show button, and assign its handler
    wmgr.getWindow("mySampleApp/ShowButton")->subscribeEvent(
        PushButton::EventClicked,
        Event::Subscriber(&myDemoClass_1::handleShowWindowButton, this));
}

bool myDemoClass_1::handleQuitButton(const CEGUI::EventArgs& args)
{
    // this does not exist in this example, it's intended to
    // represent a global object where we can signal the app
    // to terminate.
    myGlobalApp.signalQuit(true);

    // signal that we handled the event, to prevent
    // possible propogation of event to other windows.
    return true;
}

bool myDemoClass_1::handleShowWindowButton(const CEGUI::EventArgs& args)
{
    using namespace CEGUI;

    WindowManager& wmgr = WindowManager::getSingleton();
    // find the window to show/hide
    wmgr.getWindow("mySampleApp/someWindow")->show();

    // signal that we handled the event, to prevent
    // possible propogation of event to other windows.
    return true;
}

bool myDemoClass_1::handleHideWindowButton(const CEGUI::EventArgs& args)
{
    using namespace CEGUI;

    WindowManager& wmgr = WindowManager::getSingleton();
    // find the window to show/hide
    wmgr.getWindow("mySampleApp/someWindow")->hide();

    // signal that we handled the event, to prevent
    // possible propogation of event to other windows.
    return true;
}


The key thing here, which some people initially miss, is the use of the 'this' pointer when creating the Event::Subscribers. Here we're passing 'this' because this is an instance of the object containing the handler functions. If your handler functions were in some other class, say 'myHandlersClass', then instead of passing 'this' you would need to pass a pointer to an instance of the 'myHandlersClass'. If you are subscribing free functions, or static member functions you do not need this object pointer at all, and can just pass a pointer to the function.

User avatar
J_A_X
Quite a regular
Quite a regular
Posts: 72
Joined: Wed Jun 29, 2005 13:18
Contact:

Re: Subscriber problems

Postby J_A_X » Tue Aug 09, 2005 14:52

thanks eddie, now that works :D

I just have a small question now. I'm trying to a dynamic resizing grid for the application I'm creating. I have a move and a zoom button for my grid and they are subscribed to a function. They are both under the "clicked" event.

I need to know if the function subscribed is called every update while it is clicked or it is just a one time thing. If it is a one time thing, is it possible to have the function called every update with another event trigger?


Return to “Modifications / Integrations / Customisations”

Who is online

Users browsing this forum: No registered users and 4 guests