kgameproperty.h

00001 /*
00002     This file is part of the KDE games library
00003     Copyright (C) 2001 Andreas Beckermann (b_mann@gmx.de)
00004     Copyright (C) 2001 Martin Heni (martin@heni-online.de)
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Library General Public
00008     License version 2 as published by the Free Software Foundation.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to
00017     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018     Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #ifndef __KGAMEPROPERTY_H_
00022 #define __KGAMEPROPERTY_H_
00023 
00024 #include <qdatastream.h>
00025 
00026 #include <kdebug.h>
00027 #include <typeinfo>
00028 #include <kdemacros.h>
00029 class KGame;
00030 class KPlayer;
00031 class KGamePropertyHandler;
00032 using namespace std;
00033 
00042 class KDE_EXPORT KGamePropertyBase
00043 {
00044 public:
00045     enum PropertyDataIds  { // these belong to KPlayer/KGame!
00046         //KPlayer
00047         IdGroup=1,
00048         IdUserId=2,
00049         IdAsyncInput=3,
00050         IdTurn=4,
00051         IdName=5,
00052 
00053         //KGame
00054         IdGameStatus=6,
00055         IdMaxPlayer=7,
00056         IdMinPlayer=8,
00057 
00058     // Input Grabbing
00059     IdGrabInput=16,
00060     IdReleaseInput=17,
00061 
00062         IdCommand, // Reserved for internal use
00063         IdUser=256,
00064 
00065         IdAutomatic=0x7000  // Id's from here on are automatically given (16bit)
00066     };
00067 
00071     enum PropertyCommandIds 
00072     {
00073         // General
00074         CmdLock=1,
00075         
00076         // Array
00077         CmdAt=51,
00078         CmdResize=52,
00079         CmdFill=53,
00080         CmdSort=54,
00081         // List (could be the same id's actually)
00082         CmdInsert=61,
00083         CmdAppend=62,
00084         CmdRemove=63,
00085         CmdClear=64
00086     };
00087 
00109     enum PropertyPolicy
00110     {
00111         PolicyUndefined = 0,
00112         PolicyClean = 1,
00113         PolicyDirty = 2,
00114         PolicyLocal = 3
00115     };
00116 
00117 
00126     KGamePropertyBase(int id, KGamePropertyHandler* owner);
00127 
00128     KGamePropertyBase(int id, KGame* parent);
00129     KGamePropertyBase(int id, KPlayer* parent);
00130 
00135     KGamePropertyBase();
00136 
00137     virtual ~KGamePropertyBase();
00138 
00145     void setPolicy(PropertyPolicy p) { mFlags.bits.policy = p; } 
00146 
00150     PropertyPolicy policy() const { return (PropertyPolicy)mFlags.bits.policy; }
00151 
00157     void setEmittingSignal(bool p)  { mFlags.bits.emitsignal=p; }
00158 
00163     bool isEmittingSignal() const { return mFlags.bits.emitsignal; }
00164 
00169     void setOptimized(bool p) { mFlags.bits.optimize = p ; }
00170 
00175     bool isOptimized() const { return mFlags.bits.optimize; }
00176 
00180     bool isDirty() const { return mFlags.bits.dirty; }
00181 
00187     bool isLocked() const { return mFlags.bits.locked; }
00188 
00200     bool lock();
00201 
00213     bool unlock(bool force=false);
00214 
00220     virtual void load(QDataStream& s) = 0;
00221 
00225     virtual void save(QDataStream& s) = 0;
00226 
00233     virtual void command(QDataStream &stream, int msgid, bool isSender=false);
00234 
00238     int id() const { return mId; }
00239 
00244     virtual const type_info* typeinfo() { return &typeid(this); }
00245 
00264     int registerData(int id, KGamePropertyHandler* owner,PropertyPolicy p, QString name=0);
00265 
00270     int registerData(int id, KGamePropertyHandler* owner, QString name=0);
00271 
00276     int registerData(int id, KGame* owner, QString name=0);
00277 
00282     int registerData(int id, KPlayer* owner, QString name=0);
00283 
00290     int registerData(KGamePropertyHandler* owner,PropertyPolicy p=PolicyUndefined, QString name=0);
00291 
00292     void unregisterData();
00293 
00294  
00295 protected:
00306     void setLock(bool l);
00307 
00316     void setDirty(bool d) { mFlags.bits.dirty = d ; }
00317 
00329     bool sendProperty();
00330     
00344     bool sendProperty(const QByteArray& b);
00345     
00349     void emitSignal();
00350 
00351 protected:
00352     KGamePropertyHandler* mOwner;
00353     
00354     // Having this as a union of the bitfield and the char
00355     // allows us to stream this quantity easily (if we need to)
00356     // At the moment it is not yet transmitted
00357     union Flags {
00358         char flag;
00359         struct {
00360             // unsigned char dosave : 1;   // do save this property
00361             // unsigned char delaytransmit : 1;   // do not send immediately on
00362                                              // change but a KPlayer:QTimer
00363                                              // sends it later on - fast
00364                                              // changing variables
00365             unsigned char emitsignal : 1; // KPlayer notifies on variable change (true)
00366             //unsigned char readonly : 1; // whether the property can be changed (false)
00367             unsigned char optimize : 1; // whether the property tries to optimize send/emit (false)
00368             unsigned char dirty: 1; // whether the property dirty (setLocal() was used)
00369             unsigned char policy : 2; // whether the property is always consistent (see PropertyPolicy)
00370             unsigned char locked: 1; // whether the property is locked (true)
00371         } bits;
00372     } mFlags;
00373     
00374 private:
00375     friend class KGamePropertyHandler;
00376     void init();
00377     
00378 private:
00379     int mId;
00380 
00381 };
00382 
00580 template<class type>
00581 class KGameProperty  : public KGamePropertyBase
00582 {
00583 public:
00596 // TODO: ID: Very ugly - better use something like parent()->propertyId() or so which assigns a free id automatically.
00597     KGameProperty(int id, KGamePropertyHandler* owner) : KGamePropertyBase(id, owner) { init(); }
00598 
00604     KGameProperty() : KGamePropertyBase() { init(); }
00605 
00606     virtual ~KGameProperty() {}
00607 
00615     void setValue(type v)
00616     {
00617         switch (policy()) {
00618             case PolicyClean:
00619                 send(v);
00620                 break;
00621             case PolicyDirty:
00622                 changeValue(v);
00623                 break;
00624             case PolicyLocal:
00625                 setLocal(v);
00626                 break;
00627             default: // NEVER!
00628                 kdError(11001) << "Undefined Policy in property " << id() << endl;
00629                 return;
00630         }
00631     }
00632 
00633 
00670     bool send(type v)
00671     {
00672         if (isOptimized() && mData == v) {
00673             return true;
00674         }
00675         if (isLocked()) {
00676             return false;
00677         }
00678         QByteArray b;
00679         QDataStream stream(b, IO_WriteOnly);
00680         stream << v;
00681         if (!sendProperty(b)) {
00682             setLocal(v);
00683             return false;
00684         }
00685         return true;
00686     }
00687 
00715     bool setLocal(type v) 
00716     {
00717         if (isOptimized() && mData == v) {
00718             return false;
00719         }
00720         if (isLocked()) {
00721             return false;
00722         }
00723         mData = v;
00724         setDirty(true);
00725         if (isEmittingSignal()) {
00726             emitSignal();
00727         }
00728         return true;
00729     }
00730 
00744     void changeValue(type v)
00745     {
00746         send(v);
00747         setLocal(v);
00748     }
00749 
00754     virtual void save(QDataStream &stream)
00755     {
00756         stream << mData;
00757     }
00758 
00764     const type& value() const
00765     {
00766         return mData;
00767     }
00768 
00780     virtual void load(QDataStream& s)
00781     {
00782         s >> mData;
00783         setDirty(false);
00784         if (isEmittingSignal()) {
00785             emitSignal();
00786         }
00787     }
00788 
00807     const type& operator=(const type& t) 
00808     { 
00809         setValue(t); 
00810         return value();
00811     }
00812 
00818     const type& operator=(const KGameProperty& property)
00819     {
00820         setValue(property.value());
00821         return value();
00822     }
00823 
00831     operator type() const { return value(); }
00832 
00833     virtual const type_info* typeinfo() { return &typeid(type); }
00834 
00835 private:
00836     void init() { }
00837 
00838 private:
00839     type mData;
00840 };
00841 
00842 
00843 typedef KGameProperty<int>   KGamePropertyInt;
00844 typedef KGameProperty<unsigned int>   KGamePropertyUInt;
00845 typedef KGameProperty<QString>   KGamePropertyQString;
00846 typedef KGameProperty<Q_INT8>   KGamePropertyBool;
00847 
00848 #endif
KDE Home | KDE Accessibility Home | Description of Access Keys