Using QML/Javascript, quite a few options exist to *either* be declarative
(e.g., "myAnimation.paused = true") or imperative (e.g.,
"myAnimation.pause();")

IMHO, when possible, one should be declarative (long discussion for a
different thread).  However, we all probably agree that we *sometimes* must
do both.  I'm now scratching-my-head a little to understand how to handle
this marriage as it relates to order-of-operations.

For example, I'm writing a "MyLayout" element that contains "MyBucket" for
transient children:

//MyBucket.qml
Item {
  onChildrenChanged: {
     // ...do stuff with children, including set properties
  }
};

//MyLayout.qml
Item {
  id: myLayout

  MyBucket {
    id: myBucket
  }

  onChildrenChanged: {
    // Push "transient" children to our bucket.
    var i = myLayout.children.length;
    while(i--) {
      if( ...<test-if-"myLayout.children[i]"-is-transient-child>...) {
        myLayout.children[i].parent = myBucket;
      }
    }
  }
};

The above works fine.  HOWEVER, there is TONS of "supporting" code that both
declarative and imperative that triggers "behind-the-scenes" (for example,
Javascript functions get called when properties like "parent" changed, and
similarly Javascript handlers get triggered when "children" change.)

I've been using "console.log()" to trace what's going on, but it's triggered
some questions:

(1) Does console.log("My message") *guarantee* the displayed order is the
order the calls are made?  (I assume "yes" -- this is very important).

(2) Does console.log() "flush" after each message, or is there an option to
trigger flushing?  (Would be nice to have an option, but I can live without
it.)

(3) I'm getting some seriously weird order-of-operations that may possibly
force me to re-think my design.  However, since we are "declarative", by
definition I suppose there's no such thing as a "weird" order of operation.
Is there any "general guidance" on understanding order-of-operations within
the QML engine?  (For example, I'd *assume* a general preference would be
made to perform "Declarative First!", but I concede that it's probably often
quite indeterminate.)

In short, I have bound properties that are changing, that are reflected in
other bound properties.  Then, these bound properties are "used" in
imperative code (e.g., computing placement for items).  In my particular
case, the "layout" logic is being executed *before* the bound properties are
updated (so the layout incorrectly reflects the "old" values before the
properties are updated).  (The properties correctly get updated later.)

Of course, I have *tons* of design options, including manually forcing
updates, setting up hooks like "onLoadCompleted()", etc.

However, I'm now wondering if I'm thinking about the problem wrong, and I'm
interested in opinions:  How do you balance declarative and imperative?  For
example, if you have a problem where much of it *must* be imperative, my
current assumption is that it is *?best practice?* if you do one of the
following:

(a) When significant portions of your implementation must be imperative, you
should consider implementing (as much logic as possible) that couples to
that imperative implementation as *also* imperative (so order-of-operations
is deterministic).

(b) When significant portions of your implementation must be imperative, you
should consider *forcing* that to a single "clean execution point" that is
fired ONLY at discrete times where you can "trust" the property inputs
(e.g., onLoadCompleted(), at specific well-understood call points) (so you
have no coupling to "unknown/stale" property values).

My problem is that until I do either of the two, I think I can't trust my
properties from within my imperative calls.  This is an interesting design
challenge which is new to me.

Thoughts?

--charley
_______________________________________________
Qt-qml mailing list
Qt-qml@trolltech.com
http://lists.trolltech.com/mailman/listinfo/qt-qml

Reply via email to