Destroying Custom Windows

For help with general CEGUI usage:
- Questions about the usage of CEGUI and its features, if not explained in the documentation.
- Problems with the CMAKE configuration or problems occuring during the build process/compilation.
- Errors or unexpected behaviour.

Moderators: CEGUI MVP, CEGUI Team

User avatar
Kevin
Not too shy to talk
Not too shy to talk
Posts: 29
Joined: Mon May 26, 2008 15:44

Destroying Custom Windows

Postby Kevin » Sun Aug 03, 2008 06:37

Hello,

So I have created a few sub-classes of CEGUI::Window in the "proper" way (i.e. objects are created using the WindowManager::createWindow(...) function and a custom WindowFactory). This seems to work properly. However, the problem comes when I try to destroy it. The call to wmgr.destroyWindow(...) with this custom object seems to work fine, but then I get an access violation somewhere within CEGUI code after that. There is nothing of importance in the log file.

So I guess my question is this: is there some specific way to get it to destroy custom windows properly besides placing appropriate clean-up code in the destructor? If not, are there any ideas as to why it's doing this? Or is there other information that I can provide that might be helpful? As a side note, the destructor of this custom window never seems to be called, even after wmgr.destroyWindow(...) returns.

Thanks in advance!
Kevin

daves
Home away from home
Home away from home
Posts: 253
Joined: Thu Feb 02, 2006 20:12

Postby daves » Sun Aug 03, 2008 11:30

Do you build CEGUI from code?

Do you know which object is being accessed at the time of the access violation?

Have you subscribed any event handlers to your window? If so you might try to hold on to the connection that is returned by the subscribe and disconnect the connection prior to window destruction.

Can you please dump the call stack. That will help to determine where you are when the access violation occurs.

I have run into access violations on a couple of occasions. In general they are a problem in application level code. For example one that I ran into a while back was that I created a DEFAULTWINDOW but miscast it to a FrameWindow (at one point it had actually been a framewindow). I then tried to perform a FrameWindow function on it (e.g. getTitleBar() -> setAlpha()). The access violation did not happen until some point after this; though the corruption occurred at the time that I misused the window type.

So make sure that you cast all windows to the correct window types. Also use a callstack to isolate to a specific object. To the extent that its a CEGUI::Window object and the access violation occurs while cleaning the object from the dead pool then try to disconnect events prior to window destruction.

User avatar
Kevin
Not too shy to talk
Not too shy to talk
Posts: 29
Joined: Mon May 26, 2008 15:44

Postby Kevin » Sun Aug 03, 2008 17:39

daves wrote:Do you build CEGUI from code?
No, I'm using the precompiled version.

Do you know which object is being accessed at the time of the access violation?
No, I do not - I just know it's somewhere within OpenGLGUIRenderer_d.dll (function 00347dcb(), if that means anything).

Have you subscribed any event handlers to your window? If so you might try to hold on to the connection that is returned by the subscribe and disconnect the connection prior to window destruction.
Yes, I have. But removing these subscriptions results in the same access violation.

Can you please dump the call stack. That will help to determine where you are when the access violation occurs.
I'm not sure how to do this - all it wants to give me is the .dll it's in, and a hexadecimal function for CEGUI code.

I have run into access violations on a couple of occasions. In general they are a problem in application level code. For example one that I ran into a while back was that I created a DEFAULTWINDOW but miscast it to a FrameWindow (at one point it had actually been a framewindow). I then tried to perform a FrameWindow function on it (e.g. getTitleBar() -> setAlpha()). The access violation did not happen until some point after this; though the corruption occurred at the time that I misused the window type.
I don't doubt it's my problem somewhere, but based on what it's doing and what I've ruled out by trial and error, I have no idea what it could be.

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

Postby CrazyEddie » Mon Aug 04, 2008 08:55

I assume you checked that if remove the destroyWindow call the problem goes away?

With regards to the destructor not getting called, the destroyWindow call adds the window to a 'dead pool', the content of which is deleted at a later time - if the destructor never gets called, then it seems it's dying before that process happens.

I would ask for the WindowFactory code, but if it's never getting called it's a mute point.

CE.

User avatar
Kevin
Not too shy to talk
Not too shy to talk
Posts: 29
Joined: Mon May 26, 2008 15:44

Postby Kevin » Mon Aug 04, 2008 18:03

CrazyEddie wrote:I assume you checked that if remove the destroyWindow call the problem goes away?

This was definitely the case before, but now I get the access violation either destroying this custom window or the DefaultWindow it's a child of.

With regards to the destructor not getting called, the destroyWindow call adds the window to a 'dead pool', the content of which is deleted at a later time - if the destructor never gets called, then it seems it's dying before that process happens.

Yes, it seems that was the case. I have now found a number of Window* being instantiated as a FrameWindow, and not cast as such, so I have changed them all, but the same access violation results. However, the destructor is now called, which is rather strange. And as long as StaticText and/or StaticImage windows don't need to be cast as anything, then this is no longer a problem.

I would ask for the WindowFactory code, but if it's never getting called it's a mute point.

Well, for the record, it's an empty constructor that calls the WindowFactory constructor with the appropriate type, a createWindow function that just returns a new instance of the Window type, and a destroyWindow function that just deletes the window pointer.

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

Postby CrazyEddie » Tue Aug 05, 2008 08:37

Kevin wrote:
With regards to the destructor not getting called, the destroyWindow call adds the window to a 'dead pool', the content of which is deleted at a later time - if the destructor never gets called, then it seems it's dying before that process happens.

Yes, it seems that was the case. I have now found a number of Window* being instantiated as a FrameWindow, and not cast as such, so I have changed them all, but the same access violation results. However, the destructor is now called, which is rather strange. And as long as StaticText and/or StaticImage windows don't need to be cast as anything, then this is no longer a problem.

Yeah, so long as you're not actually trying to copy window objects, casting should only be required when accessing members specific to the subclass. Every widget is a Window, and should be able to be destroyed via it's base Window pointer.

CE

User avatar
Kevin
Not too shy to talk
Not too shy to talk
Posts: 29
Joined: Mon May 26, 2008 15:44

Postby Kevin » Thu Aug 07, 2008 01:11

Hello,

So I have discovered that the problem was the following: In a constructor, I have the line:

Code: Select all

_tex = (CEGUI::OpenGLTexture*)CEGUI::System::getSingleton().getRenderer()->createTexture();


So I figured I should put the corresponding line in the destructor:

Code: Select all

CEGUI::System::getSingleton().getRenderer()->destroyTexture(_tex);


but this is the line that is causing the access violation. When I comment it out, everything seems to work as expected. However, I am not sure if this texture is then hanging around (aka a memory leak) or not. Perhaps someone can shed some light on this?

The only thing I can think of right now is that deleting the imageset that this texture belongs to deletes the texture as well, but in that case I'm not sure why attempting to destroy the texture wouldn't make sure it hasn't already been deleted.

Anyways, thanks again for all the help!

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

Postby CrazyEddie » Thu Aug 07, 2008 09:28

The only thing I can think of right now is that deleting the imageset that this texture belongs to deletes the texture as well

This is indeed the case, and as far as I recall there is no check done - so that will be where the issue is coming up.

CE.


Return to “Help”

Who is online

Users browsing this forum: No registered users and 20 guests