Re: [Development] On QML, ownership, QObject-trees and QSharedPointer

2012-06-01 Thread Rene Jensen
>
> Step 1: mySharedPtr.data() ==> MyShared* P;
>> Step 2: make sure the QML engine doesn't assume ownership:
>> QDeclarativeEngine::**setObjectOwnership
>> Step 3: hand over P to QML: setProperty or setContextProperty
>>
>
> Yep, those steps seem to be the current requirement. If my patches get in
> (not guaranteed), it will be reduced to just:
>
> Step 1: setContextProperty("myname", mySharedPtr);
>
> or
>
> Step 1: setContextProperty("myname", mySharedPtr.toWeakRef());
>
> depending on your needs.
>
>
>
>> When I said the database layer should preferably remain QML agnostic,
>> I merely wanted to keep "patchup code" like "setObjectOwnership" out
>> of a clean set of data classes for purist reasons. (Really it is an
>> exaggeration imho.. I have no problem using stuff from QtDeclarative
>> in code. Will need it for QList properties anyway. It's just a design
>> reflex).
>>
>
> Yes, I agree.
>
>
>  Leaving out step 2 is bad, right?
>>
>
> Yes, and worse it might not obvious to consumers of the API that it's
> needed.
>


Hi again.
I have modified the wiki page that Sivan started (my name in
qt-project.orgis "Centipede"). In my view your advice above is serious
enough to warrant
a user comment in the footnote section of at least the documentation pages
of 4.8. But I cannot for the life of me figure out where to add such
comments. Is qt-project.org's user comment system up and running?

Best regards,
Rene Jensen
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] On QML, ownership, QObject-trees and QSharedPointer

2012-05-30 Thread Stephen Kelly
On 29.05.2012 10:55, Rene Jensen wrote:

>>> Question: How can we expose objects governed by QSharedPointer to 
>>> QML
>>> safely? I *can* guarantee the lifecycle beyond the life of my
>>> QDeclarativeEngine.
>> If you can guarantee that, then use mySharedPtr.data() as others 
>> have
>> said.
>
> Just a quick thought, would that suggesion be leading into trouble? 
> In
> only see one way to do that right:
>
> Step 1: mySharedPtr.data() ==> MyShared* P;
> Step 2: make sure the QML engine doesn't assume ownership:
> QDeclarativeEngine::setObjectOwnership
> Step 3: hand over P to QML: setProperty or setContextProperty

Yep, those steps seem to be the current requirement. If my patches get 
in (not guaranteed), it will be reduced to just:

Step 1: setContextProperty("myname", mySharedPtr);

or

Step 1: setContextProperty("myname", mySharedPtr.toWeakRef());

depending on your needs.

>
> When I said the database layer should preferably remain QML agnostic,
> I merely wanted to keep "patchup code" like "setObjectOwnership" out
> of a clean set of data classes for purist reasons. (Really it is an
> exaggeration imho.. I have no problem using stuff from QtDeclarative
> in code. Will need it for QList properties anyway. It's just a design
> reflex).

Yes, I agree.

> Leaving out step 2 is bad, right?

Yes, and worse it might not obvious to consumers of the API that it's 
needed.

Thanks,

-- 
Stephen Kelly | Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
www.kdab.com || Germany +49-30-521325470 || Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-Independent Software Solutions
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] On QML, ownership, QObject-trees and QSharedPointer

2012-05-29 Thread Rene Jensen
>>
>> Question: How can we expose objects governed by QSharedPointer to QML
>> safely? I *can* guarantee the lifecycle beyond the life of my
>> QDeclarativeEngine.
>
> If you can guarantee that, then use mySharedPtr.data() as others have said.


Just a quick thought, would that suggesion be leading into trouble? In
only see one way to do that right:

Step 1: mySharedPtr.data() ==> MyShared* P;
Step 2: make sure the QML engine doesn't assume ownership:
QDeclarativeEngine::setObjectOwnership
Step 3: hand over P to QML: setProperty or setContextProperty

When I said the database layer should preferably remain QML agnostic,
I merely wanted to keep "patchup code" like "setObjectOwnership" out
of a clean set of data classes for purist reasons. (Really it is an
exaggeration imho.. I have no problem using stuff from QtDeclarative
in code. Will need it for QList properties anyway. It's just a design
reflex).
Leaving out step 2 is bad, right?

Best regards,
Rene Jensen
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] On QML, ownership, QObject-trees and QSharedPointer

2012-05-28 Thread Rene Jensen
First of all, I just want to say thanks for the quite unexpected
amount of replies to my mail. They will take a little time to absorb,
but I still feel I have relevant comments on some of the issues - once
the "heatwave" in Denmark has passed (apparently my brain fries at
temperatures above 22 C)


>>
>> Hoping for an enriching debate,
>
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] On QML, ownership, QObject-trees and QSharedPointer

2012-05-24 Thread Kent Hansen
Den 25. mai 2012 02:35, skrev ext christopher.ad...@nokia.com:
> Hi,
>
>>> In QtQuick 2.0 (ie, Qt 5.0), we are thinking about using property var
>>> more often in the implementation (eg, of qobject-derived-type
>>> properties) to avoid some of those edge-cases, and providing more
>>> consistent (and useful) referencing semantics.
>> Can you say what 'var' is and why it would help?
> In QtQuick 1.x, you could not define a "JavaScript var-type property" in a 
> QML item.  The closest thing provided was "property variant" which, 
> internally, is a QVariant.  Assigning a JavaScript object to that property 
> would result in it being converted to a QVariantMap.  Accessing that property 
> from JS would result in that QVariantMap being converted back into a JS 
> object.  You could not store a JS function reference, or any other "special" 
> JS value in a "property variant" property (eg, null, undefined).
>
> In QtQuick 2.0, we deprecated "property variant" and added "property var".  
> Internally, "property var" properties are JS values.  Thus, you can store 
> anything created in JS, including JS function references.  This allows 
> greater dynamicity and flexibility.  Only when you access that property from 
> C++ (via QObject::property() or QQmlProperty::read()) will it be converted to 
> a QVariant (following the same conversion rules as for any other JS value to 
> QVariant conversion).
>

