• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright 2006 The Android Open Source Project
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 
10 #include "SkAnimateMaker.h"
11 #include "SkAnimator.h"
12 #include "SkAnimatorScript.h"
13 #include "SkDisplayable.h"
14 #include "SkDisplayApply.h"
15 #include "SkDisplayList.h"
16 #include "SkDisplayMovie.h"
17 #include "SkDisplayType.h"
18 #include "SkExtras.h"
19 #include "SkMemberInfo.h"
20 #include "SkStream.h"
21 #include "SkSystemEventTypes.h"
22 #include "SkTime.h"
23 
24 class DefaultTimeline : public SkAnimator::Timeline {
getMSecs() const25     virtual SkMSec getMSecs() const {
26         return SkTime::GetMSecs();
27     }
28 } gDefaultTimeline;
29 
SkAnimateMaker(SkAnimator * animator,SkCanvas * canvas,SkPaint * paint)30 SkAnimateMaker::SkAnimateMaker(SkAnimator* animator, SkCanvas* canvas, SkPaint* paint)
31     : fActiveEvent(NULL), fAdjustedStart(0), fCanvas(canvas), fEnableTime(0),
32         fHostEventSinkID(0), fMinimumInterval((SkMSec) -1), fPaint(paint), fParentMaker(NULL),
33         fTimeline(&gDefaultTimeline), fInInclude(false), fInMovie(false),
34         fFirstScriptError(false), fLoaded(false), fIDs(256), fAnimator(animator)
35 {
36     fScreenplay.time = 0;
37 #if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
38     fDebugTimeBase = (SkMSec) -1;
39 #endif
40 #ifdef SK_DUMP_ENABLED
41     fDumpEvents = fDumpGConditions = fDumpPosts = false;
42 #endif
43 }
44 
~SkAnimateMaker()45 SkAnimateMaker::~SkAnimateMaker() {
46     deleteMembers();
47 }
48 
49 #if 0
50 SkMSec SkAnimateMaker::adjustDelay(SkMSec expectedBase, SkMSec delay) {
51     SkMSec appTime = (*fTimeCallBack)();
52     if (appTime)
53         delay -= appTime - expectedBase;
54     if (delay < 0)
55         delay = 0;
56     return delay;
57 }
58 #endif
59 
appendActive(SkActive * active)60 void SkAnimateMaker::appendActive(SkActive* active) {
61     fDisplayList.append(active);
62 }
63 
clearExtraPropertyCallBack(SkDisplayTypes type)64 void SkAnimateMaker::clearExtraPropertyCallBack(SkDisplayTypes type) {
65     SkExtras** end = fExtras.end();
66     for (SkExtras** extraPtr = fExtras.begin(); extraPtr < end; extraPtr++) {
67         SkExtras* extra = *extraPtr;
68         if (extra->definesType(type)) {
69             extra->fExtraCallBack = NULL;
70             extra->fExtraStorage = NULL;
71             break;
72         }
73     }
74 }
75 
computeID(SkDisplayable * displayable,SkDisplayable * parent,SkString * newID)76 bool SkAnimateMaker::computeID(SkDisplayable* displayable, SkDisplayable* parent, SkString* newID) {
77     const char* script;
78   if (findKey(displayable, &script) == false)
79         return true;
80     return SkAnimatorScript::EvaluateString(*this, displayable, parent, script, newID);
81 }
82 
createInstance(const char name[],size_t len)83 SkDisplayable* SkAnimateMaker::createInstance(const char name[], size_t len) {
84     SkDisplayTypes type = SkDisplayType::GetType(this, name, len );
85     if ((int)type >= 0)
86         return SkDisplayType::CreateInstance(this, type);
87     return NULL;
88 }
89 
90 // differs from SkAnimator::decodeStream in that it does not reset error state
decodeStream(SkStream * stream)91 bool SkAnimateMaker::decodeStream(SkStream* stream)
92 {
93     SkDisplayXMLParser parser(*this);
94     return parser.parse(*stream);
95 }
96 
97 // differs from SkAnimator::decodeURI in that it does not set URI base
decodeURI(const char uri[])98 bool SkAnimateMaker::decodeURI(const char uri[]) {
99 //  SkDebugf("animator decode %s\n", uri);
100 
101 //    SkStream* stream = SkStream::GetURIStream(fPrefix.c_str(), uri);
102     SkStream* stream = new SkFILEStream(uri);
103 
104     SkAutoTDelete<SkStream> autoDel(stream);
105     bool success = decodeStream(stream);
106     if (hasError() && fError.hasNoun() == false)
107         fError.setNoun(uri);
108     return success;
109 }
110 
111 #if defined SK_DEBUG && 0
112 //used for the if'd out section of deleteMembers
113 #include "SkTSearch.h"
114 
115 extern "C" {
compare_disp(const void * a,const void * b)116     int compare_disp(const void* a, const void* b) {
117         return *(const SkDisplayable**)a - *(const SkDisplayable**)b;
118     }
119 }
120 #endif
121 
delayEnable(SkApply * apply,SkMSec time)122 void SkAnimateMaker::delayEnable(SkApply* apply, SkMSec time) {
123     int index = fDelayed.find(apply);
124     if (index < 0) {
125         *fDelayed.append() = apply;
126     }
127 
128     (new SkEvent(SK_EventType_Delay, fAnimator->getSinkID()))->postTime(time);
129 }
130 
deleteMembers()131 void SkAnimateMaker::deleteMembers() {
132     int index;
133 #if defined SK_DEBUG && 0
134     //this code checks to see if helpers are among the children, but it is not complete -
135     //it should check the children of the children
136     int result;
137     SkTDArray<SkDisplayable*> children(fChildren.begin(), fChildren.count());
138     SkQSort(children.begin(), children.count(), sizeof(SkDisplayable*),compare_disp);
139     for (index = 0; index < fHelpers.count(); index++) {
140         SkDisplayable* helper = fHelpers[index];
141         result = SkTSearch(children.begin(), children.count(), helper, sizeof(SkDisplayable*));
142         SkASSERT(result < 0);
143     }
144 #endif
145     for (index = 0; index < fChildren.count(); index++) {
146         SkDisplayable* child = fChildren[index];
147         delete child;
148     }
149     for (index = 0; index < fHelpers.count(); index++) {
150         SkDisplayable* helper = fHelpers[index];
151         delete helper;
152     }
153     for (index = 0; index < fExtras.count(); index++) {
154         SkExtras* extras = fExtras[index];
155         delete extras;
156     }
157 }
158 
doDelayedEvent()159 void SkAnimateMaker::doDelayedEvent() {
160     fEnableTime = getAppTime();
161     for (int index = 0; index < fDelayed.count(); ) {
162         SkDisplayable* child = fDelayed[index];
163         SkASSERT(child->isApply());
164         SkApply* apply = (SkApply*) child;
165         apply->interpolate(*this, fEnableTime);
166         if (apply->hasDelayedAnimator())
167             index++;
168         else
169             fDelayed.remove(index);
170     }
171 }
172 
doEvent(const SkEvent & event)173 bool SkAnimateMaker::doEvent(const SkEvent& event) {
174     return (!fInMovie || fLoaded) && fAnimator->doEvent(event);
175 }
176 
177 #ifdef SK_DUMP_ENABLED
dump(const char * match)178 void SkAnimateMaker::dump(const char* match) {
179         SkTDict<SkDisplayable*>::Iter iter(fIDs);
180         const char* name;
181         SkDisplayable* result;
182         while ((name = iter.next(&result)) != NULL) {
183             if (strcmp(match,name) == 0)
184                 result->dump(this);
185         }
186 }
187 #endif
188 
dynamicProperty(SkString & nameStr,SkDisplayable ** displayablePtr)189 int SkAnimateMaker::dynamicProperty(SkString& nameStr, SkDisplayable** displayablePtr ) {
190     const char* name = nameStr.c_str();
191     const char* dot = strchr(name, '.');
192     SkASSERT(dot);
193     SkDisplayable* displayable;
194     if (find(name, dot - name, &displayable) == false) {
195         SkASSERT(0);
196         return 0;
197     }
198     const char* fieldName = dot + 1;
199     const SkMemberInfo* memberInfo = displayable->getMember(fieldName);
200     *displayablePtr = displayable;
201     return (int) memberInfo->fOffset;
202 }
203 
getAppTime() const204 SkMSec SkAnimateMaker::getAppTime() const {
205     return fTimeline->getMSecs();
206 }
207 
208 #ifdef SK_DEBUG
getRoot()209 SkAnimator* SkAnimateMaker::getRoot()
210 {
211     SkAnimateMaker* maker = this;
212     while (maker->fParentMaker)
213         maker = maker->fParentMaker;
214     return maker == this ? NULL : maker->fAnimator;
215 }
216 #endif
217 
helperAdd(SkDisplayable * trackMe)218 void SkAnimateMaker::helperAdd(SkDisplayable* trackMe) {
219     SkASSERT(fHelpers.find(trackMe) < 0);
220     *fHelpers.append() = trackMe;
221 }
222 
helperRemove(SkDisplayable * alreadyTracked)223 void SkAnimateMaker::helperRemove(SkDisplayable* alreadyTracked) {
224     int helperIndex = fHelpers.find(alreadyTracked);
225     if (helperIndex >= 0)
226         fHelpers.remove(helperIndex);
227 }
228 
229 #if 0
230 void SkAnimateMaker::loadMovies() {
231     for (SkDisplayable** dispPtr = fMovies.begin(); dispPtr < fMovies.end(); dispPtr++) {
232         SkDisplayable* displayable = *dispPtr;
233         SkASSERT(displayable->getType() == SkType_Movie);
234         SkDisplayMovie* movie = (SkDisplayMovie*) displayable;
235         SkAnimateMaker* movieMaker = movie->fMovie.fMaker;
236         movieMaker->fEvents.doEvent(*movieMaker, SkDisplayEvent::kOnload, NULL);
237         movieMaker->fEvents.removeEvent(SkDisplayEvent::kOnload, NULL);
238         movieMaker->loadMovies();
239     }
240 }
241 #endif
242 
notifyInval()243 void SkAnimateMaker::notifyInval() {
244     if (fHostEventSinkID)
245         fAnimator->onEventPost(new SkEvent(SK_EventType_Inval), fHostEventSinkID);
246 }
247 
notifyInvalTime(SkMSec time)248 void SkAnimateMaker::notifyInvalTime(SkMSec time) {
249     if (fHostEventSinkID)
250         fAnimator->onEventPostTime(new SkEvent(SK_EventType_Inval), fHostEventSinkID, time);
251 }
252 
postOnEnd(SkAnimateBase * animate,SkMSec end)253 void SkAnimateMaker::postOnEnd(SkAnimateBase* animate, SkMSec end) {
254         SkEvent evt;
255         evt.setS32("time", animate->getStart() + end);
256         evt.setPtr("anim", animate);
257         evt.setType(SK_EventType_OnEnd);
258         SkEventSinkID sinkID = fAnimator->getSinkID();
259         fAnimator->onEventPost(new SkEvent(evt), sinkID);
260 }
261 
reset()262 void SkAnimateMaker::reset() {
263     deleteMembers();
264     fChildren.reset();
265     fHelpers.reset();
266     fIDs.reset();
267     fEvents.reset();
268     fDisplayList.hardReset();
269 }
270 
removeActive(SkActive * active)271 void SkAnimateMaker::removeActive(SkActive* active) {
272     if (active == NULL)
273         return;
274     fDisplayList.remove(active);
275 }
276 
resolveID(SkDisplayable * displayable,SkDisplayable * original)277 bool SkAnimateMaker::resolveID(SkDisplayable* displayable, SkDisplayable* original) {
278     SkString newID;
279     bool success = computeID(original, NULL, &newID);
280     if (success)
281         setID(displayable, newID);
282     return success;
283 }
284 
setErrorString()285 void SkAnimateMaker::setErrorString() {
286     fErrorString.reset();
287     if (fError.hasError()) {
288         SkString err;
289         if (fFileName.size() > 0)
290             fErrorString.set(fFileName.c_str());
291         else
292             fErrorString.set("screenplay error");
293         int line = fError.getLineNumber();
294         if (line >= 0) {
295             fErrorString.append(", ");
296             fErrorString.append("line ");
297             fErrorString.appendS32(line);
298         }
299         fErrorString.append(": ");
300         fError.getErrorString(&err);
301         fErrorString.append(err);
302 #if defined SK_DEBUG
303         SkDebugf("%s\n", fErrorString.c_str());
304 #endif
305     }
306 }
307 
setEnableTime(SkMSec appTime,SkMSec expectedTime)308 void SkAnimateMaker::setEnableTime(SkMSec appTime, SkMSec expectedTime) {
309 #if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
310     SkString debugOut;
311     SkMSec time = getAppTime();
312     debugOut.appendS32(time - fDebugTimeBase);
313     debugOut.append(" set enable old enable=");
314     debugOut.appendS32(fEnableTime - fDebugTimeBase);
315     debugOut.append(" old adjust=");
316     debugOut.appendS32(fAdjustedStart);
317     debugOut.append(" new enable=");
318     debugOut.appendS32(expectedTime - fDebugTimeBase);
319     debugOut.append(" new adjust=");
320     debugOut.appendS32(appTime - expectedTime);
321     SkDebugf("%s\n", debugOut.c_str());
322 #endif
323     fAdjustedStart = appTime - expectedTime;
324     fEnableTime = expectedTime;
325     SkDisplayable** firstMovie = fMovies.begin();
326     SkDisplayable** endMovie = fMovies.end();
327     for (SkDisplayable** ptr = firstMovie; ptr < endMovie; ptr++) {
328         SkDisplayMovie* movie = (SkDisplayMovie*) *ptr;
329         movie->fMovie.fMaker->setEnableTime(appTime, expectedTime);
330     }
331 }
332 
setExtraPropertyCallBack(SkDisplayTypes type,SkScriptEngine::_propertyCallBack callBack,void * userStorage)333 void SkAnimateMaker::setExtraPropertyCallBack(SkDisplayTypes type,
334         SkScriptEngine::_propertyCallBack callBack, void* userStorage) {
335     SkExtras** end = fExtras.end();
336     for (SkExtras** extraPtr = fExtras.begin(); extraPtr < end; extraPtr++) {
337         SkExtras* extra = *extraPtr;
338         if (extra->definesType(type)) {
339             extra->fExtraCallBack = callBack;
340             extra->fExtraStorage = userStorage;
341             break;
342         }
343     }
344 }
345 
setID(SkDisplayable * displayable,const SkString & newID)346 void SkAnimateMaker::setID(SkDisplayable* displayable, const SkString& newID) {
347     fIDs.set(newID.c_str(), displayable);
348 #ifdef SK_DEBUG
349     displayable->_id.set(newID);
350     displayable->id = displayable->_id.c_str();
351 #endif
352 }
353 
setScriptError(const SkScriptEngine & engine)354 void SkAnimateMaker::setScriptError(const SkScriptEngine& engine) {
355     SkString errorString;
356 #ifdef SK_DEBUG
357     engine.getErrorString(&errorString);
358 #endif
359     setErrorNoun(errorString);
360     setErrorCode(SkDisplayXMLParserError::kErrorInScript);
361 }
362 
GetStep(const char * token,size_t len,void * stepPtr,SkScriptValue * value)363 bool SkAnimateMaker::GetStep(const char* token, size_t len, void* stepPtr, SkScriptValue* value) {
364     if (SK_LITERAL_STR_EQUAL("step", token, len)) {
365         value->fOperand.fS32 = *(int32_t*) stepPtr;
366         value->fType = SkType_Int;
367         return true;
368     }
369     return false;
370 }
371