KDEGames

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

KDE's Doxygen guidelines are available online.