Also note that when you implement types on the C++ side, you can use the 
QJSValue class as a property or method parameter to transfer values 
between C++ and QML/JS without type/data loss. This also includes JS 
functions; for example, you can assign a function to a property from QML 
and call it later from C++ using QJSValue::call().

There's also QJson{Value,Object,Array} integration.

Best regards,
Kent
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] On QML, ownership, QObject-trees and QSharedPointer

2012-05-24 Thread christopher.adams
Hi,

> > In QtQuick 2.0 (ie, Qt 5.0), we are thinking about using property var
> > more often in the implementation (eg, of qobject-derived-type
> > properties) to avoid some of those edge-cases, and providing more
> > consistent (and useful) referencing semantics.
> 
> Can you say what 'var' is and why it would help?

In QtQuick 1.x, you could not define a "JavaScript var-type property" in a QML 
item.  The closest thing provided was "property variant" which, internally, is 
a QVariant.  Assigning a JavaScript object to that property would result in it 
being converted to a QVariantMap.  Accessing that property from JS would result 
in that QVariantMap being converted back into a JS object.  You could not store 
a JS function reference, or any other "special" JS value in a "property 
variant" property (eg, null, undefined).

In QtQuick 2.0, we deprecated "property variant" and added "property var".  
Internally, "property var" properties are JS values.  Thus, you can store 
anything created in JS, including JS function references.  This allows greater 
dynamicity and flexibility.  Only when you access that property from C++ (via 
QObject::property() or QQmlProperty::read()) will it be converted to a QVariant 
(following the same conversion rules as for any other JS value to QVariant 
conversion).

If we were to implement "property variant" as a synonym for "property var" in 
QtQuick 2.0, the code base would be simplified, and the referencing semantics 
made more consistent (more on this later).  I haven't benchmarked the 
performance impact of such a change, yet, however.

> 
> Does what you say about handling qobject-derived-type properties have
> anything to do with this:
> 
> https://codereview.qt-project.org/#change,13006
> 
> https://codereview.qt-project.org/#change,13007
> 
> or do you have something else in mind?

When I said "qobject-derived-type" I should have said "User-defined (via custom 
components) QML types".
Eg, if you have a file named MyButton.qml, you can use MyButton as a type.  It 
is a QQuickItem-derived type (and thus a QObject-derived type).

The problem is that currently, the ownership semantics are (in my opinion) 
quite strange.  In particular:

import QtQuick 2.0
Item {
id: root
property MyButton buttonOne: MyButton { ... }
property MyButton buttonTwo
property variant buttonThree: MyButton { ... }
property variant buttonFour
property var buttonFive: MyButton { ... }
property var buttonSix

function generateButton() {
var c = Qt.createComponent("MyButton.qml");
var o = c.createObject(null); // no explicit parent
return o;
}

function generateButtons() {
buttonTwo = generateButton();
buttonFour = generateButton();
buttonSix = generateButton();
}

Component.onCompleted: {
generateButtons();
gc(); gc(); gc(); gc();
}
}

That example will cause button two and four to be collected / destroyed via 
garbage collection.
Because the generated buttons had no explicit parent given, they have JS 
ownership and will be collected if no JS references to them exist.
QVariant-backed property types (like MyButton and variant) don't store JS 
values (and thus don't cause JS references to exist) and thus buttons two and 
four will be collected.

The only reason why buttonOne and buttonThree aren't collected is that we 
explicitly set the parent of the RHS item, during instantiation (in the VME, 
during CreateSimpleObject).  To me, it seems strange that root is the parent of 
buttonOne and buttonThree, but not the parent of buttonTwo or buttonFour (given 
that the only real difference is declaration vs assignment), and it is 
certainly strange that even though buttonTwo and buttonFour "reference" their 
associated values, the gc will still collect them.

Note that buttons five and six are not collected, because they are JS values 
(which will prevent the gc from collecting what they reference).

See QTBUG-24767 for more information.  There is a change which fixes the 
referencing strangeness, but it may have a performance impact during gc cycles, 
which we are currently evaluating.

Cheers,
Chris.

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] On QML, ownership, QObject-trees and QSharedPointer

2012-05-24 Thread Stephen Kelly

Hi Rene,

Thanks for the email. I think you raise some valid points. Some work on 
addressing them is already underway.

On Wednesday, May 23, 2012 12:25:42 Rene Jensen wrote:
> Disclaimer 3: Discussing QML seems very poisonous these days, but I
> still feel the need for a thread that focus on the good and bad with
> the current design and/or the current documentation specifically
> regarding exposing C++ to QML. Hopefully you agree and can accept that
> I bring it up on the developer list.

Yes, I think this email has the right tone and content, as others have said 
too.

>From the forum:
> Can QML gracefully handle pointers wrapped in QSharedPointer?

The answer is not yet - maybe in Qt 5.1.

