00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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 {
00046
00047 IdGroup=1,
00048 IdUserId=2,
00049 IdAsyncInput=3,
00050 IdTurn=4,
00051 IdName=5,
00052
00053
00054 IdGameStatus=6,
00055 IdMaxPlayer=7,
00056 IdMinPlayer=8,
00057
00058
00059 IdGrabInput=16,
00060 IdReleaseInput=17,
00061
00062 IdCommand,
00063 IdUser=256,
00064
00065 IdAutomatic=0x7000
00066 };
00067
00071 enum PropertyCommandIds
00072 {
00073
00074 CmdLock=1,
00075
00076
00077 CmdAt=51,
00078 CmdResize=52,
00079 CmdFill=53,
00080 CmdSort=54,
00081
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
00355
00356
00357 union Flags {
00358 char flag;
00359 struct {
00360
00361
00362
00363
00364
00365 unsigned char emitsignal : 1;
00366
00367 unsigned char optimize : 1;
00368 unsigned char dirty: 1;
00369 unsigned char policy : 2;
00370 unsigned char locked: 1;
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
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:
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