void SkApply::enableDynamic(SkAnimateMaker& maker) { SkASSERT(mode != kMode_create); // create + dynamic are not currently compatible SkDisplayable* newScope; bool success = SkAnimatorScript::EvaluateDisplayable(maker, this, dynamicScope.c_str(), &newScope); if (success && scope != newScope) { SkTDDrawableArray* pList, * gList; SkGroup* pGroup = NULL, * found = NULL; int old = maker.fDisplayList.findGroup(scope, &pList, &pGroup, &found, &gList); if (pList && old >= 0 && (*pList)[old]->isApply() && (*pList)[old] != this) { if (fAppended == false) { if (found != NULL) { SkDisplayable* oldChild = (*pList)[old]; if (oldChild->isApply() && found->copySet(old)) { found->markCopyClear(old); // delete oldChild; } } (*pList)[old] = scope; } else pList->remove(old); } scope = (SkDrawable*) newScope; onEndElement(maker); } maker.removeActive(fActive); delete fActive; fActive = NULL; }
void SkApply::endSave(int index) { SkAnimateBase* animate = fActive->fAnimators[index]; const SkMemberInfo* info = animate->fFieldInfo; SkDisplayTypes type = (SkDisplayTypes) info->fType; if (type == SkType_MemberFunction) return; SkDisplayable* target = getTarget(animate); size_t size = info->getSize(target); int count = (int) (size / sizeof(SkScalar)); int activeIndex = fActive->fDrawIndex + index; SkOperand* last = new SkOperand[count]; SkAutoTDelete<SkOperand> autoLast(last); if (type != SkType_MemberProperty) { info->getValue(target, last, count); SkOperand* saveOperand = fActive->fSaveRestore[activeIndex]; if (saveOperand) info->setValue(target, fActive->fSaveRestore[activeIndex], count); } else { SkScriptValue scriptValue; bool success = target->getProperty(info->propertyIndex(), &scriptValue); SkASSERT(success = true); last[0] = scriptValue.fOperand; scriptValue.fOperand = fActive->fSaveRestore[activeIndex][0]; target->setProperty(info->propertyIndex(), scriptValue); } SkOperand* save = fActive->fSaveRestore[activeIndex]; if (save) memcpy(save, last, count * sizeof(SkOperand)); }
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 SkHitTest::draw(SkAnimateMaker& maker) { hits.setCount(bullets.count()); value = false; int bulletCount = bullets.count(); int targetCount = targets.count(); for (int bIndex = 0; bIndex < bulletCount; bIndex++) { SkDisplayable* bullet = bullets[bIndex]; SkRect bBounds; bullet->getBounds(&bBounds); hits[bIndex] = -1; if (bBounds.fLeft == (int16_t)0x8000U) continue; for (int tIndex = 0; tIndex < targetCount; tIndex++) { SkDisplayable* target = targets[tIndex]; SkRect tBounds; target->getBounds(&tBounds); if (bBounds.intersect(tBounds)) { hits[bIndex] = tIndex; value = true; break; } } } return false; }
bool SkHitClear::enable(SkAnimateMaker& maker) { for (int tIndex = 0; tIndex < targets.count(); tIndex++) { SkDisplayable* target = targets[tIndex]; target->clearBounder(); } return true; }
bool SkAnimatorScript::EvalID(const char* token, size_t len, void* user, SkScriptValue* value) { SkAnimatorScript* engine = (SkAnimatorScript*) user; SkTDict<SkDisplayable*>* ids = &engine->fMaker.fIDs; SkDisplayable* displayable; bool success = ids->find(token, len, &displayable); if (success == false) { displayable = engine->fWorking; if (SK_LITERAL_STR_EQUAL("parent", token, len)) { SkDisplayable* parent = displayable->getParent(); if (parent == false) parent = engine->fParent; if (parent) { value->fOperand.fDisplayable = parent; value->fType = SkType_Displayable; return true; } } if (displayable && EvalMember(token, len, displayable, engine, value)) return true; value->fOperand.fString = NULL; value->fType = SkType_String; } else { SkDisplayable* working = engine->fWorking; value->fOperand.fDisplayable = displayable; value->fType = SkType_Displayable; if (displayable->canContainDependents() && working && working->isAnimate()) { SkAnimateBase* animator = (SkAnimateBase*) working; if (animator->isDynamic()) { SkDisplayDepend* depend = (SkDisplayDepend* ) displayable; depend->addDependent(working); } } } return true; }
SkDisplayable* SkDisplayEvent::contains(const SkString& match) { for (int index = 0; index < fChildren.count(); index++) { SkDisplayable* child = fChildren[index]; if (child->contains(match)) return child; } return NULL; }
void SkAnimateMaker::dump(const char* match) { SkTDict<SkDisplayable*>::Iter iter(fIDs); const char* name; SkDisplayable* result; while ((name = iter.next(&result)) != NULL) { if (strcmp(match,name) == 0) result->dump(this); } }
SkDisplayable* SkGroup::deepCopy(SkAnimateMaker* maker) { SkDisplayable* copy = INHERITED::deepCopy(maker); for (SkDrawable** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) { SkDisplayable* displayable = (SkDisplayable*)*ptr; SkDisplayable* deeperCopy = displayable->deepCopy(maker); ((SkGroup*)copy)->addChild(*maker, deeperCopy); } return copy; }
void SkAnimateMaker::loadMovies() { for (SkDisplayable** dispPtr = fMovies.begin(); dispPtr < fMovies.end(); dispPtr++) { SkDisplayable* displayable = *dispPtr; SkASSERT(displayable->getType() == SkType_Movie); SkDisplayMovie* movie = (SkDisplayMovie*) displayable; SkAnimateMaker* movieMaker = movie->fMovie.fMaker; movieMaker->fEvents.doEvent(*movieMaker, SkDisplayEvent::kOnload, NULL); movieMaker->fEvents.removeEvent(SkDisplayEvent::kOnload, NULL); movieMaker->loadMovies(); } }
bool SkHitTest::enable(SkAnimateMaker& maker) { for (int bIndex = 0; bIndex < bullets.count(); bIndex++) { SkDisplayable* bullet = bullets[bIndex]; bullet->enableBounder(); } for (int tIndex = 0; tIndex < targets.count(); tIndex++) { SkDisplayable* target = targets[tIndex]; target->enableBounder(); } return false; }
void SkAnimateMaker::doDelayedEvent() { fEnableTime = getAppTime(); for (int index = 0; index < fDelayed.count(); ) { SkDisplayable* child = fDelayed[index]; SkASSERT(child->isApply()); SkApply* apply = (SkApply*) child; apply->interpolate(*this, fEnableTime); if (apply->hasDelayedAnimator()) index++; else fDelayed.remove(index); } }
int SkAnimateMaker::dynamicProperty(SkString& nameStr, SkDisplayable** displayablePtr ) { const char* name = nameStr.c_str(); const char* dot = strchr(name, '.'); SkASSERT(dot); SkDisplayable* displayable; if (find(name, dot - name, &displayable) == false) { SkASSERT(0); return 0; } const char* fieldName = dot + 1; const SkMemberInfo* memberInfo = displayable->getMember(fieldName); *displayablePtr = displayable; return (int) memberInfo->fOffset; }
void SkDisplayEvent::populateInput(SkAnimateMaker& maker, const SkEvent& fEvent) { const SkMetaData& meta = fEvent.getMetaData(); SkMetaData::Iter iter(meta); SkMetaData::Type type; int number; const char* name; while ((name = iter.next(&type, &number)) != NULL) { if (name[0] == '\0') continue; SkDisplayable* displayable; SkInput* input; for (int index = 0; index < fChildren.count(); index++) { displayable = fChildren[index]; if (displayable->getType() != SkType_Input) continue; input = (SkInput*) displayable; if (input->name.equals(name)) goto found; } if (!maker.find(name, &displayable) || displayable->getType() != SkType_Input) continue; input = (SkInput*) displayable; found: switch (type) { case SkMetaData::kS32_Type: meta.findS32(name, &input->fInt); break; case SkMetaData::kScalar_Type: meta.findScalar(name, &input->fFloat); break; case SkMetaData::kPtr_Type: SkASSERT(0); break; // !!! not handled for now case SkMetaData::kString_Type: input->string.set(meta.findString(name)); break; default: SkASSERT(0); } } // re-evaluate all animators that may have built their values from input strings for (SkDisplayable** childPtr = fChildren.begin(); childPtr < fChildren.end(); childPtr++) { SkDisplayable* displayable = *childPtr; if (displayable->isApply() == false) continue; SkApply* apply = (SkApply*) displayable; apply->refresh(maker); } }
bool SkAnimatorScript::EvalMemberFunction(const char* member, size_t len, void* object, SkTDArray<SkScriptValue>& params, void* eng, SkScriptValue* value) { SkScriptEngine* engine = (SkScriptEngine*) eng; SkDisplayable* displayable = (SkDisplayable*) object; SkString name(member, len); const SkMemberInfo* info = displayable->getMember(name.c_str()); SkASSERT(info != NULL); /* !!! error handling unimplemented */ if (info->fType != SkType_MemberFunction) { SkASSERT(0); return false; } displayable->executeFunction(displayable, info->functionIndex(), params, info->getType(), value); return EvalMemberCommon(engine, info, displayable, value); }
void SkApply::applyValues(int animatorIndex, SkOperand* values, int count, SkDisplayTypes valuesType, SkMSec time) { SkAnimateBase* animator = fActive->fAnimators[animatorIndex]; const SkMemberInfo * info = animator->fFieldInfo; SkASSERT(animator); SkASSERT(info != NULL); SkDisplayTypes type = (SkDisplayTypes) info->fType; SkDisplayable* target = getTarget(animator); if (animator->hasExecute() || type == SkType_MemberFunction || type == SkType_MemberProperty) { SkDisplayable* executor = animator->hasExecute() ? animator : target; if (type != SkType_MemberProperty) { SkTDArray<SkScriptValue> typedValues; for (int index = 0; index < count; index++) { SkScriptValue temp; temp.fType = valuesType; temp.fOperand = values[index]; *typedValues.append() = temp; } executor->executeFunction(target, info->functionIndex(), typedValues, info->getType(), NULL); } else { SkScriptValue scriptValue; scriptValue.fOperand = values[0]; scriptValue.fType = info->getType(); target->setProperty(info->propertyIndex(), scriptValue); } } else { SkTypedArray converted; if (type == SkType_ARGB) { if (count == 4) { // !!! assert that it is SkType_Float ? animator->packARGB(&values->fScalar, count, &converted); values = converted.begin(); count = converted.count(); } else { SkASSERT(count == 1); } } // SkASSERT(type == SkType_ARGB || type == SkType_String ||info->isSettable()); if (type == SkType_String || type == SkType_DynamicString) info->setString(target, values->fString); else if (type == SkType_Drawable || type == SkType_Displayable) target->setReference(info, values->fDisplayable); else info->setValue(target, values, count); } }
void SkApply::save(int index) { SkAnimateBase* animate = fActive->fAnimators[index]; const SkMemberInfo * info = animate->fFieldInfo; SkDisplayable* target = getTarget(animate); // if (animate->hasExecute()) // info = animate->getResolvedInfo(); SkDisplayTypes type = (SkDisplayTypes) info->fType; if (type == SkType_MemberFunction) return; // nothing to save size_t size = info->getSize(target); int count = (int) (size / sizeof(SkScalar)); bool useLast = true; // !!! this all may be unneeded, at least in the dynamic case ?? int activeIndex = fActive->fDrawIndex + index; SkTDOperandArray last; if (fActive->fSaveRestore[activeIndex] == NULL) { fActive->fSaveRestore[activeIndex] = new SkOperand[count]; useLast = false; } else { last.setCount(count); memcpy(last.begin(), fActive->fSaveRestore[activeIndex], count * sizeof(SkOperand)); } if (type != SkType_MemberProperty) { info->getValue(target, fActive->fSaveRestore[activeIndex], count); if (useLast) info->setValue(target, last.begin(), count); } else { SkScriptValue scriptValue; bool success = target->getProperty(info->propertyIndex(), &scriptValue); SkASSERT(success == true); SkASSERT(scriptValue.fType == SkType_Float); fActive->fSaveRestore[activeIndex][0] = scriptValue.fOperand; if (useLast) { SkScriptValue scriptValue; scriptValue.fType = type; scriptValue.fOperand = last[0]; target->setProperty(info->propertyIndex(), scriptValue); } } // !!! end of unneeded }
bool SkAnimatorScript::EvalMember(const char* member, size_t len, void* object, void* eng, SkScriptValue* value) { SkScriptEngine* engine = (SkScriptEngine*) eng; SkDisplayable* displayable = (SkDisplayable*) object; SkString name(member, len); SkDisplayable* named = displayable->contains(name); if (named) { value->fOperand.fDisplayable = named; value->fType = SkType_Displayable; return true; } const SkMemberInfo* info = displayable->getMember(name.c_str()); if (info == NULL) return false; if (info->fType == SkType_MemberProperty) { if (displayable->getProperty(info->propertyIndex(), value) == false) { SkASSERT(0); return false; } } return EvalMemberCommon(engine, info, displayable, value); }
bool SkDisplayXMLParser::onEndElement(const char elem[]) { int parentIndex = fParents.count() - 1; if (parentIndex >= 0) { Parent& container = fParents[parentIndex]; SkDisplayable* displayable = container.fDisplayable; fMaker.fEndDepth = parentIndex; displayable->onEndElement(fMaker); if (fMaker.fError.hasError()) return true; if (parentIndex > 0) { SkDisplayable* parent = fParents[parentIndex - 1].fDisplayable; bool result = parent->add(fMaker, displayable); if (fMaker.hasError()) return true; if (result == false) { int infoCount; const SkMemberInfo* info = SkDisplayType::GetMembers(&fMaker, fParents[parentIndex - 1].fType, &infoCount); const SkMemberInfo* foundInfo; if ((foundInfo = searchContainer(info, infoCount)) != NULL) { parent->setReference(foundInfo, displayable); // if (displayable->isHelper() == false) fMaker.helperAdd(displayable); } else { fMaker.setErrorCode(SkDisplayXMLParserError::kElementTypeNotAllowedInParent); return true; } } if (parent->childrenNeedDisposing()) delete displayable; } fParents.remove(parentIndex); } fCurrDisplayable = NULL; if (fInInclude == false && strcasecmp(elem, "screenplay") == 0) { if (fMaker.fInMovie == false) { fMaker.fEnableTime = fMaker.getAppTime(); #if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING if (fMaker.fDebugTimeBase == (SkMSec) -1) fMaker.fDebugTimeBase = fMaker.fEnableTime; SkString debugOut; SkMSec time = fMaker.getAppTime(); debugOut.appendS32(time - fMaker.fDebugTimeBase); debugOut.append(" onLoad enable="); debugOut.appendS32(fMaker.fEnableTime - fMaker.fDebugTimeBase); SkDebugf("%s\n", debugOut.c_str()); #endif fMaker.fEvents.doEvent(fMaker, SkDisplayEvent::kOnload, NULL); if (fMaker.fError.hasError()) return true; fMaker.fEvents.removeEvent(SkDisplayEvent::kOnload, NULL); } fInSkia = false; } return false; }
bool SkAnimatorScript::Unbox(void* m, SkScriptValue* scriptValue) { SkAnimateMaker* maker = (SkAnimateMaker*) m; SkASSERT((unsigned) scriptValue->fType == (unsigned) SkType_Displayable); SkDisplayable* displayable = (SkDisplayable*) scriptValue->fOperand.fObject; SkDisplayTypes type = displayable->getType(); switch (displayable->getType()) { case SkType_Array: { SkDisplayArray* boxedValue = (SkDisplayArray*) displayable; scriptValue->fOperand.fArray = &boxedValue->values; } break; case SkType_Boolean: { SkDisplayBoolean* boxedValue = (SkDisplayBoolean*) displayable; scriptValue->fOperand.fS32 = boxedValue->value; } break; case SkType_Int: { SkDisplayInt* boxedValue = (SkDisplayInt*) displayable; scriptValue->fOperand.fS32 = boxedValue->value; } break; case SkType_Float: { SkDisplayFloat* boxedValue = (SkDisplayFloat*) displayable; scriptValue->fOperand.fScalar = boxedValue->value; } break; case SkType_String: { SkDisplayString* boxedValue = (SkDisplayString*) displayable; scriptValue->fOperand.fString = SkNEW_ARGS(SkString, (boxedValue->value)); } break; default: { const char* id = NULL; bool success = maker->findKey(displayable, &id); SkASSERT(success); scriptValue->fOperand.fString = SkNEW_ARGS(SkString, (id)); type = SkType_String; } } scriptValue->fType = type; return true; }
bool SkDisplayXMLParser::onStartElementLen(const char name[], size_t len) { fCurrDisplayable = NULL; // init so we'll ignore attributes if we exit early if (strncasecmp(name, "screenplay", len) == 0) { fInSkia = true; if (fInInclude == false) fMaker.idsSet(name, len, &fMaker.fScreenplay); return false; } if (fInSkia == false) return false; SkDisplayable* displayable = fMaker.createInstance(name, len); if (displayable == NULL) { fError->setNoun(name, len); fError->setCode(SkXMLParserError::kUnknownElement); return true; } SkDisplayTypes type = displayable->getType(); Parent record = { displayable, type }; *fParents.append() = record; if (fParents.count() == 1) fMaker.childrenAdd(displayable); else { Parent* parent = fParents.end() - 2; if (displayable->setParent(parent->fDisplayable)) { fError->setNoun(name, len); getError()->setCode(SkDisplayXMLParserError::kParentElementCantContain); return true; } } // set these for subsequent calls to addAttribute() fCurrDisplayable = displayable; fCurrType = type; return false; }
JSBool SkJSDisplayable::GetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { if (JSVAL_IS_INT(id) == 0) return JS_TRUE; SkJSDisplayable *p = (SkJSDisplayable *) JS_GetPrivate(cx, obj); SkDisplayable* displayable = p->fDisplayable; SkDisplayTypes displayableType = displayable->getType(); int members; const SkMemberInfo* info = SkDisplayType::GetMembers(NULL /* fMaker */, displayableType, &members); int idIndex = JSVAL_TO_INT(id); SkASSERT(idIndex >= 0 && idIndex < members); info = &info[idIndex]; SkDisplayTypes infoType = (SkDisplayTypes) info->fType; SkScalar scalar = 0; S32 s32 = 0; SkString* string= NULL; JSString *str; if (infoType == SkType_MemberProperty) { infoType = info->propertyType(); switch (infoType) { case SkType_Scalar: { SkScriptValue scriptValue; bool success = displayable->getProperty(info->propertyIndex(), &scriptValue); SkASSERT(scriptValue.fType == SkType_Scalar); scalar = scriptValue.fOperand.fScalar; } break; default: SkASSERT(0); // !!! unimplemented } } else { SkASSERT(info->fCount == 1); switch (infoType) { case SkType_Boolean: case SkType_Color: case SkType_S32: s32 = *(S32*) info->memberData(displayable); break; case SkType_String: info->getString(displayable, &string); break; case SkType_Scalar: SkOperand operand; info->getValue(displayable, &operand, 1); scalar = operand.fScalar; break; default: SkASSERT(0); // !!! unimplemented } } switch (infoType) { case SkType_Boolean: *vp = BOOLEAN_TO_JSVAL(s32); break; case SkType_Color: case SkType_S32: *vp = INT_TO_JSVAL(s32); break; case SkType_Scalar: if (SkScalarFraction(scalar) == 0) *vp = INT_TO_JSVAL(SkScalarFloor(scalar)); else #ifdef SK_SCALAR_IS_FLOAT *vp = DOUBLE_TO_JSVAL(scalar); #else *vp = DOUBLE_TO_JSVAL(scalar / 65536.0f ); #endif break; case SkType_String: str = JS_NewStringCopyN(cx, string->c_str(), string->size()); *vp = STRING_TO_JSVAL(str); break; default: SkASSERT(0); // !!! unimplemented } return JS_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; }
const SkMemberInfo* SkAnimator::getField(const SkDisplayable* ae, const char* field) { SkDisplayable* element = (SkDisplayable*) ae; const SkMemberInfo* info = element->getMember(field); return (const SkMemberInfo*) info; }
bool SkDisplayXMLParser::onAddAttributeLen(const char attrName[], const char attrValue[], size_t attrValueLen) { if (fCurrDisplayable == NULL) // this signals we should ignore attributes for this element return strncmp(attrName, "xmlns", sizeof("xmlns") - 1) != 0; SkDisplayable* displayable = fCurrDisplayable; SkDisplayTypes type = fCurrType; if (strcmp(attrName, "id") == 0) { if (fMaker.find(attrValue, attrValueLen, NULL)) { fError->setNoun(attrValue, attrValueLen); fError->setCode(SkXMLParserError::kDuplicateIDs); return true; } #ifdef SK_DEBUG displayable->_id.set(attrValue, attrValueLen); displayable->id = displayable->_id.c_str(); #endif fMaker.idsSet(attrValue, attrValueLen, displayable); int parentIndex = fParents.count() - 1; if (parentIndex > 0) { SkDisplayable* parent = fParents[parentIndex - 1].fDisplayable; parent->setChildHasID(); } return false; } const char* name = attrName; const SkMemberInfo* info = SkDisplayType::GetMember(&fMaker, type, &name); if (info == NULL) { fError->setNoun(name); fError->setCode(SkXMLParserError::kUnknownAttributeName); return true; } if (info->setValue(fMaker, NULL, 0, info->getCount(), displayable, info->getType(), attrValue, attrValueLen)) return false; if (fMaker.fError.hasError()) { fError->setNoun(attrValue, attrValueLen); return true; } SkDisplayable* ref = NULL; if (fMaker.find(attrValue, attrValueLen, &ref) == false) { ref = fMaker.createInstance(attrValue, attrValueLen); if (ref == NULL) { fError->setNoun(attrValue, attrValueLen); fError->setCode(SkXMLParserError::kErrorInAttributeValue); return true; } else fMaker.helperAdd(ref); } if (info->fType != SkType_MemberProperty) { fError->setNoun(name); fError->setCode(SkXMLParserError::kUnknownAttributeName); return true; } SkScriptValue scriptValue; scriptValue.fOperand.fDisplayable = ref; scriptValue.fType = ref->getType(); displayable->setProperty(info->propertyIndex(), scriptValue); return false; }
SkElementType SkAnimator::getElementType(const SkDisplayable* ae) { SkDisplayable* element = (SkDisplayable*) ae; const SkMemberInfo* info = SkDisplayType::GetMembers(fMaker, element->getType(), nullptr); return (SkElementType) SkDisplayType::Find(fMaker, info); }
JSBool SkJSDisplayable::SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { if (JSVAL_IS_INT(id) == 0) return JS_TRUE; SkJSDisplayable *p = (SkJSDisplayable *) JS_GetPrivate(cx, obj); SkDisplayable* displayable = p->fDisplayable; SkDisplayTypes displayableType = displayable->getType(); int members; const SkMemberInfo* info = SkDisplayType::GetMembers(NULL /* fMaker */, displayableType, &members); int idIndex = JSVAL_TO_INT(id); SkASSERT(idIndex >= 0 && idIndex < members); info = &info[idIndex]; SkDisplayTypes infoType = info->getType(); SkScalar scalar = 0; S32 s32 = 0; SkString string; JSString* str; jsval value = *vp; switch (infoType) { case SkType_Boolean: s32 = JSVAL_TO_BOOLEAN(value); break; case SkType_Color: case SkType_S32: s32 = JSVAL_TO_INT(value); break; case SkType_Scalar: if (JSVAL_IS_INT(value)) scalar = SkIntToScalar(JSVAL_TO_INT(value)); else { SkASSERT(JSVAL_IS_DOUBLE(value)); #ifdef SK_SCALAR_IS_FLOAT scalar = (float) *(double*) JSVAL_TO_DOUBLE(value); #else scalar = (SkFixed) (*(double*)JSVAL_TO_DOUBLE(value) * 65536.0); #endif } break; case SkType_String: str = JS_ValueToString(cx, value); string.set(JS_GetStringBytes(str)); break; default: SkASSERT(0); // !!! unimplemented } if (info->fType == SkType_MemberProperty) { switch (infoType) { case SkType_Scalar: { SkScriptValue scriptValue; scriptValue.fType = SkType_Scalar; scriptValue.fOperand.fScalar = scalar; displayable->setProperty(-1 - (int) info->fOffset, scriptValue); } break; default: SkASSERT(0); // !!! unimplemented } } else { SkASSERT(info->fCount == 1); switch (infoType) { case SkType_Boolean: case SkType_Color: case SkType_S32: s32 = *(S32*) ((const char*) displayable + info->fOffset); break; case SkType_String: info->setString(displayable, &string); break; case SkType_Scalar: SkOperand operand; operand.fScalar = scalar; info->setValue(displayable, &operand, 1); break; default: SkASSERT(0); // !!! unimplemented } } return JS_TRUE; }
bool SkAnimator::onEvent(const SkEvent& evt) { #ifdef SK_DEBUG SkAnimator* root = fMaker->getRoot(); if (root == NULL) root = this; if (root->isTrackingEvents()) root->eventDone(evt); #endif if (evt.isType(SK_EventType_OnEnd)) { SkEventState eventState; bool success = evt.findPtr("anim", (void**) &eventState.fDisplayable); SkASSERT(success); success = evt.findS32("time", (int32_t*) &fMaker->fEnableTime); SkASSERT(success); fMaker->fAdjustedStart = fMaker->getAppTime() - fMaker->fEnableTime; fMaker->fEvents.doEvent(*fMaker, SkDisplayEvent::kOnEnd, &eventState); fMaker->fAdjustedStart = 0; goto inval; } if (evt.isType(SK_EventType_Delay)) { fMaker->doDelayedEvent(); goto inval; } { const char* id = evt.findString("id"); if (id == NULL) return false; SkDisplayable** firstMovie = fMaker->fMovies.begin(); SkDisplayable** endMovie = fMaker->fMovies.end(); for (SkDisplayable** ptr = firstMovie; ptr < endMovie; ptr++) { SkDisplayMovie* movie = (SkDisplayMovie*) *ptr; movie->doEvent(evt); } { SkDisplayable* event; if (fMaker->find(id, &event) == false) return false; #if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING SkString debugOut; SkMSec realTime = fMaker->getAppTime(); debugOut.appendS32(realTime - fMaker->fDebugTimeBase); debugOut.append(" onEvent id="); debugOut.append(id); #endif SkMSec time = evt.getFast32(); if (time != 0) { SkMSec app = fMaker->getAppTime(); fMaker->setEnableTime(app, time); #if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING debugOut.append(" time="); debugOut.appendS32(time - fMaker->fDebugTimeBase); debugOut.append(" adjust="); debugOut.appendS32(fMaker->fAdjustedStart); #endif } #if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING SkDebugf("%s\n", debugOut.c_str()); #endif SkASSERT(event->isEvent()); SkDisplayEvent* displayEvent = (SkDisplayEvent*) event; displayEvent->populateInput(*fMaker, evt); displayEvent->enableEvent(*fMaker); } } inval: fMaker->notifyInval(); return true; }
void SkDisplayable::dumpAttrs(SkAnimateMaker* maker) { SkDisplayTypes type = getType(); if (type == SkType_Unknown) { //SkDebugf("/>\n"); return; } SkDisplayable* blankCopy = SkDisplayType::CreateInstance(maker, type); int index = -1; int propIndex = 0; const SkMemberInfo* info; const SkMemberInfo* blankInfo; SkScriptValue value; SkScriptValue blankValue; SkOperand values[2]; SkOperand blankValues[2]; do { info = this->getMember(++index); if (NULL == info) { //SkDebugf("\n"); break; } if (SkType_MemberProperty == info->fType) { if (getProperty(propIndex, &value)) { blankCopy->getProperty(propIndex, &blankValue); //last two are dummies dumpValues(info, value.fType, value.fOperand, blankValue.fOperand, value.fOperand, blankValue.fOperand); } propIndex++; continue; } if (SkDisplayType::IsDisplayable(maker, info->fType)) { continue; } if (info->fType == SkType_MemberFunction) continue; if (info->fType == SkType_Array) { SkTDOperandArray* array = (SkTDOperandArray*) info->memberData(this); int arrayCount; if (array == NULL || (arrayCount = array->count()) == 0) continue; SkDisplayTypes elementType; if (type == SkType_Array) { SkDisplayArray* dispArray = (SkDisplayArray*) this; elementType = dispArray->values.getType(); } else elementType = info->arrayType(); bool firstElem = true; SkDebugf("%s=\"[", info->fName); for (SkOperand* op = array->begin(); op < array->end(); op++) { if (!firstElem) SkDebugf(","); switch (elementType) { case SkType_Displayable: SkDebugf("%s", op->fDisplayable->id); break; case SkType_Int: SkDebugf("%d", op->fS32); break; case SkType_Float: #ifdef SK_CAN_USE_FLOAT SkDebugf("%g", SkScalarToFloat(op->fScalar)); #else SkDebugf("%x", op->fScalar); #endif break; case SkType_String: case SkType_DynamicString: SkDebugf("%s", op->fString->c_str()); break; default: break; } firstElem = false; } SkDebugf("]\" "); continue; } if (info->fType == SkType_String || info->fType == SkType_DynamicString) { SkString* string; info->getString(this, &string); if (string->isEmpty() == false) SkDebugf("%s=\"%s\"\t", info->fName, string->c_str()); continue; } blankInfo = blankCopy->getMember(index); int i = info->fCount; info->getValue(this, values, i); blankInfo->getValue(blankCopy, blankValues, i); dumpValues(info, info->fType, values[0], blankValues[0], values[1], blankValues[1]); } while (true); delete blankCopy; }
SkDisplayable* SkDisplayable::deepCopy(SkAnimateMaker* maker) { SkDisplayTypes type = getType(); if (type == SkType_Unknown) { SkASSERT(0); return NULL; } SkDisplayable* copy = SkDisplayType::CreateInstance(maker, type); int index = -1; int propIndex = 0; const SkMemberInfo* info; do { info = copy->getMember(++index); if (info == NULL) break; if (info->fType == SkType_MemberProperty) { SkScriptValue value; if (getProperty(propIndex, &value)) copy->setProperty(propIndex, value); propIndex++; continue; } if (info->fType == SkType_MemberFunction) continue; if (info->fType == SkType_Array) { SkTDOperandArray* array = (SkTDOperandArray*) info->memberData(this); int arrayCount; if (array == NULL || (arrayCount = array->count()) == 0) continue; SkTDOperandArray* copyArray = (SkTDOperandArray*) info->memberData(copy); copyArray->setCount(arrayCount); SkDisplayTypes elementType; if (type == SkType_Array) { SkDisplayArray* dispArray = (SkDisplayArray*) this; elementType = dispArray->values.getType(); } else elementType = info->arrayType(); size_t elementSize = SkMemberInfo::GetSize(elementType); size_t byteSize = elementSize * arrayCount; memcpy(copyArray->begin(), array->begin(), byteSize); continue; } if (SkDisplayType::IsDisplayable(maker, info->fType)) { SkDisplayable** displayable = (SkDisplayable**) info->memberData(this); if (*displayable == NULL || *displayable == (SkDisplayable*) -1) continue; SkDisplayable* deeper = (*displayable)->deepCopy(maker); info->setMemberData(copy, deeper, sizeof(deeper)); continue; } if (info->fType == SkType_String || info->fType == SkType_DynamicString) { SkString* string; info->getString(this, &string); info->setString(copy, string); continue; } void* data = info->memberData(this); size_t size = SkMemberInfo::GetSize(info->fType); info->setMemberData(copy, data, size); } while (true); copy->dirty(); return copy; }