Page 1 of 1
[Solved] Events with multiple possible sources
Posted: Mon Feb 20, 2017 20:27
by TheWanderer
Hi all,
I had another quick question, this time having to do with events. In this case, I'm working on a game where there are multiple objects on the screen which the user can click on. Doing so open up a "Item Information" window which, among other things, allows the user to tweak that particular item's behavior or properties (e.g. rename it, turn it on, etc). This window is shared across all items and is populated with the information for the particular item that was clicked.
The question is, once a button in the window is pressed, the callback goes to a static function which is not tied to any one item (since the window is really a global construct not tied to any one item), so I would like to pass some metadata to the callback in order to identify the object which the window is representing. Is there such a mechanism?
So far, I've considered using Properties, having an invisible window and set the text to parse in the callback (hacktastic), or some global variable on my side. I just wanted to see whether there were any alternatives before I started going down those routes (which, TBH, I'm not particularly fond of).
Thank you for any help!
Re: Events with multiple possible sources
Posted: Mon Feb 20, 2017 20:37
by Ident
Not quite sure I understand you correctly.
Can you show us a stub of the event handler, which would be the static function in your case I think?
Just remove all code you dont want to share for whatever reason. I mostly care about the signature and what data you want there.
Re: Events with multiple possible sources
Posted: Mon Feb 20, 2017 21:12
by TheWanderer
Hey, Ident,
A more concrete example. I have two NPC's on the screen, I click one, and a window comes up which allows me to rename it. The callback function for the "Apply" button is part of a Singleton system called the NPCmanager. So I need to determine which NPC was clicked during the callback on in order to rename them. I have this information when the NPC is clicked on.
Code: Select all
bool8_t NPCManager::RenameNPCUICallback( const CEGUI::EventArgs& )
{
CEGUI::Editbox *nameEditBox = static_cast<CEGUI::Editbox*>( m_uiSheet->getChildRecursive("NPCName_EditBox") );
std::string newNPCName( nameEditBox->getText().c_str() );
uint32_t npcId = 0;
/* Somehow determine which NPC this is supposed to apply to */
NPCObject *object = GetNPCById( npcId );
object->setName( newNPCName );
return true;
}
The other worthwhile piece of code would be:
Code: Select all
bool Game::mouseReleased( const OIS::MouseEvent &arg,
OIS::MouseButtonID buttonId )
{
if( buttonId == OIS::MB_Left )
{
// Determine what was clicked
NPCObject *clickedNPC = DetermineClickedNPC( arg );
if( clickedNPC != nullptr)
{
CEGUI::Window *renameWindow = m_uiSheet->getChildRecursive("NPCName_Window")
renameWindow->enable();
renameWindow->setVisible(true);
/* At this point, I would add some metadata to the window as to identify clickedNPC on the callback */
clieckedNPC->getObjId();
}
}
return true;
}
Thanks for the fast response, BTW!
Re: Events with multiple possible sources
Posted: Tue Feb 21, 2017 08:09
by Ident
You could always make a custom widget for that:
- derive from the Editbox
- setup your own WidgetLook based on the new editbox
- use that as widget where you now use some editbox widgetlook
- then override the event type and event handler
- add member variables to the new editbox class to store the info you want (and feed it in with setters in your code after you create this for your NPC)
- in the event handler then cast the event to the new derived type and retrieve the info (such as ID) that you need
or, much simpler and imo preferrable to the above lengthy approach:
- make a user-property to the editbox and just set the ID into there
or, this is what i would do (because imo nothing of this has to do with the UI directly so the UI should be unchanged):
- maintain a static container (e.g. map) of Editbox* to SomeDataStruct mappings
- Everytime you add the editbox for an NPC (in that case you should know what NPC ID it is, right?) you add the editbox to that map and setup the data with it
- later in the handler you know what editbox was clicked and you access the map to retrieve your data
or, in case you only ever can have one editbox at a time:
- make a simple cache of the last NPC ID that had an editbox created. If one is clicked it must be that one.
Re: Events with multiple possible sources
Posted: Tue Feb 21, 2017 20:13
by TheWanderer
Hey, Ident,
Thanks for all the answers. One follow up:
What's the proper way of programmatically (as opposed to in XML) defining a new Property, one that can be added with addProperty()? Would it be using the TplProperty class? I ask because that class requires getters / setters which are usually defined in the class defining the element itself. I can certainly make global ones, but then I might as well just use those directly. I also ran across the PropertyDefinition class, bu wasn't sure whether I needed to use it.
One thing that I would add to the conversation is that it would be useful if the EventArgs struct (or maybe WindowEventArgs) had a void ptr member to which you could attach some metadata (maybe when setting the callback) which is then delivered to the callback when an event is triggered. I've used this in transactional systems (Databases, WebServices, etc) and it's a pretty handy feature to have. Which already exists in Window::SetUserData( void * )

. I'll test this real quick, as its probably exactly what I want.
As always, thanks for the help

Re: Events with multiple possible sources
Posted: Wed Feb 22, 2017 20:27
by Ident
Yea, user-data is what i meant by user-property earlier, I wasnt clear about it. Afaik it is a property in the end.
Re: [Solved]Events with multiple possible sources
Posted: Wed Feb 22, 2017 20:55
by TheWanderer
I tested it and it worked like a charm. I appreciate the help, Ident. This has been a most edifying discussion, as knowing this feature will make a lot of other things easier for me to do.
Cheers!