| OLD | NEW |
| (Empty) |
| 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), fMa
ker(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 s
ink | |
| 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 fin
d 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::kErrorAddingData
ToPost); | |
| 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::kNoParentAva
ilable); | |
| 261 return; | |
| 262 } | |
| 263 } else { | |
| 264 fTargetMaker->find(ch, len, &displayable); | |
| 265 if (displayable == NULL || displayable->getType() != SkType_Movie) { | |
| 266 fTargetMaker->setErrorCode(SkDisplayXMLParserError::kExpectedMov
ie); | |
| 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 | |
| OLD | NEW |