> 
> So rewording the concerns to open up for (hopefully) useful comments -
> I can perhaps try to make a wiki article which adds any missing
> information:
> 
> OWNERSHIP...
> 
> These are the ownership "universes" (unless I'm mistaken):
> 
> 1) Objects created in C++ owned via the QObject parent/child tree
> e.g.: new MyGizmo.
> 2) Objects created in C++ owned via the QSharedPointer system, e.g.:
> QSharedPointer (new MyGizmo).
> 3) Objects created by QDeclarativeEngine or Javascript owned by the
> engine, e.g.: MyGizmo { ... properties ... }

Looks right to me.

> 
> Question: How can we expose objects governed by QSharedPointer to QML
> safely? I *can* guarantee the lifecycle beyond the life of my
> QDeclarativeEngine.

If you can guarantee that, then use mySharedPtr.data() as others have said.

> 
> These are the ways to transfer values/references from C++ to QML
> (let's ignore the other way around for now):
> 
> A) By calling QDeclarative::setRootContext (ownership not transferred:
> http://qt-project.org/doc/qt-4.8/qdeclarativecontext.html#setContextProperty

I think it's more common to use 

QDeclarativeEngine::rootContext()->setContextProperty() 

as Alberto said.

> D) By QML accessing a Q_PROPERTY on a C++ object (ownership?).

I guess you mean a binding?

> I assume that each time a value crosses a boundary between from C++ =>
> QML => Javascript an automatic conversion takes place. This conversion
> is probably the root of all evils, since a lot can happen with pointer
> references being smashed to either some form of null (as in
> unsuccessful C++ to QML assignment via (A) or (B) above) or
> "undefined" (like when a javascript expression tries to access a QML
> Component property) depending on factors not quite clear to me.
> 
> Question: What are the exact mechanisms that governs value conversion
> from one space to another?

Beyond what Christopher said, there's some more automation possible. We can 
add QSharedPointer awareness to QML, as long as doing:

if (we_know_variant_contains_a_QSharedPointer_To_QObjectDerived) {
  QSharedPointer sp;
  sp = *reinterpret_cast*>(variant.data());
}

...is ok, which I think it is. However, we'll more likely want to make that 
possible with QWeakPointer based instances (otherwise declarative might store 
our QSharedPointer and not drop its refcount - it's a tricky issue), which 
should also be possible.

After this patch:

https://codereview.qt-project.org/#change,27070

we_know_variant_contains_a_QSharedPointer_To_QObjectDerived

will be:

QMetaType::typeFlags(variant.userType()) & QMetaType::SharedPointerToQObject

or similar. We would be able to handle 
Q_PROPERTY(QSharedPointer ...) too.

After this stuff:

https://codereview.qt-project.org/#change,27071

... and a few more tricks adding function pointers to the QVariant::Handler, 
we would be able to handle Q_PROPERTY(QSharedPointer ...) too.

This is the kind of integration that I wish had been thought of for 
declarative use-cases long ago and designed into QVariant in Qt 5 with the 
hybrid QML application use-cases in mind. 

The needs QtDeclarative has needs for non-type-safety and conversions are 
mostly separate and internal, so it's not as easy as it could be to use user-
defined types and containers and QVariants with QML, like automatic handling 
of QList, QVector and generally Container. Maybe we can make this 
stuff better in 5.1 though... We'll have to see if it works and the API can be 
extended for it in a maintainable way.

Handling QObject derived types might be easily handled too (currently it 
introduces several inconveniences for hybrid apps):

https://codereview.qt-project.org/#change,13006

https://codereview.qt-project.org/#change,13007

https://codereview.qt-project.org/#change,19113

> 
> COLLECTIONS...
> 
> Collections (QList, QMap, QHash, QSet) of object references
> constitutes a special scenario which in my view is less that ideally
> solved. I would love a much simpler and more intuitive way to expose
> those to QML. But given that this topic is way too large, I don't want
> to bring it up here, although it does belong.

I have a working patch , but again, it was already pushed back to 5.1:

https://bugreports.qt-project.org/browse/QTBUG-23566



I'm still not 100% certain if th

Re: [Development] On QML, ownership, QObject-trees and QSharedPointer

2012-05-24 Thread Stephen Kelly
On Thursday, May 24, 2012 02:41:31 christopher.ad...@nokia.com wrote:
> In QtQuick 2.0 (ie, Qt 5.0), we are thinking about using property var more
> often in the implementation (eg, of qobject-derived-type properties) to
> avoid some of those edge-cases, and providing more consistent (and useful)
> referencing semantics.

Can you say what 'var' is and why it would help? 

Does what you say about handling qobject-derived-type properties have anything 
to do with this:

https://codereview.qt-project.org/#change,13006

https://codereview.qt-project.org/#change,13007

or do you have something else in mind?

Thanks,

-- 
Stephen Kelly  | Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
www.kdab.com || Germany +49-30-521325470 || Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-Independent Software Solutions

signature.asc
Description: This is a digitally signed message part.
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] On QML, ownership, QObject-trees and QSharedPointer

2012-05-24 Thread Thiago Macieira
On quinta-feira, 24 de maio de 2012 16.33.53, Olivier Goffart wrote:
> > I've long wanted to make QSharedPointer on QObject-derivatives participate
> > in the whole-tree ownership, somehow. I introduced QSharedPointer in 4.4
> > and I did some work in 4.5 to make that work.
> >
> > My original solution was to have a parent only deref its children's shared
> > pointer counter, deleting it only if it became zero. That means that if
> > you
> > had a QSharedPointer to an object in the middle of the hierarchy, that
> > object would be orphaned instead of deleted when the parent died. The
> > converse was that when the last QSharedPointer reference to a QObject went
> > away, the object might survive if it still had a parent.
>
> So that would be like having "children" be in implemented as a
> QList > ?

