Page 1 of 1

[SOLVED] Subscribing to a global function.

Posted: Fri May 07, 2010 20:14
by agamemnus
For my wrapper to work, I need to be able to subscribe to a global function, using a pointer to a function memory location.

I cannot figure out how to do this. I can't even figure out how to subscribe to a global function...

Here is the code:

Code: Select all

void DLL_EXPORT CEGUIwindowSubscribeEvent (u32 *windowPtr, char *eventString, unsigned int *funcPtr) {
((CEGUI::Window*)windowPtr)->subscribeEvent (eventString, (reinterpret_cast<bool(*)(const CEGUI::EventArgs&)>(funcPtr)) );
}


There's no error here, but it does not seem to fire at all. The test eventString is "FrameWindow:::EventClicked".

Re: Subscribing to a global function.

Posted: Sat May 08, 2010 11:23
by CrazyEddie
The code, as discussed the other day, should be fine. The event string is the issue, generally (but not always - for historical / compatibility reasons) the string content is the same as the C++ symbol but without the class name and without the 'Event' prefix. So, for the symbol FrameWindow::EventCloseClicked the string is simply "CloseClicked".

For info, there is no event with the symbol "FrameWindow:::EventClicked" used in the default system.

CE.

Re: Subscribing to a global function.

Posted: Sun May 09, 2010 04:37
by agamemnus
Wow.... it works! Thank you.

Now, all I need is to figure out how I can reference the event arguments and I'll be all set. :lol:

Edit: Omg, omg, omg, it works! It all works! *dances around ecstatically* Mouahahahaha.... :twisted:

Re: Subscribing to a global function.

Posted: Sun May 09, 2010 15:49
by CrazyEddie
:shock:

Re: Subscribing to a global function.

Posted: Mon May 10, 2010 15:55
by agamemnus
Hmm... how do I modify the event subscription call so that it took a data type pointer as a second parameter?

IE:

* I want to take the "this" from my "class" (we call them UDTs or user-define-types in Freebasic.. they work slightly differently) and convert it into a u32 pointer.
* Then, I want to pass it to the event subscription in such a way that my event callback function receives first a pointer to eventargs and then a pointer to the class.

Re: Subscribing to a global function.

Posted: Tue May 11, 2010 08:46
by CrazyEddie
The signature for an event handler must match:

Code: Select all

bool function_name(const CEGUI::EventArgs&);

You can't add (or change) arguments or argument types.

Also be aware that a class does not have a 'this' pointer. Each instance of the class has a pointer, and within that instance the pointer is 'this'.

CE.

Re: Subscribing to a global function.

Posted: Wed May 12, 2010 02:43
by agamemnus
CrazyEddie wrote:The signature for an event handler must match:

Code: Select all

bool function_name(const CEGUI::EventArgs&);

You can't add (or change) arguments or argument types.

Also be aware that a class does not have a 'this' pointer. Each instance of the class has a pointer, and within that instance the pointer is 'this'.

CE.


You mean to say the "this" pointer is somehow static within the class instance? Or what? In Freebasic, I think, the this pointer is invisibly passed to the function... in this case, it has to be visible...

Re: Subscribing to a global function.

Posted: Wed May 12, 2010 09:54
by scriptkid
'This' is not static; it's different per instance (it *is* the instance). The 'invisible' pass only happens when a method calls into another method of its own class. C++ does that too.

Okay, about passing your 'this' to a class. First, i don't understand your requirement. Cegui will only trigger events for Windows, but you want to use it for your own custom classes too? Or classes which have a 1:1 relationship with a Cegui Window?

Anyhow, here is some input which might help:

What you can do is define your own eventArgs class, which is based on CEGUI::EventArgs. Then you can add new variables to that one. For example:

Code: Select all

class MyEventArgs: public CEGUI::EventArgs {
public:
  int* m_this;
}


(for exact syntax and requirements, look at CEGUI::MouseEventArgs for example).

Of course, this only works when you are firing the event yourself, otherwise Cegui will decide for its own eventArgs versions.

If this is too much hassle, or if Cegui is firing your events, you always get the Window (args->m_window). If you have a 1:1 relation with your own object, you can set its userid or data:

Code: Select all

myWindow->setUserID((int*)this);


And then in your eventhandler:

Code: Select all

int* relatedInstance = args->m_window->getUserID();


HTH.

Re: Subscribing to a global function.

Posted: Wed May 12, 2010 15:37
by agamemnus
Hey, good idea. Hackish, but a good idea. Thanks. :D

Re: Subscribing to a global function.

Posted: Thu May 13, 2010 11:13
by scriptkid
agamemnus wrote:Hey, good idea. Hackish, but a good idea. Thanks. :D


No, it's by design to be able to do such things :)