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