Home | History | Annotate | Download | only in animator
      1 /* libs/graphics/animator/SkDisplayPost.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 "SkDisplayPost.h"
     19 #include "SkAnimateMaker.h"
     20 #include "SkAnimator.h"
     21 #include "SkDisplayMovie.h"
     22 #include "SkPostParts.h"
     23 #include "SkScript.h"
     24 #ifdef SK_DEBUG
     25 #include "SkDump.h"
     26 #include "SkTime.h"
     27 #endif
     28 
     29 enum SkPost_Properties {
     30     SK_PROPERTY(target),
     31     SK_PROPERTY(type)
     32 };
     33 
     34 #if SK_USE_CONDENSED_INFO == 0
     35 
     36 const SkMemberInfo SkPost::fInfo[] = {
     37     SK_MEMBER(delay, MSec),
     38 //  SK_MEMBER(initialized, Boolean),
     39     SK_MEMBER(mode, EventMode),
     40     SK_MEMBER(sink, String),
     41     SK_MEMBER_PROPERTY(target, String),
     42     SK_MEMBER_PROPERTY(type, String)
     43 };
     44 
     45 #endif
     46 
     47 DEFINE_GET_MEMBER(SkPost);
     48 
     49 SkPost::SkPost() : delay(0), /*initialized(SkBool(-1)), */ mode(kImmediate), fMaker(NULL),
     50     fSinkID(0), fTargetMaker(NULL), fChildHasID(false), fDirty(false) {
     51 }
     52 
     53 SkPost::~SkPost() {
     54     for (SkData** part = fParts.begin(); part < fParts.end();  part++)
     55         delete *part;
     56 }
     57 
     58 bool SkPost::add(SkAnimateMaker& , SkDisplayable* child) {
     59     SkASSERT(child && child->isData());
     60     SkData* part = (SkData*) child;
     61     *fParts.append() = part;
     62     return true;
     63 }
     64 
     65 bool SkPost::childrenNeedDisposing() const {
     66     return false;
     67 }
     68 
     69 void SkPost::dirty() {
     70     fDirty = true;
     71 }
     72 
     73 #ifdef SK_DUMP_ENABLED
     74 void SkPost::dump(SkAnimateMaker* maker) {
     75     dumpBase(maker);
     76     SkString* eventType = new SkString();
     77     fEvent.getType(eventType);
     78     if (eventType->equals("user")) {
     79         const char* target = fEvent.findString("id");
     80         SkDebugf("target=\"%s\" ", target);
     81     }
     82     else
     83         SkDebugf("type=\"%s\" ", eventType->c_str());
     84     delete eventType;
     85 
     86     if (delay > 0) {
     87 #ifdef SK_CAN_USE_FLOAT
     88         SkDebugf("delay=\"%g\" ", SkScalarToFloat(SkScalarDiv(delay, 1000)));
     89 #else
     90         SkDebugf("delay=\"%x\" ", SkScalarDiv(delay, 1000));
     91 #endif
     92     }
     93 //  if (initialized == false)
     94 //      SkDebugf("(uninitialized) ");
     95     SkString string;
     96     SkDump::GetEnumString(SkType_EventMode, mode, &string);
     97     if (!string.equals("immediate"))
     98         SkDebugf("mode=\"%s\" ", string.c_str());
     99     // !!! could enhance this to search through make hierarchy to show name of sink
    100     if (sink.size() > 0) {
    101         SkDebugf("sink=\"%s\" sinkID=\"%d\" ", sink.c_str(), fSinkID);
    102     } else if (fSinkID != maker->getAnimator()->getSinkID() && fSinkID != 0) {
    103         SkDebugf("sinkID=\"%d\" ", fSinkID);
    104     }
    105     const SkMetaData& meta = fEvent.getMetaData();
    106     SkMetaData::Iter iter(meta);
    107     SkMetaData::Type    type;
    108     int number;
    109     const char* name;
    110     bool closedYet = false;
    111     SkDisplayList::fIndent += 4;
    112     //this seems to work, but kinda hacky
    113     //for some reason the last part is id, which i don't want
    114     //and the parts seem to be in the reverse order from the one in which we find the
    115     //data itself
    116     //SkData** ptr = fParts.end();
    117     //SkData* data;
    118     //const char* ID;
    119     while ((name = iter.next(&type, &number)) != NULL) {
    120         //ptr--;
    121         if (strcmp(name, "id") == 0)
    122             continue;
    123         if (closedYet == false) {
    124             SkDebugf(">\n");
    125             closedYet = true;
    126         }
    127         //data = *ptr;
    128         //if (data->id)
    129         //    ID = data->id;
    130         //else
    131         //    ID = "";
    132         SkDebugf("%*s<data name=\"%s\" ", SkDisplayList::fIndent, "", name);
    133         switch (type) {
    134             case SkMetaData::kS32_Type: {
    135                 int32_t s32;
    136                 meta.findS32(name, &s32);
    137                 SkDebugf("int=\"%d\" ", s32);
    138                 } break;
    139             case SkMetaData::kScalar_Type: {
    140                 SkScalar scalar;
    141                 meta.findScalar(name, &scalar);
    142 #ifdef SK_CAN_USE_FLOAT
    143                 SkDebugf("float=\"%g\" ", SkScalarToFloat(scalar));
    144 #else
    145                 SkDebugf("float=\"%x\" ", scalar);
    146 #endif
    147                 } break;
    148             case SkMetaData::kString_Type:
    149                 SkDebugf("string=\"%s\" ", meta.findString(name));
    150                 break;
    151             case SkMetaData::kPtr_Type: {//when do we have a pointer
    152                     void* ptr;
    153                     meta.findPtr(name, &ptr);
    154                     SkDebugf("0x%08x ", ptr);
    155                 } break;
    156             case SkMetaData::kBool_Type: {
    157                 bool boolean;
    158                 meta.findBool(name, &boolean);
    159                 SkDebugf("boolean=\"%s\" ", boolean ? "true " : "false ");
    160                 } break;
    161             default:
    162                 break;
    163         }
    164         SkDebugf("/>\n");
    165         //ptr++;
    166 /*      perhaps this should only be done in the case of a pointer?
    167         SkDisplayable* displayable;
    168         if (maker->find(name, &displayable))
    169             displayable->dump(maker);
    170         else
    171             SkDebugf("\n");*/
    172     }
    173     SkDisplayList::fIndent -= 4;
    174     if (closedYet)
    175         dumpEnd(maker);
    176     else
    177         SkDebugf("/>\n");
    178 
    179 }
    180 #endif
    181 
    182 bool SkPost::enable(SkAnimateMaker& maker ) {
    183     if (maker.hasError())
    184         return true;
    185     if (fDirty) {
    186         if (sink.size() > 0)
    187             findSinkID();
    188         if (fChildHasID) {
    189             SkString preserveID(fEvent.findString("id"));
    190             fEvent.getMetaData().reset();
    191             if (preserveID.size() > 0)
    192                 fEvent.setString("id", preserveID);
    193             for (SkData** part = fParts.begin(); part < fParts.end();  part++) {
    194                 if ((*part)->add())
    195                     maker.setErrorCode(SkDisplayXMLParserError::kErrorAddingDataToPost);
    196             }
    197         }
    198         fDirty = false;
    199     }
    200 #ifdef SK_DUMP_ENABLED
    201     if (maker.fDumpPosts) {
    202         SkDebugf("post enable: ");
    203         dump(&maker);
    204     }
    205 #if defined SK_DEBUG_ANIMATION_TIMING
    206     SkString debugOut;
    207     SkMSec time = maker.getAppTime();
    208     debugOut.appendS32(time - maker.fDebugTimeBase);
    209     debugOut.append(" post id=");
    210     debugOut.append(_id);
    211     debugOut.append(" enable=");
    212     debugOut.appendS32(maker.fEnableTime - maker.fDebugTimeBase);
    213     debugOut.append(" delay=");
    214     debugOut.appendS32(delay);
    215 #endif
    216 #endif
    217 //  SkMSec adjustedDelay = maker.adjustDelay(maker.fEnableTime, delay);
    218     SkMSec futureTime = maker.fEnableTime + delay;
    219     fEvent.setFast32(futureTime);
    220 #if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
    221     debugOut.append(" future=");
    222     debugOut.appendS32(futureTime - maker.fDebugTimeBase);
    223     SkDebugf("%s\n", debugOut.c_str());
    224 #endif
    225     SkEventSinkID targetID = fSinkID;
    226     bool isAnimatorEvent = true;
    227     SkAnimator* anim = maker.getAnimator();
    228     if (targetID == 0) {
    229         isAnimatorEvent = fEvent.findString("id") != NULL;
    230         if (isAnimatorEvent)
    231             targetID = anim->getSinkID();
    232         else if (maker.fHostEventSinkID)
    233             targetID = maker.fHostEventSinkID;
    234         else
    235             return true;
    236     } else
    237         anim = fTargetMaker->getAnimator();
    238     if (delay == 0) {
    239         if (isAnimatorEvent && mode == kImmediate)
    240             fTargetMaker->doEvent(fEvent);
    241         else
    242             anim->onEventPost(new SkEvent(fEvent), targetID);
    243     } else
    244         anim->onEventPostTime(new SkEvent(fEvent), targetID, futureTime);
    245     return true;
    246 }
    247 
    248 void SkPost::findSinkID() {
    249     // get the next delimiter '.' if any
    250     fTargetMaker = fMaker;
    251     const char* ch = sink.c_str();
    252     do {
    253         const char* end = strchr(ch, '.');
    254         size_t len = end ? end - ch : strlen(ch);
    255         SkDisplayable* displayable = NULL;
    256         if (SK_LITERAL_STR_EQUAL("parent", ch, len)) {
    257             if (fTargetMaker->fParentMaker)
    258                 fTargetMaker = fTargetMaker->fParentMaker;
    259             else {
    260                 fTargetMaker->setErrorCode(SkDisplayXMLParserError::kNoParentAvailable);
    261                 return;
    262             }
    263         } else {
    264             fTargetMaker->find(ch, len, &displayable);
    265             if (displayable == NULL || displayable->getType() != SkType_Movie) {
    266                 fTargetMaker->setErrorCode(SkDisplayXMLParserError::kExpectedMovie);
    267                 return;
    268             }
    269             SkDisplayMovie* movie = (SkDisplayMovie*) displayable;
    270             fTargetMaker = movie->fMovie.fMaker;
    271         }
    272         if (end == NULL)
    273             break;
    274         ch = ++end;
    275     } while (true);
    276     SkAnimator* anim = fTargetMaker->getAnimator();
    277     fSinkID = anim->getSinkID();
    278 }
    279 
    280 bool SkPost::hasEnable() const {
    281     return true;
    282 }
    283 
    284 void SkPost::onEndElement(SkAnimateMaker& maker) {
    285     fTargetMaker = fMaker = &maker;
    286     if (fChildHasID == false) {
    287         for (SkData** part = fParts.begin(); part < fParts.end();  part++)
    288             delete *part;
    289         fParts.reset();
    290     }
    291 }
    292 
    293 void SkPost::setChildHasID() {
    294     fChildHasID = true;
    295 }
    296 
    297 bool SkPost::setProperty(int index, SkScriptValue& value) {
    298     SkASSERT(value.fType == SkType_String);
    299     SkString* string = value.fOperand.fString;
    300     switch(index) {
    301         case SK_PROPERTY(target): {
    302             fEvent.setType("user");
    303             fEvent.setString("id", *string);
    304             mode = kImmediate;
    305             } break;
    306         case SK_PROPERTY(type):
    307             fEvent.setType(*string);
    308             break;
    309         default:
    310             SkASSERT(0);
    311             return false;
    312     }
    313     return true;
    314 }
    315 
    316