oprypin/nim-csfml

Using sfml types with Nim objects

hakanderyal opened this issue · 7 comments

I'm using sfml objects (sprite, window etc.) in Nim objects.

import csfml

type
  Game = ref object
    text: Text # Text from nim-csfml

var game = Game()

game.text = newText()

And compiler complains with:

# Warning: usage of a type with a destructor in a non destructible context. This will become a compile time error in the future. [Destructor]

Any tips on the correct way?

http://irclogs.nim-lang.org/22-04-2015.html Ctrl+F "destructor"

Basically, destructors are an extremely limiting experimental feature, and this may even be completely impossible to do. I had no idea what I was doing when I employed destructors in this library. Destructors are not related to garbage collection, but instead use complex scope rules.
What is actually needed is finalizers, but they are available only for ref objects.

There are only 2 ways to avoid destructors:

  • Change nim-csfml: wrap every single ptr object in another ref object, duplicating every function and whatnot, and use finalizers instead of destructors.
  • Disable destructors (-d:csfmlNoDestructors) and call destroy manually 😐

...or call for some features in Nim, as discussed in IRC.

So, going from my example, when game object is freed by GC, the memory occupied by Text doesn't get freed if I don't call destroy?

And regarding wrapping ptr object with ref object, can it be done somehow with macros? or we need some other automated way like you did with generator.py?

So, going from my example, when game object is freed by GC, the memory occupied by Text doesn't get freed if I don't call destroy?

Warning: usage of a type with a destructor in a non destructible context. always, or almost always means this, yes. It used to be an error, and probably will be again in the future.

Wrapping with macros is something I can't... wrap my head around. Either impossible or very difficult. Generating wrapper objects, however, is something I did recently, but I do not wish to resort to this here. There might even be some problems preventing this.

Ok on another thought, I use sfml objects in a few of my own objects. If I disable the destructors, and call destroy on the finalizer of my objects, it should work?

You can disable destructors and call destroy manually on every object, yes. Or maybe relying on this compiler warning and destroying only those objects is an acceptable workaround.

It's a pity that CSFML's destroy procedures are not allowed to be called more than once (as far as I remember), so you can't just put manual destroy calls whenever you aren't sure if it'll be called as a destructor (you have to be sure that it won't).

Seems to work now, AFAICT

Technically yes, because I removed destructors - so all the downsides mentioned above apply.