1 /*
2     This file is part of the KDE games library
3     SPDX-FileCopyrightText: 2001 Martin Heni (kde at heni-online.de)
4     SPDX-FileCopyrightText: 2001 Andreas Beckermann (b_mann@gmx.de)
5 
6     SPDX-License-Identifier: LGPL-2.0-only
7 */
8 
9 #ifndef __KGAMEPROPERTYARRAY_H_
10 #define __KGAMEPROPERTYARRAY_H_
11 
12 // own
13 #include "kfourinline_debug.h"
14 // KDEGames
15 #define USE_UNSTABLE_LIBKDEGAMESPRIVATE_API
16 #include <libkdegamesprivate/kgame/kgamemessage.h>
17 #include <libkdegamesprivate/kgame/kgameproperty.h>
18 #include <libkdegamesprivate/kgame/kgamepropertyhandler.h>
19 // Qt
20 #include <QDataStream>
21 #include <QVector>
22 
23 /**
24  * \class KGamePropertyArray kgamepropertyarray.h <KGamePropertyArray>
25  */
26 template<class type>
27 class KGamePropertyArray : public QVector<type>, public KGamePropertyBase
28 {
29 public:
KGamePropertyArray()30   KGamePropertyArray() :QVector<type>(), KGamePropertyBase()
31   {
32     //qCDebug(KFOURINLINE_LOG) << "KGamePropertyArray init";
33   }
34 
KGamePropertyArray(int size)35   KGamePropertyArray( int size )
36   {
37     resize(size);
38   }
39 
KGamePropertyArray(const KGamePropertyArray<type> & a)40   KGamePropertyArray( const KGamePropertyArray<type> &a ) : QVector<type>(a)
41   {
42   }
43 
resize(int size)44   bool  resize( int size )
45   {
46     if (size!= QVector<type>::size())
47     {
48       bool a=true;
49       QByteArray b;
50       QDataStream s(&b, QIODevice::WriteOnly);
51       KGameMessage::createPropertyCommand(s,KGamePropertyBase::IdCommand,id(),CmdResize);
52       s << size ;
53       if (policy()==PolicyClean || policy()==PolicyDirty)
54       {
55         if (mOwner)
56         {
57           mOwner->sendProperty(s);
58         }
59       }
60       if (policy()==PolicyLocal || policy()==PolicyDirty)
61       {
62         extractProperty(b);
63 //        a=QMemArray<type>::resize(size);// FIXME: return value!
64       }
65       return a;
66     }
67     else return true;
68   }
69 
setAt(int i,type data)70   void setAt(int i,type data)
71   {
72     QByteArray b;
73     QDataStream s(&b, QIODevice::WriteOnly);
74     KGameMessage::createPropertyCommand(s,KGamePropertyBase::IdCommand,id(),CmdAt);
75     s << i ;
76     s << data;
77     if (policy()==PolicyClean || policy()==PolicyDirty)
78     {
79       if (mOwner)
80       {
81         mOwner->sendProperty(s);
82       }
83     }
84     if (policy()==PolicyLocal || policy()==PolicyDirty)
85     {
86       extractProperty(b);
87     }
88     //qCDebug(KFOURINLINE_LOG) << "KGamePropertyArray setAt send COMMAND for id="<<id() << "type=" << 1 << "at(" << i<<")="<<data;
89   }
90 
at(int i)91   const type& at( int i ) const
92   {
93     return QVector<type>::at(i);
94   }
95 
96   const type& operator[]( int i ) const
97   {
98     return QVector<type>::operator[](i);
99   }
100 
101   type& operator[]( int i )
102   {
103     return QVector<type>::operator[](i);
104   }
105 
106   KGamePropertyArray<type> &operator=(const KGamePropertyArray<type> &a)
107   {
108     return assign(a);
109   }
110 
truncate(int pos)111   bool  truncate( int pos )
112   {
113     return resize(pos);
114   }
115 
116   bool  fill( const type &data, int size = -1 )
117   {
118     bool r=true;
119     QByteArray b;
120     QDataStream s(&b, QIODevice::WriteOnly);
121     KGameMessage::createPropertyCommand(s,KGamePropertyBase::IdCommand,id(),CmdFill);
122     s << data;
123     s << size ;
124     if (policy()==PolicyClean || policy()==PolicyDirty)
125     {
126       if (mOwner)
127       {
128         mOwner->sendProperty(s);
129       }
130     }
131     if (policy()==PolicyLocal || policy()==PolicyDirty)
132     {
133       extractProperty(b);
134 //      r=QMemArray<type>::fill(data,size);//FIXME: return value!
135     }
136     return r;
137   }
138 
assign(const KGamePropertyArray<type> & a)139   KGamePropertyArray<type>& assign( const KGamePropertyArray<type>& a )
140   {
141 // note: send() has been replaced by sendProperty so it might be broken now!
142     if (policy()==PolicyClean || policy()==PolicyDirty)
143     {
144       sendProperty();
145     }
146     if (policy()==PolicyLocal || policy()==PolicyDirty)
147     {
148       QVector<type>::assign(a);
149     }
150     return *this;
151   }
assign(const type * a,int n)152   KGamePropertyArray<type>& assign( const type *a, int n )
153   {
154     if (policy()==PolicyClean || policy()==PolicyDirty)
155     {
156       sendProperty();
157     }
158     if (policy()==PolicyLocal || policy()==PolicyDirty)
159     {
160       QVector<type>::assign(a,n);
161     }
162     return *this;
163   }
duplicate(const KGamePropertyArray<type> & a)164   KGamePropertyArray<type>& duplicate( const KGamePropertyArray<type>& a )
165   {
166     if (policy()==PolicyClean || policy()==PolicyDirty)
167     {
168       sendProperty();
169     }
170     if (policy()==PolicyLocal || policy()==PolicyDirty)
171     {
172       QVector<type>::duplicate(a);
173     }
174     return *this;
175   }
duplicate(const type * a,int n)176   KGamePropertyArray<type>& duplicate( const type *a, int n )
177   {
178     if (policy()==PolicyClean || policy()==PolicyDirty)
179     {
180       sendProperty();
181     }
182     if (policy()==PolicyLocal || policy()==PolicyDirty)
183     {
184       QVector<type>::duplicate(a,n);
185     }
186     return *this;
187   }
setRawData(const type * a,int n)188   KGamePropertyArray<type>& setRawData( const type *a, int n )
189   {
190     if (policy()==PolicyClean || policy()==PolicyDirty)
191     {
192       sendProperty();
193     }
194     if (policy()==PolicyLocal || policy()==PolicyDirty)
195     {
196       QVector<type>::setRawData(a,n);
197     }
198     return *this;
199   }
200 
load(QDataStream & s)201   void load(QDataStream& s) override
202   {
203     //qCDebug(KFOURINLINE_LOG) << "KGamePropertyArray load" << id();
204     type data;
205     for (int i=0; i<QVector<type>::size(); i++)
206     {
207       s >> data;
208       QVector<type>::replace(i,data);
209     }
210     if (isEmittingSignal())
211     {
212       emitSignal();
213     }
214   }
save(QDataStream & s)215   void save(QDataStream &s) override
216   {
217     //qCDebug(KFOURINLINE_LOG) << "KGamePropertyArray save "<<id();
218     for (int i=0; i<QVector<type>::size(); i++)
219     {
220       s << at(i);
221     }
222   }
223 
command(QDataStream & stream,int msgid,bool isSender)224   void command(QDataStream &stream,int msgid, bool isSender) override
225   {
226     Q_UNUSED(isSender);
227     KGamePropertyBase::command(stream, msgid);
228     //qCDebug(KFOURINLINE_LOG) << "Array id="<<id()<<" got command ("<<msgid<<") !!!";
229     switch(msgid)
230     {
231       case CmdAt:
232       {
233         uint i;
234         type data;
235         stream >> i >> data;
236         QVector<type>::replace( i, data );
237         //qCDebug(KFOURINLINE_LOG) << "CmdAt:id="<<id()<<" i="<<i<<" data="<<data;
238         if (isEmittingSignal())
239         {
240           emitSignal();
241         }
242         break;
243       }
244       case CmdResize:
245       {
246         uint size;
247         stream >> size;
248         //qCDebug(KFOURINLINE_LOG) << "CmdResize:id="<<id()<<" oldsize="<<QMemArray<type>::size()<<" newsize="<<size;
249         if (( uint )QVector<type>::size() != size)
250         {
251           QVector<type>::resize(size);
252         }
253         break;
254       }
255       case CmdFill:
256       {
257         int size;
258         type data;
259         stream >> data >> size;
260         //qCDebug(KFOURINLINE_LOG) << "CmdFill:id="<<id()<<"size="<<size;
261         QVector<type>::fill(data,size);
262         if (isEmittingSignal())
263         {
264           emitSignal();
265         }
266         break;
267       }
268       case CmdSort:
269       {
270         //qCDebug(KFOURINLINE_LOG) << "CmdSort:id="<<id();
271         std::sort( this->begin(), this->end() );
272         break;
273       }
274       default:
275         qCCritical(KFOURINLINE_LOG) << "Error in KPropertyArray::command: Unknown command" << msgid;
276         break;
277     }
278   }
279 protected:
extractProperty(const QByteArray & b)280   void extractProperty(const QByteArray& b)
281   {
282 	QByteArray _b(b);
283     QDataStream s(&_b, QIODevice::ReadOnly);
284     int cmd;
285     int propId;
286     KGameMessage::extractPropertyHeader(s, propId);
287     KGameMessage::extractPropertyCommand(s, propId, cmd);
288     command(s, cmd, true);
289   }
290 
291 };
292 
293 #endif
294