Per-frame Sprites patch one
[profile/ivi/qtdeclarative.git] / src / quick / items / qquickspriteengine_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
6 **
7 ** This file is part of the Declarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QQUICKSPRITEENGINE_P_H
43 #define QQUICKSPRITEENGINE_P_H
44
45 #include <QObject>
46 #include <QVector>
47 #include <QTimer>
48 #include <QTime>
49 #include <QList>
50 #include <QDeclarativeListProperty>
51 #include <QImage>
52 #include <QPair>
53
54 QT_BEGIN_HEADER
55
56 QT_BEGIN_NAMESPACE
57
58 class QQuickSprite;
59 class Q_AUTOTEST_EXPORT QQuickStochasticState : public QObject //For internal use
60 {
61     Q_OBJECT
62     Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged)
63     Q_PROPERTY(int durationVariation READ durationVariance WRITE setDurationVariance NOTIFY durationVarianceChanged)
64     Q_PROPERTY(QVariantMap to READ to WRITE setTo NOTIFY toChanged)
65     Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
66     Q_PROPERTY(qreal speedModifiesDuration READ speedModifer WRITE setSpeedModifier NOTIFY speedModifierChanged)
67     Q_PROPERTY(int frames READ frames WRITE setFrames NOTIFY framesChanged)
68
69 public:
70     QQuickStochasticState(QObject* parent = 0)
71         : QObject(parent)
72         , m_frames(1)
73         , m_duration(1000)
74     {
75     }
76
77     int duration() const
78     {
79         return m_duration;
80     }
81
82     QString name() const
83     {
84         return m_name;
85     }
86
87     QVariantMap to() const
88     {
89         return m_to;
90     }
91
92     qreal speedModifer() const
93     {
94         return m_speedModifier;
95     }
96
97     int durationVariance() const
98     {
99         return m_durationVariance;
100     }
101
102
103     int variedDuration() const
104     {
105         return qMax(qreal(0.0) , m_duration
106                 + (m_durationVariance * ((qreal)qrand()/RAND_MAX) * 2)
107                 - m_durationVariance);
108     }
109
110     int frames() const
111     {
112         return m_frames;
113     }
114
115 signals:
116     void durationChanged(int arg);
117
118     void nameChanged(QString arg);
119
120     void toChanged(QVariantMap arg);
121
122     void speedModifierChanged(qreal arg);
123
124     void durationVarianceChanged(int arg);
125
126     void entered();//### Just playing around - don't expect full state API
127     void framesChanged(int arg);
128
129 public slots:
130     void setDuration(int arg)
131     {
132         if (m_duration != arg) {
133             m_duration = arg;
134             emit durationChanged(arg);
135         }
136     }
137
138     void setName(QString arg)
139     {
140         if (m_name != arg) {
141             m_name = arg;
142             emit nameChanged(arg);
143         }
144     }
145
146     void setTo(QVariantMap arg)
147     {
148         if (m_to != arg) {
149             m_to = arg;
150             emit toChanged(arg);
151         }
152     }
153
154     void setSpeedModifier(qreal arg)
155     {
156         if (m_speedModifier != arg) {
157             m_speedModifier = arg;
158             emit speedModifierChanged(arg);
159         }
160     }
161
162     void setDurationVariance(int arg)
163     {
164         if (m_durationVariance != arg) {
165             m_durationVariance = arg;
166             emit durationVarianceChanged(arg);
167         }
168     }
169
170     void setFrames(int arg)
171     {
172         if (m_frames != arg) {
173             m_frames = arg;
174             emit framesChanged(arg);
175         }
176     }
177
178 private:
179     QString m_name;
180     int m_frames;
181     QVariantMap m_to;
182     int m_duration;
183     qreal m_speedModifier;
184     int m_durationVariance;
185
186     friend class QQuickStochasticEngine;
187 };
188
189 class Q_AUTOTEST_EXPORT QQuickStochasticEngine : public QObject
190 {
191     Q_OBJECT
192     //TODO: Optimize single state case?
193     Q_PROPERTY(QString globalGoal READ globalGoal WRITE setGlobalGoal NOTIFY globalGoalChanged)
194     Q_PROPERTY(QDeclarativeListProperty<QQuickStochasticState> states READ states)
195 public:
196     explicit QQuickStochasticEngine(QObject *parent = 0);
197     QQuickStochasticEngine(QList<QQuickStochasticState*> states, QObject *parent=0);
198     ~QQuickStochasticEngine();
199
200     QDeclarativeListProperty<QQuickStochasticState> states()
201     {
202         return QDeclarativeListProperty<QQuickStochasticState>(this, m_states);
203     }
204
205     QString globalGoal() const
206     {
207         return m_globalGoal;
208     }
209
210     int count() const {return m_things.count();}
211     void setCount(int c);
212
213     void setGoal(int state, int sprite=0, bool jump=false);
214     void start(int index=0, int state=0);
215     void advance(int index=0);//Sends state to the next chosen state, unlike goal.
216     void stop(int index=0);
217     int curState(int index=0) {return m_things[index];}
218
219     QQuickStochasticState* state(int idx){return m_states[idx];}
220     int stateIndex(QQuickStochasticState* s){return m_states.indexOf(s);}
221     int stateIndex(const QString& s) {
222         for (int i=0; i<m_states.count(); i++)
223             if (m_states[i]->name() == s)
224                 return i;
225         return -1;
226     }
227
228     int stateCount() {return m_states.count();}
229 private:
230 signals:
231
232     void globalGoalChanged(QString arg);
233     void stateChanged(int idx);
234
235 public slots:
236     void setGlobalGoal(QString arg)
237     {
238         if (m_globalGoal != arg) {
239             m_globalGoal = arg;
240             emit globalGoalChanged(arg);
241         }
242     }
243
244     uint updateSprites(uint time);
245
246 protected:
247     friend class QQuickParticleSystem;
248     void restart(int index);
249     void addToUpdateList(uint t, int idx);
250     int nextState(int curState, int idx=0);
251     int goalSeek(int curState, int idx, int dist=-1);
252     QList<QQuickStochasticState*> m_states;
253     //### Consider struct or class for the four data variables?
254     QVector<int> m_things;//int is the index in m_states of the current state
255     QVector<int> m_goals;
256     QVector<int> m_duration;
257     QVector<int> m_startTimes;
258     QList<QPair<uint, QList<int> > > m_stateUpdates;//### This could be done faster - priority queue?
259
260     QTime m_advanceTime;
261     uint m_timeOffset;
262     QString m_globalGoal;
263     int m_maxFrames;
264     int m_imageStateCount;
265 };
266
267 class QQuickSpriteEngine : public QQuickStochasticEngine
268 {
269     Q_OBJECT
270     Q_PROPERTY(QDeclarativeListProperty<QQuickSprite> sprites READ sprites)
271 public:
272     explicit QQuickSpriteEngine(QObject *parent = 0);
273     QQuickSpriteEngine(QList<QQuickSprite*> sprites, QObject *parent=0);
274     ~QQuickSpriteEngine();
275     QDeclarativeListProperty<QQuickSprite> sprites()
276     {
277         return QDeclarativeListProperty<QQuickSprite>(this, m_sprites);
278     }
279
280
281     int spriteState(int sprite=0);
282     int spriteStart(int sprite=0);
283     int spriteFrames(int sprite=0);
284     int spriteDuration(int sprite=0);
285     int spriteX(int /* sprite */ = 0) { return 0; }//Currently all rows are 0 aligned, if we get more space efficient we might change this
286     int spriteY(int sprite=0);
287     int spriteWidth(int sprite=0);
288     int spriteHeight(int sprite=0);
289     int spriteCount();//Like state count, but for the image states
290     int maxFrames();
291     QImage assembledImage();
292 private:
293     QList<QQuickSprite*> m_sprites;
294 };
295
296 //Common use is to have your own list property which is transparently an engine
297 inline void spriteAppend(QDeclarativeListProperty<QQuickSprite> *p, QQuickSprite* s)
298 {
299     reinterpret_cast<QList<QQuickSprite *> *>(p->data)->append(s);
300     p->object->metaObject()->invokeMethod(p->object, "createEngine");
301 }
302
303 inline QQuickSprite* spriteAt(QDeclarativeListProperty<QQuickSprite> *p, int idx)
304 {
305     return reinterpret_cast<QList<QQuickSprite *> *>(p->data)->at(idx);
306 }
307
308 inline void spriteClear(QDeclarativeListProperty<QQuickSprite> *p)
309 {
310     reinterpret_cast<QList<QQuickSprite *> *>(p->data)->clear();
311     p->object->metaObject()->invokeMethod(p->object, "createEngine");
312 }
313
314 inline int spriteCount(QDeclarativeListProperty<QQuickSprite> *p)
315 {
316     return reinterpret_cast<QList<QQuickSprite *> *>(p->data)->count();
317 }
318
319 QT_END_NAMESPACE
320
321 QT_END_HEADER
322
323 #endif // QQUICKSPRITEENGINE_P_H