00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "kgamepropertyhandler.h"
00025 #include "kgameproperty.h"
00026 #include "kgamemessage.h"
00027
00028 #include <qmap.h>
00029 #include <qptrqueue.h>
00030
00031 #include <klocale.h>
00032 #include <typeinfo>
00033
00034 #define KPLAYERHANDLER_LOAD_COOKIE 6239
00035
00036
00037 class KGamePropertyHandlerPrivate
00038 {
00039 public:
00040 KGamePropertyHandlerPrivate()
00041 {
00042 }
00043
00044 QMap<int, QString> mNameMap;
00045 QIntDict<KGamePropertyBase> mIdDict;
00046 int mUniqueId;
00047 int mId;
00048 KGamePropertyBase::PropertyPolicy mDefaultPolicy;
00049 bool mDefaultUserspace;
00050 int mIndirectEmit;
00051 QPtrQueue<KGamePropertyBase> mSignalQueue;
00052 };
00053
00054 KGamePropertyHandler::KGamePropertyHandler(int id, const QObject* receiver, const char * sendf, const char *emitf, QObject* parent) : QObject(parent)
00055 {
00056 init();
00057 registerHandler(id,receiver,sendf,emitf);
00058 }
00059
00060 KGamePropertyHandler::KGamePropertyHandler(QObject* parent) : QObject(parent)
00061 {
00062 init();
00063 }
00064
00065 KGamePropertyHandler::~KGamePropertyHandler()
00066 {
00067 clear();
00068 delete d;
00069 }
00070
00071 void KGamePropertyHandler::init()
00072 {
00073 kdDebug(11001) << k_funcinfo << ": this=" << this << endl;
00074 d = new KGamePropertyHandlerPrivate;
00075 d->mId = 0;
00076 d->mUniqueId=KGamePropertyBase::IdAutomatic;
00077 d->mDefaultPolicy=KGamePropertyBase::PolicyLocal;
00078 d->mDefaultUserspace=true;
00079 d->mIndirectEmit=0;
00080 }
00081
00082
00083 int KGamePropertyHandler::id() const
00084 {
00085 return d->mId;
00086 }
00087
00088 void KGamePropertyHandler::setId(int id)
00089 {
00090 d->mId = id;
00091 }
00092
00093 void KGamePropertyHandler::registerHandler(int id,const QObject * receiver, const char * sendf, const char *emitf)
00094 {
00095 setId(id);
00096 if (receiver && sendf) {
00097 kdDebug(11001) << "Connecting SLOT " << sendf << endl;
00098 connect(this, SIGNAL(signalSendMessage(int, QDataStream &, bool*)), receiver, sendf);
00099 }
00100 if (receiver && emitf) {
00101 kdDebug(11001) << "Connecting SLOT " << emitf << endl;
00102 connect(this, SIGNAL(signalPropertyChanged(KGamePropertyBase *)), receiver, emitf);
00103 }
00104 }
00105
00106 bool KGamePropertyHandler::processMessage(QDataStream &stream, int id, bool isSender)
00107 {
00108
00109 if (id != d->mId) {
00110 return false;
00111 }
00112 KGamePropertyBase* p;
00113 int propertyId;
00114 KGameMessage::extractPropertyHeader(stream, propertyId);
00115
00116 if (propertyId==KGamePropertyBase::IdCommand) {
00117 int cmd;
00118 KGameMessage::extractPropertyCommand(stream, propertyId, cmd);
00119
00120 p = d->mIdDict.find(propertyId);
00121 if (p) {
00122 if (!isSender || p->policy()==KGamePropertyBase::PolicyClean) {
00123 p->command(stream, cmd, isSender);
00124 }
00125 } else {
00126 kdError(11001) << k_funcinfo << ": (cmd): property " << propertyId << " not found" << endl;
00127 }
00128 return true;
00129 }
00130 p = d->mIdDict.find(propertyId);
00131 if (p) {
00132
00133 if (!isSender || p->policy()==KGamePropertyBase::PolicyClean) {
00134 p->load(stream);
00135 }
00136 } else {
00137 kdError(11001) << k_funcinfo << ": property " << propertyId << " not found" << endl;
00138 }
00139 return true;
00140 }
00141
00142 bool KGamePropertyHandler::removeProperty(KGamePropertyBase* data)
00143 {
00144 if (!data) {
00145 return false;
00146 }
00147 d->mNameMap.erase(data->id());
00148 return d->mIdDict.remove(data->id());
00149 }
00150
00151 bool KGamePropertyHandler::addProperty(KGamePropertyBase* data, QString name)
00152 {
00153
00154 if (d->mIdDict.find(data->id())) {
00155
00156 kdError(11001) << " -> cannot add property " << data->id() << endl;
00157 return false;
00158 } else {
00159 d->mIdDict.insert(data->id(), data);
00160
00161
00162 if (!name.isNull()) {
00163 d->mNameMap[data->id()] = name;
00164
00165
00166
00167 }
00168 }
00169 return true;
00170 }
00171
00172 QString KGamePropertyHandler::propertyName(int id) const
00173 {
00174 QString s;
00175 if (d->mIdDict.find(id)) {
00176 if (d->mNameMap.contains(id)) {
00177 s = i18n("%1 (%2)").arg(d->mNameMap[id]).arg(id);
00178 } else {
00179 s = i18n("Unnamed - ID: %1").arg(id);
00180 }
00181 } else {
00182
00183 s = i18n("%1 unregistered").arg(id);
00184 }
00185 return s;
00186 }
00187
00188 bool KGamePropertyHandler::load(QDataStream &stream)
00189 {
00190
00191 lockDirectEmit();
00192 uint count,i;
00193 stream >> count;
00194 kdDebug(11001) << k_funcinfo << ": " << count << " KGameProperty objects " << endl;
00195 for (i = 0; i < count; i++) {
00196 processMessage(stream, id(),false);
00197 }
00198 Q_INT16 cookie;
00199 stream >> cookie;
00200 if (cookie == KPLAYERHANDLER_LOAD_COOKIE) {
00201 kdDebug(11001) << " KGamePropertyHandler loaded propertly"<<endl;
00202 } else {
00203 kdError(11001) << "KGamePropertyHandler loading error. probably format error"<<endl;
00204 }
00205
00206 unlockDirectEmit();
00207 return true;
00208 }
00209
00210 bool KGamePropertyHandler::save(QDataStream &stream)
00211 {
00212 kdDebug(11001) << k_funcinfo << ": " << d->mIdDict.count() << " KGameProperty objects " << endl;
00213 stream << (uint)d->mIdDict.count();
00214 QIntDictIterator<KGamePropertyBase> it(d->mIdDict);
00215 while (it.current()) {
00216 KGamePropertyBase *base=it.current();
00217 if (base) {
00218 KGameMessage::createPropertyHeader(stream, base->id());
00219 base->save(stream);
00220 }
00221 ++it;
00222 }
00223 stream << (Q_INT16)KPLAYERHANDLER_LOAD_COOKIE;
00224 return true;
00225 }
00226
00227 KGamePropertyBase::PropertyPolicy KGamePropertyHandler::policy()
00228 {
00229
00230 return d->mDefaultPolicy;
00231 }
00232 void KGamePropertyHandler::setPolicy(KGamePropertyBase::PropertyPolicy p,bool userspace)
00233 {
00234
00235 d->mDefaultPolicy=p;
00236 d->mDefaultUserspace=userspace;
00237 QIntDictIterator<KGamePropertyBase> it(d->mIdDict);
00238 while (it.current()) {
00239 if (!userspace || it.current()->id()>=KGamePropertyBase::IdUser) {
00240 it.current()->setPolicy((KGamePropertyBase::PropertyPolicy)p);
00241 }
00242 ++it;
00243 }
00244 }
00245
00246 void KGamePropertyHandler::unlockProperties()
00247 {
00248 QIntDictIterator<KGamePropertyBase> it(d->mIdDict);
00249 while (it.current()) {
00250 it.current()->unlock();
00251 ++it;
00252 }
00253 }
00254
00255 void KGamePropertyHandler::lockProperties()
00256 {
00257 QIntDictIterator<KGamePropertyBase> it(d->mIdDict);
00258 while (it.current()) {
00259 it.current()->lock();
00260 ++it;
00261 }
00262 }
00263
00264 int KGamePropertyHandler::uniquePropertyId()
00265 {
00266 return d->mUniqueId++;
00267 }
00268
00269 void KGamePropertyHandler::flush()
00270 {
00271 QIntDictIterator<KGamePropertyBase> it(d->mIdDict);
00272 while (it.current()) {
00273 if (it.current()->isDirty()) {
00274 it.current()->sendProperty();
00275 }
00276 ++it;
00277 }
00278 }
00279
00280
00281
00282
00283 void KGamePropertyHandler::lockDirectEmit()
00284 {
00285 d->mIndirectEmit++;
00286 }
00287
00288 void KGamePropertyHandler::unlockDirectEmit()
00289 {
00290
00291 d->mIndirectEmit--;
00292 if (d->mIndirectEmit<=0)
00293 {
00294 KGamePropertyBase *prop;
00295 while((prop=d->mSignalQueue.dequeue()) != 0)
00296 {
00297
00298 emit signalPropertyChanged(prop);
00299 }
00300 }
00301 }
00302
00303 void KGamePropertyHandler::emitSignal(KGamePropertyBase *prop)
00304 {
00305
00306
00307
00308
00309
00310 if (d->mIndirectEmit>0)
00311 {
00312
00313 d->mSignalQueue.enqueue(prop);
00314 }
00315 else
00316 {
00317
00318 emit signalPropertyChanged(prop);
00319 }
00320 }
00321
00322 bool KGamePropertyHandler::sendProperty(QDataStream &s)
00323 {
00324 bool sent = false;
00325 emit signalSendMessage(id(), s, &sent);
00326 return sent;
00327 }
00328
00329 KGamePropertyBase *KGamePropertyHandler::find(int id)
00330 {
00331 return d->mIdDict.find(id);
00332 }
00333
00334 void KGamePropertyHandler::clear()
00335 {
00336 kdDebug(11001) << k_funcinfo << id() << endl;
00337 QIntDictIterator<KGamePropertyBase> it(d->mIdDict);
00338 while (it.toFirst()) {
00339 KGamePropertyBase* p = it.toFirst();
00340 p->unregisterData();
00341 if (d->mIdDict.find(p->id())) {
00342
00343
00344 removeProperty(p);
00345 }
00346 }
00347 }
00348
00349 QIntDict<KGamePropertyBase>& KGamePropertyHandler::dict() const
00350 {
00351 return d->mIdDict;
00352 }
00353
00354 QString KGamePropertyHandler::propertyValue(KGamePropertyBase* prop)
00355 {
00356 if (!prop) {
00357 return i18n("NULL pointer");
00358 }
00359
00360 int id = prop->id();
00361 QString name = propertyName(id);
00362 QString value;
00363
00364 const type_info* t = prop->typeinfo();
00365 if (*t == typeid(int)) {
00366 value = QString::number(((KGamePropertyInt*)prop)->value());
00367 } else if (*t == typeid(unsigned int)) {
00368 value = QString::number(((KGamePropertyUInt *)prop)->value());
00369 } else if (*t == typeid(long int)) {
00370 value = QString::number(((KGameProperty<long int> *)prop)->value());
00371 } else if (*t == typeid(unsigned long int)) {
00372 value = QString::number(((KGameProperty<unsigned long int> *)prop)->value());
00373 } else if (*t == typeid(QString)) {
00374 value = ((KGamePropertyQString*)prop)->value();
00375 } else if (*t == typeid(Q_INT8)) {
00376 value = ((KGamePropertyBool*)prop)->value() ? i18n("True") : i18n("False");
00377 } else {
00378 emit signalRequestValue(prop, value);
00379 }
00380
00381 if (value.isNull()) {
00382 value = i18n("Unknown");
00383 }
00384 return value;
00385 }
00386
00387 void KGamePropertyHandler::Debug()
00388 {
00389 kdDebug(11001) << "-----------------------------------------------------------" << endl;
00390 kdDebug(11001) << "KGamePropertyHandler:: Debug this=" << this << endl;
00391
00392 kdDebug(11001) << " Registered properties: (Policy,Lock,Emit,Optimized, Dirty)" << endl;
00393 QIntDictIterator<KGamePropertyBase> it(d->mIdDict);
00394 while (it.current()) {
00395 KGamePropertyBase *p=it.current();
00396 kdDebug(11001) << " "<< p->id() << ": p=" << p->policy()
00397 << " l="<<p->isLocked()
00398 << " e="<<p->isEmittingSignal()
00399 << " o=" << p->isOptimized()
00400 << " d="<<p->isDirty()
00401 << endl;
00402 ++it;
00403 }
00404 kdDebug(11001) << "-----------------------------------------------------------" << endl;
00405 }
00406
00407 #include "kgamepropertyhandler.moc"