Yes, like that, but not actually implemented with that.

> But I personaly think it shoud not be the case.  QSharedPointer is
> orthogonal with object tree as much as it is orthogonal with
> std::shared_ptr or QScopedPointer or manually delete.
>
> You have to pick how you do thememory management for a given pointer and
> stick to it.

It is orthogonal and right now it's working orthogonally.

This was just something I experimented with, but didn't work as intended. It
crashed QWidget left and right.

--
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center
 Intel Sweden AB - Registration Number: 556189-6027
 Knarrarnäsgatan 15, 164 40 Kista, Stockholm, Sweden


signature.asc
Description: This is a digitally signed message part.
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] On QML, ownership, QObject-trees and QSharedPointer

2012-05-24 Thread Sivan Greenberg
Hi Rene,

On Wed, May 23, 2012 at 1:25 PM, Rene Jensen  wrote:
>
> DOCUMENTATION...
>
> The truth is that initially in ten out of ten cases I resorted to
> guessing about the type and ownership of a value when I cross a
> boundary. Since I have thoroughly cross examined the docs, it must
> mean that (subjectively) I find it hard to extract the proper
> information from them. I miss clear best practices, and often feel
> more confused by reading the docs than I feel enlightened. In fact,
> let me upgrade that statement:
>
When I started with Qt , eager to get developing and contributing to
Qt itself , I also  hit similar walls. Now days I resort to use the
source (tm) more and more as I need more advanced stuff, especially
when trying to extend QML.
The question of ownership/linkage/transport of objects from QML to C++
and vice verse is indeed involved, and is a challenge to document to
all tastes. I think task based docs might be a partial solution to
start with.

> *you* the burden of reading messy prose text). We need quick reference
> cards containing COMPLETE information about all possibilities in one
> place. You are only asking for trouble if you make it mandatory to
> read every article under
> http://doc-snapshot.qt-project.org/4.8/qtquick.html to be able to
> write bug free code.
> Sorry. But I'm learning a new technology just about every week - most
> in vain. I get my dose of documentation, thank you.

 Thanks to your post and Christopher's reply (and ofcourse Kai who
discussed some of this a while ago on interest@), I personally feel
*much*  more enlightened  about it, and not just with regards to my
project's use case.

The docs are far from being in ideal shape- hopefully we this will
change.  I listed task based docs as suggested discussion point for
the docs session[0] next month in Berlin qt summit.

Realizing that improving Qt is now a community wide effort, I'd
appreciate if you could add your own feedback there if you see fit (I
know that it is all time consuming and apologize for that in advance,
but there's simply no other way to improve).

And on a related note, your email has been very informative and
specific in describing the issues we face. I would suggest that next
time don't hesitate to post even if it is a long post. Following the
Qt mailing lists for a while now, I learned that the large posts are
usually (1) gold mines for knowledge and expertise of Qt,  (2) highly
interesting. Your post scored both (1) and (2).

I also think that now, when Qt is trying to out reach new communities,
platforms and problem domains- this sort of constructive communication
is of grave importance. This is the sort of discussion I enjoy
following.

-Sivan

[0]: http://qt-project.org/groups/qt-contributors-summit-2012/wiki/Documentation
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] On QML, ownership, QObject-trees and QSharedPointer

2012-05-24 Thread Olivier Goffart
On Wednesday 23 May 2012 13:43:22 Thiago Macieira wrote:
> On quarta-feira, 23 de maio de 2012 14.16.12, Alberto Mardegan wrote:
> > On 05/23/2012 01:25 PM, Rene Jensen wrote:
> > > Question: How can we expose objects governed by QSharedPointer to QML
> > > safely? I can guarantee the lifecycle beyond the life of my
> > > QDeclarativeEngine.
> > 
> > As neither of us knows exactly how QML handles QSharedPointer (my guess
> > is that it simply doesn't; QSharedPointer is a template class which can
> > be used with many other types than QObject, so I don't think that
> > exposing it in QML is trivial), I would simply recommend you not to use
> > it.
> > I actually mentioned QSharedPointer in a recent blog post of mine [0],
> > which you might find interesting especially if your use of
> > QSharedPointer is suggested by your previous experience with other
> > toolkits. If you really think that QSharedPointer is absolutely necessary
> > in your case (I still doubt), then just expose its QObject data to QML,
> > since you also claim that you can make sure its lifetime will survive the
> > engine.
> Just a tidbit...
> 
> I've long wanted to make QSharedPointer on QObject-derivatives participate
> in the whole-tree ownership, somehow. I introduced QSharedPointer in 4.4
> and I did some work in 4.5 to make that work.
> 
> My original solution was to have a parent only deref its children's shared
> pointer counter, deleting it only if it became zero. That means that if you
> had a QSharedPointer to an object in the middle of the hierarchy, that
> object would be orphaned instead of deleted when the parent died. The
> converse was that when the last QSharedPointer reference to a QObject went
> away, the object might survive if it still had a parent.


So that would be like having "children" be in implemented as a 
QList > ?

But I personaly think it shoud not be the case.  QSharedPointer is orthogonal 
with object tree as much as it is orthogonal with std::shared_ptr or 
QScopedPointer or manually delete.

You have to pick how you do thememory management for a given pointer and stick 
to it.

-- 
Olivier

Woboq - Qt services and support - http://woboq.com
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] On QML, ownership, QObject-trees and QSharedPointer

2012-05-24 Thread Thiago Macieira
On quinta-feira, 24 de maio de 2012 16.26.19, Olivier Goffart wrote:
> > Then you would also be able to make the "delete" operator work
> > consistently with reference-counted QObjects, by overriding it and make
> > it just decrement the count (and delete the object if the count is 0).
>
> No. That's not how the delete operator works.
> The operator delete is called after the destructors has already been run,
> and  its purpose is just to release the memory.  the operator delete cannot
> decide not to delete.

No, but a QSharedPointer custom deleter can decide not to call delete in the
first place.
--
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center
 Intel Sweden AB - Registration Number: 556189-6027
 Knarrarnäsgatan 15, 164 40 Kista, Stockholm, Sweden


signature.asc
Description: This is a digitally signed message part.
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] On QML, ownership, QObject-trees and QSharedPointer

2012-05-24 Thread Olivier Goffart
On Thursday 24 May 2012 11:46:05 Alberto Mardegan wrote:
> On 05/23/2012 02:43 PM, Thiago Macieira wrote:
> > My original solution was to have a parent only deref its children's shared
> > pointer counter, deleting it only if it became zero. That means that if
> > you
> > had a QSharedPointer to an object in the middle of the hierarchy, that
> > object would be orphaned instead of deleted when the parent died. The
> > converse was that when the last QSharedPointer reference to a QObject
> > went away, the object might survive if it still had a parent.
> 
> Nice! However, a very hard thing to do as an aftertought. IMHO, it would
> be easier if the reference count was built in QObject itself, and
> QSharedPointer would just play with that reference count.


Then it would be like a QExplicitlySharedDataPointer<>  (Not a really good 
name, but already does what you want)
And you can have that for any object if you have multiple inheritence with 
some QObject and QSharedData for example.

> Then you would also be able to make the "delete" operator work
> consistently with reference-counted QObjects, by overriding it and make
> it just decrement the count (and delete the object if the count is 0).

No. That's not how the delete operator works.
The operator delete is called after the destructors has already been run, and 
its purpose is just to release the memory.  the operator delete cannot decide 
not to delete.

-- 
Olivier

Woboq - Qt services and support - http://woboq.com
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] On QML, ownership, QObject-trees and QSharedPointer

2012-05-24 Thread Alberto Mardegan
On 05/23/2012 02:43 PM, Thiago Macieira wrote:
> My original solution was to have a parent only deref its children's shared 
> pointer counter, deleting it only if it became zero. That means that if you 
> had a QSharedPointer to an object in the middle of the hierarchy, that object 
> would be orphaned instead of deleted when the parent died. The converse was 
> that when the last QSharedPointer reference to a QObject went away, the 
> object 
> might survive if it still had a parent.

Nice! However, a very hard thing to do as an aftertought. IMHO, it would
be easier if the reference count was built in QObject itself, and
QSharedPointer would just play with that reference count.
Then you would also be able to make the "delete" operator work
consistently with reference-counted QObjects, by overriding it and make
it just decrement the count (and delete the object if the count is 0).

However, I didn't think it thoroughly through, and I'm sure there would
be issues with this approach as well. But indeed I'm convinced that
using QSharedPointer and the unmodified really-deleting delete operator
in the same code is also a recipe for disaster.

> There were a few problems with that solution. I can remember now:
> 
> 1) it didn't play very well with QWidgets after the Alien project. QWidgets 
> often reference the top-level window, which is the ultimate parent widget 
> (the 
> one with no parents). Orphaning a QWidget from QWidget's destructor was a 
> recipe for disaster, since the original TLW data might have been gone already.
> 
> 2) it didn't play very well with QObject siblings talking to each other 
> during 
> destruction or, worse, deleting each other. This is a huge pain and source of 
> complexity during QObject infanticide.

Indeed, all code which assumes that the parent object is always there
should be fixed to gracefully handle being orphaned.

> 3) what happens if you had a QSharedPointer with a parent, dropped 
> the last QSharedPointer reference (it survives because of the parent) and 
> later orphaned that object via setParent(0)? Should it be deleted?

Unless the code calling object->setParent(0) still has a reference to
the object, yes.

Ciao,
  Alberto

-- 
http://blog.mardy.it <- geek in un lingua international!
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] On QML, ownership, QObject-trees and QSharedPointer

2012-05-23 Thread christopher.adams
Hi Rene,

I certainly agree that constructive discussion about the QML language and ways 
that it could be improved are important.  You raise a lot of important points, 
some of which will be addressed in Qt5.0, some of which we still need to 
consider how to fix, and what priority they should be, for future minor 
releases of Qt.

More comments inline (some sections removed for brevity).

> OWNERSHIP...
> 
> These are the ownership "universes" (unless I'm mistaken):
> 
> 1) Objects created in C++ owned via the QObject parent/child tree
> e.g.: new MyGizmo.
> 2) Objects created in C++ owned via the QSharedPointer system, e.g.:
> QSharedPointer (new MyGizmo).
> 3) Objects created by QDeclarativeEngine or Javascript owned by the engine,
> e.g.: MyGizmo { ... properties ... }
> 
> Question: How can we expose objects governed by QSharedPointer to QML
> safely? I *can* guarantee the lifecycle beyond the life of my
> QDeclarativeEngine.

