diff options
Diffstat (limited to 'libkdegames/kgame/kgamepropertyhandler.h')
-rw-r--r-- | libkdegames/kgame/kgamepropertyhandler.h | 353 |
1 files changed, 353 insertions, 0 deletions
diff --git a/libkdegames/kgame/kgamepropertyhandler.h b/libkdegames/kgame/kgamepropertyhandler.h new file mode 100644 index 00000000..6147c071 --- /dev/null +++ b/libkdegames/kgame/kgamepropertyhandler.h @@ -0,0 +1,353 @@ +/* + This file is part of the KDE games library + Copyright (C) 2001 Andreas Beckermann (b_mann@gmx.de) + Copyright (C) 2001 Martin Heni (martin@heni-online.de) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef __KGAMEPROPERTYHANDLER_H_ +#define __KGAMEPROPERTYHANDLER_H_ + +#include <qobject.h> +#include <qintdict.h> + +#include "kgameproperty.h" +#include <kdemacros.h> + +class QDataStream; +class KGame; +class KPlayer; +//class KGamePropertyBase; + +class KGamePropertyHandlerPrivate; // wow - what a name ;-) + +/** + * @short A collection class for KGameProperty objects + * + * The KGamePropertyHandler class is some kind of a collection class for + * KGameProperty. You usually don't have to create one yourself, as both + * KPlayer and KGame provide a handler. In most cases you do not even have + * to care about the KGamePropertHandler. KGame and KPlayer implement + * all features of KGamePropertyHandler so you will rather use it there. + * + * You have to use the KGamePropertyHandler as parent for all KGameProperty + * objects but you can also use KPlayer or KGame as parent - then + * KPlayer::dataHandler or KGame::dataHandler will be used. + * + * Every KGamePropertyHandler must have - just like every KGameProperty - + * a unique ID. This ID is provided either in the constructor or in + * registerHandler. The ID is used to assign an incoming message (e.g. a changed + * property) to the correct handler. Inside the handler the property ID is used + * to change the correct property. + * + * The constructor or registerHandler takes 3 addittional arguments: a + * receiver and two slots. The first slot is connected to + * signalSendMessage, the second to signalPropertyChanged. You must provide + * these in order to use the KGamePropertyHandler. + * + * The most important function of KGamePropertyHandler is processMessage + * which assigns an incoming value to the correct property. + * + * A KGamePropertyHandler is also used - indirectly using emitSignal - to + * emit a signal when the value of a property changes. This is done this way + * because a KGameProperty does not inherit QObject because of memory + * advantages. Many games can have dozens or even hundreds of KGameProperty + * objects so every additional variable in KGameProperty would be + * multiplied. + * + **/ +class KDE_EXPORT KGamePropertyHandler : public QObject +{ + Q_OBJECT + +public: + /** + * Construct an unregistered KGamePropertyHandler + * + * You have to call registerHandler before you can use this + * handler! + **/ + KGamePropertyHandler(QObject* parent = 0); + + /** + * Construct a registered handler. + * + * @see registerHandler + **/ + KGamePropertyHandler(int id, const QObject* receiver, const char* sendf, const char* emitf, QObject* parent = 0); + ~KGamePropertyHandler(); + + /** + * Register the handler with a parent. This is to use + * if the constructor without arguments has been chosen. + * Otherwise you need not call this. + * + * @param id The id of the message to listen for + * @param receiver The object that will receive the signals of + * KGamePropertyHandler + * @param send A slot that is being connected to signalSendMessage + * @param emit A slot that is being connected to signalPropertyChanged + **/ + void registerHandler(int id, const QObject *receiver, const char * send, const char *emit); + + /** + * Main message process function. This has to be called by + * the parent's message event handler. If the id of the message + * agrees with the id of the handler, the message is extracted + * and processed. Otherwise false is returned. + * Example: + * \code + * if (mProperties.processMessage(stream,msgid,sender==gameId())) return ; + * \endcode + * + * @param stream The data stream containing the message + * @param id the message id of the message + * @param isSender Whether the receiver is also the sender + * @return true on message processed otherwise false + **/ + bool processMessage(QDataStream &stream, int id, bool isSender ); + + /** + * @return the id of the handler + **/ + int id() const; + + /** + * Adds a KGameProperty property to the handler + * @param data the property + * @param name A description of the property, which will be returned by + * propertyName. This is used for debugging, e.g. in KGameDebugDialog + * @return true on success + **/ + bool addProperty(KGamePropertyBase *data, QString name=0); + + /** + * Removes a property from the handler + * @param data the property + * @return true on success + **/ + bool removeProperty(KGamePropertyBase *data); + + /** + * returns a unique property ID starting called usually with a base of + * KGamePropertyBase::IdAutomatic. This is used internally by + * the property base to assign automtic id's. Not much need to + * call this yourself. + **/ + int uniquePropertyId(); + + + /** + * Loads properties from the datastream + * + * @param stream the datastream to load from + * @return true on success otherwise false + **/ + virtual bool load(QDataStream &stream); + + /** + * Saves properties into the datastream + * + * @param stream the datastream to save to + * @return true on success otherwise false + **/ + virtual bool save(QDataStream &stream); + + /** + * called by a property to send itself into the + * datastream. This call is simply forwarded to + * the parent object + **/ + bool sendProperty(QDataStream &s); + + void sendLocked(bool l); + + /** + * called by a property to emit a signal + * This call is simply forwarded to + * the parent object + **/ + void emitSignal(KGamePropertyBase *data); + + /** + * @param id The ID of the property + * @return A name of the property which can be used for debugging. Don't + * depend on this function! It it possible not to provide a name or to + * provide the same name for multiple properties! + **/ + QString propertyName(int id) const; + + /** + * @param id The ID of the property. See KGamePropertyBase::id + * @return The KGameProperty this ID is assigned to + **/ + KGamePropertyBase *find(int id); + + /** + * Clear the KGamePropertyHandler. Note that the properties are + * <em>not</em> deleted so if you created your KGameProperty + * objects dynamically like + * \code + * KGamePropertyInt* myProperty = new KGamePropertyInt(id, dataHandler()); + * \endcode + * you also have to delete it: + * \code + * dataHandler()->clear(); + * delete myProperty; + * \endcode + **/ + void clear(); + + /** + * Use id as new ID for this KGamePropertyHandler. This is used + * internally only. + **/ + void setId(int id);//AB: TODO: make this protected in KGamePropertyHandler!! + + /** + * Calls KGamePropertyBase::setReadOnly(false) for all properties of this + * player. See also lockProperties + **/ + void unlockProperties(); + + /** + * Set the policy for all kgame variables which are currently registerd in + * the KGame proeprty handler. See KGamePropertyBase::setPolicy + * + * @param p is the new policy for all properties of this handler + * @param userspace if userspace is true (default) only user properties are changed. + * Otherwise the system properties are also changed. + **/ + void setPolicy(KGamePropertyBase::PropertyPolicy p, bool userspace=true); + + /** + * Called by the KGame or KPlayer object or the handler itself to delay + * emmiting of signals. Lockign keeps a counter and unlock is only achieved + * when every lock is canceld by an unlock. + * While this is set signals are quequed and only emmited after this + * is reset. Its deeper meaning is to prevent inconsistencies in a game + * load or network transfer where a emit could access a property not + * yet loaded or transmitted. Calling this by yourself you better know + * what your are doing. + **/ + void lockDirectEmit(); + + /** + * Removes the lock from the emitting of property signals. Corresponds to + * the lockIndirectEmits + **/ + void unlockDirectEmit(); + + /** + * Returns the default policy for this property handler. All properties + * registered newly, will have this property. + **/ + KGamePropertyBase::PropertyPolicy policy(); + + /** + * Calls KGamePropertyBase::setReadOnly(true) for all properties of this + * handler + * + * Use with care! This will even lock the core properties, like name, + * group and myTurn!! + * + * @see unlockProperties + **/ + void lockProperties(); + + /** + * Sends all properties which are marked dirty over the network. This will + * make a forced synchornisation of the properties and mark them all not dirty. + **/ + void flush(); + + /** + * Reference to the internal dictionary + **/ + QIntDict<KGamePropertyBase> &dict() const; + + /** + * In several situations you just want to have a QString of a + * KGameProperty object. This is the case in the + * KGameDebugDialog where the value of all properties is displayed. This + * function will provide you with such a QString for all the types + * used inside of all KGame classes. If you have a non-standard + * property (probably a self defined class or something like this) you + * also need to connect to signalRequestValue to make this function + * useful. + * @param property Return the value of this KGameProperty + * @return The value of a KGameProperty + **/ + QString propertyValue(KGamePropertyBase* property); + + + /** + * Writes some debug output to the console. + **/ + void Debug(); + + +signals: + /** + * This is emitted by a property. KGamePropertyBase::emitSignal + * calls emitSignal which emits this signal. + * + * This signal is emitted whenever the property is changed. Note that + * you can switch off this behaviour using + * KGamePropertyBase::setEmittingSignal in favor of performance. Note + * that you won't experience any performance loss using signals unless + * you use dozens or hundreds of properties which change very often. + **/ + void signalPropertyChanged(KGamePropertyBase *); + + /** + * This signal is emitted when a property needs to be sent. Only the + * parent has to react to this. + * @param msgid The id of the handler + * @param sent set this to true if the property was sent successfully - + * otherwise don't touch + **/ + void signalSendMessage(int msgid, QDataStream &, bool* sent); // AB shall we change bool* into bool& again? + + /** + * If you call propertyValue with a non-standard KGameProperty + * it is possible that the value cannot automatically be converted into a + * QString. Then this signal is emitted and asks you to provide the + * correct value. You probably want to use something like this to achieve + * this: + * \code + * #include <typeinfo> + * void slotRequestValue(KGamePropertyBase* p, QString& value) + * { + * if (*(p->typeinfo()) == typeid(MyType) { + * value = QString(((KGameProperty<MyType>*)p)->value()); + * } + * } + * \endcode + * + * @param property The KGamePropertyBase the value is requested for + * @param value The value of this property. You have to set this. + **/ + void signalRequestValue(KGamePropertyBase* property, QString& value); + +private: + void init(); + +private: + KGamePropertyHandlerPrivate* d; +}; + +#endif |