October 15, 2013
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
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
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
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
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
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
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
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
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
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.