Page 1 of 2
Subscriber problems
Posted: Tue Aug 02, 2005 14:07
by J_A_X
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.
Re: Subscriber problems
Posted: Tue Aug 02, 2005 19:55
by lindquist
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)
Re: Subscriber problems
Posted: Tue Aug 02, 2005 20:19
by J_A_X
*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.
![Crying or Very sad :cry:](./images/smilies/icon_cry.gif)
Re: Subscriber problems
Posted: Tue Aug 02, 2005 20:25
by lindquist
The line above should not cause any trouble. But it's impossible to say anything without more information. CEGUI log / call stack etc...
Re: Subscriber problems
Posted: Tue Aug 02, 2005 20:34
by J_A_X
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...
Re: Subscriber problems
Posted: Wed Aug 03, 2005 15:17
by lindquist
I'm not sure I quite get your description, and you should really be debugging with a debug build....
Re: Subscriber problems
Posted: Wed Aug 03, 2005 16:53
by J_A_X
it is a debug build....
Re: Subscriber problems
Posted: Thu Aug 04, 2005 09:15
by CrazyEddie
It would be helpful if you told us the exeption that you're catching
![Wink ;)](./images/smilies/icon_wink.gif)
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.
Re: Subscriber problems
Posted: Thu Aug 04, 2005 13:25
by J_A_X
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.
Re: Subscriber problems
Posted: Fri Aug 05, 2005 07:55
by CrazyEddie
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?
Re: Subscriber problems
Posted: Fri Aug 05, 2005 13:35
by J_A_X
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...
Re: Subscriber problems
Posted: Fri Aug 05, 2005 18:19
by CrazyEddie
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
![Confused :?](./images/smilies/icon_confused.gif)
Re: Subscriber problems
Posted: Fri Aug 05, 2005 18:37
by J_A_X
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
Re: Subscriber problems
Posted: Sat Aug 06, 2005 08:03
by CrazyEddie
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.
Re: Subscriber problems
Posted: Tue Aug 09, 2005 14:52
by J_A_X
thanks eddie, now that works
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?