21 #include <glib-object.h>
22 #include <QtCore/QStringList>
23 #include <QtCore/QDebug>
26 #define QGLIB_G_VALUE_INITIALIZER {0, {{0}, {0}}}
34 struct QTGLIB_NO_EXPORT Signal::Private :
public QSharedData
36 Private(uint i) : id(i), m_queryInitialized(false) {}
39 GSignalQuery *query()
const;
42 mutable GSignalQuery m_query;
43 mutable bool m_queryInitialized;
46 GSignalQuery *Signal::Private::query()
const
48 if (!m_queryInitialized) {
49 g_signal_query(
id, &m_query);
50 m_queryInitialized =
true;
57 Signal::Signal(uint
id)
62 Signal::Signal(
const Signal & other)
67 Signal & Signal::operator=(
const Signal & other)
89 return QString::fromUtf8(d->query()->signal_name);
94 return QFlag(d->query()->signal_flags);
99 return d->query()->itype;
104 return d->query()->return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE;
110 for(uint i=0; i<d->query()->n_params; ++i) {
111 result.append(d->query()->param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE);
119 return Signal(g_signal_lookup(name, type));
125 QList<Signal> result;
127 uint *ids = g_signal_list_ids(type, &n_ids);
128 for(uint i=0; i<n_ids; ++i) {
129 result.append(
Signal(ids[i]));
141 Value emit(
void *instance,
const char *detailedSignal,
Quark detail,
const QList<Value> & args)
144 Type itype = Type::fromInstance(instance);
145 QStringList signalParts = QString::fromUtf8(detailedSignal).split(QLatin1String(
"::"));
146 if (!detail && signalParts.size() > 1) {
151 GValue *values =
new GValue[args.size() + 1];
152 memset(values, 0,
sizeof(GValue) * (args.size() + 1));
155 g_value_init(&values[0], itype);
156 g_value_set_instance(&values[0], instance);
161 if (!signal.isValid()) {
162 throw QString(QLatin1String(
"Could not find any signal named %1 "
163 "on this instance type")).arg(signalParts[0]);
166 QList<Type> paramTypes = signal.paramTypes();
167 if (paramTypes.size() != args.size()) {
168 throw QString(QLatin1String(
"The number of arguments that the signal accepts differ "
169 "from the number of arguments provided to emit"));
173 for(
int i=0; i<args.size(); i++) {
174 if (!args[i].type().isA(paramTypes[i])) {
175 throw QString(QLatin1String(
"Argument %1 provided to emit is not of the "
176 "type that the signal expects")).arg(i);
178 g_value_init(&values[i+1], args[i].type());
179 g_value_copy(args[i], &values[i+1]);
184 GValue returnValue = QGLIB_G_VALUE_INITIALIZER;
185 if (signal.returnType() != Type::None) {
186 g_value_init(&returnValue, signal.returnType());
190 g_signal_emitv(values, signal.id(), detail, &returnValue);
192 if (G_IS_VALUE(&returnValue)) {
193 result = Value(&returnValue);
194 g_value_unset(&returnValue);
196 }
catch (
const QString & msg) {
197 QString instanceName = Value(&values[0]).toString();
199 qCritical() <<
"Error during emission of signal" << detailedSignal
200 <<
"on object"<< instanceName <<
":" << msg;
204 for(
int i=0; i<args.size() + 1; i++) {
205 g_value_unset(&values[i]);