• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdegames API Reference
  • KDE Home
  • Contact Us
 

libkdegames/libkdegamesprivate/kgame

  • sources
  • kde-4.14
  • kdegames
  • libkdegames
  • libkdegamesprivate
  • kgame
kgamepropertyhandler.cpp
Go to the documentation of this file.
1 /*
2  This file is part of the KDE games library
3  Copyright (C) 2001 Andreas Beckermann (b_mann@gmx.de)
4  Copyright (C) 2001 Martin Heni (kde at heni-online.de)
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License version 2 as published by the Free Software Foundation.
9 
10  This library 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 GNU
13  Library General Public License for more details.
14 
15  You should have received a copy of the GNU Library General Public License
16  along with this library; see the file COPYING.LIB. If not, write to
17  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  Boston, MA 02110-1301, USA.
19 */
20 
21 #include "kgamepropertyhandler.h"
22 #include "kgameproperty.h"
23 #include "kgamemessage.h"
24 
25 #include <QMap>
26 #include <QQueue>
27 
28 #include <klocale.h>
29 #include <typeinfo>
30 
31 #define KPLAYERHANDLER_LOAD_COOKIE 6239
32 
33 //---------------------- KGamePropertyHandler -----------------------------------
34 class KGamePropertyHandlerPrivate
35 {
36 public:
37  KGamePropertyHandlerPrivate(KGamePropertyHandler *qq)
38  : q(qq), mUniqueId(KGamePropertyBase::IdAutomatic), mId(0),
39  mDefaultPolicy(KGamePropertyBase::PolicyLocal), mDefaultUserspace(true),
40  mIndirectEmit(0)
41  {
42  //kDebug(11001) << ": this=" << q;
43  }
44 
45  KGamePropertyHandler *q;
46  QMap<int, QString> mNameMap;
47  QMultiHash<int, KGamePropertyBase*> mIdDict;
48  int mUniqueId;
49  int mId;
50  KGamePropertyBase::PropertyPolicy mDefaultPolicy;
51  bool mDefaultUserspace;
52  int mIndirectEmit;
53  QQueue<KGamePropertyBase*> mSignalQueue;
54 };
55 
56 KGamePropertyHandler::KGamePropertyHandler(int id, const QObject* receiver, const char * sendf, const char *emitf, QObject* parent)
57  : QObject(parent), d(new KGamePropertyHandlerPrivate(this))
58 {
59  registerHandler(id,receiver,sendf,emitf);
60 }
61 
62 KGamePropertyHandler::KGamePropertyHandler(QObject* parent)
63  : QObject(parent), d(new KGamePropertyHandlerPrivate(this))
64 {
65 }
66 
67 KGamePropertyHandler::~KGamePropertyHandler()
68 {
69  //kDebug(11001) ;
70  clear();
71  delete d;
72  //kDebug(11001) << "done";
73 }
74 
75 int KGamePropertyHandler::id() const
76 {
77  return d->mId;
78 }
79 
80 void KGamePropertyHandler::setId(int id)
81 {
82  d->mId = id;
83 }
84 
85 void KGamePropertyHandler::registerHandler(int id,const QObject * receiver, const char * sendf, const char *emitf)
86 {
87  setId(id);
88  if (receiver && sendf) {
89  connect(this, SIGNAL(signalSendMessage(int,QDataStream&,bool*)), receiver, sendf);
90  }
91  if (receiver && emitf) {
92  connect(this, SIGNAL(signalPropertyChanged(KGamePropertyBase*)), receiver, emitf);
93  }
94 }
95 
96 bool KGamePropertyHandler::processMessage(QDataStream &stream, int id, bool isSender)
97 {
98 // kDebug(11001) << ": id=" << id << "mId=" << d->mId;
99  if (id != d->mId) {
100  return false; // Is the message meant for us?
101  }
102  KGamePropertyBase* p;
103  int propertyId;
104  KGameMessage::extractPropertyHeader(stream, propertyId);
105 // kDebug(11001) << ": Got property" << propertyId;
106  if (propertyId==KGamePropertyBase::IdCommand) {
107  int cmd;
108  KGameMessage::extractPropertyCommand(stream, propertyId, cmd);
109 //kDebug(11001) << ": Got COMMAND for id= "<<propertyId;
110  QMultiHash<int, KGamePropertyBase*>::iterator it = d->mIdDict.find(propertyId);
111  if (it != d->mIdDict.end()) {
112  p = *it;
113  if (!isSender || p->policy()==KGamePropertyBase::PolicyClean) {
114  p->command(stream, cmd, isSender);
115  }
116  } else {
117  kError(11001) << ": (cmd): property" << propertyId << "not found";
118  }
119  return true;
120  }
121  QMultiHash<int, KGamePropertyBase*>::iterator it = d->mIdDict.find(propertyId);
122  if (it != d->mIdDict.end()) {
123  p = *it;
124  //kDebug(11001) << ": Loading" << propertyId;
125  if (!isSender || p->policy()==KGamePropertyBase::PolicyClean) {
126  p->load(stream);
127  }
128  } else {
129  kError(11001) << ": property" << propertyId << "not found";
130  }
131  return true;
132 }
133 
134 bool KGamePropertyHandler::removeProperty(KGamePropertyBase* data)
135 {
136  if (!data) {
137  return false;
138  }
139 
140  d->mNameMap.remove(data->id());
141  return d->mIdDict.remove(data->id());
142 }
143 
144 bool KGamePropertyHandler::addProperty(KGamePropertyBase* data, const QString& name)
145 {
146  //kDebug(11001) << ":" << data->id();
147  if ( d->mIdDict.find(data->id()) != d->mIdDict.end() ) {
148  // this id already exists
149  kError(11001) << " -> cannot add property" << data->id();
150  return false;
151  } else {
152  d->mIdDict.insert(data->id(), data);
153  // if here is a check for "is_debug" or so we can add the strings only in debug mode
154  // and save memory!!
155  if (!name.isNull()) {
156  d->mNameMap[data->id()] = name;
157  //kDebug(11001) << ": nid="<< (data->id()) << "inserted in Map name=" << d->mNameMap[data->id()];
158  //kDebug(11001) << "Typeid=" << typeid(data).name();
159  //kDebug(11001) << "Typeid call=" << data->typeinfo()->name();
160  }
161  }
162  return true;
163 }
164 
165 QString KGamePropertyHandler::propertyName(int id) const
166 {
167  QString s;
168  if (d->mIdDict.find(id) != d->mIdDict.end()) {
169  if (d->mNameMap.contains(id)) {
170  s = i18n("%1 (%2)", d->mNameMap[id], id);
171  } else {
172  s = i18n("Unnamed - ID: %1", id);
173  }
174  } else {
175  // Should _never_ happen
176  s = i18np("%1 unregistered", "%1 unregistered", id);
177  }
178  return s;
179 }
180 
181 bool KGamePropertyHandler::load(QDataStream &stream)
182 {
183  // Prevent direct emmiting until all is loaded
184  lockDirectEmit();
185  uint count,i;
186  stream >> count;
187  kDebug(11001) << ":" << count << "KGameProperty objects";
188  for (i = 0; i < count; ++i) {
189  processMessage(stream, id(),false);
190  }
191  qint16 cookie;
192  stream >> cookie;
193  if (cookie == KPLAYERHANDLER_LOAD_COOKIE) {
194  kDebug(11001) << " KGamePropertyHandler loaded propertly";
195  } else {
196  kError(11001) << "KGamePropertyHandler loading error. probably format error";
197  }
198  // Allow direct emmiting (if no other lock still holds)
199  unlockDirectEmit();
200  return true;
201 }
202 
203 bool KGamePropertyHandler::save(QDataStream &stream)
204 {
205  kDebug(11001) << ":" << d->mIdDict.count() << "KGameProperty objects";
206  stream << (uint)d->mIdDict.count();
207  QHashIterator<int, KGamePropertyBase*> it(d->mIdDict);
208  while (it.hasNext()) {
209 it.next();
210  KGamePropertyBase *base=it.value();
211  if (base) {
212  KGameMessage::createPropertyHeader(stream, base->id());
213  base->save(stream);
214  }
215  }
216  stream << (qint16)KPLAYERHANDLER_LOAD_COOKIE;
217  return true;
218 }
219 
220 KGamePropertyBase::PropertyPolicy KGamePropertyHandler::policy()
221 {
222 // kDebug(11001) << ":" << d->mDefaultPolicy;
223  return d->mDefaultPolicy;
224 }
225 void KGamePropertyHandler::setPolicy(KGamePropertyBase::PropertyPolicy p,bool userspace)
226 {
227  // kDebug(11001) << ":" << p;
228  d->mDefaultPolicy=p;
229  d->mDefaultUserspace=userspace;
230  QHashIterator<int, KGamePropertyBase*> it(d->mIdDict);
231  while (it.hasNext()) {
232 it.next();
233  if (!userspace || it.value()->id()>=KGamePropertyBase::IdUser) {
234  it.value()->setPolicy((KGamePropertyBase::PropertyPolicy)p);
235  }
236  }
237 }
238 
239 void KGamePropertyHandler::unlockProperties()
240 {
241  QHashIterator<int, KGamePropertyBase*> it(d->mIdDict);
242  while (it.hasNext()) {
243 it.next();
244  it.value()->unlock();
245  }
246 }
247 
248 void KGamePropertyHandler::lockProperties()
249 {
250  QHashIterator<int, KGamePropertyBase*> it(d->mIdDict);
251  while (it.hasNext()) {
252 it.next();
253  it.value()->lock();
254  }
255 }
256 
257 int KGamePropertyHandler::uniquePropertyId()
258 {
259  return d->mUniqueId++;
260 }
261 
262 void KGamePropertyHandler::flush()
263 {
264  QHashIterator<int, KGamePropertyBase*> it(d->mIdDict);
265  while (it.hasNext()) {
266 it.next();
267  if (it.value()->isDirty()) {
268  it.value()->sendProperty();
269  }
270  }
271 }
272 
273 /* Fire all property signal changed which are collected in
274  * the queque
275  **/
276 void KGamePropertyHandler::lockDirectEmit()
277 {
278  d->mIndirectEmit++;
279 }
280 
281 void KGamePropertyHandler::unlockDirectEmit()
282 {
283  // If the flag is <=0 we emit the queued signals
284  d->mIndirectEmit--;
285  if (d->mIndirectEmit<=0)
286  {
287  while(!d->mSignalQueue.isEmpty())
288  {
289  KGamePropertyBase *prop=d->mSignalQueue.dequeue();
290 // kDebug(11001) << "emmiting signal for" << prop->id();
291  emit signalPropertyChanged(prop);
292  }
293  }
294 }
295 
296 void KGamePropertyHandler::emitSignal(KGamePropertyBase *prop)
297 {
298  // If the indirect flag is set (load and network transmit)
299  // we cannot emit the signals directly as it can happend that
300  // a sigal causes an access to a property which is e.g. not
301  // yet loaded or received
302 
303  if (d->mIndirectEmit>0)
304  {
305  // Queque the signal
306  d->mSignalQueue.enqueue(prop);
307  }
308  else
309  {
310  // directly emit
311  emit signalPropertyChanged(prop);
312  }
313 }
314 
315 bool KGamePropertyHandler::sendProperty(QDataStream &s)
316 {
317  bool sent = false;
318  emit signalSendMessage(id(), s, &sent);
319  return sent;
320 }
321 
322 KGamePropertyBase* KGamePropertyHandler::find(int id)
323 {
324  if (d->mIdDict.find(id) == d->mIdDict.end())
325  return 0;
326  return *(d->mIdDict.find(id));
327 }
328 
329 void KGamePropertyHandler::clear()
330 {
331  // Note: Hash iterator method 'toFront()' crashes when applied to first item.
332  // Therefore we get the keys as list first.
333  QList<int> list = d->mIdDict.keys();
334  for (int i = 0; i < list.size(); ++i)
335  {
336  int key = list.at(i);
337  KGamePropertyBase* p = d->mIdDict.value(key);
338  p->unregisterData();
339  if (d->mIdDict.find(p->id()) != d->mIdDict.end())
340  {
341  // shouldn't happen - but if mOwner in KGamePropertyBase is NULL
342  // this might be possible
343  removeProperty(p);
344  }
345  }
346 }
347 
348 QMultiHash<int, KGamePropertyBase*>& KGamePropertyHandler::dict() const
349 {
350  return d->mIdDict;
351 }
352 
353 QString KGamePropertyHandler::propertyValue(KGamePropertyBase* prop)
354 {
355  if (!prop) {
356  return i18n("NULL pointer");
357  }
358 
359  int id = prop->id();
360  QString name = propertyName(id);
361  QString value;
362 
363  const type_info* t = prop->typeinfo();
364  if (*t == typeid(int)) {
365  value = QString::number(((KGamePropertyInt*)prop)->value());
366  } else if (*t == typeid(unsigned int)) {
367  value = QString::number(((KGamePropertyUInt *)prop)->value());
368  } else if (*t == typeid(long int)) {
369  value = QString::number(((KGameProperty<qint64> *)prop)->value());
370  } else if (*t == typeid(unsigned long int)) {
371  value = QString::number(((KGameProperty<quint64> *)prop)->value());
372  } else if (*t == typeid(QString)) {
373  value = ((KGamePropertyQString*)prop)->value();
374  } else if (*t == typeid(qint8)) {
375  value = ((KGamePropertyBool*)prop)->value() ? i18n("True") : i18n("False");
376  } else {
377  emit signalRequestValue(prop, value);
378  }
379 
380  if (value.isNull()) {
381  value = i18n("Unknown");
382  }
383  return value;
384 }
385 
386 void KGamePropertyHandler::Debug()
387 {
388  kDebug(11001) << "-----------------------------------------------------------";
389  kDebug(11001) << "KGamePropertyHandler:: Debug this=" << this;
390 
391  kDebug(11001) << " Registered properties: (Policy,Lock,Emit,Optimized, Dirty)";
392  QHashIterator<int, KGamePropertyBase*> it(d->mIdDict);
393  while (it.hasNext()) {
394 it.next();
395  KGamePropertyBase *p=it.value();
396  kDebug(11001) << " "<< p->id() << ": p=" << p->policy()
397  << "l="<<p->isLocked()
398  << "e="<<p->isEmittingSignal()
399  << "o=" << p->isOptimized()
400  << "d="<<p->isDirty();
401  }
402  kDebug(11001) << "-----------------------------------------------------------";
403 }
404 
405 #include "kgamepropertyhandler.moc"
KGamePropertyHandler::propertyName
QString propertyName(int id) const
Definition: kgamepropertyhandler.cpp:165
KGamePropertyBase::IdUser
Definition: kgameproperty.h:66
KGamePropertyBase::PolicyClean
Definition: kgameproperty.h:115
KGamePropertyHandler::lockDirectEmit
void lockDirectEmit()
Called by the KGame or KPlayer object or the handler itself to delay emmiting of signals.
Definition: kgamepropertyhandler.cpp:276
KGamePropertyHandler::setId
void setId(int id)
Use id as new ID for this KGamePropertyHandler.
Definition: kgamepropertyhandler.cpp:80
QQueue< KGamePropertyBase * >
KGamePropertyBase::isLocked
bool isLocked() const
A locked property can only be changed by the player who has set the lock.
Definition: kgameproperty.h:190
QDataStream
KGamePropertyHandler
A collection class for KGameProperty objects.
Definition: kgamepropertyhandler.h:73
KGamePropertyHandler::flush
void flush()
Sends all properties which are marked dirty over the network.
Definition: kgamepropertyhandler.cpp:262
QHashIterator::hasNext
bool hasNext() const
KGamePropertyHandler::removeProperty
bool removeProperty(KGamePropertyBase *data)
Removes a property from the handler.
Definition: kgamepropertyhandler.cpp:134
QList::at
const T & at(int i) const
QMap< int, QString >
KGamePropertyBase::PropertyPolicy
PropertyPolicy
The policy of the property.
Definition: kgameproperty.h:112
KGamePropertyHandler::clear
void clear()
Clear the KGamePropertyHandler.
Definition: kgamepropertyhandler.cpp:329
KGamePropertyHandler::signalRequestValue
void signalRequestValue(KGamePropertyBase *property, QString &value)
If you call propertyValue with a non-standard KGameProperty it is possible that the value cannot auto...
KGamePropertyHandler::id
int id() const
Definition: kgamepropertyhandler.cpp:75
KGameMessage::createPropertyHeader
static void createPropertyHeader(QDataStream &msg, int id)
Creates a property header given the property id.
Definition: kgamemessage.cpp:72
KGameMessage::extractPropertyCommand
static void extractPropertyCommand(QDataStream &msg, int &pid, int &cmd)
Retrieves the property id from a property message header.
Definition: kgamemessage.cpp:91
KGamePropertyHandler::load
virtual bool load(QDataStream &stream)
Loads properties from the datastream.
Definition: kgamepropertyhandler.cpp:181
KGamePropertyHandler::registerHandler
void registerHandler(int id, const QObject *receiver, const char *send, const char *emit)
Register the handler with a parent.
Definition: kgamepropertyhandler.cpp:85
QList::size
int size() const
QString::isNull
bool isNull() const
KGamePropertyHandler::Debug
void Debug()
Writes some debug output to the console.
Definition: kgamepropertyhandler.cpp:386
QObject::name
const char * name() const
QString::number
QString number(int n, int base)
kgamepropertyhandler.h
KGamePropertyHandler::save
virtual bool save(QDataStream &stream)
Saves properties into the datastream.
Definition: kgamepropertyhandler.cpp:203
KGamePropertyHandler::find
KGamePropertyBase * find(int id)
Definition: kgamepropertyhandler.cpp:322
kgameproperty.h
KGamePropertyHandler::emitSignal
void emitSignal(KGamePropertyBase *data)
called by a property to emit a signal This call is simply forwarded to the parent object ...
Definition: kgamepropertyhandler.cpp:296
QObject
KGamePropertyBase::isDirty
bool isDirty() const
Definition: kgameproperty.h:183
KGamePropertyBase::PolicyLocal
Definition: kgameproperty.h:117
QHashIterator
KPLAYERHANDLER_LOAD_COOKIE
#define KPLAYERHANDLER_LOAD_COOKIE
Definition: kgamepropertyhandler.cpp:31
KGamePropertyHandler::lockProperties
void lockProperties()
Calls KGamePropertyBase::setReadOnly(true) for all properties of this handler.
Definition: kgamepropertyhandler.cpp:248
KGamePropertyBase::typeinfo
virtual const type_info * typeinfo()
Definition: kgameproperty.h:246
QString
QList< int >
KGamePropertyHandler::uniquePropertyId
int uniquePropertyId()
returns a unique property ID starting called usually with a base of KGamePropertyBase::IdAutomatic.
Definition: kgamepropertyhandler.cpp:257
KGamePropertyHandler::signalPropertyChanged
void signalPropertyChanged(KGamePropertyBase *)
This is emitted by a property.
KGamePropertyBase::IdCommand
Definition: kgameproperty.h:65
kgamemessage.h
KGamePropertyHandler::setPolicy
void setPolicy(KGamePropertyBase::PropertyPolicy p, bool userspace=true)
Set the policy for all kgame variables which are currently registerd in the KGame proeprty handler...
Definition: kgamepropertyhandler.cpp:225
KGamePropertyBase::isOptimized
bool isOptimized() const
See also setOptimize.
Definition: kgameproperty.h:178
KGamePropertyHandler::sendProperty
bool sendProperty(QDataStream &s)
called by a property to send itself into the datastream.
Definition: kgamepropertyhandler.cpp:315
KGamePropertyHandler::signalSendMessage
void signalSendMessage(int msgid, QDataStream &, bool *sent)
This signal is emitted when a property needs to be sent.
KGamePropertyHandler::propertyValue
QString propertyValue(KGamePropertyBase *property)
In several situations you just want to have a QString of a KGameProperty object.
Definition: kgamepropertyhandler.cpp:353
KGamePropertyHandler::dict
QMultiHash< int, KGamePropertyBase * > & dict() const
Reference to the internal dictionary.
Definition: kgamepropertyhandler.cpp:348
KGamePropertyBase
Base class of KGameProperty.
Definition: kgameproperty.h:45
QHashIterator::next
Item next()
KGamePropertyHandler::KGamePropertyHandler
KGamePropertyHandler(QObject *parent=0)
Construct an unregistered KGamePropertyHandler.
Definition: kgamepropertyhandler.cpp:62
KGamePropertyBase::load
virtual void load(QDataStream &s)=0
This will read the value of this property from the stream.
KGamePropertyBase::unregisterData
void unregisterData()
Definition: kgameproperty.cpp:112
KGamePropertyBase::save
virtual void save(QDataStream &s)=0
Write the value into a stream.
KGamePropertyHandler::addProperty
bool addProperty(KGamePropertyBase *data, const QString &name=QString())
Adds a KGameProperty property to the handler.
Definition: kgamepropertyhandler.cpp:144
KGamePropertyBase::IdAutomatic
Definition: kgameproperty.h:68
KGamePropertyHandler::~KGamePropertyHandler
~KGamePropertyHandler()
Definition: kgamepropertyhandler.cpp:67
KGamePropertyBase::policy
PropertyPolicy policy() const
Definition: kgameproperty.h:153
KGamePropertyBase::command
virtual void command(QDataStream &stream, int msgid, bool isSender=false)
send a command to advanced properties like arrays
Definition: kgameproperty.cpp:192
KGamePropertyHandler::processMessage
bool processMessage(QDataStream &stream, int id, bool isSender)
Main message process function.
Definition: kgamepropertyhandler.cpp:96
QHashIterator::value
const T & value() const
KGameMessage::extractPropertyHeader
static void extractPropertyHeader(QDataStream &msg, int &id)
Retrieves the property id from a property message header.
Definition: kgamemessage.cpp:77
KGamePropertyHandler::unlockProperties
void unlockProperties()
Calls KGamePropertyBase::setReadOnly(false) for all properties of this player.
Definition: kgamepropertyhandler.cpp:239
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
KGamePropertyHandler::policy
KGamePropertyBase::PropertyPolicy policy()
Returns the default policy for this property handler.
Definition: kgamepropertyhandler.cpp:220
KGameProperty< int >
KGamePropertyHandler::unlockDirectEmit
void unlockDirectEmit()
Removes the lock from the emitting of property signals.
Definition: kgamepropertyhandler.cpp:281
KGamePropertyBase::id
int id() const
Definition: kgameproperty.h:241
QMultiHash< int, KGamePropertyBase * >
KGamePropertyBase::isEmittingSignal
bool isEmittingSignal() const
See also setEmittingSignal.
Definition: kgameproperty.h:166
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:18:54 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

libkdegames/libkdegamesprivate/kgame

Skip menu "libkdegames/libkdegamesprivate/kgame"
  • Main Page
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdegames API Reference

Skip menu "kdegames API Reference"
  • granatier
  • kapman
  • kblackbox
  • kgoldrunner
  • kigo
  • kmahjongg
  • KShisen
  • ksquares
  • libkdegames
  •   highscore
  •   libkdegamesprivate
  •     kgame
  • libkmahjongg
  • palapeli
  •   libpala

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal