On Wednesday, 16 October 2013 at 09:56:21 UTC, Max Samukha wrote:
On Wednesday, 16 October 2013 at 07:25:08 UTC, w0rp wrote:
On Wednesday, 16 October 2013 at 06:53:24 UTC, Jacob Carlborg
wrote:
In D, using the GC, you can call GC.addRoot to avoid that
problem.
Yes, I was thinking of using core.memory stuff to stop things
from being collected, or perhaps scan inside Qt memory. For
instance, you could store a class pointer inside of a QObject
with setProperty. One option is to have QObject in D hold an
array of pointers for keeping references to children, etc.
There are some tricky parts.
---
// Okay, this is a root object, when do we collect this?
auto widget = new QWidget();
// This is just a free object, not attached to anything.
// Clearly we can collect this.
auto label = new QLabel("Hello!");
auto layout = new QHBoxLayout;
layout.addWidget(label);
// Wait, now label implicitly becomes a child object of widget.
// its memory is now managed by that, so when do we collect it?
widget.setLayout(layout);
// Does this work?
assert(label.parent is widget);
---
So in other words, I haven't yet reached a point where I
think, "Yes, I have covered every case and I'm happy."
I've ended up with a system that would not allocate Qt objects
on the GC heap at all:
// This would be destroyed at the end of the scope,
auto widget = scoped!QWidget;
// Or, if we allocate the object on heap, we should care
// to destroy it unless Qt takes ownership at some point after
// construction.
auto widget = make!QWidget;
...
dispose(widget);
auto widget = make!QLabel("Hello!");
auto layout = make!QHBoxLayout;
// Safe to pass ownership to parent because no GC is involved.
layout.addWidget(label);
// ditto
widget.setLayout(layout);
// This would work because references to polymorphic Qt objects
are
// implemented as tagged pointers, and in this case
// both references would point to the same C++ object.
assert(label.parent is widget);
In other words, you manage memory the same way you do in Qt.
Advantages:
- Noticeable simplification of the generator and bindings.
- Performance - no redundant copies, hash lookups, etc.
- Fewer problems with multithreading.
Disadvantages:
- You have to be as careful about memory management as you are
in Qt.
- Implementation requires a debugged D compiler, which does not
exist yet. :)
An interesting endeavor would be to figure out whether things
could be simplified with "interface(C++)".
There's one very big disadvantage there, I think. It looks ugly.
I do have to point out that this opinion somewhat stems from me
just not liking 'scoped.' I think the above example just makes me
think, "The best solution has not yet been found." Again, I don't
know what that is yet.