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     SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(uri));
    103     if (stream.get()) {
    104         bool success = decodeStream(stream);
    105         if (hasError() && fError.hasNoun() == false)
    106             fError.setNoun(uri);
    107         return success;
    108     } else {
    109         return false;
    110     }
    111 }
    112 
    113 #if defined SK_DEBUG && 0
    114 //used for the if'd out section of deleteMembers
    115 #include "SkTSearch.h"
    116 
    117 extern "C" {
    118     int compare_disp(const void* a, const void* b) {
    119         return *(const SkDisplayable**)a - *(const SkDisplayable**)b;
    120     }
    121 }
    122 #endif
    123 
    124 void SkAnimateMaker::delayEnable(SkApply* apply, SkMSec time) {
    125     int index = fDelayed.find(apply);
    126     if (index < 0) {
    127         *fDelayed.append() = apply;
    128     }
    129 
    130     (new SkEvent(SK_EventType_Delay, fAnimator->getSinkID()))->postTime(time);
    131 }
    132 
    133 void SkAnimateMaker::deleteMembers() {
    134     int index;
    135 #if defined SK_DEBUG && 0
    136     //this code checks to see if helpers are among the children, but it is not complete -
    137     //it should check the children of the children
    138     int result;
    139     SkTDArray<SkDisplayable*> children(fChildren.begin(), fChildren.count());
    140     SkQSort(children.begin(), children.count(), sizeof(SkDisplayable*),compare_disp);
    141     for (index = 0; index < fHelpers.count(); index++) {
    142         SkDisplayable* helper = fHelpers[index];
    143         result = SkTSearch(children.begin(), children.count(), helper, sizeof(SkDisplayable*));
    144         SkASSERT(result < 0);
    145     }
    146 #endif
    147     for (index = 0; index < fChildren.count(); index++) {
    148         SkDisplayable* child = fChildren[index];
    149         delete child;
    150     }
    151     for (index = 0; index < fHelpers.count(); index++) {
    152         SkDisplayable* helper = fHelpers[index];
    153         delete helper;
    154     }
    155     for (index = 0; index < fExtras.count(); index++) {
    156         SkExtras* extras = fExtras[index];
    157         delete extras;
    158     }
    159 }
    160 
    161 void SkAnimateMaker::doDelayedEvent() {
    162     fEnableTime = getAppTime();
    163     for (int index = 0; index < fDelayed.count(); ) {
    164         SkDisplayable* child = fDelayed[index];
    165         SkASSERT(child->isApply());
    166         SkApply* apply = (SkApply*) child;
    167         apply->interpolate(*this, fEnableTime);
    168         if (apply->hasDelayedAnimator())
    169             index++;
    170         else
    171             fDelayed.remove(index);
    172     }
    173 }
    174 
    175 bool SkAnimateMaker::doEvent(const SkEvent& event) {
    176     return (!fInMovie || fLoaded) && fAnimator->doEvent(event);
    177 }
    178 
    179 #ifdef SK_DUMP_ENABLED
    180 void SkAnimateMaker::dump(const char* match) {
    181         SkTDict<SkDisplayable*>::Iter iter(fIDs);
    182         const char* name;
    183         SkDisplayable* result;
    184         while ((name = iter.next(&result)) != NULL) {
    185             if (strcmp(match,name) == 0)
    186                 result->dump(this);
    187         }
    188 }
    189 #endif
    190 
    191 int SkAnimateMaker::dynamicProperty(SkString& nameStr, SkDisplayable** displayablePtr ) {
    192     const char* name = nameStr.c_str();
    193     const char* dot = strchr(name, '.');
    194     SkASSERT(dot);
    195     SkDisplayable* displayable;
    196     if (find(name, dot - name, &displayable) == false) {
    197         SkASSERT(0);
    198         return 0;
    199     }
    200     const char* fieldName = dot + 1;
    201     const SkMemberInfo* memberInfo = displayable->getMember(fieldName);
    202     *displayablePtr = displayable;
    203     return (int) memberInfo->fOffset;
    204 }
    205 
    206 SkMSec SkAnimateMaker::getAppTime() const {
    207     return fTimeline->getMSecs();
    208 }
    209 
    210 #ifdef SK_DEBUG
    211 SkAnimator* SkAnimateMaker::getRoot()
    212 {
    213     SkAnimateMaker* maker = this;
    214     while (maker->fParentMaker)
    215         maker = maker->fParentMaker;
    216     return maker == this ? NULL : maker->fAnimator;
    217 }
    218 #endif
    219 
    220 void SkAnimateMaker::helperAdd(SkDisplayable* trackMe) {
    221     SkASSERT(fHelpers.find(trackMe) < 0);
    222     *fHelpers.append() = trackMe;
    223 }
    224 
    225 void SkAnimateMaker::helperRemove(SkDisplayable* alreadyTracked) {
    226     int helperIndex = fHelpers.find(alreadyTracked);
    227     if (helperIndex >= 0)
    228         fHelpers.remove(helperIndex);
    229 }
    230 
    231 #if 0
    232 void SkAnimateMaker::loadMovies() {
    233     for (SkDisplayable** dispPtr = fMovies.begin(); dispPtr < fMovies.end(); dispPtr++) {
    234         SkDisplayable* displayable = *dispPtr;
    235         SkASSERT(displayable->getType() == SkType_Movie);
    236         SkDisplayMovie* movie = (SkDisplayMovie*) displayable;
    237         SkAnimateMaker* movieMaker = movie->fMovie.fMaker;
    238         movieMaker->fEvents.doEvent(*movieMaker, SkDisplayEvent::kOnload, NULL);
    239         movieMaker->fEvents.removeEvent(SkDisplayEvent::kOnload, NULL);
    240         movieMaker->loadMovies();
    241     }
    242 }
    243 #endif
    244 
    245 void SkAnimateMaker::notifyInval() {
    246     if (fHostEventSinkID)
    247         fAnimator->onEventPost(new SkEvent(SK_EventType_Inval), fHostEventSinkID);
    248 }
    249 
    250 void SkAnimateMaker::notifyInvalTime(SkMSec time) {
    251     if (fHostEventSinkID)
    252         fAnimator->onEventPostTime(new SkEvent(SK_EventType_Inval), fHostEventSinkID, time);
    253 }
    254 
    255 void SkAnimateMaker::postOnEnd(SkAnimateBase* animate, SkMSec end) {
    256         SkEvent evt;
    257         evt.setS32("time", animate->getStart() + end);
    258         evt.setPtr("anim", animate);
    259         evt.setType(SK_EventType_OnEnd);
    260         SkEventSinkID sinkID = fAnimator->getSinkID();
    261         fAnimator->onEventPost(new SkEvent(evt), sinkID);
    262 }
    263 
    264 void SkAnimateMaker::reset() {
    265     deleteMembers();
    266     fChildren.reset();
    267     fHelpers.reset();
    268     fIDs.reset();
    269     fEvents.reset();
    270     fDisplayList.hardReset();
    271 }
    272 
    273 void SkAnimateMaker::removeActive(SkActive* active) {
    274     if (active == NULL)
    275         return;
    276     fDisplayList.remove(active);
    277 }
    278 
    279 bool SkAnimateMaker::resolveID(SkDisplayable* displayable, SkDisplayable* original) {
    280     SkString newID;
    281     bool success = computeID(original, NULL, &newID);
    282     if (success)
    283         setID(displayable, newID);
    284     return success;
    285 }
    286 
    287 void SkAnimateMaker::setErrorString() {
    288     fErrorString.reset();
    289     if (fError.hasError()) {
    290         SkString err;
    291         if (fFileName.size() > 0)
    292             fErrorString.set(fFileName.c_str());
    293         else
    294             fErrorString.set("screenplay error");
    295         int line = fError.getLineNumber();
    296         if (line >= 0) {
    297             fErrorString.append(", ");
    298             fErrorString.append("line ");
    299             fErrorString.appendS32(line);
    300         }
    301         fErrorString.append(": ");
    302         fError.getErrorString(&err);
    303         fErrorString.append(err);
    304 #if defined SK_DEBUG
    305         SkDebugf("%s\n", fErrorString.c_str());
    306 #endif
    307     }
    308 }
    309 
    310 void SkAnimateMaker::setEnableTime(SkMSec appTime, SkMSec expectedTime) {
    311 #if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
    312     SkString debugOut;
    313     SkMSec time = getAppTime();
    314     debugOut.appendS32(time - fDebugTimeBase);
    315     debugOut.append(" set enable old enable=");
    316     debugOut.appendS32(fEnableTime - fDebugTimeBase);
    317     debugOut.append(" old adjust=");
    318     debugOut.appendS32(fAdjustedStart);
    319     debugOut.append(" new enable=");
    320     debugOut.appendS32(expectedTime - fDebugTimeBase);
    321     debugOut.append(" new adjust=");
    322     debugOut.appendS32(appTime - expectedTime);
    323     SkDebugf("%s\n", debugOut.c_str());
    324 #endif
    325     fAdjustedStart = appTime - expectedTime;
    326     fEnableTime = expectedTime;
    327     SkDisplayable** firstMovie = fMovies.begin();
    328     SkDisplayable** endMovie = fMovies.end();
    329     for (SkDisplayable** ptr = firstMovie; ptr < endMovie; ptr++) {
    330         SkDisplayMovie* movie = (SkDisplayMovie*) *ptr;
    331         movie->fMovie.fMaker->setEnableTime(appTime, expectedTime);
    332     }
    333 }
    334 
    335 void SkAnimateMaker::setExtraPropertyCallBack(SkDisplayTypes type,
    336         SkScriptEngine::_propertyCallBack callBack, void* userStorage) {
    337     SkExtras** end = fExtras.end();
    338     for (SkExtras** extraPtr = fExtras.begin(); extraPtr < end; extraPtr++) {
    339         SkExtras* extra = *extraPtr;
    340         if (extra->definesType(type)) {
    341             extra->fExtraCallBack = callBack;
    342             extra->fExtraStorage = userStorage;
    343             break;
    344         }
    345     }
    346 }
    347 
    348 void SkAnimateMaker::setID(SkDisplayable* displayable, const SkString& newID) {
    349     fIDs.set(newID.c_str(), displayable);
    350 #ifdef SK_DEBUG
    351     displayable->_id.set(newID);
    352     displayable->id = displayable->_id.c_str();
    353 #endif
    354 }
    355 
    356 void SkAnimateMaker::setScriptError(const SkScriptEngine& engine) {
    357     SkString errorString;
    358 #ifdef SK_DEBUG
    359     engine.getErrorString(&errorString);
    360 #endif
    361     setErrorNoun(errorString);
    362     setErrorCode(SkDisplayXMLParserError::kErrorInScript);
    363 }
    364 
    365 bool SkAnimateMaker::GetStep(const char* token, size_t len, void* stepPtr, SkScriptValue* value) {
    366     if (SK_LITERAL_STR_EQUAL("step", token, len)) {
    367         value->fOperand.fS32 = *(int32_t*) stepPtr;
    368         value->fType = SkType_Int;
    369         return true;
    370     }
    371     return false;
    372 }
    373