File indexing completed on 2024-07-14 04:00:03

0001 /*
0002     This file is part of the KDE games library
0003     SPDX-FileCopyrightText: 2001 Martin Heni (kde at heni-online.de)
0004     SPDX-FileCopyrightText: 2001 Andreas Beckermann (b_mann@gmx.de)
0005 
0006     SPDX-License-Identifier: LGPL-2.0-only
0007 */
0008 
0009 #ifndef __KGAMEPROPERTYARRAY_H_
0010 #define __KGAMEPROPERTYARRAY_H_
0011 
0012 // own
0013 #include "kfourinline_debug.h"
0014 // KDEGames
0015 #define USE_UNSTABLE_LIBKDEGAMESPRIVATE_API
0016 #include <libkdegamesprivate/kgame/kgamemessage.h>
0017 #include <libkdegamesprivate/kgame/kgameproperty.h>
0018 #include <libkdegamesprivate/kgame/kgamepropertyhandler.h>
0019 // Qt
0020 #include <QDataStream>
0021 #include <QList>
0022 
0023 /**
0024  * \class KGamePropertyArray kgamepropertyarray.h <KGamePropertyArray>
0025  */
0026 template<class type>
0027 class KGamePropertyArray : public QList<type>, public KGamePropertyBase
0028 {
0029 public:
0030     KGamePropertyArray()
0031         : QList<type>()
0032         , KGamePropertyBase()
0033     {
0034         // qCDebug(KFOURINLINE_LOG) << "KGamePropertyArray init";
0035     }
0036 
0037     KGamePropertyArray(int size)
0038     {
0039         resize(size);
0040     }
0041 
0042     KGamePropertyArray(const KGamePropertyArray<type> &a)
0043         : QList<type>(a)
0044     {
0045     }
0046 
0047     bool resize(int size)
0048     {
0049         if (size != QList<type>::size()) {
0050             bool a = true;
0051             QByteArray b;
0052             QDataStream s(&b, QIODevice::WriteOnly);
0053             KGameMessage::createPropertyCommand(s, KGamePropertyBase::IdCommand, id(), CmdResize);
0054             s << size;
0055             if (policy() == PolicyClean || policy() == PolicyDirty) {
0056                 if (mOwner) {
0057                     mOwner->sendProperty(s);
0058                 }
0059             }
0060             if (policy() == PolicyLocal || policy() == PolicyDirty) {
0061                 extractProperty(b);
0062                 //        a=QMemArray<type>::resize(size);// FIXME: return value!
0063             }
0064             return a;
0065         } else
0066             return true;
0067     }
0068 
0069     void setAt(int i, type data)
0070     {
0071         QByteArray b;
0072         QDataStream s(&b, QIODevice::WriteOnly);
0073         KGameMessage::createPropertyCommand(s, KGamePropertyBase::IdCommand, id(), CmdAt);
0074         s << i;
0075         s << data;
0076         if (policy() == PolicyClean || policy() == PolicyDirty) {
0077             if (mOwner) {
0078                 mOwner->sendProperty(s);
0079             }
0080         }
0081         if (policy() == PolicyLocal || policy() == PolicyDirty) {
0082             extractProperty(b);
0083         }
0084         // qCDebug(KFOURINLINE_LOG) << "KGamePropertyArray setAt send COMMAND for id="<<id() << "type=" << 1 << "at(" << i<<")="<<data;
0085     }
0086 
0087     const type &at(int i) const
0088     {
0089         return QList<type>::at(i);
0090     }
0091 
0092     const type &operator[](int i) const
0093     {
0094         return QList<type>::operator[](i);
0095     }
0096 
0097     type &operator[](int i)
0098     {
0099         return QList<type>::operator[](i);
0100     }
0101 
0102     KGamePropertyArray<type> &operator=(const KGamePropertyArray<type> &a)
0103     {
0104         return assign(a);
0105     }
0106 
0107     bool truncate(int pos)
0108     {
0109         return resize(pos);
0110     }
0111 
0112     bool fill(const type &data, int size = -1)
0113     {
0114         bool r = true;
0115         QByteArray b;
0116         QDataStream s(&b, QIODevice::WriteOnly);
0117         KGameMessage::createPropertyCommand(s, KGamePropertyBase::IdCommand, id(), CmdFill);
0118         s << data;
0119         s << size;
0120         if (policy() == PolicyClean || policy() == PolicyDirty) {
0121             if (mOwner) {
0122                 mOwner->sendProperty(s);
0123             }
0124         }
0125         if (policy() == PolicyLocal || policy() == PolicyDirty) {
0126             extractProperty(b);
0127             //      r=QMemArray<type>::fill(data,size);//FIXME: return value!
0128         }
0129         return r;
0130     }
0131 
0132     KGamePropertyArray<type> &assign(const KGamePropertyArray<type> &a)
0133     {
0134         // note: send() has been replaced by sendProperty so it might be broken now!
0135         if (policy() == PolicyClean || policy() == PolicyDirty) {
0136             sendProperty();
0137         }
0138         if (policy() == PolicyLocal || policy() == PolicyDirty) {
0139             QList<type>::assign(a);
0140         }
0141         return *this;
0142     }
0143     KGamePropertyArray<type> &assign(const type *a, int n)
0144     {
0145         if (policy() == PolicyClean || policy() == PolicyDirty) {
0146             sendProperty();
0147         }
0148         if (policy() == PolicyLocal || policy() == PolicyDirty) {
0149             QList<type>::assign(a, n);
0150         }
0151         return *this;
0152     }
0153     KGamePropertyArray<type> &duplicate(const KGamePropertyArray<type> &a)
0154     {
0155         if (policy() == PolicyClean || policy() == PolicyDirty) {
0156             sendProperty();
0157         }
0158         if (policy() == PolicyLocal || policy() == PolicyDirty) {
0159             QList<type>::duplicate(a);
0160         }
0161         return *this;
0162     }
0163     KGamePropertyArray<type> &duplicate(const type *a, int n)
0164     {
0165         if (policy() == PolicyClean || policy() == PolicyDirty) {
0166             sendProperty();
0167         }
0168         if (policy() == PolicyLocal || policy() == PolicyDirty) {
0169             QList<type>::duplicate(a, n);
0170         }
0171         return *this;
0172     }
0173     KGamePropertyArray<type> &setRawData(const type *a, int n)
0174     {
0175         if (policy() == PolicyClean || policy() == PolicyDirty) {
0176             sendProperty();
0177         }
0178         if (policy() == PolicyLocal || policy() == PolicyDirty) {
0179             QList<type>::setRawData(a, n);
0180         }
0181         return *this;
0182     }
0183 
0184     void load(QDataStream &s) override
0185     {
0186         // qCDebug(KFOURINLINE_LOG) << "KGamePropertyArray load" << id();
0187         type data;
0188         for (int i = 0; i < QList<type>::size(); i++) {
0189             s >> data;
0190             QList<type>::replace(i, data);
0191         }
0192         if (isEmittingSignal()) {
0193             emitSignal();
0194         }
0195     }
0196     void save(QDataStream &s) override
0197     {
0198         // qCDebug(KFOURINLINE_LOG) << "KGamePropertyArray save "<<id();
0199         for (int i = 0; i < QList<type>::size(); i++) {
0200             s << at(i);
0201         }
0202     }
0203 
0204     void command(QDataStream &stream, int msgid, bool isSender) override
0205     {
0206         Q_UNUSED(isSender);
0207         KGamePropertyBase::command(stream, msgid);
0208         // qCDebug(KFOURINLINE_LOG) << "Array id="<<id()<<" got command ("<<msgid<<") !!!";
0209         switch (msgid) {
0210         case CmdAt: {
0211             uint i;
0212             type data;
0213             stream >> i >> data;
0214             QList<type>::replace(i, data);
0215             // qCDebug(KFOURINLINE_LOG) << "CmdAt:id="<<id()<<" i="<<i<<" data="<<data;
0216             if (isEmittingSignal()) {
0217                 emitSignal();
0218             }
0219             break;
0220         }
0221         case CmdResize: {
0222             uint size;
0223             stream >> size;
0224             // qCDebug(KFOURINLINE_LOG) << "CmdResize:id="<<id()<<" oldsize="<<QMemArray<type>::size()<<" newsize="<<size;
0225             if ((uint)QList<type>::size() != size) {
0226                 QList<type>::resize(size);
0227             }
0228             break;
0229         }
0230         case CmdFill: {
0231             int size;
0232             type data;
0233             stream >> data >> size;
0234             // qCDebug(KFOURINLINE_LOG) << "CmdFill:id="<<id()<<"size="<<size;
0235             QList<type>::fill(data, size);
0236             if (isEmittingSignal()) {
0237                 emitSignal();
0238             }
0239             break;
0240         }
0241         case CmdSort: {
0242             // qCDebug(KFOURINLINE_LOG) << "CmdSort:id="<<id();
0243             std::sort(this->begin(), this->end());
0244             break;
0245         }
0246         default:
0247             qCCritical(KFOURINLINE_LOG) << "Error in KPropertyArray::command: Unknown command" << msgid;
0248             break;
0249         }
0250     }
0251 
0252 protected:
0253     void extractProperty(const QByteArray &b)
0254     {
0255         QByteArray _b(b);
0256         QDataStream s(&_b, QIODevice::ReadOnly);
0257         int cmd;
0258         int propId;
0259         KGameMessage::extractPropertyHeader(s, propId);
0260         KGameMessage::extractPropertyCommand(s, propId, cmd);
0261         command(s, cmd, true);
0262     }
0263 };
0264 
0265 #endif