Models

Most models are defined on the C++ side of the application as they reflect state of the player or the medialibrary. The general principle for creating QML model from C++ is explained in Qt documentation.

Dependency injection

Qml objects don’t have constructor per se, a more typical approach is to pass the context of the object by injecting it in the object properties.

Beware that property assignation is not atomic, if your model requires multiple property to be set, you must ensure manually that all property have been provided. Some typical object that can be injected in models are MainCtx to access most application settings, or MediaLib to access the Medialibrary

class MyModel : public QObject
{
    Q_PROPERTY(MainCtx* ctx READ getCtx WRITE setCtx NOTIFY ctxChanged FINAL)

    ///....
};
MyModel {
    ctx: MainCtx
}

Injecting global objects

Some objects can be made accessible globally to the application, for this prefer registering the class as a singleton using qmlRegisterSingletonType instead of creating context properties. The registration should be made in along with the other type registration in the MainUI class

see:

- maininterface/mainui.cpp

God object Single Store

The MainCtx object is the typical entry point for the QML to access the application state. It allows retrieving most common VLC objects (the vlc_object)

At moment the structure is mostly flat, properties are directly accessible as MainCtx.property

BaseModel

The BaseModel class provide a base implementation for list models that changes over time. The base model will automatically handle the data cache and is responsible for requesting data and notifying data changes

The BaseModel uses the pimpl pattern (commonly used by the Qt framework), the BaseModel class contains the public API and properties common to all models, the BaseModelPrivate contains all the private data and cache mechanism. This class is designed as a template with the type stored in the cache. A submodel should inherit BaseModelPrivateT<T> where T is the actual data type. The submodels should provide a loader object that implents the ListCacheLoader<T> interface. This class is responsible for loading the actual data, it will be called by the base model to count or load data. If loading the data requires accessing slow (disk or network) resource, it is its responsilibty to perform the operations in a background thread.

Two specialized submodels exists:

  • MLBaseModel which is specialized for data that comes from the medialibrary, this model will handle running ML queries in the right thread, and will have specialized. See models such as MLGenreModel or MLAlbumModel

  • LocalListBaseModelPrivate allow exposing models where all the data is stored directly in the model. See models such as NetworkMediaModel or StandardPathModel