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 +}