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
Destroying Custom Windows
Moderators: CEGUI MVP, CEGUI Team
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.
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.
No, I'm using the precompiled version.daves wrote:Do you build CEGUI from code?
No, I do not - I just know it's somewhere within OpenGLGUIRenderer_d.dll (function 00347dcb(), if that means anything).Do you know which object is being accessed at the time of the access violation?
Yes, I have. But removing these subscriptions results in the same 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.
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.Can you please dump the call stack. That will help to determine where you are when the access violation occurs.
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.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.
- CrazyEddie
- CEGUI Project Lead
- Posts: 6760
- Joined: Wed Jan 12, 2005 12:06
- Location: England
- Contact:
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.
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.
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.
- CrazyEddie
- CEGUI Project Lead
- Posts: 6760
- Joined: Wed Jan 12, 2005 12:06
- Location: England
- Contact:
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
Hello,
So I have discovered that the problem was the following: In a constructor, I have the line:
So I figured I should put the corresponding line in the destructor:
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!
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!
- CrazyEddie
- CEGUI Project Lead
- Posts: 6760
- Joined: Wed Jan 12, 2005 12:06
- Location: England
- Contact:
Who is online
Users browsing this forum: No registered users and 9 guests