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; }
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); }
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); }
const SkMemberInfo* SkAnimator::getField(const SkDisplayable* ae, const char* field) { SkDisplayable* element = (SkDisplayable*) ae; const SkMemberInfo* info = element->getMember(field); return (const SkMemberInfo*) info; }
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; }
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; }