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 "kgameproperty.h"
14 #include "libkdegamesprivate_export.h"
15 // Qt
16 #include <QMultiHash>
17 #include <QObject>
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 class KDEGAMESPRIVATE_EXPORT KGamePropertyHandler : public QObject
64 {
65  Q_OBJECT
66 
67 public:
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 
290 Q_SIGNALS:
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  */
301  void signalPropertyChanged(KGamePropertyBase *);
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  */
331  void signalRequestValue(KGamePropertyBase *property, QString &value);
332 
333 private:
334  friend class KGamePropertyHandlerPrivate;
335  std::unique_ptr<KGamePropertyHandlerPrivate> const d;
336 
338 };
339 
340 #endif
The main KDE game object.
Definition: kgame.h:55
PropertyPolicy
The policy of the property.
A collection class for KGameProperty objects.
Base class of KGameProperty.
Definition: kgameproperty.h:36
Q_SIGNALSQ_SIGNALS
Q_DISABLE_COPY(Class)
virtual bool removeProperty(ScriptableExtension *callerPrincipal, quint64 objId, const QString &propName)
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Thu Sep 28 2023 03:47:32 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.