Weird destructor problem

New to FreeBASIC? Post your questions here.
Post Reply
datwill310
Posts: 355
Joined: May 29, 2015 20:37

Weird destructor problem

Post by datwill310 »

Yes, this is yet another post about the OGL...

Take this example code:

Code: Select all

#include "ogl.bi"
using OGL
dim as MSG msg
dim as GUIWIN win = GUIWIN(5, 5, 300, 200)
do
	waitevent_all(msg)
loop until uponclose_any(msg)
'HERE you should take note
win.destructor
'you'll need -s console: in -s gui mode, this issue doesn't occur...
The initial destruction of the win object works OK.

But then the program decides to try and destroy win AGAIN, upon the program terminating, causing ending crash.

This is especially weird because no destructor of win is called if win.destructor isn't there (I've tested using print statements of the different components of the destruction). EDIT: I lied, I've tested it again, and yes, the destructor is called when program ends. As I will say, I'd like the user to destroy a GUIWIN object, whenever they'd like. Is this possible to do safely without using pointers?

Ideally, I would like the user of my library to be able to destroy a GUIWIN object without crashes. They should be able to call the destructor in some way (with or without pointers: the user shouldn't have to care).

This problem is apparent ever since OGL version 2.0. However, this problem was also apparent in OGL 1.0 and 1.1, but I then programed the destructor in such a way as to worry if I destroy anything at all...

Is this my library, or this a behaviour with FB which I should be aware about? If it's my library, what can I do to stop the crashes? If it's FB, which process should I take to destroy GUIWIN objects without crashes i.e. safely?

If I can fix the problem, I'll release a 2.2 fixing this issue, because it's really buggy me.

Thanks again.
vdecampo
Posts: 2992
Joined: Aug 07, 2007 23:20
Location: Maryland, USA
Contact:

Re: Weird destructor problem

Post by vdecampo »

Assuming GUIWIN is an FB class you created, you don't normally need to call the destructor explicitly as it will be called automatically when the variable falls out of scope. IIRC

-Vince
datwill310
Posts: 355
Joined: May 29, 2015 20:37

Re: Weird destructor problem

Post by datwill310 »

vdecampo wrote:Assuming GUIWIN is an FB class you created, you don't normally need to call the destructor explicitly as it will be called automatically when the variable falls out of scope. IIRC

-Vince
Thanks for the reply.

Yes, GUIWIN is a fully FB coded class. I do appreciate the auto. feature. However, when the GUIWIN destructor is called, it acts as an extended version of DestroyWindow() to the window within GUIWIN. The user might want the window to be destroyed half way through the program, especially if that program is complicated.

Could you use GUIWIN ptr, new, and delete? Would this be a safer way to destroy a class mid-program?
vdecampo
Posts: 2992
Joined: Aug 07, 2007 23:20
Location: Maryland, USA
Contact:

Re: Weird destructor problem

Post by vdecampo »

datwill310 wrote: Could you use GUIWIN ptr, new, and delete? Would this be a safer way to destroy a class mid-program?
No the destructor will get called. Why would you destroy the whole class just to get rid of the window? And why couldn't you recreate the class if needed? Could you just put in a separate method to destroy the window without calling the destructor?

-Vince
datwill310
Posts: 355
Joined: May 29, 2015 20:37

Re: Weird destructor problem

Post by datwill310 »

vdecampo wrote:
datwill310 wrote: Could you use GUIWIN ptr, new, and delete? Would this be a safer way to destroy a class mid-program?
No the destructor will get called. Why would you destroy the whole class just to get rid of the window? And why couldn't you recreate the class if needed? Could you just put in a separate method to destroy the window without calling the destructor?

-Vince
The GUIWIN class contains info only specific to that window. By calling the destructor, it actually destroys a lot more than just the main window, such as child controls, images associated with those controls, child GUIWIN objects, and much more besides, and to come. If the window is to be destroyed, then why keep all that specific data?

A separate method would be useful for a temporary destruction though. But then why don't you just hide the window? It has a similar if not the same effect. A separate method would be a pain as DestroyWindow() destroys a parent and its children. The structure within a GUIWIN object is complex, and this presents issues especially for child GUIWIN objects.

But then coming to think of it, if you wanted to get rid of a window mid-program, just hide it... Then the program at the end will destroy things fine. Yeah, that makes sense.

Still, thanks for your info: it's helped me understand more about how object-orientation works in FB.
SARG
Posts: 1766
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Weird destructor problem

Post by SARG »

Hi,

Maybe by adding a counter. Simple but it works fine.

Code: Select all

Type twincounter
   As Long counter
   Declare sub addone
   Declare Sub subone
   Declare Function value As Long
End Type	
Dim As twincounter wincounter
Sub twincounter.addone
   counter+=1
End Sub
Sub twincounter.subone
   counter-=1
End Sub
Function twincounter.value As Long
   Return counter
End Function
   
    
Constructor OGL.GUIWIN
   wincounter.addone
   ............
   
Destructor OGL.GUIWIN()
   If wincounter.value=0 Then Return
   wincounter.subone
   ............
   
datwill310
Posts: 355
Joined: May 29, 2015 20:37

Re: Weird destructor problem

Post by datwill310 »

SARG wrote:Hi,

Maybe by adding a counter. Simple but it works fine.

Code: Select all

Type twincounter
   As Long counter
   Declare sub addone
   Declare Sub subone
   Declare Function value As Long
End Type	
Dim As twincounter wincounter
Sub twincounter.addone
   counter+=1
End Sub
Sub twincounter.subone
   counter-=1
End Sub
Function twincounter.value As Long
   Return counter
End Function
   
    
Constructor OGL.GUIWIN
   wincounter.addone
   ............
   
Destructor OGL.GUIWIN()
   If wincounter.value=0 Then Return
   wincounter.subone
   ............
   
I have a similar set-up in OGL1.x, except I use a boolean flag. Of course, OGL2.x is quite different ;).
SARG
Posts: 1766
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Weird destructor problem

Post by SARG »

Is there only one window ?
With several windows a boolean is not usable.
datwill310
Posts: 355
Joined: May 29, 2015 20:37

Re: Weird destructor problem

Post by datwill310 »

SARG wrote:Is there only one window ?
With several windows a boolean is not usable.
Honestly, a lot has changed since 1.x, I can't really remember how it worked.

I remember that all the windows had to be destroyed individually.

So yeah, there was only one window.
dkl
Site Admin
Posts: 3235
Joined: Jul 28, 2005 14:45
Location: Germany

Re: Weird destructor problem

Post by dkl »

I think a destroy() or close() method would be best. It should close/destroy the window, and clear the internal data structures (e.g. set handles to NULL, etc.), so it will do nothing if called again.

Then the destructor would also call the destroy() method, to automatically destroy the window if it wasn't done manually yet.
datwill310
Posts: 355
Joined: May 29, 2015 20:37

Re: Weird destructor problem

Post by datwill310 »

dkl wrote:I think a destroy() or close() method would be best. It should close/destroy the window, and clear the internal data structures (e.g. set handles to NULL, etc.), so it will do nothing if called again.

Then the destructor would also call the destroy() method, to automatically destroy the window if it wasn't done manually yet.
The OGL does exactly this :D. Not with the main window, though, but with all child windows and images.
Post Reply