bool SkDisplayEvent::enableEvent(SkAnimateMaker& maker) { maker.fActiveEvent = this; if (fChildren.count() == 0) return false; if (disable) return false; #ifdef SK_DUMP_ENABLED if (maker.fDumpEvents) { SkDebugf("enable: "); dumpEvent(&maker); } #endif SkDisplayList& displayList = maker.fDisplayList; for (int index = 0; index < fChildren.count(); index++) { SkDisplayable* displayable = fChildren[index]; if (displayable->isGroup()) { SkTDDrawableArray* parentList = displayList.getDrawList(); *parentList->append() = (SkADrawable*) displayable; // make it findable before children are enabled } if (displayable->enable(maker)) continue; if (maker.hasError()) return true; if (displayable->isDrawable() == false) return true; // error SkADrawable* drawable = (SkADrawable*) displayable; SkTDDrawableArray* parentList = displayList.getDrawList(); *parentList->append() = drawable; } return false; }
bool SkApply::enable(SkAnimateMaker& maker) { fEnabled = true; bool initialized = fActive != NULL; if (dynamicScope.size() > 0) enableDynamic(maker); if (maker.fError.hasError()) return false; int animators = fAnimators.count(); int index; for (index = 0; index < animators; index++) { SkAnimateBase* animator = fAnimators[index]; animator->fStart = maker.fEnableTime; animator->fResetPending = animator->fReset; } if (scope && scope->isApply()) ((SkApply*) scope)->setEmbedded(); /* if (mode == kMode_once) { if (scope) { activate(maker); interpolate(maker, maker.fEnableTime); inactivate(maker); } return true; }*/ if ((mode == kMode_immediate || mode == kMode_create) && scope == NULL) return false; // !!! error? bool enableMe = scope && (scope->hasEnable() || scope->isApply() || scope->isDrawable() == false); if (mode == kMode_immediate && enableMe || mode == kMode_create) activate(maker); // for non-drawables like post, prime them here if (mode == kMode_immediate && enableMe) fActive->enable(); if (mode == kMode_create && scope != NULL) { enableCreate(maker); return true; } if (mode == kMode_immediate) { return scope->isApply() || scope->isDrawable() == false; } refresh(maker); SkDisplayList& displayList = maker.fDisplayList; SkDrawable* drawable; #if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING SkString debugOut; SkMSec time = maker.getAppTime(); debugOut.appendS32(time - maker.fDebugTimeBase); debugOut.append(" apply enable id="); debugOut.append(_id); debugOut.append("; start="); debugOut.appendS32(maker.fEnableTime - maker.fDebugTimeBase); SkDebugf("%s\n", debugOut.c_str()); #endif if (scope == NULL || scope->isApply() || scope->getType() == SkType_Movie || scope->isDrawable() == false) { activate(maker); // for non-drawables like post, prime them here if (initialized) { append(this); } fEnabling = true; interpolate(maker, maker.fEnableTime); fEnabling = false; if (scope != NULL && dontDraw == false) scope->enable(maker); return true; } else if (initialized && restore == false) append(this); #if 0 bool wasActive = inactivate(maker); // start fresh if (wasActive) { activate(maker); interpolate(maker, maker.fEnableTime); return true; } #endif // start here; // now that one apply might embed another, only the parent apply should replace the scope // or get appended to the display list // similarly, an apply added by an add immediate has already been located in the display list // and should not get moved or added again here if (fEmbedded) { return false; // already added to display list by embedder } drawable = (SkDrawable*) scope; SkTDDrawableArray* parentList; SkTDDrawableArray* grandList; SkGroup* parentGroup; SkGroup* thisGroup; int old = displayList.findGroup(drawable, &parentList, &parentGroup, &thisGroup, &grandList); if (old < 0) goto append; else if (fContainsScope) { if ((*parentList)[old] != this || restore == true) { append: if (parentGroup) parentGroup->markCopySize(old); if (parentList->count() < 10000) { fAppended = true; *parentList->append() = this; } else maker.setErrorCode(SkDisplayXMLParserError::kDisplayTreeTooDeep); old = -1; } else reset(); } else { SkASSERT(old < parentList->count()); if ((*parentList)[old]->isApply()) { SkApply* apply = (SkApply*) (*parentList)[old]; if (apply != this && apply->fActive == NULL) apply->activate(maker); apply->append(this); parentGroup = NULL; } else { if (parentGroup) parentGroup->markCopySize(old); SkDrawable** newApplyLocation = &(*parentList)[old]; SkGroup* pGroup; int oldApply = displayList.findGroup(this, &parentList, &pGroup, &thisGroup, &grandList); if (oldApply >= 0) { (*parentList)[oldApply] = (SkDrawable*) SkDisplayType::CreateInstance(&maker, SkType_Apply); parentGroup = NULL; fDeleteScope = true; } *newApplyLocation = this; } } if (parentGroup) { parentGroup->markCopySet(old); fDeleteScope = dynamicScope.size() == 0; } return true; }
bool SkAdd::enable(SkAnimateMaker& maker ) { SkDisplayTypes type = getType(); SkDisplayList& displayList = maker.fDisplayList; SkTDDrawableArray* parentList = displayList.getDrawList(); if (type == SkType_Add) { if (use == NULL) // not set in apply yet return true; } bool skipAddToParent = true; SkASSERT(type != SkType_Replace || where); SkTDDrawableArray* grandList SK_INIT_TO_AVOID_WARNING; SkGroup* parentGroup = NULL; SkGroup* thisGroup = NULL; int index = where ? displayList.findGroup(where, &parentList, &parentGroup, &thisGroup, &grandList) : 0; if (index < 0) return true; int max = parentList->count(); if (where == NULL && type == SkType_Move) index = max; if (offset != SK_MaxS32) { index += offset; if (index > max) { maker.setErrorCode(SkDisplayXMLParserError::kIndexOutOfRange); return true; // caller should not add } } if (offset < 0 && where == NULL) index += max + 1; switch (type) { case SkType_Add: if (offset == SK_MaxS32 && where == NULL) { if (use->isDrawable()) { skipAddToParent = mode == kMode_immediate; if (skipAddToParent) { if (where == NULL) { SkTDDrawableArray* useParentList; index = displayList.findGroup(this, &useParentList, &parentGroup, &thisGroup, &grandList); if (index >= 0) { parentGroup->markCopySize(index); parentGroup->markCopySet(index); useParentList->begin()[index] = use; break; } } *parentList->append() = use; } } break; } else { if (thisGroup) thisGroup->markCopySize(index); *parentList->insert(index) = use; if (thisGroup) thisGroup->markCopySet(index); if (use->isApply()) ((SkApply*) use)->setEmbedded(); } break; case SkType_Move: { int priorLocation = parentList->find(use); if (priorLocation < 0) break; *parentList->insert(index) = use; if (index < priorLocation) priorLocation++; parentList->remove(priorLocation); } break; case SkType_Remove: { SkDisplayable* old = (*parentList)[index]; if (((SkRemove*)(this))->fDelete) { delete old; goto noHelperNeeded; } for (int inner = 0; inner < maker.fChildren.count(); inner++) { SkDisplayable* child = maker.fChildren[inner]; if (child == old || child->contains(old)) goto noHelperNeeded; } if (maker.fHelpers.find(old) < 0) maker.helperAdd(old); noHelperNeeded: parentList->remove(index); } break; case SkType_Replace: if (thisGroup) { thisGroup->markCopySize(index); if (thisGroup->markedForDelete(index)) { SkDisplayable* old = (*parentList)[index]; if (maker.fHelpers.find(old) < 0) maker.helperAdd(old); } } (*parentList)[index] = use; if (thisGroup) thisGroup->markCopySet(index); break; default: SkASSERT(0); } if (type == SkType_Remove) return true; if (use->hasEnable()) use->enable(maker); return skipAddToParent; // append if indirect: *parentList->append() = this; }