Currently, QML isn't aware of QSharedPointer and friends, but internally uses 
its own guard-types to react to QObject deletion.
If you want to ensure that the engine won't delete the QObject you pass in, you 
need to explicitly set the ownership of the QObject to CppOwnership (there's a 
QQmlEngine function to do so).
Alternatively, if the QObject has a parent (ownership parent) set, the engine 
won't delete it.

> 
> These are the ways to transfer values/references from C++ to QML (let's
> ignore the other way around for now):
> 
> A) By calling QDeclarative::setRootContext (ownership not transferred:
> http://qt-project.org/doc/qt-
> 4.8/qdeclarativecontext.html#setContextProperty).
> B) By calling QObject::setProperty on the instantiated component
> (ownership?)
> C) By QML calling a method on a C++ object and getting a response
> (ownership IS transferred to QML. In the docs somewhere.)
> D) By QML accessing a Q_PROPERTY on a C++ object (ownership?).
> 
> Now, A+B lend themselves badly as mechanisms to expose subobjects, but
> makes it easy to specify ownership via
> QDeclarativeEngine::setObjectOwnership.
> Conversely C+D are better at exposing subobjects or related collections (in
> QML... myProperty: myGizmo.findAllTimelineEvents() ), but I don't see how I
> can specify ownership in a QML-agnostic way (C++ models should not know
> about QML!)

I don't understand your last point.  What do you mean "in a QML-agnostic way"?  
The QML engine respects normal QObject parenting.
You are correct about (c) by the way: if the QObject returned from a 
Q_INVOKABLE function to JS does not have CppOwnership explicitly set, it will 
become JavaScriptOwnership owned.  To avoid that, you can explicitly set the 
ownership semantic prior to returning it.
With (b) ownership is not transferred.  However, it should be noted that if you 
define a QObject-derived-type property in QML with its value declared (ie, via 
"property Item propName: Item { id: child }") that property's QObject value 
will be owned by the object with the propName property.  But this isn't 
directly related to interacting with QML from C++, and so is probably unrelated 
to what you are talking about.

> 
> Question: What happens to ownership in each of these transfers?
>

To summarise:
a) no ownership change
b) no ownership change
c) ownership change if ownership semantics were not previously explicitly set
d) no ownership change

> TYPESYSTEM...
> 
> Then there is the issue of what type is associated with the object.
> This is relevant when specifying properties in QML. I believe that a major
> source of confusion comes from the notion that there are three type
> systems involved:
> 
> 1) The traditional Qt/C++ moc/compiler types (perhaps QObjects, perhaps
> declared Q_DECLARE_METATYPE to make QVariant understand them)
> 2) The types that the Javascript engine knows (Object, Function, Number,
> String etc.)
> 3) The types that the QML engine understands (http://doc-snapshot.qt-
> project.org/4.8/qdeclarativebasictypes.html
> plus those registered with qmlRegisterType). QVariants can be used too.
> 
> Question: Are there 2 or 3 typesystems?

I guess it depends on how you define the term.
There are only two property types that the QML engine understands: JavaScript 
vars, and QVariant properties.
It just happens that it builds type information from the loaded component set, 
and enforces type safety when assigning to properties of those types (which is 
why you cannot assign an Item {} to a property of type Rectangle).
But internally, all properties are stored as either QVariants or JavaScript 
vars.

> 
> I assume that each time a value crosses a boundary between from C++ =>
> QML => Javascript an automatic conversion takes place. This conversion is
> probably the root of all evils, since a lot can happen with pointer references
> being smashed to either some form of null (as in unsuccessful C++ to QML
> assignment via (A) or (B) above) or "undefined" (like when a javascript
> expression tries to access a QML Component p

Re: [Development] On QML, ownership, QObject-trees and QSharedPointer

2012-05-23 Thread Atlant Schmidt
All:

> W00t should have a backlog which covers the conversation,
> if it was done on our public channels :-)

  If only Pierre de Fermat had had that feature!

Atlant

-Original Message-
From: development-bounces+aschmidt=dekaresearch@qt-project.org 
[mailto:development-bounces+aschmidt=dekaresearch@qt-project.org] On Behalf 
Of marius.storm-ol...@nokia.com
Sent: Wednesday, May 23, 2012 09:52
To: development@qt-project.org; thiago.macie...@intel.com
Subject: Re: [Development] On QML, ownership, QObject-trees and QSharedPointer

W00t should have a backlog which covers the conversation, if it was done on our 
public channels :-)

--
Sent from my Nokia N9On 5/23/12 13:44 ext Thiago Macieira wrote:
On quarta-feira, 23 de maio de 2012 14.16.12, Alberto Mardegan wrote:
> On 05/23/2012 01:25 PM, Rene Jensen wrote:
> > Question: How can we expose objects governed by QSharedPointer to QML
> > safely? I can guarantee the lifecycle beyond the life of my
> > QDeclarativeEngine.
>
> As neither of us knows exactly how QML handles QSharedPointer (my guess
> is that it simply doesn't; QSharedPointer is a template class which can
> be used with many other types than QObject, so I don't think that
> exposing it in QML is trivial), I would simply recommend you not to use it.
> I actually mentioned QSharedPointer in a recent blog post of mine [0],
> which you might find interesting especially if your use of
> QSharedPointer is suggested by your previous experience with other toolkits.
> If you really think that QSharedPointer is absolutely necessary in your
> case (I still doubt), then just expose its QObject data to QML, since you
> also claim that you can make sure its lifetime will survive the engine.

Just a tidbit...

