gfx/skia/trunk/src/animator/SkAnimateMaker.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/animator/SkAnimateMaker.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,372 @@
     1.4 +
     1.5 +/*
     1.6 + * Copyright 2006 The Android Open Source Project
     1.7 + *
     1.8 + * Use of this source code is governed by a BSD-style license that can be
     1.9 + * found in the LICENSE file.
    1.10 + */
    1.11 +
    1.12 +
    1.13 +#include "SkAnimateMaker.h"
    1.14 +#include "SkAnimator.h"
    1.15 +#include "SkAnimatorScript.h"
    1.16 +#include "SkDisplayable.h"
    1.17 +#include "SkDisplayApply.h"
    1.18 +#include "SkDisplayList.h"
    1.19 +#include "SkDisplayMovie.h"
    1.20 +#include "SkDisplayType.h"
    1.21 +#include "SkExtras.h"
    1.22 +#include "SkMemberInfo.h"
    1.23 +#include "SkStream.h"
    1.24 +#include "SkSystemEventTypes.h"
    1.25 +#include "SkTime.h"
    1.26 +
    1.27 +class DefaultTimeline : public SkAnimator::Timeline {
    1.28 +    virtual SkMSec getMSecs() const {
    1.29 +        return SkTime::GetMSecs();
    1.30 +    }
    1.31 +} gDefaultTimeline;
    1.32 +
    1.33 +SkAnimateMaker::SkAnimateMaker(SkAnimator* animator, SkCanvas* canvas, SkPaint* paint)
    1.34 +    : fActiveEvent(NULL), fAdjustedStart(0), fCanvas(canvas), fEnableTime(0),
    1.35 +        fHostEventSinkID(0), fMinimumInterval((SkMSec) -1), fPaint(paint), fParentMaker(NULL),
    1.36 +        fTimeline(&gDefaultTimeline), fInInclude(false), fInMovie(false),
    1.37 +        fFirstScriptError(false), fLoaded(false), fIDs(256), fAnimator(animator)
    1.38 +{
    1.39 +    fScreenplay.time = 0;
    1.40 +#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
    1.41 +    fDebugTimeBase = (SkMSec) -1;
    1.42 +#endif
    1.43 +#ifdef SK_DUMP_ENABLED
    1.44 +    fDumpEvents = fDumpGConditions = fDumpPosts = false;
    1.45 +#endif
    1.46 +}
    1.47 +
    1.48 +SkAnimateMaker::~SkAnimateMaker() {
    1.49 +    deleteMembers();
    1.50 +}
    1.51 +
    1.52 +#if 0
    1.53 +SkMSec SkAnimateMaker::adjustDelay(SkMSec expectedBase, SkMSec delay) {
    1.54 +    SkMSec appTime = (*fTimeCallBack)();
    1.55 +    if (appTime)
    1.56 +        delay -= appTime - expectedBase;
    1.57 +    if (delay < 0)
    1.58 +        delay = 0;
    1.59 +    return delay;
    1.60 +}
    1.61 +#endif
    1.62 +
    1.63 +void SkAnimateMaker::appendActive(SkActive* active) {
    1.64 +    fDisplayList.append(active);
    1.65 +}
    1.66 +
    1.67 +void SkAnimateMaker::clearExtraPropertyCallBack(SkDisplayTypes type) {
    1.68 +    SkExtras** end = fExtras.end();
    1.69 +    for (SkExtras** extraPtr = fExtras.begin(); extraPtr < end; extraPtr++) {
    1.70 +        SkExtras* extra = *extraPtr;
    1.71 +        if (extra->definesType(type)) {
    1.72 +            extra->fExtraCallBack = NULL;
    1.73 +            extra->fExtraStorage = NULL;
    1.74 +            break;
    1.75 +        }
    1.76 +    }
    1.77 +}
    1.78 +
    1.79 +bool SkAnimateMaker::computeID(SkDisplayable* displayable, SkDisplayable* parent, SkString* newID) {
    1.80 +    const char* script;
    1.81 +  if (findKey(displayable, &script) == false)
    1.82 +        return true;
    1.83 +    return SkAnimatorScript::EvaluateString(*this, displayable, parent, script, newID);
    1.84 +}
    1.85 +
    1.86 +SkDisplayable* SkAnimateMaker::createInstance(const char name[], size_t len) {
    1.87 +    SkDisplayTypes type = SkDisplayType::GetType(this, name, len );
    1.88 +    if ((int)type >= 0)
    1.89 +        return SkDisplayType::CreateInstance(this, type);
    1.90 +    return NULL;
    1.91 +}
    1.92 +
    1.93 +// differs from SkAnimator::decodeStream in that it does not reset error state
    1.94 +bool SkAnimateMaker::decodeStream(SkStream* stream)
    1.95 +{
    1.96 +    SkDisplayXMLParser parser(*this);
    1.97 +    return parser.parse(*stream);
    1.98 +}
    1.99 +
   1.100 +// differs from SkAnimator::decodeURI in that it does not set URI base
   1.101 +bool SkAnimateMaker::decodeURI(const char uri[]) {
   1.102 +//  SkDebugf("animator decode %s\n", uri);
   1.103 +
   1.104 +//    SkStream* stream = SkStream::GetURIStream(fPrefix.c_str(), uri);
   1.105 +    SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(uri));
   1.106 +    if (stream.get()) {
   1.107 +        bool success = decodeStream(stream);
   1.108 +        if (hasError() && fError.hasNoun() == false)
   1.109 +            fError.setNoun(uri);
   1.110 +        return success;
   1.111 +    } else {
   1.112 +        return false;
   1.113 +    }
   1.114 +}
   1.115 +
   1.116 +#if defined SK_DEBUG && 0
   1.117 +//used for the if'd out section of deleteMembers
   1.118 +#include "SkTSearch.h"
   1.119 +
   1.120 +extern "C" {
   1.121 +    int compare_disp(const void* a, const void* b) {
   1.122 +        return *(const SkDisplayable**)a - *(const SkDisplayable**)b;
   1.123 +    }
   1.124 +}
   1.125 +#endif
   1.126 +
   1.127 +void SkAnimateMaker::delayEnable(SkApply* apply, SkMSec time) {
   1.128 +    int index = fDelayed.find(apply);
   1.129 +    if (index < 0) {
   1.130 +        *fDelayed.append() = apply;
   1.131 +    }
   1.132 +
   1.133 +    (new SkEvent(SK_EventType_Delay, fAnimator->getSinkID()))->postTime(time);
   1.134 +}
   1.135 +
   1.136 +void SkAnimateMaker::deleteMembers() {
   1.137 +    int index;
   1.138 +#if defined SK_DEBUG && 0
   1.139 +    //this code checks to see if helpers are among the children, but it is not complete -
   1.140 +    //it should check the children of the children
   1.141 +    int result;
   1.142 +    SkTDArray<SkDisplayable*> children(fChildren.begin(), fChildren.count());
   1.143 +    SkQSort(children.begin(), children.count(), sizeof(SkDisplayable*),compare_disp);
   1.144 +    for (index = 0; index < fHelpers.count(); index++) {
   1.145 +        SkDisplayable* helper = fHelpers[index];
   1.146 +        result = SkTSearch(children.begin(), children.count(), helper, sizeof(SkDisplayable*));
   1.147 +        SkASSERT(result < 0);
   1.148 +    }
   1.149 +#endif
   1.150 +    for (index = 0; index < fChildren.count(); index++) {
   1.151 +        SkDisplayable* child = fChildren[index];
   1.152 +        delete child;
   1.153 +    }
   1.154 +    for (index = 0; index < fHelpers.count(); index++) {
   1.155 +        SkDisplayable* helper = fHelpers[index];
   1.156 +        delete helper;
   1.157 +    }
   1.158 +    for (index = 0; index < fExtras.count(); index++) {
   1.159 +        SkExtras* extras = fExtras[index];
   1.160 +        delete extras;
   1.161 +    }
   1.162 +}
   1.163 +
   1.164 +void SkAnimateMaker::doDelayedEvent() {
   1.165 +    fEnableTime = getAppTime();
   1.166 +    for (int index = 0; index < fDelayed.count(); ) {
   1.167 +        SkDisplayable* child = fDelayed[index];
   1.168 +        SkASSERT(child->isApply());
   1.169 +        SkApply* apply = (SkApply*) child;
   1.170 +        apply->interpolate(*this, fEnableTime);
   1.171 +        if (apply->hasDelayedAnimator())
   1.172 +            index++;
   1.173 +        else
   1.174 +            fDelayed.remove(index);
   1.175 +    }
   1.176 +}
   1.177 +
   1.178 +bool SkAnimateMaker::doEvent(const SkEvent& event) {
   1.179 +    return (!fInMovie || fLoaded) && fAnimator->doEvent(event);
   1.180 +}
   1.181 +
   1.182 +#ifdef SK_DUMP_ENABLED
   1.183 +void SkAnimateMaker::dump(const char* match) {
   1.184 +        SkTDict<SkDisplayable*>::Iter iter(fIDs);
   1.185 +        const char* name;
   1.186 +        SkDisplayable* result;
   1.187 +        while ((name = iter.next(&result)) != NULL) {
   1.188 +            if (strcmp(match,name) == 0)
   1.189 +                result->dump(this);
   1.190 +        }
   1.191 +}
   1.192 +#endif
   1.193 +
   1.194 +int SkAnimateMaker::dynamicProperty(SkString& nameStr, SkDisplayable** displayablePtr ) {
   1.195 +    const char* name = nameStr.c_str();
   1.196 +    const char* dot = strchr(name, '.');
   1.197 +    SkASSERT(dot);
   1.198 +    SkDisplayable* displayable;
   1.199 +    if (find(name, dot - name, &displayable) == false) {
   1.200 +        SkASSERT(0);
   1.201 +        return 0;
   1.202 +    }
   1.203 +    const char* fieldName = dot + 1;
   1.204 +    const SkMemberInfo* memberInfo = displayable->getMember(fieldName);
   1.205 +    *displayablePtr = displayable;
   1.206 +    return (int) memberInfo->fOffset;
   1.207 +}
   1.208 +
   1.209 +SkMSec SkAnimateMaker::getAppTime() const {
   1.210 +    return fTimeline->getMSecs();
   1.211 +}
   1.212 +
   1.213 +#ifdef SK_DEBUG
   1.214 +SkAnimator* SkAnimateMaker::getRoot()
   1.215 +{
   1.216 +    SkAnimateMaker* maker = this;
   1.217 +    while (maker->fParentMaker)
   1.218 +        maker = maker->fParentMaker;
   1.219 +    return maker == this ? NULL : maker->fAnimator;
   1.220 +}
   1.221 +#endif
   1.222 +
   1.223 +void SkAnimateMaker::helperAdd(SkDisplayable* trackMe) {
   1.224 +    SkASSERT(fHelpers.find(trackMe) < 0);
   1.225 +    *fHelpers.append() = trackMe;
   1.226 +}
   1.227 +
   1.228 +void SkAnimateMaker::helperRemove(SkDisplayable* alreadyTracked) {
   1.229 +    int helperIndex = fHelpers.find(alreadyTracked);
   1.230 +    if (helperIndex >= 0)
   1.231 +        fHelpers.remove(helperIndex);
   1.232 +}
   1.233 +
   1.234 +#if 0
   1.235 +void SkAnimateMaker::loadMovies() {
   1.236 +    for (SkDisplayable** dispPtr = fMovies.begin(); dispPtr < fMovies.end(); dispPtr++) {
   1.237 +        SkDisplayable* displayable = *dispPtr;
   1.238 +        SkASSERT(displayable->getType() == SkType_Movie);
   1.239 +        SkDisplayMovie* movie = (SkDisplayMovie*) displayable;
   1.240 +        SkAnimateMaker* movieMaker = movie->fMovie.fMaker;
   1.241 +        movieMaker->fEvents.doEvent(*movieMaker, SkDisplayEvent::kOnload, NULL);
   1.242 +        movieMaker->fEvents.removeEvent(SkDisplayEvent::kOnload, NULL);
   1.243 +        movieMaker->loadMovies();
   1.244 +    }
   1.245 +}
   1.246 +#endif
   1.247 +
   1.248 +void SkAnimateMaker::notifyInval() {
   1.249 +    if (fHostEventSinkID)
   1.250 +        fAnimator->onEventPost(new SkEvent(SK_EventType_Inval), fHostEventSinkID);
   1.251 +}
   1.252 +
   1.253 +void SkAnimateMaker::notifyInvalTime(SkMSec time) {
   1.254 +    if (fHostEventSinkID)
   1.255 +        fAnimator->onEventPostTime(new SkEvent(SK_EventType_Inval), fHostEventSinkID, time);
   1.256 +}
   1.257 +
   1.258 +void SkAnimateMaker::postOnEnd(SkAnimateBase* animate, SkMSec end) {
   1.259 +        SkEvent evt;
   1.260 +        evt.setS32("time", animate->getStart() + end);
   1.261 +        evt.setPtr("anim", animate);
   1.262 +        evt.setType(SK_EventType_OnEnd);
   1.263 +        SkEventSinkID sinkID = fAnimator->getSinkID();
   1.264 +        fAnimator->onEventPost(new SkEvent(evt), sinkID);
   1.265 +}
   1.266 +
   1.267 +void SkAnimateMaker::reset() {
   1.268 +    deleteMembers();
   1.269 +    fChildren.reset();
   1.270 +    fHelpers.reset();
   1.271 +    fIDs.reset();
   1.272 +    fEvents.reset();
   1.273 +    fDisplayList.hardReset();
   1.274 +}
   1.275 +
   1.276 +void SkAnimateMaker::removeActive(SkActive* active) {
   1.277 +    if (active == NULL)
   1.278 +        return;
   1.279 +    fDisplayList.remove(active);
   1.280 +}
   1.281 +
   1.282 +bool SkAnimateMaker::resolveID(SkDisplayable* displayable, SkDisplayable* original) {
   1.283 +    SkString newID;
   1.284 +    bool success = computeID(original, NULL, &newID);
   1.285 +    if (success)
   1.286 +        setID(displayable, newID);
   1.287 +    return success;
   1.288 +}
   1.289 +
   1.290 +void SkAnimateMaker::setErrorString() {
   1.291 +    fErrorString.reset();
   1.292 +    if (fError.hasError()) {
   1.293 +        SkString err;
   1.294 +        if (fFileName.size() > 0)
   1.295 +            fErrorString.set(fFileName.c_str());
   1.296 +        else
   1.297 +            fErrorString.set("screenplay error");
   1.298 +        int line = fError.getLineNumber();
   1.299 +        if (line >= 0) {
   1.300 +            fErrorString.append(", ");
   1.301 +            fErrorString.append("line ");
   1.302 +            fErrorString.appendS32(line);
   1.303 +        }
   1.304 +        fErrorString.append(": ");
   1.305 +        fError.getErrorString(&err);
   1.306 +        fErrorString.append(err);
   1.307 +#if defined SK_DEBUG
   1.308 +        SkDebugf("%s\n", fErrorString.c_str());
   1.309 +#endif
   1.310 +    }
   1.311 +}
   1.312 +
   1.313 +void SkAnimateMaker::setEnableTime(SkMSec appTime, SkMSec expectedTime) {
   1.314 +#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
   1.315 +    SkString debugOut;
   1.316 +    SkMSec time = getAppTime();
   1.317 +    debugOut.appendS32(time - fDebugTimeBase);
   1.318 +    debugOut.append(" set enable old enable=");
   1.319 +    debugOut.appendS32(fEnableTime - fDebugTimeBase);
   1.320 +    debugOut.append(" old adjust=");
   1.321 +    debugOut.appendS32(fAdjustedStart);
   1.322 +    debugOut.append(" new enable=");
   1.323 +    debugOut.appendS32(expectedTime - fDebugTimeBase);
   1.324 +    debugOut.append(" new adjust=");
   1.325 +    debugOut.appendS32(appTime - expectedTime);
   1.326 +    SkDebugf("%s\n", debugOut.c_str());
   1.327 +#endif
   1.328 +    fAdjustedStart = appTime - expectedTime;
   1.329 +    fEnableTime = expectedTime;
   1.330 +    SkDisplayable** firstMovie = fMovies.begin();
   1.331 +    SkDisplayable** endMovie = fMovies.end();
   1.332 +    for (SkDisplayable** ptr = firstMovie; ptr < endMovie; ptr++) {
   1.333 +        SkDisplayMovie* movie = (SkDisplayMovie*) *ptr;
   1.334 +        movie->fMovie.fMaker->setEnableTime(appTime, expectedTime);
   1.335 +    }
   1.336 +}
   1.337 +
   1.338 +void SkAnimateMaker::setExtraPropertyCallBack(SkDisplayTypes type,
   1.339 +        SkScriptEngine::_propertyCallBack callBack, void* userStorage) {
   1.340 +    SkExtras** end = fExtras.end();
   1.341 +    for (SkExtras** extraPtr = fExtras.begin(); extraPtr < end; extraPtr++) {
   1.342 +        SkExtras* extra = *extraPtr;
   1.343 +        if (extra->definesType(type)) {
   1.344 +            extra->fExtraCallBack = callBack;
   1.345 +            extra->fExtraStorage = userStorage;
   1.346 +            break;
   1.347 +        }
   1.348 +    }
   1.349 +}
   1.350 +
   1.351 +void SkAnimateMaker::setID(SkDisplayable* displayable, const SkString& newID) {
   1.352 +    fIDs.set(newID.c_str(), displayable);
   1.353 +#ifdef SK_DEBUG
   1.354 +    displayable->_id.set(newID);
   1.355 +    displayable->id = displayable->_id.c_str();
   1.356 +#endif
   1.357 +}
   1.358 +
   1.359 +void SkAnimateMaker::setScriptError(const SkScriptEngine& engine) {
   1.360 +    SkString errorString;
   1.361 +#ifdef SK_DEBUG
   1.362 +    engine.getErrorString(&errorString);
   1.363 +#endif
   1.364 +    setErrorNoun(errorString);
   1.365 +    setErrorCode(SkDisplayXMLParserError::kErrorInScript);
   1.366 +}
   1.367 +
   1.368 +bool SkAnimateMaker::GetStep(const char* token, size_t len, void* stepPtr, SkScriptValue* value) {
   1.369 +    if (SK_LITERAL_STR_EQUAL("step", token, len)) {
   1.370 +        value->fOperand.fS32 = *(int32_t*) stepPtr;
   1.371 +        value->fType = SkType_Int;
   1.372 +        return true;
   1.373 +    }
   1.374 +    return false;
   1.375 +}

mercurial