aboutsummaryrefslogtreecommitdiffstats
path: root/include/qdotnetsignal.h
blob: e9e0254b96e5b6734815280da32d2d730b64ee59 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/***************************************************************************************************
 Copyright (C) 2025 The Qt Company Ltd.
 SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
***************************************************************************************************/

#pragma once

#include "qdotnetobject.h"
#include "qdotnetarray.h"
#include "qdotnetevent.h"

#ifdef __GNUC__
#   pragma GCC diagnostic push
#   pragma GCC diagnostic ignored "-Wconversion"
#endif
#include <QList>
#ifdef __GNUC__
#   pragma GCC diagnostic pop
#endif

class QDotNetSignal : public QDotNetObject
{
public:
    Q_DOTNET_OBJECT_INLINE(QDotNetSignal, "Qt.MetaObject.Signal, Qt.DotNet.Adapter");

    static QList<QDotNetSignal> fromEvent(const QString& name, QDotNetRef sender)
    {
        if (!typeSignal.isValid())
            typeSignal = QDotNetType::typeOf(AssemblyQualifiedName);
        if (typeSignal.isValid() && !fnFromEvent.isValid())
            typeSignal.staticMethod("FromEvent", fnFromEvent);
        if (!fnFromEvent.isValid())
            return {};
        auto signalRefs = fnFromEvent(name, sender);
        if (!signalRefs.isValid())
            return {};
        QList<QDotNetSignal> signalList;
        for (int i = 0; i < signalRefs.length(); ++i) {
            auto signalObj = signalRefs.get(i).cast<QDotNetSignal>();
            if (!signalObj.isValid())
                continue;
            signalList.append(signalObj);
        }
        return signalList;
    }

    static bool convert(QDotNetSignal signalObj, QDotNetRef sender, QDotNetEventArgs args)
    {
        if (!typeSignal.isValid())
            typeSignal = QDotNetType::typeOf(AssemblyQualifiedName);
        if (typeSignal.isValid() && !fnConvert.isValid()) {
            fnConvert = adapter().resolveStaticMethod(AssemblyQualifiedName, "Convert",
                {
                    UnmanagedType::Bool,
                    AssemblyQualifiedName,
                    QDotNetOutbound<QDotNetRef>::Parameter,
                    QDotNetOutbound<QDotNetEventArgs>::Parameter
                });
        }
        if (!fnConvert.isValid())
            return false;
        return fnConvert(signalObj, sender, args);
    }

    QString name() const
    {
        return method("get_Name", fnName).invoke(*this);
    }

    int count() const
    {
        return method("get_Count", fnCount).invoke(*this);
    }

    QDotNetObject item(int index) const
    {
        return method("get_Item", fnItem).invoke(*this, index);
    }

    template<typename T>
    T arg(int argIdx)
    {
        const QString argName = QString("get_Arg%1").arg(argIdx + 1);
        QDotNetFunction<T> fnGetArg = method<T>(argName);
        return fnGetArg();
    }

    QDotNetType type(int argIdx)
    {
        if (argIdx < 0 || argIdx >= count())
            return { nullptr };
        auto fnGetType = method<QDotNetType>(QString("get_Type%1").arg(argIdx + 1));
        return fnGetType();
    }

    bool is(int argIdx, const QString &typeName)
    {
        if (argIdx < 0 || argIdx >= count())
            return false;
        auto argType = type(argIdx);
        return argType.isValid() && argType.isAssignableTo(QDotNetType::typeOf(typeName));
    }

private:
    static inline
        QDotNetType typeSignal = nullptr;
    static inline
        QDotNetFunction<QDotNetArray<QDotNetRef>, QString, QDotNetRef> fnFromEvent = nullptr;
    static inline
        QDotNetFunction<bool, QDotNetRef, QDotNetRef, QDotNetEventArgs> fnConvert = nullptr;
    mutable QDotNetFunction<QString> fnName = nullptr;
    mutable QDotNetFunction<int> fnCount = nullptr;
    mutable QDotNetFunction<QDotNetObject, int> fnItem = nullptr;
};