October 15, 2013 Re: Qt bindings for D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Abdulhaq | On Monday, 14 October 2013 at 19:11:39 UTC, Abdulhaq wrote:
> Ultimately, it didn't work for me before whereas it does now :-)
It may fail for someone else similarly to how you describe it worked in other developers' setup.
|
October 15, 2013 Re: Qt bindings for D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Abdulhaq | On Monday, 14 October 2013 at 09:45:18 UTC, Abdulhaq wrote: >> >> I recommend to dump it and start from scratch. A clang-based generator would be an interesting option to explore. Or, if you want to preserve your sanity, just write Qt applications in C++/QML. > > Hi Max, so why dump it? I can see a few reasons why you might > propose that: > > 1) You think it's a dead end because QtJambi is dead, so it would > be problematic to move it forward with new versions of Qt That is one reason. Also, QtJambi is based on a limited and outdated C++ parser, and we had problems getting necessary information from it. When Qt moves to C++11, the situation will get worse. So I think it is reasonable to switch to clang soon. > 2) There are some problems with the architecture of the binding > that you're aware of that would prevent it from working reliably > > For (1), I think even only having 4.8 is still a real asset. I > don't know the code base really well (but spent a fair amount of > time with it, and know the PyQt technology fairly well too) so > can't speak to (2) but if you had specific concerns it would be > very interesting to know what they were. > > From my testing it seems to me that a lot is working, enough to > write useful GUIs in it - tell me what I'm missing (a lot, I > know, but is anything really fatally flawed)? Well, you can use the bindings for simple short-living utilities if you don't mind occasional memory leaks and crashes. Long story short, D allows for two approaches to bindings like QtD: 1. The traditional one is to allocate "shells" on GC heap and have a set of manually specified rules for ownership transfers and reference count adjustments. 2. The other is more interesting - abandon the idea of reference/ownership annotations and go with semi-automatic memory management as it is in Qt, with no reliance on the GC. At some point I wanted to switch to 2 completely, so QtD is somewhere between 1 and 2, quite a mess. |
October 15, 2013 Re: Qt bindings for D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Monday, 14 October 2013 at 11:35:05 UTC, Jacob Carlborg wrote:
> On 2013-10-14 11:03, Max Samukha wrote:
>
>> I recommend to dump it and start from scratch. A clang-based generator
>> would be an interesting option to explore. Or, if you want to preserve
>> your sanity, just write Qt applications in C++/QML.
>
> I already have a Clang based tool, DStep, but that's only for C and Objective-C. It could be extended to support C++ as well.
>
> https://github.com/jacob-carlborg/dstep
Nice! That may come in handy some day.
|
October 15, 2013 Re: Qt bindings for D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Max Samukha | On Tuesday, 15 October 2013 at 09:38:15 UTC, Max Samukha wrote:
> Long story short, D allows for two approaches to bindings like QtD:
>
> 1. The traditional one is to allocate "shells" on GC heap and have a set of manually specified rules for ownership transfers and reference count adjustments.
> 2. The other is more interesting - abandon the idea of reference/ownership annotations and go with semi-automatic memory management as it is in Qt, with no reliance on the GC.
>
> At some point I wanted to switch to 2 completely, so QtD is somewhere between 1 and 2, quite a mess.
This is a really interersting point, and the part of desiging the API I found the most difficult. How do you write an interface for Qt in D that is both polymorphic and avoids memory management problems? For instance, in PyQt and PySide, you can have objects vanish because you didn't keep a reference to them, even though some other part of Qt itself might own a reference to the object.
I couldn't think of a way to do it myself which was elegant.
|
October 15, 2013 Re: Qt bindings for D | ||||
---|---|---|---|---|
| ||||
Posted in reply to w0rp | On 10/15/13, w0rp <devw0rp@gmail.com> wrote:
> I couldn't think of a way to do it myself which was elegant.
Perhaps you can pin the object and hook into the C++ destructor somehow?
|
October 16, 2013 Re: Qt bindings for D | ||||
---|---|---|---|---|
| ||||
Posted in reply to w0rp | On 2013-10-15 17:55, w0rp wrote: > This is a really interersting point, and the part of desiging the API I > found the most difficult. How do you write an interface for Qt in D that > is both polymorphic and avoids memory management problems? For instance, > in PyQt and PySide, you can have objects vanish because you didn't keep > a reference to them, even though some other part of Qt itself might own > a reference to the object. > > I couldn't think of a way to do it myself which was elegant. In D, using the GC, you can call GC.addRoot to avoid that problem. -- /Jacob Carlborg |
October 16, 2013 Re: Qt bindings for D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | 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."
|
October 16, 2013 Re: Qt bindings for D | ||||
---|---|---|---|---|
| ||||
Posted in reply to w0rp | 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++)".
|
October 16, 2013 Re: Qt bindings for D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Max Samukha | On Tuesday, 15 October 2013 at 09:38:15 UTC, Max Samukha wrote: > On Monday, 14 October 2013 at 09:45:18 UTC, Abdulhaq wrote: >>> >>> I recommend to dump it and start from scratch. A clang-based generator would be an interesting option to explore. Or, if you want to preserve your sanity, just write Qt applications in C++/QML. >> >> Hi Max, so why dump it? I can see a few reasons why you might >> propose that: >> >> 1) You think it's a dead end because QtJambi is dead, so it would >> be problematic to move it forward with new versions of Qt > > That is one reason. Also, QtJambi is based on a limited and outdated C++ parser, and we had problems getting necessary information from it. When Qt moves to C++11, the situation will get worse. So I think it is reasonable to switch to clang soon. > OK I see (unfortunately !) > Long story short, D allows for two approaches to bindings like QtD: > > 1. The traditional one is to allocate "shells" on GC heap and have a set of manually specified rules for ownership transfers and reference count adjustments. > 2. The other is more interesting - abandon the idea of reference/ownership annotations and go with semi-automatic memory management as it is in Qt, with no reliance on the GC. > > At some point I wanted to switch to 2 completely, so QtD is somewhere between 1 and 2, quite a mess. I did notice when in the code that it was partially in a transitional state - now I know what you were doing! I have to confess that in the light of this and some of your other posts, the siren call of 'start again' is singing in my ear. |
October 16, 2013 Re: Qt bindings for D | ||||
---|---|---|---|---|
| ||||
Posted in reply to w0rp | On 10/16/13, w0rp <devw0rp@gmail.com> wrote:
> or perhaps scan inside Qt memory.
I've never managed to make this work in some C++ libs I've tried to wrap. I think it's because the D GC probably knows which memory it allocated and will not scan pointers to memory it did not allocate. That's just a guess though.
|
Copyright © 1999-2021 by the D Language Foundation