I've long wanted to make QSharedPointer on QObject-derivatives participate in
the whole-tree ownership, somehow. I introduced QSharedPointer in 4.4 and I
did some work in 4.5 to make that work.

My original solution was to have a parent only deref its children's shared
pointer counter, deleting it only if it became zero. That means that if you
had a QSharedPointer to an object in the middle of the hierarchy, that object
would be orphaned instead of deleted when the parent died. The converse was
that when the last QSharedPointer reference to a QObject went away, the object
might survive if it still had a parent.

There were a few problems with that solution. I can remember now:

1) it didn't play very well with QWidgets after the Alien project. QWidgets
often reference the top-level window, which is the ultimate parent widget (the
one with no parents). Orphaning a QWidget from QWidget's destructor was a
recipe for disaster, since the original TLW data might have been gone already.

2) it didn't play very well with QObject siblings talking to each other during
destruction or, worse, deleting each other. This is a huge pain and source of
complexity during QObject infanticide.

3) what happens if you had a QSharedPointer with a parent, dropped
the last QSharedPointer reference (it survives because of the parent) and
later orphaned that object via setParent(0)? Should it be deleted?

The worst of it all is that I remember having a discussion during 4.6 times
with someone on IRC and coming up with a brilliant and simple solution.
Something like "don't orphan, but keep a refcount on the entire tree". The
problem is that I didn't write it down, because I thought it was so simple and
evident that I'd be able to remember or work it out again.

I haven't been able to. Fermat would be proud.

Anyway, that reminds me I have some pending QSharedPointer work to do. I'll
get on with it.
--
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center
 Intel Sweden AB - Registration Number: 556189-6027
 Knarrarnäsgatan 15, 164 40 Kista, Stockholm, Sweden
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


 Click 
https://www.mailcontrol.com/sr/Bj8gU1boyQLTndxI!oX7UjaeDmea67kX7SqObTicsrBLI7iRALOOZRgXDSSm+ebxNAjdtRoTpmRPbv5+FCDqIw==
  to report this email as spam.

This e-mail and the information, including any attachments, it contains are 
intended to be a confidential communication only to the person or entity to 
whom it is addressed and may contain information that is privileged. If the 
reader of this message is not the intended recipient, you are hereby notified 
that any dissemination, distribution or copying of this communication is 
strictly prohibited. If you have received this communication in error, please 
immediately notify the sender and destroy the original message.

Thank you.

Please consider the environment before printing this email.
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] On QML, ownership, QObject-trees and QSharedPointer

2012-05-23 Thread marius.storm-olsen
W00t should have a backlog which covers the conversation, if it was done on our 
public channels :-)

--
Sent from my Nokia N9On 5/23/12 13:44 ext Thiago Macieira wrote:
On quarta-feira, 23 de maio de 2012 14.16.12, Alberto Mardegan wrote:
> On 05/23/2012 01:25 PM, Rene Jensen wrote:
> > Question: How can we expose objects governed by QSharedPointer to QML
> > safely? I can guarantee the lifecycle beyond the life of my
> > QDeclarativeEngine.
> 
> As neither of us knows exactly how QML handles QSharedPointer (my guess
> is that it simply doesn't; QSharedPointer is a template class which can
> be used with many other types than QObject, so I don't think that
> exposing it in QML is trivial), I would simply recommend you not to use it.
> I actually mentioned QSharedPointer in a recent blog post of mine [0],
> which you might find interesting especially if your use of
> QSharedPointer is suggested by your previous experience with other toolkits.
> If you really think that QSharedPointer is absolutely necessary in your
> case (I still doubt), then just expose its QObject data to QML, since you
> also claim that you can make sure its lifetime will survive the engine.

Just a tidbit...

I've long wanted to make QSharedPointer on QObject-derivatives participate in 
the whole-tree ownership, somehow. I introduced QSharedPointer in 4.4 and I 
did some work in 4.5 to make that work.

My original solution was to have a parent only deref its children's shared 
pointer counter, deleting it only if it became zero. That means that if you 
had a QSharedPointer to an object in the middle of the hierarchy, that object 
would be orphaned instead of deleted when the parent died. The converse was 
that when the last QSharedPointer reference to a QObject went away, the object 
might survive if it still had a parent.

There were a few problems with that solution. I can remember now:

1) it didn't play very well with QWidgets after the Alien project. QWidgets 
often reference the top-level window, which is the ultimate parent widget (the 
one with no parents). Orphaning a QWidget from QWidget's destructor was a 
recipe for disaster, since the original TLW data might have been gone already.

2) it didn't play very well with QObject siblings talking to each other during 
destruction or, worse, deleting each other. This is a huge pain and source of 
complexity during QObject infanticide.

3) what happens if you had a QSharedPointer with a parent, dropped 
the last QSharedPointer reference (it survives because of the parent) and 
later orphaned that object via setParent(0)? Should it be deleted?

The worst of it all is that I remember having a discussion during 4.6 times 
with someone on IRC and coming up with a brilliant and simple solution. 
Something like "don't orphan, but keep a refcount on the entire tree". The 
problem is that I didn't write it down, because I thought it was so simple and 
evident that I'd be able to remember or work it out again.

I haven't been able to. Fermat would be proud.

Anyway, that reminds me I have some pending QSharedPointer work to do. I'll 
get on with it.
-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center
 Intel Sweden AB - Registration Number: 556189-6027
 Knarrarnäsgatan 15, 164 40 Kista, Stockholm, Sweden
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] On QML, ownership, QObject-trees and QSharedPointer

