application callback hookup

Forum for general chit-chat or off-topic discussion.

Moderators: CEGUI MVP, CEGUI Team

User avatar
granx
Quite a regular
Quite a regular
Posts: 80
Joined: Fri Apr 29, 2005 21:58

application callback hookup

Postby granx » Thu Jun 16, 2005 02:01

Hi,
I was wondering, how can I make sure my application's callbacks are assigned to components in the GUI? Does this happen during the parse of the XML file? If so, how do I register my callbacks? Is this how people are using CEGUI?

If this is not supported, I would like to help make sure it is supported. What I am looking for is a mechanism to hook up unique identifiers (strings,ints), which will be found in the XML layout file, to my app's callback functions.

Please tell me if I need to explain more as I feel I am not doing a good job of it. :(
Thanks,
-John

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

Re: application callback hookup

Postby CrazyEddie » Fri Jun 17, 2005 08:09

Hi,

There is currently no fixed provision for doing this, mainly due to the fact that at the XML level there's no way of knowing how your application is structured. I have a great distaste of anything that forces people to use what I might think is the 'best' way; there is no easy, fits all scenarios, generic solution. However, this does not mean that it can't be done ;)

The system already supports binding of events to scripted code via the XML interface for layouts using the <Event> tag. If you're using a scripting module, you could use this to despatch events back into your code (or any number of other permutations).

Another common alternative, if you're not using scripting, is to write a 'dummy' script module, which can then map names of event handlers from the XML to names of functions you have registered in some application defined 'callback registry'.

Hope this helps,

CE.

User avatar
granx
Quite a regular
Quite a regular
Posts: 80
Joined: Fri Apr 29, 2005 21:58

Re: application callback hookup

Postby granx » Fri Jun 17, 2005 17:26

Hi CE,
Thanks for your reply. You're helping me to understand the whole picture. The ideas about scripting might prove to be a good solution. However, I had another idea in my head, so I'll try to explain that.

I would like to try to use the CELayout Editor to build the GUI for my application. I thought it would make sense to "hook up" a registered application callback to any action buttons I create in the GUI layout.

Now you are telling me an "Event" tag is in the XML spec. First off, where can I find documentation on available tags? This is possibly the structure I am needing. I just glanced at the API reference and I think it will work. However, I think it will be the responsibility of the layout file parser to actually 'hook up' Events to GUI elements when one is found in the layout.

The possibility of an editor helping to enable application Events is exciting, and I hope I can help to enable a general way for CEGUI to take advantage of this. If I was doing a better job explaining the thoughts running around in my head, maybe others would be excited too :roll:

My thought is that while using the editor, I would add an identifier to an Event tag. While parsing the layout file, this identifier would be a key to a map of application functions.

One challenge is asking client code to 'register' (fill the map) application function pointers with identifiers that will exactly match the Event tag's identifier. I see the registration happening on an instance of the class that parses the layout.xml.

The other challenge is for a user of the editor to pick from a list of identifiers that will eventually correspond to callback functions. Perhaps this could be as dumb as relying upon an application's documentation to provide a list of identifiers and which have been hard coded to register with CEGUI's xml parser.

Does this sound possible to anyone but me?

Some pseudocode might describe this better:
<a href="http://rafb.net/paste/results/YdShBb97.html">app code</a>

From this code, you can see the identifiers can be strings that make sense to the user. "QuitGame" could identify App::QuitGame(), for example. This would make it easier for the "modeler" using the CELayout Editor.

I could help to add this support, I think I know what needs to happen. If this sounds reasonable, I think it would really increase the power and flexibility of CEGUI.

Thanks for listening. Please stay in touch,
-granx

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

Re: application callback hookup

Postby lindquist » Fri Jun 17, 2005 20:35

I've been unable to get a connection to the pseudo-code link, but from the text I have an idea that could be implemented fairly easily.

If we were to add another virtual member to CEGUI::ScriptModule, say:

Code: Select all

virtual Event::Subscriber CEGUI::ScriptModule::getEventSubscriber(const String& function);
(a better name probably exists...)

and modify the XML-layout-handler's event-subscription-code from this:

Code: Select all

d_stack.back()->subscribeEvent(eventName, ScriptFunctor(functionName));


to this:

Code: Select all

ScriptModule* script_module = System::getSingleton().getScriptingModule();
if (script_module!=NULL)
{
   d_stack.back()->subscribeEvent(eventName, script_module->getEventSubscriber(functionName));
}
else
{
   d_stack.back()->subscribeEvent(eventName, ScriptFunctor(functionName));
}



the ScriptModule::getEventSubscriber could have a default implementation like this:

Code: Select all

Event::Subscriber ScriptModule::getEventSubscriber(const String& function)
{
   return ScriptFunctor(function);
}


but a user could easily inherit from fx the Lua module or make a dud-module that did nothing (but overrides getEventSubscriber).
so this function could become:

Code: Select all

