/****************************************************************************
**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Contact: http://www.qt-project.org/
**
** This file is part of the QtDeclarative module of the Qt Toolkit.
**
#ifndef QDECLARATIVENOTIFIER_P_H
#define QDECLARATIVENOTIFIER_P_H
-#include "private/qdeclarativeguard_p.h"
+#include "qdeclarativedata_p.h"
+#include "qdeclarativeguard_p.h"
QT_BEGIN_NAMESPACE
class QDeclarativeNotifierEndpoint;
-class QDeclarativeNotifier
+class Q_DECLARATIVE_EXPORT QDeclarativeNotifier
{
public:
inline QDeclarativeNotifier();
inline void notify();
private:
+ friend class QDeclarativeData;
friend class QDeclarativeNotifierEndpoint;
static void emitNotify(QDeclarativeNotifierEndpoint *);
{
public:
inline QDeclarativeNotifierEndpoint();
- inline QDeclarativeNotifierEndpoint(QObject *t, int m);
inline ~QDeclarativeNotifierEndpoint();
- QObject *target;
- int targetMethod;
+ typedef void (*Callback)(QDeclarativeNotifierEndpoint *);
+ Callback callback;
inline bool isConnected();
inline bool isConnected(QObject *source, int sourceSignal);
inline void connect(QDeclarativeNotifier *);
inline void disconnect();
+ inline bool isNotifying() const;
+ inline void cancelNotify();
+
void copyAndClear(QDeclarativeNotifierEndpoint &other);
private:
+ friend class QDeclarativeData;
friend class QDeclarativeNotifier;
- struct Signal {
- QDeclarativeGuard<QObject> source;
- int sourceSignal;
- };
-
- struct Notifier {
- QDeclarativeNotifier *notifier;
- QDeclarativeNotifierEndpoint **disconnected;
-
- QDeclarativeNotifierEndpoint *next;
- QDeclarativeNotifierEndpoint **prev;
- };
-
- enum { InvalidType, SignalType, NotifierType } type;
union {
- char signalData[sizeof(Signal)];
- char notifierData[sizeof(Notifier)];
+ QDeclarativeNotifier *notifier;
+ QObject *source;
};
-
- inline Notifier *toNotifier();
- inline Notifier *asNotifier();
- inline Signal *toSignal();
- inline Signal *asSignal();
+ unsigned int notifying : 1;
+ signed int sourceSignal : 31;
+ QDeclarativeNotifierEndpoint **disconnected;
+ QDeclarativeNotifierEndpoint *next;
+ QDeclarativeNotifierEndpoint **prev;
};
QDeclarativeNotifier::QDeclarativeNotifier()
{
QDeclarativeNotifierEndpoint *endpoint = endpoints;
while (endpoint) {
- QDeclarativeNotifierEndpoint::Notifier *n = endpoint->asNotifier();
+ QDeclarativeNotifierEndpoint *n = endpoint;
endpoint = n->next;
n->next = 0;
n->prev = 0;
n->notifier = 0;
+ n->sourceSignal = -1;
if (n->disconnected) *n->disconnected = 0;
n->disconnected = 0;
}
}
QDeclarativeNotifierEndpoint::QDeclarativeNotifierEndpoint()
-: target(0), targetMethod(0), type(InvalidType)
-{
-}
-
-QDeclarativeNotifierEndpoint::QDeclarativeNotifierEndpoint(QObject *t, int m)
-: target(t), targetMethod(m), type(InvalidType)
+: callback(0), notifier(0), notifying(0), sourceSignal(-1), disconnected(0), next(0), prev(0)
{
}
QDeclarativeNotifierEndpoint::~QDeclarativeNotifierEndpoint()
{
disconnect();
- if (SignalType == type) {
- Signal *s = asSignal();
- s->~Signal();
- }
}
bool QDeclarativeNotifierEndpoint::isConnected()
{
- if (SignalType == type) {
- return asSignal()->source;
- } else if (NotifierType == type) {
- return asNotifier()->notifier;
- } else {
- return false;
- }
+ return prev != 0;
}
bool QDeclarativeNotifierEndpoint::isConnected(QObject *source, int sourceSignal)
{
- return SignalType == type && asSignal()->source == source && asSignal()->sourceSignal == sourceSignal;
+ return this->sourceSignal != -1 && this->source == source && this->sourceSignal == sourceSignal;
}
bool QDeclarativeNotifierEndpoint::isConnected(QDeclarativeNotifier *notifier)
{
- return NotifierType == type && asNotifier()->notifier == notifier;
+ return sourceSignal == -1 && this->notifier == notifier;
}
void QDeclarativeNotifierEndpoint::connect(QDeclarativeNotifier *notifier)
{
- Notifier *n = toNotifier();
-
- if (n->notifier == notifier)
- return;
-
disconnect();
- n->next = notifier->endpoints;
- if (n->next) { n->next->asNotifier()->prev = &n->next; }
+ next = notifier->endpoints;
+ if (next) { next->prev = &next; }
notifier->endpoints = this;
- n->prev = ¬ifier->endpoints;
- n->notifier = notifier;
+ prev = ¬ifier->endpoints;
+ this->notifier = notifier;
}
void QDeclarativeNotifierEndpoint::disconnect()
{
- if (type == SignalType) {
- Signal *s = (Signal *)&signalData;
- if (s->source) {
- QMetaObject::disconnectOne(s->source, s->sourceSignal, target, targetMethod);
- s->source = 0;
- }
- } else if (type == NotifierType) {
- Notifier *n = asNotifier();
-
- if (n->next) n->next->asNotifier()->prev = n->prev;
- if (n->prev) *n->prev = n->next;
- if (n->disconnected) *n->disconnected = 0;
- n->next = 0;
- n->prev = 0;
- n->disconnected = 0;
- n->notifier = 0;
- }
-}
-
-QDeclarativeNotifierEndpoint::Notifier *QDeclarativeNotifierEndpoint::toNotifier()
-{
- if (NotifierType == type)
- return asNotifier();
-
- if (SignalType == type) {
- disconnect();
- Signal *s = asSignal();
- s->~Signal();
- }
-
- Notifier *n = asNotifier();
- n->next = 0;
- n->prev = 0;
- n->disconnected = 0;
- n->notifier = 0;
- type = NotifierType;
- return n;
+ if (next) next->prev = prev;
+ if (prev) *prev = next;
+ if (disconnected) *disconnected = 0;
+ next = 0;
+ prev = 0;
+ disconnected = 0;
+ notifier = 0;
+ notifying = 0;
+ sourceSignal = -1;
}
-QDeclarativeNotifierEndpoint::Notifier *QDeclarativeNotifierEndpoint::asNotifier()
-{
- return (Notifier *)(¬ifierData);
-}
+/*!
+Returns true if a notify is in progress. This means that the signal or QDeclarativeNotifier
+that this endpoing is connected to has been triggered, but this endpoint's callback has not
+yet been called.
-QDeclarativeNotifierEndpoint::Signal *QDeclarativeNotifierEndpoint::toSignal()
+An in progress notify can be cancelled by calling cancelNotify.
+*/
+bool QDeclarativeNotifierEndpoint::isNotifying() const
{
- if (SignalType == type)
- return asSignal();
-
- disconnect();
- Signal *s = asSignal();
- new (s) Signal;
- type = SignalType;
-
- return s;
+ return notifying == 1;
}
-QDeclarativeNotifierEndpoint::Signal *QDeclarativeNotifierEndpoint::asSignal()
-{
- return (Signal *)(&signalData);
+/*!
+Cancel any notifies that are in progress.
+*/
+void QDeclarativeNotifierEndpoint::cancelNotify()
+{
+ notifying = 0;
+ if (disconnected) {
+ *disconnected = 0;
+ disconnected = 0;
+ }
}
QT_END_NAMESPACE