2012-05-23 Thread Thiago Macieira
On quarta-feira, 23 de maio de 2012 14.16.12, Alberto Mardegan wrote:
> On 05/23/2012 01:25 PM, Rene Jensen wrote:
> > Question: How can we expose objects governed by QSharedPointer to QML
> > safely? I can guarantee the lifecycle beyond the life of my
> > QDeclarativeEngine.
>
> As neither of us knows exactly how QML handles QSharedPointer (my guess
> is that it simply doesn't; QSharedPointer is a template class which can
> be used with many other types than QObject, so I don't think that
> exposing it in QML is trivial), I would simply recommend you not to use it.
> I actually mentioned QSharedPointer in a recent blog post of mine [0],
> which you might find interesting especially if your use of
> QSharedPointer is suggested by your previous experience with other toolkits.
> If you really think that QSharedPointer is absolutely necessary in your
> case (I still doubt), then just expose its QObject data to QML, since you
> also claim that you can make sure its lifetime will survive the engine.

Just a tidbit...

I've long wanted to make QSharedPointer on QObject-derivatives participate in
the whole-tree ownership, somehow. I introduced QSharedPointer in 4.4 and I
did some work in 4.5 to make that work.

My original solution was to have a parent only deref its children's shared
pointer counter, deleting it only if it became zero. That means that if you
had a QSharedPointer to an object in the middle of the hierarchy, that object
would be orphaned instead of deleted when the parent died. The converse was
that when the last QSharedPointer reference to a QObject went away, the object
might survive if it still had a parent.

There were a few problems with that solution. I can remember now:

1) it didn't play very well with QWidgets after the Alien project. QWidgets
often reference the top-level window, which is the ultimate parent widget (the
one with no parents). Orphaning a QWidget from QWidget's destructor was a
recipe for disaster, since the original TLW data might have been gone already.

2) it didn't play very well with QObject siblings talking to each other during
destruction or, worse, deleting each other. This is a huge pain and source of
complexity during QObject infanticide.

3) what happens if you had a QSharedPointer with a parent, dropped
the last QSharedPointer reference (it survives because of the parent) and
later orphaned that object via setParent(0)? Should it be deleted?

The worst of it all is that I remember having a discussion during 4.6 times
with someone on IRC and coming up with a brilliant and simple solution.
Something like "don't orphan, but keep a refcount on the entire tree". The
problem is that I didn't write it down, because I thought it was so simple and
evident that I'd be able to remember or work it out again.

I haven't been able to. Fermat would be proud.

Anyway, that reminds me I have some pending QSharedPointer work to do. I'll
get on with it.
--
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center
 Intel Sweden AB - Registration Number: 556189-6027
 Knarrarnäsgatan 15, 164 40 Kista, Stockholm, Sweden


signature.asc
Description: This is a digitally signed message part.
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] On QML, ownership, QObject-trees and QSharedPointer

2012-05-23 Thread Alberto Mardegan
Hi Rene,
  I don't have real answers for your questions, but just a piece of
advice: KISS.

On 05/23/2012 01:25 PM, Rene Jensen wrote:
> Question: How can we expose objects governed by QSharedPointer to QML
> safely? I *can* guarantee the lifecycle beyond the life of my
> QDeclarativeEngine.

As neither of us knows exactly how QML handles QSharedPointer (my guess
is that it simply doesn't; QSharedPointer is a template class which can
be used with many other types than QObject, so I don't think that
exposing it in QML is trivial), I would simply recommend you not to use it.
I actually mentioned QSharedPointer in a recent blog post of mine [0],
which you might find interesting especially if your use of
QSharedPointer is suggested by your previous experience with other toolkits.
If you really think that QSharedPointer is absolutely necessary in your
case (I still doubt), then just expose its QObject data to QML, since
you also claim that you can make sure its lifetime will survive the engine.

> These are the ways to transfer values/references from C++ to QML
> (let's ignore the other way around for now):
> 
> A) By calling QDeclarative::setRootContext (ownership not transferred:
> http://qt-project.org/doc/qt-4.8/qdeclarativecontext.html#setContextProperty).

Note that you don't need to call setRootContext(); you can just get the
existing context (with QDeclarative::rootContext()) and call
setContextProperty() on it (maybe that's exactly the same you meant?).

> B) By calling QObject::setProperty on the instantiated component (ownership?)
> C) By QML calling a method on a C++ object and getting a response
> (ownership IS transferred to QML. In the docs somewhere.)

Sure? That would seem a bit weird to me: how can QML know whether the
object you return is a newly created one, or some object owned by some
other object (and what if the object is "const"?)?

> D) By QML accessing a Q_PROPERTY on a C++ object (ownership?).

E) Implement your own QDeclarative component in C++, which could wrap
your hard-to-expose-to-QML object, and let it implement properties and
methods which expose only data types that are safe and easy to use in QML.

[...]
As I said, I don't have the knowledge to reply to your other questions;
but my gut feeling is that if you need to know the answers, you have
already lost. :-) The key, IMHO, is to find a way to design your
software so that you use the toolkit to the extent that you rely only on
its well-documented properties. Refactoring your code and making it
simple will not only help you to make it work with QML, but also make it
easier for you to maintain it.

IMHO, whatever the answers to your questions, you should try to forget
them immediately or at least not rely on them. It will make your life
easier on the long run. :-)

Ciao,
  Alberto

[0]: http://blog.mardy.it/2012/05/from-g-to-q.html

-- 
http://blog.mardy.it <- geek in un lingua international!
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development