B3D -> Max Conversion

BlitzMax Forums/BlitzMax Programming/B3D -> Max Conversion

Jeremy Alessi(Posted 2008) [#1]
I have a few questions.

How are people handling the deletion of type objects in the conversion process?

dp.dynamicParticle = New dynamicParticle
delete( dp )

I've attempted to add a Free method which is ineffective. The documentation doesn't give a clear explanation for TBBType nor could I locate the source code for it within BRL mods.

Method Free()
_link.Remove()
End Method

In addition have people been using the B3D extensions? If so what modifications did you have to make?


GfK(Posted 2008) [#2]
Don't you just use dp = Null and let GC take care of it?


Jeremy Alessi(Posted 2008) [#3]
I tried that one too. I don't think I'm using the GC properly. Do you still have to implement it the way it was originally? I thought Mark changed to to be more automagical.


plash(Posted 2008) [#4]
I tried that one too. I don't think I'm using the GC properly. Do you still have to implement it the way it was originally? I thought Mark changed to to be more automagical.
AFAIK you don't *use* GC.


GfK(Posted 2008) [#5]
GC is automatic - you can turn it off and call GCCollect manually but I don't recommend it.

You can keep an eye on it by using GCMemAlloced().

There is a new type of GC implemented in the threaded version of Blitzmax but that's for a different thread (pun).

In case you weren't aware, GC ditches objects when they go out of scope. In layman's terms, that means when you don't have anything pointing to an object (I.e. because you set it to Null as I mentioned earlier), GC throws it out and you lose whatever data was held there.


dmaz(Posted 2008) [#6]
Jeremy, there is no need to delete it... it will be deleted once it goes out of scope and is no longer referenced. so in your example, you just create the new particle and it will be cleaned up just like an int would be in B3D.... ie: don't worry about it.

with that said, there are a few times when you do have to clean up after yourself.... in those cases (cyclic references) just null them and you will be fine.


Jeremy Alessi(Posted 2008) [#7]
I set the objects to Null in a For EachIn loop and was still running into issues where a crash occurred due to Null object references in my list. The only way I could avoid this was by setting the handle of my TMesh to 0 and then making sure I applied no operations on a mesh referenced from the list if the mesh didn't exist.

So I should be able to do this:

For pointer:bbType = EachIn List
   If ( Not timeExpired ) 
      Move
      Rotate
      Scale
   else
      FreeEntity( pointer.entity )
      pointer:List = Null
   endif
Next


But instead I have to resort to this:

For pointer:bbType = EachIn List
   If ( pointer.entity And ( Not timeExpired ) )
      Move
      Rotate
      Scale
   Else
      if ( pointer.entity )
         FreeEntity( pointer.entity )
         pointer.entity = 0
         pointer:List = Null
      Endif
   Endif
Next


I'll have to recheck the code, if what everyone says is true then I was using it correctly and perhaps there's another issue going on. It seems like the GC doesn't work deterministically.


Jeremy Alessi(Posted 2008) [#8]
Actually, I realized I was only able to fix this issue by not deleting any particles. I'm at a loss for the reason this doesn't work.


dmaz(Posted 2008) [#9]
well you can't call operations on something you nulled out.... but what are you nulling out exactly and why... don't null it unless it's a circular reference or could lead to a circular reference.

you code above seems to say you are nulling out the object pointer in the TLink of the list but leaving the actual TLink. when you do a eachin you get back pointers from each of the TLinks. to remove an object from a list you need to remove the TLink not null or remove the actual object.

if you just remove the TLink, then object will then be cleaned up by the GC because there are no further references to it (the TLink remove method nulls it pointer to the object there by reducing the reference counter of the object.)

here's a short version of what I do.
Type TObject
	Global list:TList = New TList
	
	Field link:TLink
	Field x:Int
	Field y:int
	
	Method New()
		link = list.AddLast(Self)
	End Method
	
	Method Remove()
		link.Remove
	End Method
	
End Type
here, if you have a reference to an object and then call the Remove method, it will be removed from the global list in the type there by allowing it to be cleaned up by the GC.


dmaz(Posted 2008) [#10]
ok wait... I missed pointer.entity. again there is no reason (at least in this limited example) to set that to 0 or null. the GC will take care of that when the parent object is cleaned up. don't worry about cleaning up entity unless entity *also* points back to the parent ("pointer" in this case). if that is indeed what you are doing then yes you need to make sure you null them out.... is that what you are doing?


Jeremy Alessi(Posted 2008) [#11]
I also had this method:

Type bbdynamicEntity Extends TBBType

Method New()
Add(dynamicEntity_list)
End Method

-> Method Free()
_link.Remove()
End Method

However, it doesn't seem to do the job as I stated above.


Jeremy Alessi(Posted 2008) [#12]
OK, just to clarify using a .Remove() method works fine and I should have realized this because it was working for everything in my game besides my particles. What happened was that I have a mold system which copies textures or entities. In B3D I was able to return the handle to a texture, a model, or a CopyEntity() from a single function since they were represented by integer handles. However, in Max I'm unable to return CopyEntity() from the same function so I must return the model handle and then CopyEntity() on the CopyMold() call.

So something like this in the classic TBBType works:

Type bbdynamicParticle Extends TBBType

	Method New()
		Add(dynamicParticle_list)
	End Method
	
	Method Remove()
		FreeEntity( eHandle )
		_link.Remove()
	End Method