Event::Subscriber MyScriptModule::getEventSubscriber(const String& function)
{
   if (function==(utf8*)QuitGame)
   {
      return Event::Subscriber(GameCoreObject::QuitGameHandler, GameCoreObject::getSingletonPrt());
   }
   ...
   ...
   ...
   return ScriptFunctor(function);
}



this would make sure that events that correspond to gamecore functions would be bound a xml load time, and the scriptmodule would never do anything for those special function names.

If using a "real" scripting module behind it, names that was not checked for would behave normally (be scripted).

I think this would be an OK addition to the system...
Let me know what you think (all of you)

If I have'nt missed something totally crucial, this should'nt take too long to get into CVS.

User avatar
granx
Quite a regular
Quite a regular
Posts: 80
Joined: Fri Apr 29, 2005 21:58

Re: application callback hookup

Postby granx » Fri Jun 17, 2005 20:48

Hi lindquist,
Here is the application involvement that I was imagining, actually a somewhat revised version:

Code: Select all

My::App::register_callbacks()
{
  CEGUI::WindowManager* wmgr = CEGUI::WindowManager::getSingletonPtr();
 
  // function signature might need to be templated, or just hard coded.
  wmgr->register_callback(&App::Restart, "Restart" );
  wmgr->register_callback(&App::Quit,    "Quit" );
  wmgr->register_callback(&App::Login,   "Login" );

  wmgr->loadWindowLayout( this->GetLaytoutFile() ); // parse xml & add hooks
}


I was anticipating that the XML parse would hook up the Events, as you showed, and the string found in the XML would help ID the correct callback function. Of course, the rules about the function's signature would have be followed.

Also, I would prefer not to need to make a script, but if that is the only way, then I'll start looking for examples to do this. I use python a little, but I was hoping for complete C++ API support. I'm not sure what using the CEGUI::ScriptModule implies, as I am still learning CEGUI's architecture.

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

Re: application callback hookup

Postby lindquist » Sat Jun 18, 2005 02:24

The approach I mentioned earlier does not necessarily include any scripting.
You're creating a bogus script module that does callback bindings instead...

User avatar
granx
Quite a regular
Quite a regular
Posts: 80
Joined: Fri Apr 29, 2005 21:58

Re: application callback hookup

Postby granx » Mon Jun 27, 2005 18:32

CE,
So, I'm finally into the phase of my development to crank out a ScriptModule that knows about all app callbacks and a string to map them into a registry. Are their any examples? If not, I would be happy to write an Imbiciles guide, with some help.

Also, I am still looking for the XML docs about how to form Event tags.

Thanks, -granx

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

Re: application callback hookup

Postby CrazyEddie » Tue Jun 28, 2005 08:36

Hi,

The ./XMLRefSchema/Readme.txt file contains documentation for the XML files. What you're looking for is right at the end of that file (all current versions).

There's no examples for this specifically. The closest thing would be Lindquists Lua tutorials on the Wiki, though these focus more on using the supplied Lua based ScriptModule rather than writing a new one from scratch.

So, please do contribute some kind of tutorial/guide once you have things working :)

User avatar
granx
Quite a regular
Quite a regular
Posts: 80
Joined: Fri Apr 29, 2005 21:58

Re: application callback hookup

Postby granx » Fri Jul 01, 2005 17:18

Ehhhhh,
I'm am ever closer to having a nice example of a Producer-CEGUI based application, with behavior driven from the Event tag. My script module seems to be doing its job. I have overloaded the function:

Code: Select all

virtual bool executeScriptedEventHandler(const CEGUI::String& handler_name, const CEGUI::EventArgs& e)

to respond to a map of strings corresponding to application callbacks. If the 'handler_name' string is in the map, I execute the corresponding callback. I think its quite nice, but I am wondering what I should be doing with the second argument passed into the script module's function,

Code: Select all

const CEGUI::EventArgs& e


The EventArgs.h file says there is a member, d_handled, in which "handlers" should set this value to 'true' when handled. Well, I thought my script module was the handler, but I have no idea how I am supposed to modify the members of a const argument. So, why is the script module's interface requiring the EventArg? What can a script module do with it? What is the EventArg's purpose?

Thanks, -granx

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

Re: application callback hookup

Postby CrazyEddie » Fri Jul 01, 2005 18:34

Good to hear things are coming along for you :)

The EventArgs is a base class for some other object that your handler gets passed. The exact object type depends upon the event - and you can cast to the specific type when you need to extract relevant information. For example, mouse events get passed a MouseEventArgs which would tell you what button was pressed, or where the mouse is. Most window based events (like sized or moved) give you a WindowEventArgs, which basically contains a pointer to the window that generated the event.

The passed EventArgs based object is const, so in order to tell the system whether or not you handled the event, you need to return a boolean from the executeScriptedEventHandler method, the system will combine results from all subscribed listeners and ultimately decide whether the event was consumed. Basically, in that method you probably want to be passing the EventArgs on to your 'real' handler method and then returning the result from that.

CE.


Return to “Offtopic Discussion”

Who is online

Users browsing this forum: No registered users and 15 guests