Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / QtCollider / QcObjectFactory.h
blob1244eeacd6dc9f2e31d637821c15dffc7998d581
1 /************************************************************************
3 * Copyright 2010-2012 Jakob Leben (jakob.leben@gmail.com)
5 * This file is part of SuperCollider Qt GUI.
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ************************************************************************/
22 #ifndef QC_OBJECT_FACTORY_H
23 #define QC_OBJECT_FACTORY_H
25 #include "QObjectProxy.h"
26 #include "Common.h"
27 #include "Slot.h"
29 #include <PyrObject.h>
31 #include <QMetaObject>
32 #include <QObject>
33 #include <QWidget>
34 #include <QHash>
36 class QcAbstractFactory;
38 typedef QHash<QString,QcAbstractFactory*> QcFactoryHash;
40 namespace QtCollider {
41 QcFactoryHash & factories ();
44 class QcAbstractFactory
46 public:
47 virtual const QMetaObject *metaObject() = 0;
48 virtual QObjectProxy *newInstance( PyrObject *, QtCollider::Variant arg[10] ) = 0;
51 static void qcNoConstructorMsg( const QMetaObject *metaObject, int argc, QtCollider::Variant *argv )
53 QString str = QString("No appropriate constructor found for %1 (")
54 .arg( metaObject->className() );
56 for (int i = 0; i < argc; ++i) {
57 int t_id = argv[i].type();
59 if (t_id != QMetaType::Void)
61 if (i > 0) str += ", ";
62 str += QMetaType::typeName(t_id);
64 else
65 break;
68 str += ")";
70 qcErrorMsg( str );
73 template <class QOBJECT> class QcObjectFactory : public QcAbstractFactory
75 public:
77 const QMetaObject *metaObject() {
78 return &QOBJECT::staticMetaObject;
81 virtual QObjectProxy *newInstance( PyrObject *scObject, QtCollider::Variant arg[10] ) {
82 QOBJECT *qObject;
84 if( arg[0].type() == QMetaType::Void ) {
85 qObject = new QOBJECT;
87 else {
88 QObject *obj = QOBJECT::staticMetaObject.newInstance(
89 arg[0].asGenericArgument(),
90 arg[1].asGenericArgument(),
91 arg[2].asGenericArgument(),
92 arg[3].asGenericArgument(),
93 arg[4].asGenericArgument(),
94 arg[5].asGenericArgument(),
95 arg[6].asGenericArgument(),
96 arg[7].asGenericArgument(),
97 arg[8].asGenericArgument(),
98 arg[9].asGenericArgument()
101 qObject = qobject_cast<QOBJECT*>(obj);
102 if( !qObject ) {
103 qcNoConstructorMsg( metaObject(), 10, arg );
104 return 0;
108 return proxy( qObject, scObject );
111 protected:
113 virtual QObjectProxy *proxy( QOBJECT *obj, PyrObject *sc_obj ) {
114 QObjectProxy *prox( new QObjectProxy(obj, sc_obj) );
115 initialize( prox, obj );
116 return prox;
119 virtual void initialize( QObjectProxy *proxy, QOBJECT *obj ) {};
122 #define QC_DECLARE_FACTORY( QOBJECT, FACTORY ) \
123 namespace QtCollider { \
124 void add_factory_##QOBJECT () { \
125 QcAbstractFactory *factory = new FACTORY; \
126 factories().insert( factory->metaObject()->className(), factory ); \
130 #define QC_DECLARE_QOBJECT_FACTORY( QOBJECT ) QC_DECLARE_FACTORY( QOBJECT, QcObjectFactory<QOBJECT> )
132 #define QC_ADD_FACTORY( QOBJECT ) \
133 void add_factory_##QOBJECT(); \
134 add_factory_##QOBJECT()
138 #endif //QC_OBJECT_FACTORY_H