Home | History | Annotate | Download | only in animator
      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 {
     25     virtual SkMSec getMSecs() const {
     26         return SkTime::GetMSecs();
     27     }
     28 } gDefaultTimeline;
     29 
     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 
     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 
     60 void SkAnimateMaker::appendActive(SkActive* active) {
     61     fDisplayList.append(active);
     62 }
     63 
     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 
     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 
     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
     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
     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" {
    116     int compare_disp(const void* a, const void* b) {
    117         return *(const SkDisplayable**)a - *(const SkDisplayable**)b;
    118     }
    119 }
    120 #endif
    121 
    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 
    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 
    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 
    173 bool SkAnimateMaker::doEvent(const SkEvent& event) {
    174     return (!fInMovie || fLoaded) && fAnimator->doEvent(event);
    175 }
    176 
    177 #ifdef SK_DUMP_ENABLED
    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 
    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 
    204 SkMSec SkAnimateMaker::getAppTime() const {
    205     return fTimeline->getMSecs();
    206 }
    207 
    208 #ifdef SK_DEBUG
    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 
    218 void SkAnimateMaker::helperAdd(SkDisplayable* trackMe) {
    219     SkASSERT(fHelpers.find(trackMe) < 0);
    220     *fHelpers.append() = trackMe;
    221 }
    222 
    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 
    243 void SkAnimateMaker::notifyInval() {
    244     if (fHostEventSinkID)
    245         fAnimator->onEventPost(new SkEvent(SK_EventType_Inval), fHostEventSinkID);
    246 }
    247 
    248 void SkAnimateMaker::notifyInvalTime(SkMSec time) {
    249     if (fHostEventSinkID)
    250         fAnimator->onEventPostTime(new SkEvent(SK_EventType_Inval), fHostEventSinkID, time);
    251 }
    252 
    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 
    262 void SkAnimateMaker::reset() {
    263     deleteMembers();
    264     fChildren.reset();
    265     fHelpers.reset();
    266     fIDs.reset();
    267     fEvents.reset();
    268     fDisplayList.hardReset();
    269 }
    270 
    271 void SkAnimateMaker::removeActive(SkActive* active) {
    272     if (active == NULL)
    273         return;
    274     fDisplayList.remove(active);
    275 }
    276 
    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 
    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 
    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 
    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 
    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 
    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 
    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