diff --git a/lib/include/DOtherSide/DOtherSide.h b/lib/include/DOtherSide/DOtherSide.h index da842e7..0617fbd 100644 --- a/lib/include/DOtherSide/DOtherSide.h +++ b/lib/include/DOtherSide/DOtherSide.h @@ -335,6 +335,9 @@ DOS_API DosQObject *DOS_CALL dos_qvariant_toQObject(const DosQVariant *vptr); /// \param slotDefinitions The SlotDefinitions struct /// \param propertyDefinitions The PropertyDefinitions struct /// \note The returned QMetaObject should be freed using dos_qmetaobject_delete(). +/// \attention The QMetaObject should live more than the QObject it refears to. +/// Depending on the implementation usually the QMetaObject should be modeled as static variable +/// So with a lifetime equals to the entire application DOS_API DosQMetaObject *DOS_CALL dos_qmetaobject_create(DosQMetaObject *superClassMetaObject, const char *className, const SignalDefinitions *signalDefinitions, @@ -426,7 +429,7 @@ DOS_API bool DOS_CALL dos_qobject_signal_disconnect(DosQObject *senderVPtr, /// \brief Return the DosQObject objectName /// \param vptr The DosQObject pointer /// \return A string in UTF8 format -/// \note The returned string should be freed using the dos_chararray_delete function +/// \note The returned string should be freed using the dos_chararray_delete() function DOS_API char *DOS_CALL dos_qobject_objectName(const DosQObject *vptr); @@ -471,16 +474,51 @@ DOS_API char *DOS_CALL dos_qhash_int_qbytearray_value (DosQHashIntQByteArray *vp // QResource DOS_API void DOS_CALL dos_qresource_register(const char *filename); -// QUrl +/// \defgroup QUrl QUrl +/// \brief Functions related to the QUrl class +/// @{ + +/// \brief Create a new QUrl +/// \param url The UTF-8 string that represents an url +/// \param parsingMode The parsing mode +/// \note The retuned QUrl should be freed using the dos_qurl_delete() function DOS_API DosQUrl *DOS_CALL dos_qurl_create(const char *url, int parsingMode); + +/// \brief Free the memory allocated for the QUrl +/// \param vptr The QUrl to be freed DOS_API void DOS_CALL dos_qurl_delete(DosQUrl *vptr); + +/// \brief Calls the QUrl::toString() function +/// \param vptr The QUrl +/// \return The url as an UTF-8 string +/// \note The returned string should be freed using the dos_chararray_delete() function DOS_API char *DOS_CALL dos_qurl_to_string(const DosQUrl *vptr); + + +/// \brief Class the QUrl::isValid() function +/// \param vptr The QUrl +/// \return True if the QUrl is valid, false otherwise DOS_API bool dos_qurl_isValid(const DosQUrl *vptr); -// QDeclarative +/// @} + +/// \defgroup QDeclarative QDeclarative +/// \brief Functions related to the QDeclarative module +/// @{ + +/// \brief Register a type in order to be instantiable from QML +/// \return An integer value that represents the registration ID in the +/// qml environment +/// \note The \p qmlRegisterType is owned by the caller thus it will not be freed DOS_API int DOS_CALL dos_qdeclarative_qmlregistertype(const QmlRegisterType *qmlRegisterType); + +/// \brief Register a singleton type in order to be accessible from QML +/// \return An integer value that represents the registration ID in the +/// \note The \p qmlRegisterType is owned by the caller thus it will not be freed DOS_API int DOS_CALL dos_qdeclarative_qmlregistersingletontype(const QmlRegisterType *qmlRegisterType); +/// @} + #ifdef __cplusplus } #endif diff --git a/lib/include/DOtherSide/DOtherSideTypes.h b/lib/include/DOtherSide/DOtherSideTypes.h index daaca9f..3376ee4 100644 --- a/lib/include/DOtherSide/DOtherSideTypes.h +++ b/lib/include/DOtherSide/DOtherSideTypes.h @@ -1,6 +1,6 @@ /** - * @file DOtherSideTypes.h - * @brief The DOtherSide types + * \file DOtherSideTypes.h + * \brief The DOtherSide types * * This file contains all the type definitions for structs and callbacks * used by the DOtherSide library @@ -22,38 +22,38 @@ extern "C" { #endif -/// \brief A pointer to a QVariant +/// A pointer to a QVariant typedef void DosQVariant; -/// \brief A pointer to a QModelIndex +/// A pointer to a QModelIndex typedef void DosQModelIndex; -/// \brief A pointer to a QAbstractListModel +/// A pointer to a QAbstractListModel typedef void DosQAbstractListModel; -/// \brief A pointer to a QQmlApplicationEngine +/// A pointer to a QQmlApplicationEngine typedef void DosQQmlApplicationEngine; -/// \brief A pointer to a QQuickView +/// pA pointer to a QQuickView typedef void DosQQuickView; -/// \brief A pointer to a QQmlContext +/// A pointer to a QQmlContext typedef void DosQQmlContext; -/// \brief A pointer to a QHash +/// A pointer to a QHash typedef void DosQHashIntQByteArray; -/// \brief A pointer to a QUrl +/// A pointer to a QUrl typedef void DosQUrl; -/// \brief A pointer to a QMetaObject +/// A pointer to a QMetaObject typedef void DosQMetaObject; -/// \brief A pointer to a QObject +/// A pointer to a QObject typedef void DosQObject; +/// Called when a slot should be executed /** - * \brief Called when a slot should be executed * \param self The pointer to the QObject in the binded language * \param slotName The slotName as DosQVariant. It should not be deleted * \param argc The number of arguments @@ -61,24 +61,24 @@ typedef void DosQObject; */ typedef void (DOS_CALL *DObjectCallback)(void *self, DosQVariant *slotName, int argc, DosQVariant **argv); +/// Called when the QAbstractListModel::rowCount method must be executed /** - * \brief Called when the QAbstractListModel::rowCount method must be executed * \param self The pointer to the QAbstractListModel in the binded language * \param index The parent DosQModelIndex. It should not be deleted * \param result The rowCount result. This must be deferenced and filled from the binded language. It should not be deleted */ typedef void (DOS_CALL *RowCountCallback)(void *self, const DosQModelIndex *parent, int *result); +/// Called when the QAbstractListModel::columnCount method must be executed /** - * \brief Called when the QAbstractListModel::columnCount method must be executed * \param self The pointer to the QAbstractListModel in the binded language * \param index The parent DosQModelIndex. It should not be deleted * \param result The rowCount result. This must be deferenced and filled from the binded language. It should not be deleted */ typedef void (DOS_CALL *ColumnCountCallback)(void *self, const DosQModelIndex *parent, int *result); +/// Called when the QAbstractListModel::data method must be executed /** - * \brief Called when the QAbstractListModel::data method must be executed * \param self The pointer to the QAbstractListModel in the binded language * \param index The DosQModelIndex to which we request the data. It should not be deleted * \param result The DosQVariant result. This must be deferenced and filled from the binded language. @@ -86,37 +86,95 @@ typedef void (DOS_CALL *ColumnCountCallback)(void *self, const DosQModelIndex *p */ typedef void (DOS_CALL *DataCallback)(void *self, const DosQModelIndex *index, int role, DosQVariant *result); -/** - * \brief Called when the QAbstractListModel::setData method must be executed - */ + +/// Called when the QAbstractListModel::setData method must be executed typedef void (DOS_CALL *SetDataCallback)(void *self, const DosQModelIndex *index, const DosQVariant *value, int role, bool *result); -/** - * \brief Called when the QAbstractListModel::roleNames method must be executed - */ +/// Called when the QAbstractListModel::roleNames method must be executed typedef void (DOS_CALL *RoleNamesCallback)(void *self, DosQHashIntQByteArray *result); -/** - * \brief Called when the QAbstractListModel::flags method must be called - */ + +/// Called when the QAbstractListModel::flags method must be called typedef void (DOS_CALL *FlagsCallback)(void *self, const DosQModelIndex *index, int *result); -/** - * \brief Called when the QAbstractListModel::headerData method must be called - */ + +/// Called when the QAbstractListModel::headerData method must be called typedef void (DOS_CALL *HeaderDataCallback)(void *self, int section, int orientation, int role, DosQVariant *result); -typedef void (DOS_CALL *CreateDObject)(int, void *, void **, void **); +/// Callback called from QML for creating a registered type +/** + * When a type is created through the QML engine a new QObject \i"Wrapper" is created. This becomes a proxy + * between the "default" QObject created through dos_qobject_create() and the QML engine. This imply that implementation + * for this callback should swap the DosQObject* stored in the binded language with the wrapper. At the end the wrapper + * becomes the owner of the original "default" DosQObject. Furthermore if the binding language is garbage collected you + * should disable (pin/ref) the original object and unref in the DeleteDObject() callback. Since the wrapper has been created + * from QML is QML that expect to free the memory for it thus it shouldn't be destroyed by the QObject in the binded language. + * + * An example of implementation in pseudocode is: \n + * \code{.nim} +proc createCallback(.....) = + # Call the constructor for the given type and create a QObject in Nim + let nimQObject = constructorMap[id]() -typedef void (DOS_CALL *DeleteDObject)(int, void *); + # Disable GC + GC.ref(nimQObject) + # Retrieve the DosQObject created dos_qobject_create() inside the nimQObject + *dosQObject = nimQObject.vptr + + # Store the pointer to the nimQObject + *bindedQObject = cast[ptr](&nimQObject) + + # Swap the vptr inside the nimQObject with the wrapper + nimQObject.vptr = wrapper + + # The QObject in the Nim language should not destroy its inner DosQObject + nimQObject.owner = false + +\endcode + + * \param id This is the id for which we are requesting the creation. + * This is the same value that was returned during registration through the calls + * to dos_qdeclarative_qmlregistertype() or dos_qdeclarative_qmlregistersingletontype() + * \param wrapper This is the QObject wrapper that should be stored by the binded language and to which forward the + * DOtherSide calls + * \param dosQObject This should be deferenced and assigned with the DosQObject pointer you gained from calling the dos_qobject_create() function + * \param bindedQObject This should be deferenced and assigned with the pointer of the QObject modeled in the binded language + */ +typedef void (DOS_CALL *CreateDObject)(int id, void *wrapper, void **dosQObject, void **bindedQObject); + +/// Callback invoked from QML for deleting a registered type +/** + * This is called when the wrapper gets deleted from QML. The implementation should unref/unpin + * the \p bindedQObject or delete it in the case of languages without GC + * \param id This is the type id for which we are requesting the deletion + * \param bindedQObject This is the pointer you given in the CreateDObject callback and you can use it + * for obtaining the QObject in your binded language. This allows you to unpin/unref it or delete it. + */ +typedef void (DOS_CALL *DeleteDObject)(int id, void * bindedQObject); + +/// The data needed for registering a custom type in the QML environment +/** + * This is used from dos_qdeclarative_qmlregistertype() and dos_qdeclarative_qmlregistersingletontype() calls. + * \see dos_qdeclarative_qmlregistertype() + * \see dos_qdeclarative_qmlregistersingletontype() + * \note All string and objects are considered to be owned by the caller thus they'll + * not be freed +*/ struct QmlRegisterType { + /// The Module major version int major; + /// The Module minor version int minor; + /// The Module uri const char *uri; + /// The type name to be used in QML files const char *qml; - void *staticMetaObject; + /// The type QMetaObject + DosQMetaObject *staticMetaObject; + /// The callback invoked from QML when this type should be created CreateDObject createDObject; + /// The callback invoked from QML when this type should be deleted DeleteDObject deleteDObject; };