Fixed crash when joining new channels
[quassel.git] / src / contrib / qxt / qxtboundfunction.h
1 /****************************************************************************
2 **
3 ** Copyright (C) Qxt Foundation. Some rights reserved.
4 **
5 ** This file is part of the QxtCore module of the Qt eXTension library
6 **
7 ** This library is free software; you can redistribute it and/or modify it
8 ** under the terms of th Common Public License, version 1.0, as published by
9 ** IBM.
10 **
11 ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
12 ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
13 ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
14 ** FITNESS FOR A PARTICULAR PURPOSE.
15 **
16 ** You should have received a copy of the CPL along with this file.
17 ** See the LICENSE file and the cpl1.0.txt file included with the source
18 ** distribution for more information. If you did not receive a copy of the
19 ** license, contact the Qxt Foundation.
20 **
21 ** <http://libqxt.sourceforge.net>  <foundation@libqxt.org>
22 **
23 ****************************************************************************/
24
25 #ifndef QXTBOUNDFUNCTION_H
26 #define QXTBOUNDFUNCTION_H
27
28 #include <QObject>
29 #include <QMetaObject>
30 #include <QGenericArgument>
31 #include <qxtmetaobject.h>
32 #include <qxtnull.h>
33 #include <QThread>
34
35 class QxtBoundFunction : public QObject
36 {
37     Q_OBJECT
38 public:
39     template <class T>
40     inline QxtNullable<T> invoke(QXT_PROTO_10ARGS(QVariant))
41     {
42         if (QThread::currentThread() == parent()->thread())
43             return invoke<T>(Qt::DirectConnection, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); 
44 #if QT_VERSION >= 0x040300
45         return invoke<T>(Qt::BlockingQueuedConnection, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
46 #else
47         qWarning() << "QxtBoundFunction::invoke: Cannot return a value using a queued connection";
48         return QxtNull();
49 #endif
50     }
51
52     template <class T>
53     QxtNullable<T> invoke(Qt::ConnectionType type, QXT_PROTO_10ARGS(QVariant))
54     {
55         if (type == Qt::QueuedConnection)
56         {
57             qWarning() << "QxtBoundFunction::invoke: Cannot return a value using a queued connection";
58             return qxtNull;
59         }
60         T retval;
61         // I know this is a totally ugly function call
62         if (invoke(type, QGenericReturnArgument(qVariantFromValue<T>(*reinterpret_cast<T*>(0)).typeName(), reinterpret_cast<void*>(&retval)),
63                    p1, p2, p3, p4, p5, p6, p7, p8, p9, p10))
64         {
65             return retval;
66         }
67         else
68         {
69             return qxtNull;
70         }
71     }
72
73     inline bool invoke(QXT_PROTO_10ARGS(QVariant))
74     {
75         return invoke(Qt::AutoConnection, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
76     }
77     bool invoke(Qt::ConnectionType, QXT_PROTO_10ARGS(QVariant));
78
79     inline bool invoke(QXT_PROTO_10ARGS(QGenericArgument))
80     {
81         return invoke(Qt::AutoConnection, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
82     }
83     inline bool invoke(Qt::ConnectionType type, QXT_PROTO_10ARGS(QGenericArgument)) {
84         return invoke(type, QGenericReturnArgument(), p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
85     }
86
87     inline bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QVariant))
88     {
89         return invoke(Qt::AutoConnection, returnValue, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
90     }
91     bool invoke(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QVariant));
92
93     inline bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument))
94     {
95         return invoke(Qt::AutoConnection, returnValue, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
96     }
97     bool invoke(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument));
98
99 protected:
100     QxtBoundFunction(QObject* parent = 0);
101     virtual bool invokeImpl(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument)) = 0;
102 };
103
104 #endif