Qt bindings for D

Max Samukha maxsamukha at gmail.com
Tue Oct 22 15:34:40 PDT 2013


On Tuesday, 22 October 2013 at 21:01:49 UTC, w0rp wrote:
> 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.

There is no best solution. You have to trade off. For my purpose, 
that was the best option, which was maintainable, performant and 
correct (apparenty). I do not care much about how it looks, given 
that it is concise. Some don't like the look of chinese 
hieroglyphs or black skin. I for one don't see much beauty in 
"new". Anyway, the project QtD was intended for was cancelled 
long ago, so you are free to transform it according to yor vision.


More information about the Digitalmars-d mailing list