Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-138742

Support function types in QML

XMLWordPrintable

      In QML, we have from time to time properties that expect a function with a certain signature. Examples include TableView's rowHeightProvider, or the initial design of SortFilterProxyModel (which latter switched to using a function with a fixed name as an alternative).

       

      Currently, this is generally solved in one of two ways: Either by having a property of type QJSValue (TableView), or by have some internal "magic" naming convention (like SortFilterProxyModel). Neither is ideal: The first is quite bad for tooling (QJSValue could be basically anything), the second is bad for discovery (e.g. can't find the property via auto-complete).

       

      An alternative would be to have function properties, which specify the actual type they expect. Syntax wise, we can try to follow list properties and add another modifier,  maybe with some inspiration from C++: `property func<bool(int)>`filter`

       

      Semantic wise, we should initially do the most basic implementation: Check if what we assign to the property is a function, and if it is, whether the argument and return types match exactly. If that's the case, accept the assignment. If we want to support moving pre-existing code to the new property type, we also need to accept completely untyped functions. That is actually possible by creating a wrapper around it which accepts the correctly typed arguments, forwards them to the function, takes it return type and converts it to the desired output type, and finally returns the result of that conversion. Support for untyped functions can however be done as a second step.

      An empty function property should most likely throw a (JS) exception when called.

       

      Implementation wise, we need a few things:

      1. An untyped base-type (QQmlFunctionRefBase) storing a list of expected types, probably as QQmlType + a reference to a function. That reference needs to be able to store a QML function, and maybe also  a C++ function. The initial draft should focus on the QML case. Whether the reference should be weak or strong needs to be investigated. The `func<bool(int, int)>` construct would directly map to it.
      2.  For better C++ integration, and for tooling, we also need some template around it: Something like `template<class R, class... ArgTypes> class QQmlFunctionRef<R(ArgTypes...)`, with a call operator. It should be noted that this allows the creation of functions which most of the time can't be called in QML, unless we allow at least some basic conversions (upcasting pointers to objects)
      3. Such C++ types might not need explicit registration, but we would need to check (in lint_module) that the argument and return types are registered.
      4. We need to add support in QQmlPropertyWritePrivate::write, and maybe in a few other places: The necessary data should already be in place, QV4::Function has a union storing JSTypedFunction/AOTCompiledFunction/<no types>.
      5. We need to also make sure that calling an instance of QQmlFunctionRefBase works from QML

       

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

            diseraluca Luca Di Sera
            fabiankosmale Fabian Kosmale
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:

                There are no open Gerrit changes