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"