KDEGames

kgamepropertyhandler.h
1/*
2 This file is part of the KDE games library
3 SPDX-FileCopyrightText: 2001 Andreas Beckermann <b_mann@gmx.de>
4 SPDX-FileCopyrightText: 2001 Martin Heni <kde at heni-online.de>
5
6 SPDX-License-Identifier: LGPL-2.0-only
7*/
8
9#ifndef __KGAMEPROPERTYHANDLER_H_
10#define __KGAMEPROPERTYHANDLER_H_
11
12// own
13#include "kdegamesprivate_export.h"
14#include "kgameproperty.h"
15// Qt
16#include <QMultiHash>
17#include <QObject>
18// Std
19#include <memory>
20
21class QDataStream;
22class KGame;
23// class KGamePropertyBase;
24
25class KGamePropertyHandlerPrivate; // wow - what a name ;-)
26
27/**
28 * \class KGamePropertyHandler kgamepropertyhandler.h <KGame/KGamePropertyHandler>
29 *
30 * @short A collection class for KGameProperty objects
31 *
32 * The KGamePropertyHandler class is some kind of a collection class for
33 * KGameProperty. You usually don't have to create one yourself, as both
34 * KPlayer and KGame provide a handler. In most cases you do not even have
35 * to care about the KGamePropertHandler. KGame and KPlayer implement
36 * all features of KGamePropertyHandler so you will rather use it there.
37 *
38 * You have to use the KGamePropertyHandler as parent for all KGameProperty
39 * objects but you can also use KPlayer or KGame as parent - then
40 * KPlayer::dataHandler or KGame::dataHandler will be used.
41 *
42 * Every KGamePropertyHandler must have - just like every KGameProperty -
43 * a unique ID. This ID is provided either in the constructor or in
44 * registerHandler. The ID is used to assign an incoming message (e.g. a changed
45 * property) to the correct handler. Inside the handler the property ID is used
46 * to change the correct property.
47 *
48 * The constructor or registerHandler takes 3 additional arguments: a
49 * receiver and two slots. The first slot is connected to
50 * signalSendMessage, the second to signalPropertyChanged. You must provide
51 * these in order to use the KGamePropertyHandler.
52 *
53 * The most important function of KGamePropertyHandler is processMessage
54 * which assigns an incoming value to the correct property.
55 *
56 * A KGamePropertyHandler is also used - indirectly using emitSignal - to
57 * emit a signal when the value of a property changes. This is done this way
58 * because a KGameProperty does not inherit QObject because of memory
59 * advantages. Many games can have dozens or even hundreds of KGameProperty
60 * objects so every additional variable in KGameProperty would be
61 * multiplied.
62 */
63class KDEGAMESPRIVATE_EXPORT KGamePropertyHandler : public QObject
64{
65 Q_OBJECT
66
67public:
68 /**
69 * Construct an unregistered KGamePropertyHandler
70 *
71 * You have to call registerHandler before you can use this
72 * handler!
73 */
74 explicit KGamePropertyHandler(QObject *parent = nullptr);
75
76 /**
77 * Construct a registered handler.
78 *
79 * @see registerHandler
80 */
81 KGamePropertyHandler(int id, const QObject *receiver, const char *sendf, const char *emitf, QObject *parent = nullptr);
82 ~KGamePropertyHandler() override;
83
84 /**
85 * Register the handler with a parent. This is to use
86 * if the constructor without arguments has been chosen.
87 * Otherwise you need not call this.
88 *
89 * @param id The id of the message to listen for
90 * @param receiver The object that will receive the signals of
91 * KGamePropertyHandler
92 * @param send A slot that is being connected to signalSendMessage
93 * @param emit A slot that is being connected to signalPropertyChanged
94 */
95 void registerHandler(int id, const QObject *receiver, const char *send, const char *emit);
96
97 /**
98 * Main message process function. This has to be called by
99 * the parent's message event handler. If the id of the message
100 * agrees with the id of the handler, the message is extracted
101 * and processed. Otherwise false is returned.
102 * Example:
103 * \code
104 * if (mProperties.processMessage(stream,msgid,sender==gameId())) return ;
105 * \endcode
106 *
107 * @param stream The data stream containing the message
108 * @param id the message id of the message
109 * @param isSender Whether the receiver is also the sender
110 * @return true on message processed otherwise false
111 */
112 bool processMessage(QDataStream &stream, int id, bool isSender);
113
114 /**
115 * @return the id of the handler
116 */
117 int id() const;
118
119 /**
120 * Adds a KGameProperty property to the handler
121 * @param data the property
122 * @param name A description of the property, which will be returned by
123 * propertyName. This is used for debugging
124 * @return true on success
125 */
126 bool addProperty(KGamePropertyBase *data, const QString &name = QString());
127
128 /**
129 * Removes a property from the handler
130 * @param data the property
131 * @return true on success
132 */
133 bool removeProperty(KGamePropertyBase *data);
134
135 /**
136 * returns a unique property ID starting called usually with a base of
137 * KGamePropertyBase::IdAutomatic. This is used internally by
138 * the property base to assign automatic id's. Not much need to
139 * call this yourself.
140 */
141 int uniquePropertyId();
142
143 /**
144 * Loads properties from the datastream
145 *
146 * @param stream the datastream to load from
147 * @return true on success otherwise false
148 */
149 virtual bool load(QDataStream &stream);
150
151 /**
152 * Saves properties into the datastream
153 *
154 * @param stream the datastream to save to
155 * @return true on success otherwise false
156 */
157 virtual bool save(QDataStream &stream);
158
159 /**
160 * called by a property to send itself into the
161 * datastream. This call is simply forwarded to
162 * the parent object
163 */
164 bool sendProperty(QDataStream &s);
165
166 void sendLocked(bool l);
167
168 /**
169 * called by a property to emit a signal
170 * This call is simply forwarded to
171 * the parent object
172 */
173 void emitSignal(KGamePropertyBase *data);
174
175 /**
176 * @param id The ID of the property
177 * @return A name of the property which can be used for debugging. Don't
178 * depend on this function! It it possible not to provide a name or to
179 * provide the same name for multiple properties!
180 */
181 QString propertyName(int id) const;
182
183 /**
184 * @param id The ID of the property. See KGamePropertyBase::id
185 * @return The KGameProperty this ID is assigned to
186 */
187 KGamePropertyBase *find(int id);
188
189 /**
190 * Clear the KGamePropertyHandler. Note that the properties are
191 * <em>not</em> deleted so if you created your KGameProperty
192 * objects dynamically like
193 * \code
194 * KGamePropertyInt* myProperty = new KGamePropertyInt(id, dataHandler());
195 * \endcode
196 * you also have to delete it:
197 * \code
198 * dataHandler()->clear();
199 * delete myProperty;
200 * \endcode
201 */
202 void clear();
203
204 /**
205 * Use id as new ID for this KGamePropertyHandler. This is used
206 * internally only.
207 */
208 void setId(int id); // AB: TODO: make this protected in KGamePropertyHandler!!
209
210 /**
211 * Calls KGamePropertyBase::setReadOnly(false) for all properties of this
212 * player. See also lockProperties
213 */
214 void unlockProperties();
215
216 /**
217 * Set the policy for all kgame variables which are currently registered in
218 * the KGame property handler. See KGamePropertyBase::setPolicy
219 *
220 * @param p is the new policy for all properties of this handler
221 * @param userspace if userspace is true (default) only user properties are changed.
222 * Otherwise the system properties are also changed.
223 */
224 void setPolicy(KGamePropertyBase::PropertyPolicy p, bool userspace = true);
225
226 /**
227 * Called by the KGame or KPlayer object or the handler itself to delay
228 * emitting of signals. Locking keeps a counter and unlock is only achieved
229 * when every lock is canceled by an unlock.
230 * While this is set signals are queued and only emitted after this
231 * is reset. Its deeper meaning is to prevent inconsistencies in a game
232 * load or network transfer where a emit could access a property not
233 * yet loaded or transmitted. Calling this by yourself you better know
234 * what your are doing.
235 */
236 void lockDirectEmit();
237
238 /**
239 * Removes the lock from the emitting of property signals. Corresponds to
240 * the lockIndirectEmits
241 */
242 void unlockDirectEmit();
243
244 /**
245 * Returns the default policy for this property handler. All properties
246 * registered newly, will have this property.
247 */
249
250 /**
251 * Calls KGamePropertyBase::setReadOnly(true) for all properties of this
252 * handler
253 *
254 * Use with care! This will even lock the core properties, like name,
255 * group and myTurn!!
256 *
257 * @see unlockProperties
258 */
259 void lockProperties();
260
261 /**
262 * Sends all properties which are marked dirty over the network. This will
263 * make a forced synchronization of the properties and mark them all not dirty.
264 */
265 void flush();
266
267 /**
268 * Reference to the internal dictionary
269 */
271
272 /**
273 * In several situations you just want to have a QString of a
274 * KGameProperty object. This
275 * function will provide you with such a QString for all the types
276 * used inside of all KGame classes. If you have a non-standard
277 * property (probably a self defined class or something like this) you
278 * also need to connect to signalRequestValue to make this function
279 * useful.
280 * @param property Return the value of this KGameProperty
281 * @return The value of a KGameProperty
282 */
283 QString propertyValue(KGamePropertyBase *property);
284
285 /**
286 * Writes some debug output to the console.
287 */
288 void Debug();
289
291 /**
292 * This is emitted by a property. KGamePropertyBase::emitSignal
293 * calls emitSignal which emits this signal.
294 *
295 * This signal is emitted whenever the property is changed. Note that
296 * you can switch off this behaviour using
297 * KGamePropertyBase::setEmittingSignal in favor of performance. Note
298 * that you won't experience any performance loss using signals unless
299 * you use dozens or hundreds of properties which change very often.
300 */
302
303 /**
304 * This signal is emitted when a property needs to be sent. Only the
305 * parent has to react to this.
306 * @param msgid The id of the handler
307 * @param sent set this to true if the property was sent successfully -
308 * otherwise don't touch
309 */
310 void signalSendMessage(int msgid, QDataStream &, bool *sent); // AB shall we change bool* into bool& again?
311
312 /**
313 * If you call propertyValue with a non-standard KGameProperty
314 * it is possible that the value cannot automatically be converted into a
315 * QString. Then this signal is emitted and asks you to provide the
316 * correct value. You probably want to use something like this to achieve
317 * this:
318 * \code
319 * #include <typeinfo>
320 * void slotRequestValue(KGamePropertyBase* p, QString& value)
321 * {
322 * if (*(p->typeinfo()) == typeid(MyType) {
323 * value = QString(((KGameProperty<MyType>*)p)->value());
324 * }
325 * }
326 * \endcode
327 *
328 * @param property The KGamePropertyBase the value is requested for
329 * @param value The value of this property. You have to set this.
330 */
332
333private:
334 friend class KGamePropertyHandlerPrivate;
335 std::unique_ptr<KGamePropertyHandlerPrivate> const d;
336
337 Q_DISABLE_COPY(KGamePropertyHandler)
338};
339
340#endif
Base class of KGameProperty.
PropertyPolicy
The policy of the property.
A collection class for KGameProperty objects.
void signalRequestValue(KGamePropertyBase *property, QString &value)
If you call propertyValue with a non-standard KGameProperty it is possible that the value cannot auto...
void signalPropertyChanged(KGamePropertyBase *)
This is emitted by a property.
void signalSendMessage(int msgid, QDataStream &, bool *sent)
This signal is emitted when a property needs to be sent.
The main KDE game object.
Definition kgame.h:47
Q_SIGNALSQ_SIGNALS
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 16:59:04 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.