Overlay name repetition on multiple loads

Jekteir

26-07-2007 17:35:57

Hi, this is a resource/overlay-loading/creation issue:

I'm using QuickGUI in an editor which one can enter and leave again multiple times during the course of one application's run. In order to be tidy and keep memory free, I'm deleting the editor in between uses, and creating it when it's needed. Now, I'm deleting QuickGUI each time, and creating it again the next time, but due to the way Ogre handles resources (I think) I'm getting errors on, for example:

newOverlayContainer = static_cast<Ogre::OverlayContainer*>(Ogre::OverlayManager::getSingleton().createOverlayElement("Panel",name));

because the name of the overlaycontainer already exists for ogre from the last run. Is there any way to get Ogre to 'flush out' the old resources/overlays etc that were meant to have been destroyed from the last QuickGUI's destructor, so that the names don't conflict upon the multiple loads?

Thanks,

Jek

P.S. in case it's of use, the first error happens as:

OGRE EXCEPTION(4:ItemIdentityException): OverlayElement with name DefaultSheet.ChildrenContainer already exists

kungfoomasta

26-07-2007 20:54:47

Hm, I thought I managed all the containers properly. Are you using GUIManager::clearAll() function?

It could be that I missed a call to delete somewhere in a deconstructor.

Right now my codebase doesn't use any overlays at all, so in the next version this won't be a problem. But the next version is still in the works.. :wink:

Jekteir

26-07-2007 21:14:00

No, I delete the gui manager, and in its destructor that has:

GUIManager::~GUIManager()
{
clearAll();
destroyMouseCursor();
}


So that should be OK. Next version sounds good: what are you using instead of overlays?

On a separate matter, I'm playing with the QuickGUI events system right now. The issue is, I'd like to pass the event type and the object whose event it is to my event-handler function, rather than writing 20 functions or whatever. Right now I'm trying to modify MemberFunctionSlot, to have a second argument for execute(), so it becomes:

virtual bool execute(const EventArgs& args,Event eventType);

I'm getting missing type compile errors, though. At first I had tried Widget::Event (since we're already in the QuickGUI namespace), but it said Event was not a member of Widget. I also tried including QuickGUIWidget.h above the use of Event in the QuickGUIMemberFunctionPointer header.

I just tried changing the 'typedef enum Event' to 'enum Event' (what's the difference between these, by the way? I'm not familiar with typedef enum...), and put that in the OgrePrerequisites.h , and included that at the top of MemberFunctionSlot, but I'm still getting missing type specifier errors in MemberFunctionSlot. This is in Debug mode of VC++ 2005, by the way.

I know I haven't yet edited the event functions themselves, or the handlers, to deal with this functionality -- but I'd like to see these errors not happening before I mess with this any more.

Is this a sensible approach (I'll also be wanting to pass the actual widget the event is happening on, as well as the event type, once I get this working), or should I wait for a newer version of QuickGUI, or just hang my head and write however many specific functions are required for all the different objects and events? Or am I misunderstanding the current functionality?

Thanks,

Jek

Jekteir

26-07-2007 22:53:01

I thought I had missed something and would be able to accomplish getting information about the widget like so:


bool WorldEditor::generalWidgetEvent(const QuickGUI::EventArgs& args)
{
QuickGUI::Widget *evtWidget = static_cast<QuickGUI::WidgetEventArgs>(args).widget;

if (evtWidget->getInstanceName()=="listHelpItem")
{
// do widget-specific activity here
}


Unfortunately I get this compile error:

error C2440: 'static_cast' : cannot convert from 'const QuickGUI::EventArgs' to 'QuickGUI::WidgetEventArgs'
1> No constructor could take the source type, or constructor overload resolution was ambiguous


I'm assuming you're not meant to be able to do this, and even that the widget information is no longer part of the object, but was removed somewhere earlier in the event-passing tree. Is that right? Is there any relatively straightforward way to get the event and widget information at the final called function?

Thanks,

Jek

Jekteir

26-07-2007 23:28:29

I'm trying to use multiple event functions right now. But I'd also like to be able to call them from my own code, so that my functions for handling certain events can be reused by more than one source (e.g. the QuickGUI menu's help button event calls my help function, but my keycapture for F1 should also call the same function).

So, my question is, if the function looks like:

bool WorldEditor::exitCmd(const QuickGUI::EventArgs& args)

How do I create the QuickGUI::EventArgs& args to call this from my source file? I tried creating a new EventArgs in various ways, but had no success. I'd rather not duplicate the functions for everything (i.e. have my help-button-press function call another 'do help' function, which my F1-capture code also calls, instead of putting the help functionality in the help-button-press function and having the f1-capturer call that).

Thanks,

Jek

kungfoomasta

27-07-2007 21:55:56

You shouldn't need to creat your own EventArgs. If I understand correctly, you want to include the event into the eventArgs class? That doesn't sound like a bad idea, I will consider adding it.

Although all event handlers are passed EventArgs, some of those objects are actually WidgetEventArgs. To cast it correctly, use this example:


bool evtHndlr_changeAnimations(const QuickGUI::EventArgs& args)
{
const QuickGUI::WidgetEventArgs* wea = static_cast<const QuickGUI::WidgetEventArgs*>(&args);


This will minimize duplication of functions. It seems like you want to have one function with a ton of "if" statements. Not sure that is the right way to go, but that's your call.

Hope that helps!

Jekteir

27-07-2007 23:06:57

Thanks a lot, yeah, I spotted an example of that in the example header today. I haven't yet figured out the way to get the type of event itself (if there is a way) in the function.

I agree that pointing to a specific function for each event is probably faster (at a small expense of size, which is always the right tradeoff for games), but I'd just like to avoid a load of functions, really, and also avoid duplicating functionality in different parts of my program.

If you could add the event type to the event, that'd be really useful. I guess there isn't any tabbing between controls yet, so figuring out whether a button event is a keypress (e.g. Return key) or a mouseup isn't really an issue yet? Because I'm not sure how you would know which sort of event (keys or mouse) to cast the EventArgs to.

Jek

kungfoomasta

27-07-2007 23:24:56

Well there is a difference between QGUI_EVENT_MOUSE_BUTTON_DOWN and QGUI_EVENT_KEY_DOWN, right? :wink:

Keys are not buttons, although you could inject them that way if you wish. The only *buttons* I have enums for are mouse buttons.

But you have given me good ideas. I will add the Event type in the EventArgs, and also create an Enum for the type of EventArgs. This way you will know what type of EventArg it is, and can safely cast and use it.

Thanks for the input. :)

Jekteir

28-07-2007 00:26:13

That would be fantastic. I wasn't very clear, but what I meant by "whether a button event is a keypress (e.g. Return key) or a mouseup" was actually, whether the EventArgs was a key event or a mouse event type. So, that'd be great : )

Do let me know if you'd like me to take a quick stab at that MultiLineTextBox. I've no idea how feasible it would be, but most of your stuff seems to inherit nicely so it might be possible to do one without it being broken by your core changes?

Jek