#include <QtCore/qdebug.h>
#include <QtCore/qmetaobject.h>
+#include <private/qmetaobject_p.h>
QT_BEGIN_NAMESPACE
prop.value = expr->expression();
QObject *scope = expr->scopeObject();
if (scope) {
- QString methodName = QString::fromLatin1(scope->metaObject()->method(signalHandler->index()).name());
+ QString methodName = QString::fromLatin1(QMetaObjectPrivate::signal(scope->metaObject(), signalHandler->index()).name());
if (!methodName.isEmpty()) {
prop.name = QLatin1String("on") + methodName[0].toUpper()
+ methodName.mid(1);
#include "qqmlboundsignal_p.h"
+#include <private/qmetaobject_p.h>
#include <private/qmetaobjectbuilder_p.h>
#include "qqmlengine_p.h"
#include "qqmlexpression_p.h"
}
}
+/*! \internal
+ \a signal MUST be in the signal index range (see QObjectPrivate::signalIndex()).
+ This is different from QMetaMethod::methodIndex().
+*/
QQmlBoundSignal::QQmlBoundSignal(QObject *scope, int signal, QObject *owner,
QQmlEngine *engine)
: m_expression(0), m_params(0), m_scope(scope), m_index(signal)
*/
if (QQmlData::get(scope, false) && QQmlData::get(scope, false)->propertyCache) {
QQmlPropertyCache *cache = QQmlData::get(scope, false)->propertyCache;
- while (cache->method(m_index)->isCloned())
+ while (cache->signal(m_index)->isCloned())
--m_index;
} else {
- while (scope->metaObject()->method(m_index).attributes() & QMetaMethod::Cloned)
+ while (QMetaObjectPrivate::signal(scope->metaObject(), m_index).attributes() & QMetaMethod::Cloned)
--m_index;
}
delete m_params;
}
+/*!
+ Returns the signal index in the range returned by QObjectPrivate::signalIndex().
+ This is different from QMetaMethod::methodIndex().
+*/
int QQmlBoundSignal::index() const
{
return m_index;
return;
if (QQmlDebugService::isDebuggingEnabled())
- QV8DebugService::instance()->signalEmitted(QString::fromLatin1(s->m_scope->metaObject()->method(s->m_index).methodSignature()));
+ QV8DebugService::instance()->signalEmitted(QString::fromLatin1(QMetaObjectPrivate::signal(s->m_scope->metaObject(), s->m_index).methodSignature()));
QQmlHandlingSignalProfiler prof(s->m_expression);
s->setIsEvaluating(true);
if (!s->paramsValid()) {
- QList<QByteArray> names = QQmlPropertyCache::methodParameterNames(*s->m_scope, s->m_index);
+ QList<QByteArray> names = QQmlPropertyCache::signalParameterNames(*s->m_scope, s->m_index);
if (!names.isEmpty()) {
- QMetaMethod signal = s->m_scope->metaObject()->method(s->m_index);
+ QMetaMethod signal = QMetaObjectPrivate::signal(s->m_scope->metaObject(), s->m_index);
s->m_params = new QQmlBoundSignalParameters(signal, s);
}
if (prop->value || !prop->values.isOne())
COMPILE_EXCEPTION(prop, tr("Incorrectly specified signal assignment"));
- prop->index = sig->coreIndex;
+ prop->index = propertyCacheForObject(obj)->methodIndexToSignalIndex(sig->coreIndex);
prop->core = *sig;
obj->addSignalProperty(prop);
// Dynamic properties (except var and aliases)
- effectiveMethodIndex = cache->methodIndexCacheStart;
+ int effectiveSignalIndex = cache->signalHandlerIndexCacheStart;
for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p;
p = obj->dynamicProperties.next(p)) {
p->name.hash());
if (p->isDefaultProperty) cache->_defaultPropertyName = propertyName.toUtf16();
cache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++,
- propertyType, effectiveMethodIndex);
+ propertyType, effectiveSignalIndex);
} else {
QString propertyName = p->name.toString();
if (p->isDefaultProperty) cache->_defaultPropertyName = propertyName;
cache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++,
- propertyType, effectiveMethodIndex);
+ propertyType, effectiveSignalIndex);
}
- effectiveMethodIndex++;
+ effectiveSignalIndex++;
VMD *vmd = (QQmlVMEMetaData *)dynamicData.data();
(vmd->propertyData() + vmd->propertyCount)->propertyType = vmePropertyType;
p->name.hash());
if (p->isDefaultProperty) cache->_defaultPropertyName = propertyName.toUtf16();
cache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++,
- QMetaType::QVariant, effectiveMethodIndex);
+ QMetaType::QVariant, effectiveSignalIndex);
} else {
QString propertyName = p->name.toString();
if (p->isDefaultProperty) cache->_defaultPropertyName = propertyName;
cache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++,
- QMetaType::QVariant, effectiveMethodIndex);
+ QMetaType::QVariant, effectiveSignalIndex);
}
- effectiveMethodIndex++;
+ effectiveSignalIndex++;
}
// Alias property count. Actual data is setup in buildDynamicMetaAliases
QQmlPropertyCache *cache = obj->synthCache;
char *cStringData = cache->_dynamicStringData.data();
- int effectiveMethodIndex = cache->methodIndexCacheStart + cache->propertyIndexCache.count();
+ int effectiveSignalIndex = cache->signalHandlerIndexCacheStart + cache->propertyIndexCache.count();
int effectivePropertyIndex = cache->propertyIndexCacheStart + cache->propertyIndexCache.count();
int effectiveAliasIndex = 0;
p->name.hash());
if (p->isDefaultProperty) cache->_defaultPropertyName = propertyName.toUtf16();
cache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++,
- type, effectiveMethodIndex++);
+ type, effectiveSignalIndex++);
} else {
QString propertyName = p->name.toString();
if (p->isDefaultProperty) cache->_defaultPropertyName = propertyName;
cache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++,
- type, effectiveMethodIndex++);
+ type, effectiveSignalIndex++);
}
}
d = property(object, propName, notInRevision);
if (d)
- return cache->method(d->notifyIndex);
+ return cache->signal(d->notifyIndex);
}
return 0;
#include <qjsengine.h>
#include <QtCore/qvarlengtharray.h>
+#include <private/qmetaobject_p.h>
#include <QtCore/qdebug.h>
QT_BEGIN_NAMESPACE
{
Q_D(QQmlContext);
if (d->notifyIndex == -1)
- d->notifyIndex = this->metaObject()->methodCount();
+ d->notifyIndex = QMetaObjectPrivate::absoluteSignalCount(&QQmlContext::staticMetaObject);
QQmlContextData *data = d->data;
data->refreshExpressions();
} else {
d->propertyValues[idx] = value;
- QMetaObject::activate(this, idx + d->notifyIndex, 0);
+ QMetaObject::activate(this, d->notifyIndex, idx, 0);
}
}
{
Q_D(QQmlContext);
if (d->notifyIndex == -1)
- d->notifyIndex = this->metaObject()->methodCount();
+ d->notifyIndex = QMetaObjectPrivate::absoluteSignalCount(&QQmlContext::staticMetaObject);
QQmlContextData *data = d->data;
data->refreshExpressions();
} else {
d->propertyValues[idx] = QVariant::fromValue(value);
- QMetaObject::activate(this, idx + d->notifyIndex, 0);
+ QMetaObject::activate(this, d->notifyIndex, idx, 0);
}
}
public:
QPointer<QObject> target;
- virtual int qt_metacall(QMetaObject::Call, int id, void **a) {
+ virtual int qt_metacall(QMetaObject::Call, int methodIndex, void **a) {
if (!target)
return -1;
+ QMetaMethod method = target->metaObject()->method(methodIndex);
+ Q_ASSERT(method.methodType() == QMetaMethod::Signal);
+ int signalIndex = QMetaObjectPrivate::signalIndex(method);
QQmlData *ddata = QQmlData::get(target, false);
- QQmlNotifierEndpoint *ep = ddata->notify(id);
+ QQmlNotifierEndpoint *ep = ddata->notify(signalIndex);
if (ep) QQmlNotifier::emitNotify(ep, a);
delete this;
if (!QObjectPrivate::get(object)->threadData->thread)
return;
- QMetaMethod m = object->metaObject()->method(index);
+ QMetaMethod m = QMetaObjectPrivate::signal(object->metaObject(), index);
QList<QByteArray> parameterTypes = m.parameterTypes();
int *types = (int *)malloc((parameterTypes.count() + 1) * sizeof(int));
args[ii + 1] = QMetaType::create(types[ii + 1], a[ii + 1]);
}
- QMetaCallEvent *ev = new QMetaCallEvent(index, 0, 0, object, index,
+ QMetaCallEvent *ev = new QMetaCallEvent(m.methodIndex(), 0, 0, object, index,
parameterTypes.count() + 1, types, args);
QQmlThreadNotifierProxyObject *mpo = new QQmlThreadNotifierProxyObject;
}
}
-bool QQml_isSignalConnected(QObject *obj, int signal_index, int index)
+bool QQml_isSignalConnected(QObject *obj, int signal_index)
{
QQmlData *data = QQmlData::get(obj);
- return QObjectPrivate::get(obj)->isSignalConnected(signal_index) || (data && data->signalHasEndpoint(index));
+ return QObjectPrivate::get(obj)->isSignalConnected(signal_index) || (data && data->signalHasEndpoint(signal_index));
}
/*
- index MUST be the index returned by QMetaMethod::index()
- This is different than the index returned by QObjectPrivate::signalIndex()
+ index MUST in the range returned by QObjectPrivate::signalIndex()
+ This is different than the index returned by QMetaMethod::methodIndex()
*/
bool QQmlData::signalHasEndpoint(int index)
{
return 0;
}
-bool Q_QML_PRIVATE_EXPORT QQml_isSignalConnected(QObject*, int, int);
+bool Q_QML_PRIVATE_EXPORT QQml_isSignalConnected(QObject*, int);
#define IS_SIGNAL_CONNECTED(Sender, SenderType, Name, Arguments) \
do { \
void (SenderType::*signal)Arguments = &SenderType::Name; \
static QMetaMethod method = QMetaMethod::fromSignal(signal); \
static int signalIdx = QMetaObjectPrivate::signalIndex(method); \
- static int methodIdx = method.methodIndex(); \
- return QQml_isSignalConnected(sender, signalIdx, methodIdx); \
+ return QQml_isSignalConnected(sender, signalIdx); \
} while (0)
struct QQmlGraphics_DerivedObject : public QObject
}
}
+/*! \internal
+ \reimp
+
+ \a n is in the signal index range (see QObjectPrivate::signalIndex()).
+*/
void QQmlJavaScriptExpression::GuardCapture::captureProperty(QObject *o, int c, int n)
{
if (expression) {
}
}
+/*! \internal
+ \a sourceSignal MUST be in the signal index range (see QObjectPrivate::signalIndex()).
+ This is different from QMetaMethod::methodIndex().
+*/
void QQmlNotifierEndpoint::connect(QObject *source, int sourceSignal, QQmlEngine *engine)
{
disconnect();
inline QQmlNotifier *senderAsNotifier() const;
Callback callback:4;
+ // The index is in the range returned by QObjectPrivate::signalIndex().
+ // This is different from QMetaMethod::methodIndex().
signed int sourceSignal:28;
QQmlNotifierEndpoint *next;
return prev != 0;
}
+/*! \internal
+ \a sourceSignal MUST be in the signal index range (see QObjectPrivate::signalIndex()).
+ This is different from QMetaMethod::methodIndex().
+*/
bool QQmlNotifierEndpoint::isConnected(QObject *source, int sourceSignal)
{
return this->sourceSignal != -1 && senderAsObject() == source &&
#include "qqmlvaluetypeproxybinding_p.h"
#include <QStringList>
+#include <private/qmetaobject_p.h>
#include <QtCore/qdebug.h>
#include <math.h>
if (d && d->notifyIndex != -1) {
object = currentObject;
- core = *ddata->propertyCache->method(d->notifyIndex);
+ core = *ddata->propertyCache->signal(d->notifyIndex);
return;
}
}
}
}
+/*! \internal
+ Returns the index of this property's signal, in the signal index range
+ (see QObjectPrivate::signalIndex()). This is different from
+ QMetaMethod::methodIndex().
+*/
+int QQmlPropertyPrivate::signalIndex() const
+{
+ Q_ASSERT(type() == QQmlProperty::SignalProperty);
+ QMetaMethod m = object->metaObject()->method(core.coreIndex);
+ return QMetaObjectPrivate::signalIndex(m);
+}
+
/*!
Create a copy of \a other.
*/
QQmlAbstractBoundSignal *signalHandler = data->signalHandlers;
- while (signalHandler && signalHandler->index() != that.index())
+ while (signalHandler && signalHandler->index() != QQmlPropertyPrivate::get(that)->signalIndex())
signalHandler = signalHandler->m_nextSignal;
if (signalHandler)
QQmlAbstractBoundSignal *signalHandler = data->signalHandlers;
- while (signalHandler && signalHandler->index() != that.index())
+ while (signalHandler && signalHandler->index() != QQmlPropertyPrivate::get(that)->signalIndex())
signalHandler = signalHandler->m_nextSignal;
if (signalHandler)
return signalHandler->takeExpression(expr);
if (expr) {
- QQmlBoundSignal *signal = new QQmlBoundSignal(that.d->object, that.index(), that.d->object,
+ int signalIndex = QQmlPropertyPrivate::get(that)->signalIndex();
+ QQmlBoundSignal *signal = new QQmlBoundSignal(that.d->object, signalIndex, that.d->object,
expr->context()->engine);
signal->takeExpression(expr);
}
return QMetaMethod();
}
-static inline void flush_vme_signal(const QObject *object, int index)
+/*! \internal
+ If \a indexInSignalRange is true, \a index is treated as a signal index
+ (see QObjectPrivate::signalIndex()), otherwise it is treated as a
+ method index (QMetaMethod::methodIndex()).
+*/
+static inline void flush_vme_signal(const QObject *object, int index, bool indexInSignalRange)
{
QQmlData *data = static_cast<QQmlData *>(QObjectPrivate::get(const_cast<QObject *>(object))->declarativeData);
if (data && data->propertyCache) {
- QQmlPropertyData *property = data->propertyCache->method(index);
+ QQmlPropertyData *property = indexInSignalRange ? data->propertyCache->signal(index)
+ : data->propertyCache->method(index);
if (property && property->isVMESignal()) {
- QQmlVMEMetaObject *vme = QQmlVMEMetaObject::getForMethod(const_cast<QObject *>(object),
- index);
- vme->connectAliasSignal(index);
+ QQmlVMEMetaObject *vme;
+ if (indexInSignalRange)
+ vme = QQmlVMEMetaObject::getForSignal(const_cast<QObject *>(object), index);
+ else
+ vme = QQmlVMEMetaObject::getForMethod(const_cast<QObject *>(object), index);
+ vme->connectAliasSignal(index, indexInSignalRange);
}
}
}
const QObject *receiver, int method_index,
int type, int *types)
{
- flush_vme_signal(sender, signal_index);
- flush_vme_signal(receiver, method_index);
+ static const bool indexInSignalRange = false;
+ flush_vme_signal(sender, signal_index, indexInSignalRange);
+ flush_vme_signal(receiver, method_index, indexInSignalRange);
return QMetaObject::connect(sender, signal_index, receiver, method_index, type, types);
}
+/*! \internal
+ \a signal_index MUST be in the signal index range (see QObjectPrivate::signalIndex()).
+ This is different from QMetaMethod::methodIndex().
+*/
void QQmlPropertyPrivate::flushSignal(const QObject *sender, int signal_index)
{
- flush_vme_signal(sender, signal_index);
+ static const bool indexInSignalRange = true;
+ flush_vme_signal(sender, signal_index, indexInSignalRange);
}
QT_END_NAMESPACE
const QQmlPropertyData &,
QQmlContextData *);
+ int signalIndex() const;
+
static inline QQmlPropertyPrivate *get(const QQmlProperty &p) {
return p.d;
}
Q_UNUSED(engine);
coreIndex = p.propertyIndex();
- notifyIndex = p.notifySignalIndex();
+ notifyIndex = QMetaObjectPrivate::signalIndex(p.notifySignal());
Q_ASSERT(p.revision() <= Q_INT16_MAX);
revision = p.revision();
{
propType = p.userType();
coreIndex = p.propertyIndex();
- notifyIndex = p.notifySignalIndex();
+ notifyIndex = QMetaObjectPrivate::signalIndex(p.notifySignal());
flags = fastFlagsForProperty(p) | flagsForPropertyType(propType, engine);
Q_ASSERT(p.revision() <= Q_INT16_MAX);
revision = p.revision();
return rv;
}
+/*! \internal
+
+ \a notifyIndex MUST be in the signal index range (see QObjectPrivate::signalIndex()).
+ This is different from QMetaMethod::methodIndex().
+*/
void QQmlPropertyCache::appendProperty(const QString &name,
quint32 flags, int coreIndex, int propType, int notifyIndex)
{
updateRecur(engine,metaObject);
}
+/*! \internal
+ \a index MUST be in the signal index range (see QObjectPrivate::signalIndex()).
+ This is different from QMetaMethod::methodIndex().
+*/
+QQmlPropertyData *
+QQmlPropertyCache::signal(int index) const
+{
+ if (index < 0 || index >= (signalHandlerIndexCacheStart + signalHandlerIndexCache.count()))
+ return 0;
+
+ if (index < signalHandlerIndexCacheStart)
+ return _parent->signal(index);
+
+ QQmlPropertyData *rv = const_cast<QQmlPropertyData *>(&methodIndexCache.at(index - signalHandlerIndexCacheStart));
+ if (rv->notFullyResolved()) resolve(rv);
+ Q_ASSERT(rv->isSignal() || rv->coreIndex == -1);
+ return rv;
+}
+
+int QQmlPropertyCache::methodIndexToSignalIndex(int index) const
+{
+ if (index < 0 || index >= (methodIndexCacheStart + methodIndexCache.count()))
+ return index;
+
+ if (index < methodIndexCacheStart)
+ return _parent->methodIndexToSignalIndex(index);
+
+ return index - methodIndexCacheStart + signalHandlerIndexCacheStart;
+}
+
QQmlPropertyData *
QQmlPropertyCache::property(int index) const
{
return type;
}
-QList<QByteArray> QQmlPropertyCache::methodParameterNames(QObject *object, int index)
+/*! \internal
+ \a index MUST be in the signal index range (see QObjectPrivate::signalIndex()).
+ This is different from QMetaMethod::methodIndex().
+*/
+QList<QByteArray> QQmlPropertyCache::signalParameterNames(QObject *object, int index)
{
QQmlData *data = QQmlData::get(object, false);
if (data->propertyCache) {
- QQmlPropertyData *p = data->propertyCache->method(index);
+ QQmlPropertyData *p = data->propertyCache->signal(index);
if (!p->hasArguments())
return QList<QByteArray>();
}
- return object->metaObject()->method(index).parameterNames();
+ return QMetaObjectPrivate::signal(object->metaObject(), index).parameterNames();
}
// Returns an array of the arguments for method \a index. The first entry in the array
int notifierId = -1;
if (data->notifyIndex != -1)
- notifierId = data->notifyIndex - methodIndexCacheStart;
+ notifierId = data->notifyIndex - signalHandlerIndexCacheStart;
QMetaPropertyBuilder property = builder.addProperty(properties.at(ii).first.toUtf8(),
QMetaType::typeName(data->propType),
};
int coreIndex;
union {
+ // The notify index is in the range returned by QObjectPrivate::signalIndex().
+ // This is different from QMetaMethod::methodIndex().
int notifyIndex; // When !IsFunction
void *arguments; // When IsFunction && HasArguments
};
QQmlPropertyData *property(const QString &) const;
QQmlPropertyData *property(int) const;
QQmlPropertyData *method(int) const;
+ QQmlPropertyData *signal(int) const;
+ int methodIndexToSignalIndex(int) const;
QStringList propertyNames() const;
QString defaultPropertyName() const;
QQmlPropertyData &);
static int *methodParameterTypes(QObject *, int index, QVarLengthArray<int, 9> &dummy,
QByteArray *unknownTypeError);
- static QList<QByteArray> methodParameterNames(QObject *, int index);
+ static QList<QByteArray> signalParameterNames(QObject *, int index);
const char *className() const;
}
}
-void QQmlVMEMetaObject::connectAliasSignal(int index)
+void QQmlVMEMetaObject::connectAliasSignal(int index, bool indexInSignalRange)
{
- int aliasId = (index - methodOffset()) - metaData->propertyCount;
+ int aliasId = (index - (indexInSignalRange ? signalOffset() : methodOffset())) - metaData->propertyCount;
if (aliasId < 0 || aliasId >= metaData->aliasCount)
return;
connectAlias(aliasId);
}
+/*! \internal
+ \a index is in the method index range (QMetaMethod::methodIndex()).
+*/
void QQmlVMEMetaObject::activate(QObject *object, int index, void **args)
{
- int signalOffset = cache->signalOffset();
- int methodOffset = cache->methodOffset();
-
- QMetaObject::activate(object, methodOffset, signalOffset, index - methodOffset, args);
+ QMetaObject::activate(object, signalOffset(), index - methodOffset(), args);
}
QQmlVMEMetaObject *QQmlVMEMetaObject::getForProperty(QObject *o, int coreIndex)
return vme;
}
+/*! \internal
+ \a coreIndex is in the signal index range (see QObjectPrivate::signalIndex()).
+ This is different from QMetaMethod::methodIndex().
+*/
+QQmlVMEMetaObject *QQmlVMEMetaObject::getForSignal(QObject *o, int coreIndex)
+{
+ QQmlVMEMetaObject *vme = QQmlVMEMetaObject::get(o);
+ while (vme->signalOffset() > coreIndex) {
+ Q_ASSERT(vme->parent.isT1());
+ vme = static_cast<QQmlVMEMetaObject *>(vme->parent.asT1());
+ }
+ return vme;
+}
+
QT_END_NAMESPACE
v8::Handle<v8::Value> vmeProperty(int index);
void setVMEProperty(int index, v8::Handle<v8::Value> v);
- void connectAliasSignal(int index);
+ void connectAliasSignal(int index, bool indexInSignalRange);
virtual QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *o);
static inline QQmlVMEMetaObject *get(QObject *o);
static QQmlVMEMetaObject *getForProperty(QObject *o, int coreIndex);
static QQmlVMEMetaObject *getForMethod(QObject *o, int coreIndex);
+ static QQmlVMEMetaObject *getForSignal(QObject *o, int coreIndex);
protected:
virtual int metaCall(QMetaObject::Call _c, int _id, void **_a);
const QQmlVMEMetaData *metaData;
inline int propOffset() const;
inline int methodOffset() const;
+ inline int signalOffset() const;
bool hasAssignedMetaObjectData;
QQmlVMEVariant *data;
return cache->methodOffset();
}
+int QQmlVMEMetaObject::signalOffset() const
+{
+ return cache->signalOffset();
+}
+
QT_END_NAMESPACE
#endif // QQMLVMEMETAOBJECT_P_H
bool QQuickKeysAttached::isConnected(const char *signalName)
{
Q_D(QQuickKeysAttached);
- //### doing two string-based lookups isn't ideal
int signal_index = d->signalIndex(signalName);
- int index = metaObject()->indexOfSignal(signalName);
- return QQml_isSignalConnected(this, signal_index, index);
+ return QQml_isSignalConnected(this, signal_index);
}
/*!
QQmlProperty prop(target(), propName);
if (prop.isValid() && (prop.type() & QQmlProperty::SignalProperty)) {
QQmlBoundSignal *signal =
- new QQmlBoundSignal(target(), prop.index(), this, qmlEngine(this));
+ new QQmlBoundSignal(target(), QQmlPropertyPrivate::get(prop)->signalIndex(), this, qmlEngine(this));
QString location;
QQmlContextData *ctxtdata = 0;