[Development] Reference cycles in QML

David McFarland corngood at gmail.com
Sat Aug 17 02:47:14 CEST 2013


On Fri, Aug 16, 2013 at 3:33 PM, Alan Alpert <416365416c at gmail.com> wrote:
>
> On Thu, Aug 15, 2013 at 7:54 PM, David McFarland <corngood at gmail.com> wrote:
> > I found that having dependency cycles in QML components causes the
> > typeloader to get stuck with all blobs in a loading state (i.e. no useful
> > diagnostics).  This can be caused by something like this:
> >
> > A.qml
> > --------
> > QtObject {
> >     property B foo
> > }
> > --------
> > B.qml:
> > --------
> > QtObject {
> >     property A foo
> > }
> > --------
> >
> > or
> >
> > A.qml
> > --------
> > QtObject {
> >     property Component foo: B {}
> > }
> > --------
> > B.qml:
> > --------
> > QtObject {
> >     property Component foo: A {}
> > }
> > --------
> >
> > I couldn't find any discussion of this in the archives, so I started
> > experimenting.
> >
> > I've attached a patch of my current progress, which will allow the above
> > cases to succeed.  I wouldn't consider it ready to commit, as I wrote it
> > incrementally while learning the systems, so it's a bit messy.  It could
> > easily have some bad side-effects, but it does work without any obvious
> > problems in a fairly complex project (game), using Layouts, Controls, a
> > couple of my own plugins, etc.
> >
> > I haven't even run it on any of the examples/tests yet, which obviously
> > should be done, but I wanted to see if anyone had any plans to deal with
> > this problem (or reasons not to).
> >
> > Here's roughly what the patch does:
> >
> > - detects cycles of blobs typeloader who are all waiting on dependencies,
> > and forces them to complete
> > - allows compilation of type data to trigger compliation of other type data
> > - allows type data compilation to happen in two passes, so that the root
> > component can be built without building all components
> > - creates synthesised types earlier so that they are available when there's
> > a dependency cycle (e.g. through a property)
> >
> > Again, the patch definitely needs cleaning up.  I just made it to learn the
> > system and prove to myself that there were no obvious roadblocks to fixing
> > this.
> >
> > I'll carry on testing it, and look forward to hearing your feedback.
>
> Patches need to go to gerrit, even if they're not complete. Just
> mention that it's not ready for submission in the commit message
> (which can be amended once it is ready for submission).
>
> As well as being good practice, it's easier to review, discuss and
> test with changes once on gerrit. I'll be happy to look at the
> implementation once it's there.
>
> Conceptually there's no reason to block cyclic dependencies if it's
> feasible, but I think it's only feasible in certain situations (when
> it's a component or uninitalized property type) and not the general
> case. Any case where we aren't certain the cyclic dependency can be
> resolved in finite time we need to give a compile error instead.
>
> --
> Alan Alpert

Here it is: https://codereview.qt-project.org/63220


Something like:

A.qml
--------
QtObject {
    property B foo: B {}
}
--------
B.qml:
--------
QtObject {
    property A foo: A {}
}
--------

will be impossible to compile properly, let alone execute, due to the
way object creation is built into the component code.  I don't foresee
any problem with detecting it and providing a helpful message.

Another case that currently doesn't work, even with my patch, is a
reference to itself, like:

A.qml
--------
QtObject {
    property A foo: null
}
--------

That should be pretty simple to fix though, with the same restrictions
as cycles.



More information about the Development mailing list