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

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/animator/SkDisplayPost.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,298 @@
     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 "SkDisplayPost.h"
    1.14 +#include "SkAnimateMaker.h"
    1.15 +#include "SkAnimator.h"
    1.16 +#include "SkDisplayMovie.h"
    1.17 +#include "SkPostParts.h"
    1.18 +#include "SkScript.h"
    1.19 +#ifdef SK_DEBUG
    1.20 +#include "SkDump.h"
    1.21 +#include "SkTime.h"
    1.22 +#endif
    1.23 +
    1.24 +enum SkPost_Properties {
    1.25 +    SK_PROPERTY(target),
    1.26 +    SK_PROPERTY(type)
    1.27 +};
    1.28 +
    1.29 +#if SK_USE_CONDENSED_INFO == 0
    1.30 +
    1.31 +const SkMemberInfo SkPost::fInfo[] = {
    1.32 +    SK_MEMBER(delay, MSec),
    1.33 +//  SK_MEMBER(initialized, Boolean),
    1.34 +    SK_MEMBER(mode, EventMode),
    1.35 +    SK_MEMBER(sink, String),
    1.36 +    SK_MEMBER_PROPERTY(target, String),
    1.37 +    SK_MEMBER_PROPERTY(type, String)
    1.38 +};
    1.39 +
    1.40 +#endif
    1.41 +
    1.42 +DEFINE_GET_MEMBER(SkPost);
    1.43 +
    1.44 +SkPost::SkPost() : delay(0), /*initialized(SkBool(-1)), */ mode(kImmediate), fMaker(NULL),
    1.45 +    fSinkID(0), fTargetMaker(NULL), fChildHasID(false), fDirty(false) {
    1.46 +}
    1.47 +
    1.48 +SkPost::~SkPost() {
    1.49 +    for (SkDataInput** part = fParts.begin(); part < fParts.end();  part++)
    1.50 +        delete *part;
    1.51 +}
    1.52 +
    1.53 +bool SkPost::addChild(SkAnimateMaker& , SkDisplayable* child) {
    1.54 +    SkASSERT(child && child->isDataInput());
    1.55 +    SkDataInput* part = (SkDataInput*) child;
    1.56 +    *fParts.append() = part;
    1.57 +    return true;
    1.58 +}
    1.59 +
    1.60 +bool SkPost::childrenNeedDisposing() const {
    1.61 +    return false;
    1.62 +}
    1.63 +
    1.64 +void SkPost::dirty() {
    1.65 +    fDirty = true;
    1.66 +}
    1.67 +
    1.68 +#ifdef SK_DUMP_ENABLED
    1.69 +void SkPost::dump(SkAnimateMaker* maker) {
    1.70 +    dumpBase(maker);
    1.71 +    SkString* eventType = new SkString();
    1.72 +    fEvent.getType(eventType);
    1.73 +    if (eventType->equals("user")) {
    1.74 +        const char* target = fEvent.findString("id");
    1.75 +        SkDebugf("target=\"%s\" ", target);
    1.76 +    }
    1.77 +    else
    1.78 +        SkDebugf("type=\"%s\" ", eventType->c_str());
    1.79 +    delete eventType;
    1.80 +
    1.81 +    if (delay > 0) {
    1.82 +        SkDebugf("delay=\"%g\" ", SkScalarToFloat(SkScalarDiv(delay, 1000)));
    1.83 +    }
    1.84 +//  if (initialized == false)
    1.85 +//      SkDebugf("(uninitialized) ");
    1.86 +    SkString string;
    1.87 +    SkDump::GetEnumString(SkType_EventMode, mode, &string);
    1.88 +    if (!string.equals("immediate"))
    1.89 +        SkDebugf("mode=\"%s\" ", string.c_str());
    1.90 +    // !!! could enhance this to search through make hierarchy to show name of sink
    1.91 +    if (sink.size() > 0) {
    1.92 +        SkDebugf("sink=\"%s\" sinkID=\"%d\" ", sink.c_str(), fSinkID);
    1.93 +    } else if (fSinkID != maker->getAnimator()->getSinkID() && fSinkID != 0) {
    1.94 +        SkDebugf("sinkID=\"%d\" ", fSinkID);
    1.95 +    }
    1.96 +    const SkMetaData& meta = fEvent.getMetaData();
    1.97 +    SkMetaData::Iter iter(meta);
    1.98 +    SkMetaData::Type    type;
    1.99 +    int number;
   1.100 +    const char* name;
   1.101 +    bool closedYet = false;
   1.102 +    SkDisplayList::fIndent += 4;
   1.103 +    //this seems to work, but kinda hacky
   1.104 +    //for some reason the last part is id, which i don't want
   1.105 +    //and the parts seem to be in the reverse order from the one in which we find the
   1.106 +    //data itself
   1.107 +    //SkDataInput** ptr = fParts.end();
   1.108 +    //SkDataInput* data;
   1.109 +    //const char* ID;
   1.110 +    while ((name = iter.next(&type, &number)) != NULL) {
   1.111 +        //ptr--;
   1.112 +        if (strcmp(name, "id") == 0)
   1.113 +            continue;
   1.114 +        if (closedYet == false) {
   1.115 +            SkDebugf(">\n");
   1.116 +            closedYet = true;
   1.117 +        }
   1.118 +        //data = *ptr;
   1.119 +        //if (data->id)
   1.120 +        //    ID = data->id;
   1.121 +        //else
   1.122 +        //    ID = "";
   1.123 +        SkDebugf("%*s<data name=\"%s\" ", SkDisplayList::fIndent, "", name);
   1.124 +        switch (type) {
   1.125 +            case SkMetaData::kS32_Type: {
   1.126 +                int32_t s32;
   1.127 +                meta.findS32(name, &s32);
   1.128 +                SkDebugf("int=\"%d\" ", s32);
   1.129 +                } break;
   1.130 +            case SkMetaData::kScalar_Type: {
   1.131 +                SkScalar scalar;
   1.132 +                meta.findScalar(name, &scalar);
   1.133 +                SkDebugf("float=\"%g\" ", SkScalarToFloat(scalar));
   1.134 +                } break;
   1.135 +            case SkMetaData::kString_Type:
   1.136 +                SkDebugf("string=\"%s\" ", meta.findString(name));
   1.137 +                break;
   1.138 +            case SkMetaData::kPtr_Type: {//when do we have a pointer
   1.139 +                    void* ptr;
   1.140 +                    meta.findPtr(name, &ptr);
   1.141 +                    SkDebugf("0x%08x ", ptr);
   1.142 +                } break;
   1.143 +            case SkMetaData::kBool_Type: {
   1.144 +                bool boolean;
   1.145 +                meta.findBool(name, &boolean);
   1.146 +                SkDebugf("boolean=\"%s\" ", boolean ? "true " : "false ");
   1.147 +                } break;
   1.148 +            default:
   1.149 +                break;
   1.150 +        }
   1.151 +        SkDebugf("/>\n");
   1.152 +        //ptr++;
   1.153 +/*      perhaps this should only be done in the case of a pointer?
   1.154 +        SkDisplayable* displayable;
   1.155 +        if (maker->find(name, &displayable))
   1.156 +            displayable->dump(maker);
   1.157 +        else
   1.158 +            SkDebugf("\n");*/
   1.159 +    }
   1.160 +    SkDisplayList::fIndent -= 4;
   1.161 +    if (closedYet)
   1.162 +        dumpEnd(maker);
   1.163 +    else
   1.164 +        SkDebugf("/>\n");
   1.165 +
   1.166 +}
   1.167 +#endif
   1.168 +
   1.169 +bool SkPost::enable(SkAnimateMaker& maker ) {
   1.170 +    if (maker.hasError())
   1.171 +        return true;
   1.172 +    if (fDirty) {
   1.173 +        if (sink.size() > 0)
   1.174 +            findSinkID();
   1.175 +        if (fChildHasID) {
   1.176 +            SkString preserveID(fEvent.findString("id"));
   1.177 +            fEvent.getMetaData().reset();
   1.178 +            if (preserveID.size() > 0)
   1.179 +                fEvent.setString("id", preserveID);
   1.180 +            for (SkDataInput** part = fParts.begin(); part < fParts.end();  part++) {
   1.181 +                if ((*part)->add())
   1.182 +                    maker.setErrorCode(SkDisplayXMLParserError::kErrorAddingDataToPost);
   1.183 +            }
   1.184 +        }
   1.185 +        fDirty = false;
   1.186 +    }
   1.187 +#ifdef SK_DUMP_ENABLED
   1.188 +    if (maker.fDumpPosts) {
   1.189 +        SkDebugf("post enable: ");
   1.190 +        dump(&maker);
   1.191 +    }
   1.192 +#if defined SK_DEBUG_ANIMATION_TIMING
   1.193 +    SkString debugOut;
   1.194 +    SkMSec time = maker.getAppTime();
   1.195 +    debugOut.appendS32(time - maker.fDebugTimeBase);
   1.196 +    debugOut.append(" post id=");
   1.197 +    debugOut.append(_id);
   1.198 +    debugOut.append(" enable=");
   1.199 +    debugOut.appendS32(maker.fEnableTime - maker.fDebugTimeBase);
   1.200 +    debugOut.append(" delay=");
   1.201 +    debugOut.appendS32(delay);
   1.202 +#endif
   1.203 +#endif
   1.204 +//  SkMSec adjustedDelay = maker.adjustDelay(maker.fEnableTime, delay);
   1.205 +    SkMSec futureTime = maker.fEnableTime + delay;
   1.206 +    fEvent.setFast32(futureTime);
   1.207 +#if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
   1.208 +    debugOut.append(" future=");
   1.209 +    debugOut.appendS32(futureTime - maker.fDebugTimeBase);
   1.210 +    SkDebugf("%s\n", debugOut.c_str());
   1.211 +#endif
   1.212 +    SkEventSinkID targetID = fSinkID;
   1.213 +    bool isAnimatorEvent = true;
   1.214 +    SkAnimator* anim = maker.getAnimator();
   1.215 +    if (targetID == 0) {
   1.216 +        isAnimatorEvent = fEvent.findString("id") != NULL;
   1.217 +        if (isAnimatorEvent)
   1.218 +            targetID = anim->getSinkID();
   1.219 +        else if (maker.fHostEventSinkID)
   1.220 +            targetID = maker.fHostEventSinkID;
   1.221 +        else
   1.222 +            return true;
   1.223 +    } else
   1.224 +        anim = fTargetMaker->getAnimator();
   1.225 +    if (delay == 0) {
   1.226 +        if (isAnimatorEvent && mode == kImmediate)
   1.227 +            fTargetMaker->doEvent(fEvent);
   1.228 +        else
   1.229 +            anim->onEventPost(new SkEvent(fEvent), targetID);
   1.230 +    } else
   1.231 +        anim->onEventPostTime(new SkEvent(fEvent), targetID, futureTime);
   1.232 +    return true;
   1.233 +}
   1.234 +
   1.235 +void SkPost::findSinkID() {
   1.236 +    // get the next delimiter '.' if any
   1.237 +    fTargetMaker = fMaker;
   1.238 +    const char* ch = sink.c_str();
   1.239 +    do {
   1.240 +        const char* end = strchr(ch, '.');
   1.241 +        size_t len = end ? (size_t) (end - ch) : strlen(ch);
   1.242 +        SkDisplayable* displayable = NULL;
   1.243 +        if (SK_LITERAL_STR_EQUAL("parent", ch, len)) {
   1.244 +            if (fTargetMaker->fParentMaker)
   1.245 +                fTargetMaker = fTargetMaker->fParentMaker;
   1.246 +            else {
   1.247 +                fTargetMaker->setErrorCode(SkDisplayXMLParserError::kNoParentAvailable);
   1.248 +                return;
   1.249 +            }
   1.250 +        } else {
   1.251 +            fTargetMaker->find(ch, len, &displayable);
   1.252 +            if (displayable == NULL || displayable->getType() != SkType_Movie) {
   1.253 +                fTargetMaker->setErrorCode(SkDisplayXMLParserError::kExpectedMovie);
   1.254 +                return;
   1.255 +            }
   1.256 +            SkDisplayMovie* movie = (SkDisplayMovie*) displayable;
   1.257 +            fTargetMaker = movie->fMovie.fMaker;
   1.258 +        }
   1.259 +        if (end == NULL)
   1.260 +            break;
   1.261 +        ch = ++end;
   1.262 +    } while (true);
   1.263 +    SkAnimator* anim = fTargetMaker->getAnimator();
   1.264 +    fSinkID = anim->getSinkID();
   1.265 +}
   1.266 +
   1.267 +bool SkPost::hasEnable() const {
   1.268 +    return true;
   1.269 +}
   1.270 +
   1.271 +void SkPost::onEndElement(SkAnimateMaker& maker) {
   1.272 +    fTargetMaker = fMaker = &maker;
   1.273 +    if (fChildHasID == false) {
   1.274 +        for (SkDataInput** part = fParts.begin(); part < fParts.end();  part++)
   1.275 +            delete *part;
   1.276 +        fParts.reset();
   1.277 +    }
   1.278 +}
   1.279 +
   1.280 +void SkPost::setChildHasID() {
   1.281 +    fChildHasID = true;
   1.282 +}
   1.283 +
   1.284 +bool SkPost::setProperty(int index, SkScriptValue& value) {
   1.285 +    SkASSERT(value.fType == SkType_String);
   1.286 +    SkString* string = value.fOperand.fString;
   1.287 +    switch(index) {
   1.288 +        case SK_PROPERTY(target): {
   1.289 +            fEvent.setType("user");
   1.290 +            fEvent.setString("id", *string);
   1.291 +            mode = kImmediate;
   1.292 +            } break;
   1.293 +        case SK_PROPERTY(type):
   1.294 +            fEvent.setType(*string);
   1.295 +            break;
   1.296 +        default:
   1.297 +            SkASSERT(0);
   1.298 +            return false;
   1.299 +    }
   1.300 +    return true;
   1.301 +}

mercurial