animation/qparallelanimationgroup.cpp

Source codeSwitch to Preprocessed file
LineSource CodeCoverage
1/**************************************************************************** -
2** -
3** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -
4** Contact: http://www.qt-project.org/legal -
5** -
6** This file is part of the QtCore module of the Qt Toolkit. -
7** -
8** $QT_BEGIN_LICENSE:LGPL$ -
9** Commercial License Usage -
10** Licensees holding valid commercial Qt licenses may use this file in -
11** accordance with the commercial license agreement provided with the -
12** Software or, alternatively, in accordance with the terms contained in -
13** a written agreement between you and Digia. For licensing terms and -
14** conditions see http://qt.digia.com/licensing. For further information -
15** use the contact form at http://qt.digia.com/contact-us. -
16** -
17** GNU Lesser General Public License Usage -
18** Alternatively, this file may be used under the terms of the GNU Lesser -
19** General Public License version 2.1 as published by the Free Software -
20** Foundation and appearing in the file LICENSE.LGPL included in the -
21** packaging of this file. Please review the following information to -
22** ensure the GNU Lesser General Public License version 2.1 requirements -
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -
24** -
25** In addition, as a special exception, Digia gives you certain additional -
26** rights. These rights are described in the Digia Qt LGPL Exception -
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -
28** -
29** GNU General Public License Usage -
30** Alternatively, this file may be used under the terms of the GNU -
31** General Public License version 3.0 as published by the Free Software -
32** Foundation and appearing in the file LICENSE.GPL included in the -
33** packaging of this file. Please review the following information to -
34** ensure the GNU General Public License version 3.0 requirements will be -
35** met: http://www.gnu.org/copyleft/gpl.html. -
36** -
37** -
38** $QT_END_LICENSE$ -
39** -
40****************************************************************************/ -
41 -
42/*! -
43 \class QParallelAnimationGroup -
44 \inmodule QtCore -
45 \brief The QParallelAnimationGroup class provides a parallel group of animations. -
46 \since 4.6 -
47 \ingroup animation -
48 -
49 QParallelAnimationGroup--a \l{QAnimationGroup}{container for -
50 animations}--starts all its animations when it is -
51 \l{QAbstractAnimation::start()}{started} itself, i.e., runs all -
52 animations in parallel. The animation group finishes when the -
53 longest lasting animation has finished. -
54 -
55 You can treat QParallelAnimation as any other QAbstractAnimation, -
56 e.g., pause, resume, or add it to other animation groups. -
57 -
58 \code -
59 QParallelAnimationGroup *group = new QParallelAnimationGroup; -
60 group->addAnimation(anim1); -
61 group->addAnimation(anim2); -
62 -
63 group->start(); -
64 \endcode -
65 -
66 In this example, \c anim1 and \c anim2 are two -
67 \l{QPropertyAnimation}s that have already been set up. -
68 -
69 \sa QAnimationGroup, QPropertyAnimation, {The Animation Framework} -
70*/ -
71 -
72 -
73#include "qparallelanimationgroup.h" -
74#include "qparallelanimationgroup_p.h" -
75//#define QANIMATION_DEBUG -
76 -
77#ifndef QT_NO_ANIMATION -
78 -
79QT_BEGIN_NAMESPACE -
80 -
81/*! -
82 Constructs a QParallelAnimationGroup. -
83 \a parent is passed to QObject's constructor. -
84*/ -
85QParallelAnimationGroup::QParallelAnimationGroup(QObject *parent) -
86 : QAnimationGroup(*new QParallelAnimationGroupPrivate, parent) -
87{ -
88}
executed: }
Execution Count:81
81
89 -
90/*! -
91 \internal -
92*/ -
93QParallelAnimationGroup::QParallelAnimationGroup(QParallelAnimationGroupPrivate &dd, -
94 QObject *parent) -
95 : QAnimationGroup(dd, parent) -
96{ -
97}
never executed: }
0
98 -
99/*! -
100 Destroys the animation group. It will also destroy all its animations. -
101*/ -
102QParallelAnimationGroup::~QParallelAnimationGroup() -
103{ -
104} -
105 -
106/*! -
107 \reimp -
108*/ -
109int QParallelAnimationGroup::duration() const -
110{ -
111 Q_D(const QParallelAnimationGroup);
executed (the execution status of this line is deduced): const QParallelAnimationGroupPrivate * const d = d_func();
-
112 int ret = 0;
executed (the execution status of this line is deduced): int ret = 0;
-
113 -
114 for (int i = 0; i < d->animations.size(); ++i) {
evaluated: i < d->animations.size()
TRUEFALSE
yes
Evaluation Count:1362
yes
Evaluation Count:505
505-1362
115 QAbstractAnimation *animation = d->animations.at(i);
executed (the execution status of this line is deduced): QAbstractAnimation *animation = d->animations.at(i);
-
116 const int currentDuration = animation->totalDuration();
executed (the execution status of this line is deduced): const int currentDuration = animation->totalDuration();
-
117 if (currentDuration == -1)
evaluated: currentDuration == -1
TRUEFALSE
yes
Evaluation Count:9
yes
Evaluation Count:1353
9-1353
118 return -1; // Undetermined length
executed: return -1;
Execution Count:9
9
119 -
120 ret = qMax(ret, currentDuration);
executed (the execution status of this line is deduced): ret = qMax(ret, currentDuration);
-
121 }
executed: }
Execution Count:1353
1353
122 -
123 return ret;
executed: return ret;
Execution Count:505
505
124} -
125 -
126/*! -
127 \reimp -
128*/ -
129void QParallelAnimationGroup::updateCurrentTime(int currentTime) -
130{ -
131 Q_D(QParallelAnimationGroup);
executed (the execution status of this line is deduced): QParallelAnimationGroupPrivate * const d = d_func();
-
132 if (d->animations.isEmpty())
partially evaluated: d->animations.isEmpty()
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:325
0-325
133 return;
never executed: return;
0
134 -
135 if (d->currentLoop > d->lastLoop) {
evaluated: d->currentLoop > d->lastLoop
TRUEFALSE
yes
Evaluation Count:45
yes
Evaluation Count:280
45-280
136 // simulate completion of the loop -
137 int dura = duration();
executed (the execution status of this line is deduced): int dura = duration();
-
138 if (dura > 0) {
partially evaluated: dura > 0
TRUEFALSE
yes
Evaluation Count:45
no
Evaluation Count:0
0-45
139 for (int i = 0; i < d->animations.size(); ++i) {
evaluated: i < d->animations.size()
TRUEFALSE
yes
Evaluation Count:136
yes
Evaluation Count:45
45-136
140 QAbstractAnimation *animation = d->animations.at(i);
executed (the execution status of this line is deduced): QAbstractAnimation *animation = d->animations.at(i);
-
141 if (animation->state() != QAbstractAnimation::Stopped)
evaluated: animation->state() != QAbstractAnimation::Stopped
TRUEFALSE
yes
Evaluation Count:52
yes
Evaluation Count:84
52-84
142 d->animations.at(i)->setCurrentTime(dura); // will stop
executed: d->animations.at(i)->setCurrentTime(dura);
Execution Count:52
52
143 }
executed: }
Execution Count:136
136
144 }
executed: }
Execution Count:45
45
145 } else if (d->currentLoop < d->lastLoop) {
executed: }
Execution Count:45
evaluated: d->currentLoop < d->lastLoop
TRUEFALSE
yes
Evaluation Count:28
yes
Evaluation Count:252
28-252
146 // simulate completion of the loop seeking backwards -
147 for (int i = 0; i < d->animations.size(); ++i) {
evaluated: i < d->animations.size()
TRUEFALSE
yes
Evaluation Count:84
yes
Evaluation Count:28
28-84
148 QAbstractAnimation *animation = d->animations.at(i);
executed (the execution status of this line is deduced): QAbstractAnimation *animation = d->animations.at(i);
-
149 //we need to make sure the animation is in the right state -
150 //and then rewind it -
151 d->applyGroupState(animation);
executed (the execution status of this line is deduced): d->applyGroupState(animation);
-
152 animation->setCurrentTime(0);
executed (the execution status of this line is deduced): animation->setCurrentTime(0);
-
153 animation->stop();
executed (the execution status of this line is deduced): animation->stop();
-
154 }
executed: }
Execution Count:84
84
155 }
executed: }
Execution Count:28
28
156 -
157#ifdef QANIMATION_DEBUG -
158 qDebug("QParallellAnimationGroup %5d: setCurrentTime(%d), loop:%d, last:%d, timeFwd:%d, lastcurrent:%d, %d", -
159 __LINE__, d->currentTime, d->currentLoop, d->lastLoop, timeFwd, d->lastCurrentTime, state()); -
160#endif -
161 // finally move into the actual time of the current loop -
162 for (int i = 0; i < d->animations.size(); ++i) {
evaluated: i < d->animations.size()
TRUEFALSE
yes
Evaluation Count:950
yes
Evaluation Count:325
325-950
163 QAbstractAnimation *animation = d->animations.at(i);
executed (the execution status of this line is deduced): QAbstractAnimation *animation = d->animations.at(i);
-
164 const int dura = animation->totalDuration();
executed (the execution status of this line is deduced): const int dura = animation->totalDuration();
-
165 //if the loopcount is bigger we should always start all animations -
166 if (d->currentLoop > d->lastLoop
evaluated: d->currentLoop > d->lastLoop
TRUEFALSE
yes
Evaluation Count:136
yes
Evaluation Count:814
136-814
167 //if we're at the end of the animation, we need to start it if it wasn't already started in this loop
executed (the execution status of this line is deduced):
-
168 //this happens in Backward direction where not all animations are started at the same time
executed (the execution status of this line is deduced):
-
169 || d->shouldAnimationStart(animation, d->lastCurrentTime > dura /*startIfAtEnd*/)) {
evaluated: d->shouldAnimationStart(animation, d->lastCurrentTime > dura )
TRUEFALSE
yes
Evaluation Count:549
yes
Evaluation Count:265
265-549
170 d->applyGroupState(animation);
executed (the execution status of this line is deduced): d->applyGroupState(animation);
-
171 }
executed: }
Execution Count:685
685
172 -
173 if (animation->state() == state()) {
evaluated: animation->state() == state()
TRUEFALSE
yes
Evaluation Count:765
yes
Evaluation Count:185
185-765
174 animation->setCurrentTime(currentTime);
executed (the execution status of this line is deduced): animation->setCurrentTime(currentTime);
-
175 if (dura > 0 && currentTime > dura)
evaluated: dura > 0
TRUEFALSE
yes
Evaluation Count:653
yes
Evaluation Count:112
evaluated: currentTime > dura
TRUEFALSE
yes
Evaluation Count:32
yes
Evaluation Count:621
32-653
176 animation->stop();
executed: animation->stop();
Execution Count:32
32
177 }
executed: }
Execution Count:765
765
178 }
executed: }
Execution Count:950
950
179 d->lastLoop = d->currentLoop;
executed (the execution status of this line is deduced): d->lastLoop = d->currentLoop;
-
180 d->lastCurrentTime = currentTime;
executed (the execution status of this line is deduced): d->lastCurrentTime = currentTime;
-
181}
executed: }
Execution Count:325
325
182 -
183/*! -
184 \reimp -
185*/ -
186void QParallelAnimationGroup::updateState(QAbstractAnimation::State newState, -
187 QAbstractAnimation::State oldState) -
188{ -
189 Q_D(QParallelAnimationGroup);
executed (the execution status of this line is deduced): QParallelAnimationGroupPrivate * const d = d_func();
-
190 QAnimationGroup::updateState(newState, oldState);
executed (the execution status of this line is deduced): QAnimationGroup::updateState(newState, oldState);
-
191 -
192 switch (newState) { -
193 case Stopped: -
194 for (int i = 0; i < d->animations.size(); ++i)
evaluated: i < d->animations.size()
TRUEFALSE
yes
Evaluation Count:41
yes
Evaluation Count:57
41-57
195 d->animations.at(i)->stop();
executed: d->animations.at(i)->stop();
Execution Count:41
41
196 d->disconnectUncontrolledAnimations();
executed (the execution status of this line is deduced): d->disconnectUncontrolledAnimations();
-
197 break;
executed: break;
Execution Count:57
57
198 case Paused: -
199 for (int i = 0; i < d->animations.size(); ++i)
evaluated: i < d->animations.size()
TRUEFALSE
yes
Evaluation Count:6
yes
Evaluation Count:4
4-6
200 if (d->animations.at(i)->state() == Running)
evaluated: d->animations.at(i)->state() == Running
TRUEFALSE
yes
Evaluation Count:5
yes
Evaluation Count:1
1-5
201 d->animations.at(i)->pause();
executed: d->animations.at(i)->pause();
Execution Count:5
5
202 break;
executed: break;
Execution Count:4
4
203 case Running: -
204 d->connectUncontrolledAnimations();
executed (the execution status of this line is deduced): d->connectUncontrolledAnimations();
-
205 for (int i = 0; i < d->animations.size(); ++i) {
evaluated: i < d->animations.size()
TRUEFALSE
yes
Evaluation Count:168
yes
Evaluation Count:62
62-168
206 QAbstractAnimation *animation = d->animations.at(i);
executed (the execution status of this line is deduced): QAbstractAnimation *animation = d->animations.at(i);
-
207 if (oldState == Stopped)
evaluated: oldState == Stopped
TRUEFALSE
yes
Evaluation Count:164
yes
Evaluation Count:4
4-164
208 animation->stop();
executed: animation->stop();
Execution Count:164
164
209 animation->setDirection(d->direction);
executed (the execution status of this line is deduced): animation->setDirection(d->direction);
-
210 if (d->shouldAnimationStart(animation, oldState == Stopped))
evaluated: d->shouldAnimationStart(animation, oldState == Stopped)
TRUEFALSE
yes
Evaluation Count:114
yes
Evaluation Count:54
54-114
211 animation->start();
executed: animation->start();
Execution Count:114
114
212 }
executed: }
Execution Count:168
168
213 break;
executed: break;
Execution Count:62
62
214 } -
215}
executed: }
Execution Count:123
123
216 -
217void QParallelAnimationGroupPrivate::_q_uncontrolledAnimationFinished() -
218{ -
219 Q_Q(QParallelAnimationGroup);
executed (the execution status of this line is deduced): QParallelAnimationGroup * const q = q_func();
-
220 -
221 QAbstractAnimation *animation = qobject_cast<QAbstractAnimation *>(q->sender());
executed (the execution status of this line is deduced): QAbstractAnimation *animation = qobject_cast<QAbstractAnimation *>(q->sender());
-
222 Q_ASSERT(animation);
executed (the execution status of this line is deduced): qt_noop();
-
223 -
224 int uncontrolledRunningCount = 0;
executed (the execution status of this line is deduced): int uncontrolledRunningCount = 0;
-
225 if (animation->duration() == -1 || animation->loopCount() < 0) {
evaluated: animation->duration() == -1
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:1
partially evaluated: animation->loopCount() < 0
TRUEFALSE
yes
Evaluation Count:1
no
Evaluation Count:0
0-1
226 QHash<QAbstractAnimation *, int>::iterator it = uncontrolledFinishTime.begin();
executed (the execution status of this line is deduced): QHash<QAbstractAnimation *, int>::iterator it = uncontrolledFinishTime.begin();
-
227 while (it != uncontrolledFinishTime.end()) {
evaluated: it != uncontrolledFinishTime.end()
TRUEFALSE
yes
Evaluation Count:4
yes
Evaluation Count:2
2-4
228 if (it.key() == animation) {
evaluated: it.key() == animation
TRUEFALSE
yes
Evaluation Count:2
yes
Evaluation Count:2
2
229 *it = animation->currentTime();
executed (the execution status of this line is deduced): *it = animation->currentTime();
-
230 }
executed: }
Execution Count:2
2
231 if (it.value() == -1)
evaluated: it.value() == -1
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:3
1-3
232 ++uncontrolledRunningCount;
executed: ++uncontrolledRunningCount;
Execution Count:1
1
233 ++it;
executed (the execution status of this line is deduced): ++it;
-
234 }
executed: }
Execution Count:4
4
235 }
executed: }
Execution Count:2
2
236 -
237 if (uncontrolledRunningCount > 0)
evaluated: uncontrolledRunningCount > 0
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:1
1
238 return;
executed: return;
Execution Count:1
1
239 -
240 int maxDuration = 0;
executed (the execution status of this line is deduced): int maxDuration = 0;
-
241 for (int i = 0; i < animations.size(); ++i)
evaluated: i < animations.size()
TRUEFALSE
yes
Evaluation Count:3
yes
Evaluation Count:1
1-3
242 maxDuration = qMax(maxDuration, animations.at(i)->totalDuration());
executed: maxDuration = qMax(maxDuration, animations.at(i)->totalDuration());
Execution Count:3
3
243 -
244 if (currentTime >= maxDuration)
partially evaluated: currentTime >= maxDuration
TRUEFALSE
yes
Evaluation Count:1
no
Evaluation Count:0
0-1
245 q->stop();
executed: q->stop();
Execution Count:1
1
246}
executed: }
Execution Count:1
1
247 -
248void QParallelAnimationGroupPrivate::disconnectUncontrolledAnimations() -
249{ -
250 QHash<QAbstractAnimation *, int>::iterator it = uncontrolledFinishTime.begin();
executed (the execution status of this line is deduced): QHash<QAbstractAnimation *, int>::iterator it = uncontrolledFinishTime.begin();
-
251 while (it != uncontrolledFinishTime.end()) {
evaluated: it != uncontrolledFinishTime.end()
TRUEFALSE
yes
Evaluation Count:3
yes
Evaluation Count:57
3-57
252 disconnectUncontrolledAnimation(it.key());
executed (the execution status of this line is deduced): disconnectUncontrolledAnimation(it.key());
-
253 ++it;
executed (the execution status of this line is deduced): ++it;
-
254 }
executed: }
Execution Count:3
3
255 -
256 uncontrolledFinishTime.clear();
executed (the execution status of this line is deduced): uncontrolledFinishTime.clear();
-
257}
executed: }
Execution Count:57
57
258 -
259void QParallelAnimationGroupPrivate::connectUncontrolledAnimations() -
260{ -
261 for (int i = 0; i < animations.size(); ++i) {
evaluated: i < animations.size()
TRUEFALSE
yes
Evaluation Count:168
yes
Evaluation Count:62
62-168
262 QAbstractAnimation *animation = animations.at(i);
executed (the execution status of this line is deduced): QAbstractAnimation *animation = animations.at(i);
-
263 if (animation->duration() == -1 || animation->loopCount() < 0) {
evaluated: animation->duration() == -1
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:167
evaluated: animation->loopCount() < 0
TRUEFALSE
yes
Evaluation Count:3
yes
Evaluation Count:164
1-167
264 uncontrolledFinishTime[animation] = -1;
executed (the execution status of this line is deduced): uncontrolledFinishTime[animation] = -1;
-
265 connectUncontrolledAnimation(animation);
executed (the execution status of this line is deduced): connectUncontrolledAnimation(animation);
-
266 }
executed: }
Execution Count:4
4
267 }
executed: }
Execution Count:168
168
268}
executed: }
Execution Count:62
62
269 -
270bool QParallelAnimationGroupPrivate::shouldAnimationStart(QAbstractAnimation *animation, bool startIfAtEnd) const -
271{ -
272 const int dura = animation->totalDuration();
executed (the execution status of this line is deduced): const int dura = animation->totalDuration();
-
273 if (dura == -1)
evaluated: dura == -1
TRUEFALSE
yes
Evaluation Count:20
yes
Evaluation Count:962
20-962
274 return !isUncontrolledAnimationFinished(animation);
executed: return !isUncontrolledAnimationFinished(animation);
Execution Count:20
20
275 if (startIfAtEnd)
evaluated: startIfAtEnd
TRUEFALSE
yes
Evaluation Count:335
yes
Evaluation Count:627
335-627
276 return currentTime <= dura;
executed: return currentTime <= dura;
Execution Count:335
335
277 if (direction == QAbstractAnimation::Forward)
evaluated: direction == QAbstractAnimation::Forward
TRUEFALSE
yes
Evaluation Count:564
yes
Evaluation Count:63
63-564
278 return currentTime < dura;
executed: return currentTime < dura;
Execution Count:564
564
279 else //direction == QAbstractAnimation::Backward -
280 return currentTime && currentTime <= dura;
executed: return currentTime && currentTime <= dura;
Execution Count:63
63
281} -
282 -
283void QParallelAnimationGroupPrivate::applyGroupState(QAbstractAnimation *animation) -
284{ -
285 switch (state) -
286 { -
287 case QAbstractAnimation::Running: -
288 animation->start();
executed (the execution status of this line is deduced): animation->start();
-
289 break;
executed: break;
Execution Count:632
632
290 case QAbstractAnimation::Paused: -
291 animation->pause();
never executed (the execution status of this line is deduced): animation->pause();
-
292 break;
never executed: break;
0
293 case QAbstractAnimation::Stopped: -
294 default: -
295 break;
executed: break;
Execution Count:137
137
296 } -
297}
executed: }
Execution Count:769
769
298 -
299 -
300bool QParallelAnimationGroupPrivate::isUncontrolledAnimationFinished(QAbstractAnimation *anim) const -
301{ -
302 return uncontrolledFinishTime.value(anim, -1) >= 0;
executed: return uncontrolledFinishTime.value(anim, -1) >= 0;
Execution Count:20
20
303} -
304 -
305void QParallelAnimationGroupPrivate::animationRemoved(int index, QAbstractAnimation *anim) -
306{ -
307 QAnimationGroupPrivate::animationRemoved(index, anim);
executed (the execution status of this line is deduced): QAnimationGroupPrivate::animationRemoved(index, anim);
-
308 disconnectUncontrolledAnimation(anim);
executed (the execution status of this line is deduced): disconnectUncontrolledAnimation(anim);
-
309 uncontrolledFinishTime.remove(anim);
executed (the execution status of this line is deduced): uncontrolledFinishTime.remove(anim);
-
310}
executed: }
Execution Count:164
164
311 -
312/*! -
313 \reimp -
314*/ -
315void QParallelAnimationGroup::updateDirection(QAbstractAnimation::Direction direction) -
316{ -
317 Q_D(QParallelAnimationGroup);
executed (the execution status of this line is deduced): QParallelAnimationGroupPrivate * const d = d_func();
-
318 //we need to update the direction of the current animation -
319 if (state() != Stopped) {
partially evaluated: state() != Stopped
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:19
0-19
320 for (int i = 0; i < d->animations.size(); ++i) {
never evaluated: i < d->animations.size()
0
321 QAbstractAnimation *animation = d->animations.at(i);
never executed (the execution status of this line is deduced): QAbstractAnimation *animation = d->animations.at(i);
-
322 animation->setDirection(direction);
never executed (the execution status of this line is deduced): animation->setDirection(direction);
-
323 }
never executed: }
0
324 } else {
never executed: }
0
325 if (direction == Forward) {
partially evaluated: direction == Forward
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:19
0-19
326 d->lastLoop = 0;
never executed (the execution status of this line is deduced): d->lastLoop = 0;
-
327 d->lastCurrentTime = 0;
never executed (the execution status of this line is deduced): d->lastCurrentTime = 0;
-
328 } else {
never executed: }
0
329 // Looping backwards with loopCount == -1 does not really work well... -
330 d->lastLoop = (d->loopCount == -1 ? 0 : d->loopCount - 1);
evaluated: d->loopCount == -1
TRUEFALSE
yes
Evaluation Count:3
yes
Evaluation Count:16
3-16
331 d->lastCurrentTime = duration();
executed (the execution status of this line is deduced): d->lastCurrentTime = duration();
-
332 }
executed: }
Execution Count:19
19
333 } -
334} -
335 -
336/*! -
337 \reimp -
338*/ -
339bool QParallelAnimationGroup::event(QEvent *event) -
340{ -
341 return QAnimationGroup::event(event);
executed: return QAnimationGroup::event(event);
Execution Count:520
520
342} -
343 -
344QT_END_NAMESPACE -
345 -
346#include "moc_qparallelanimationgroup.cpp" -
347 -
348#endif //QT_NO_ANIMATION -
349 -
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial