1 | /*************************************************************************** |
2 | * Copyright (C) 2005-2014 by the Quassel Project * |
3 | * devel@quassel-irc.org * |
4 | * * |
5 | * This program is free software; you can redistribute it and/or modify * |
6 | * it under the terms of the GNU General Public License as published by * |
7 | * the Free Software Foundation; either version 2 of the License, or * |
8 | * (at your option) version 3. * |
9 | * * |
10 | * This program is distributed in the hope that it will be useful, * |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
13 | * GNU General Public License for more details. * |
14 | * * |
15 | * You should have received a copy of the GNU General Public License * |
16 | * along with this program; if not, write to the * |
17 | * Free Software Foundation, Inc., * |
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * |
19 | ***************************************************************************/ |
20 | |
21 | #ifndef SYNCABLEOBJECT_H |
22 | #define SYNCABLEOBJECT_H |
23 | |
24 | #include <QDataStream> |
25 | #include <QMetaType> |
26 | #include <QObject> |
27 | #include <QVariantMap> |
28 | |
29 | #include "signalproxy.h" |
30 | |
31 | #define SYNCABLE_OBJECT static const int _classNameOffset__; |
32 | #define INIT_SYNCABLE_OBJECT(x) const int x ::_classNameOffset__ = QByteArray(staticMetaObject.className()).length() + 2; |
33 | |
34 | #ifdef Q_CC_MSVC |
35 | # define SYNC(...) sync_call__(SignalProxy::Server, (__FUNCTION__ + _classNameOffset__), __VA_ARGS__); |
36 | # define REQUEST(...) sync_call__(SignalProxy::Client, (__FUNCTION__ + _classNameOffset__), __VA_ARGS__); |
37 | #else |
38 | # define SYNC(...) sync_call__(SignalProxy::Server, __func__, __VA_ARGS__); |
39 | # define REQUEST(...) sync_call__(SignalProxy::Client, __func__, __VA_ARGS__); |
40 | #endif //Q_CC_MSVC |
41 | |
42 | #define SYNC_OTHER(x, ...) sync_call__(SignalProxy::Server, #x, __VA_ARGS__); |
43 | #define REQUEST_OTHER(x, ...) sync_call__(SignalProxy::Client, #x, __VA_ARGS__); |
44 | |
45 | #define ARG(x) const_cast<void *>(reinterpret_cast<const void *>(&x)) |
46 | #define NO_ARG 0 |
47 | |
48 | class SyncableObject : public QObject |
49 | { |
50 | SYNCABLE_OBJECT |
51 | Q_OBJECT |
52 | |
53 | public: |
54 | SyncableObject(QObject *parent = 0); |
55 | SyncableObject(const QString &objectName, QObject *parent = 0); |
56 | SyncableObject(const SyncableObject &other, QObject *parent = 0); |
57 | ~SyncableObject(); |
58 | |
59 | //! Stores the object's state into a QVariantMap. |
60 | /** The default implementation takes dynamic properties as well as getters that have |
61 | * names starting with "init" and stores them in a QVariantMap. Override this method in |
62 | * derived classes in order to store the object state in a custom form. |
63 | * \note This is used by SignalProxy to transmit the state of the object to clients |
64 | * that request the initial object state. Later updates use a different mechanism |
65 | * and assume that the state is completely covered by properties and init* getters. |
66 | * DO NOT OVERRIDE THIS unless you know exactly what you do! |
67 | * |
68 | * \return The object's state in a QVariantMap |
69 | */ |
70 | virtual QVariantMap toVariantMap(); |
71 | |
72 | //! Initialize the object's state from a given QVariantMap. |
73 | /** \see toVariantMap() for important information concerning this method. |
74 | */ |
75 | virtual void fromVariantMap(const QVariantMap &properties); |
76 | |
77 | virtual bool isInitialized() const; |
78 | |
79 | virtual const QMetaObject *syncMetaObject() const { return metaObject(); }; |
80 | |
81 | inline void setAllowClientUpdates(bool allow) { _allowClientUpdates = allow; } |
82 | inline bool allowClientUpdates() const { return _allowClientUpdates; } |
83 | |
84 | public slots: |
85 | virtual void setInitialized(); |
86 | void requestUpdate(const QVariantMap &properties); |
87 | virtual void update(const QVariantMap &properties); |
88 | |
89 | protected: |
90 | void sync_call__(SignalProxy::ProxyMode modeType, const char *funcname, ...) const; |
91 | |
92 | void renameObject(const QString &newName); |
93 | SyncableObject &operator=(const SyncableObject &other); |
94 | |
95 | signals: |
96 | void initDone(); |
97 | void updatedRemotely(); |
98 | void updated(); |
99 | |
100 | private: |
101 | void synchronize(SignalProxy *proxy); |
102 | void stopSynchronize(SignalProxy *proxy); |
103 | |
104 | bool setInitValue(const QString &property, const QVariant &value); |
105 | |
106 | bool _initialized; |
107 | bool _allowClientUpdates; |
108 | |
109 | QList<SignalProxy *> _signalProxies; |
110 | |
111 | friend class SignalProxy; |
112 | }; |
113 | |
114 | |
115 | #endif |
116 | |