-
Notifications
You must be signed in to change notification settings - Fork 75
/
qffilter.cpp
182 lines (137 loc) · 3.84 KB
/
qffilter.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#include <QtCore>
#include <QMetaObject>
#include <QtQml>
#include "priv/quickfluxfunctions.h"
#include "qffilter.h"
/*!
\qmltype Filter
\brief Add filter rule to AppListener
Filter component listens for the parent's dispatched signal, if a dispatched signal
match with its type, it will emit its own "dispatched" signal. Otherwise, it will
simply ignore the signal.
This component provides an alternative way to filter incoming message which is
suitable for making Store component.
Example:
\code
pragma Singleton
import QtQuick 2.0
import QuickFlux 1.0
import "../actions"
AppListener {
id: store
property ListModel model: ListModel { }
Filter {
type: ActionTypes.addTask
onDispatched: {
model.append({task: message.task});
}
}
}
\endcode
It is not suggested to use nested AppListener in a Store component. Because nested AppListener
do not share the same AppListener::listenerId, it will be difficult to control the order
of message reception between store component.
In contrast, Filter share the same listenerId with its parent, and therefore it is a solution
for above problem.
*/
/*!
\qmlsignal Filter::dispatched(string type, object message)
It is a proxy of parent's dispatched signal. If the parent emits a signal matched with the Filter::type / Filter::types property,
it will emit this signal
*/
QFFilter::QFFilter(QObject *parent) : QObject(parent)
{
}
/*! \qmlproperty string Filter::type
These types determine the filtering rule for incoming message. Only type matched will emit the "dispatched" signal.
\code
AppListener {
Filter {
type: "action1"
onDispatched: {
// handle the action
}
}
}
\endcode
\sa Filter::types
*/
QString QFFilter::type() const
{
if (m_types.size() == 0) {
return "";
} else {
return m_types[0];
}
}
void QFFilter::setType(const QString &type)
{
m_types = QStringList() << type;
emit typeChanged();
emit typesChanged();
}
void QFFilter::classBegin()
{
}
void QFFilter::componentComplete()
{
QObject* object = parent();
m_engine = qmlEngine(this);
if (!object) {
qDebug() << "Filter - Disabled due to missing parent.";
return;
}
const QMetaObject* meta = object->metaObject();
if (meta->indexOfSignal("dispatched(QString,QJSValue)") >= 0) {
connect(object,SIGNAL(dispatched(QString,QJSValue)),
this,SLOT(filter(QString,QJSValue)));
} else if (meta->indexOfSignal("dispatched(QString,QVariant)") >= 0) {
connect(object,SIGNAL(dispatched(QString,QVariant)),
this,SLOT(filter(QString,QVariant)));
} else {
qDebug() << "Filter - Disabled due to missing dispatched signal in parent object.";
return;
}
}
void QFFilter::filter(QString type, QJSValue message)
{
if (m_types.indexOf(type) >= 0) {
QF_PRECHECK_DISPATCH(m_engine.data(), type, message);
emit dispatched(type, message);
}
}
void QFFilter::filter(QString type, QVariant message)
{
if (m_types.indexOf(type) >= 0) {
QJSValue value = message.value<QJSValue>();
QF_PRECHECK_DISPATCH(m_engine.data(), type, value);
emit dispatched(type, value);
}
}
/*! \qmlproperty array Filter::types
These types determine the filtering rule for incoming message. Only type matched will emit the "dispatched" signal.
\code
AppListener {
Filter {
types: ["action1", "action2"]
onDispatched: {
// handle the action
}
}
}
\endcode
\sa Filter::type
*/
QStringList QFFilter::types() const
{
return m_types;
}
void QFFilter::setTypes(const QStringList &types)
{
m_types = types;
}
QQmlListProperty<QObject> QFFilter::children()
{
return QQmlListProperty<QObject>(qobject_cast<QObject*>(this),
m_children);
}