gfx/skia/trunk/src/animator/SkAnimator.cpp

Wed, 31 Dec 2014 07:53:36 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:53:36 +0100
branch
TOR_BUG_3246
changeset 5
4ab42b5ab56c
permissions
-rw-r--r--

Correct small whitespace inconsistency, lost while renaming variables.

michael@0 1
michael@0 2 /*
michael@0 3 * Copyright 2006 The Android Open Source Project
michael@0 4 *
michael@0 5 * Use of this source code is governed by a BSD-style license that can be
michael@0 6 * found in the LICENSE file.
michael@0 7 */
michael@0 8
michael@0 9
michael@0 10 #include "SkAnimator.h"
michael@0 11 #include "SkAnimateMaker.h"
michael@0 12 #include "SkCanvas.h"
michael@0 13 #include "SkDisplayApply.h"
michael@0 14 #include "SkDisplayMovie.h"
michael@0 15 #include "SkDisplayTypes.h"
michael@0 16 #include "SkDisplayXMLParser.h"
michael@0 17 #include "SkStream.h"
michael@0 18 #include "SkScript.h"
michael@0 19 #include "SkScript2.h" // compiled script experiment
michael@0 20 #include "SkSystemEventTypes.h"
michael@0 21 #include "SkTypedArray.h"
michael@0 22 #ifdef SK_BUILD_FOR_ANDROID
michael@0 23 #include "SkDrawExtraPathEffect.h"
michael@0 24 #endif
michael@0 25 #ifdef SK_DEBUG
michael@0 26 #include "SkTime.h"
michael@0 27 #endif
michael@0 28
michael@0 29 #if defined SK_BUILD_FOR_WIN32 && defined SK_DEBUG
michael@0 30 #define _static
michael@0 31 extern const char gMathPrimerText[];
michael@0 32 extern const char gMathPrimerBinary[];
michael@0 33 #else
michael@0 34 #define _static static
michael@0 35 #endif
michael@0 36
michael@0 37 _static const char gMathPrimerText[] =
michael@0 38 "<screenplay>"
michael@0 39 "<Math id=\"Math\"/>"
michael@0 40 "<Number id=\"Number\"/>"
michael@0 41 "</screenplay>";
michael@0 42
michael@0 43 #define gMathPrimer gMathPrimerText
michael@0 44
michael@0 45 SkAnimator::SkAnimator() : fMaker(NULL) {
michael@0 46 initialize();
michael@0 47 }
michael@0 48
michael@0 49 SkAnimator::~SkAnimator() {
michael@0 50 SkDELETE(fMaker);
michael@0 51 }
michael@0 52
michael@0 53 void SkAnimator::addExtras(SkExtras* extras) {
michael@0 54 *fMaker->fExtras.append() = extras;
michael@0 55 }
michael@0 56
michael@0 57 bool SkAnimator::appendStream(SkStream* stream) {
michael@0 58 return decodeStream(stream);
michael@0 59 }
michael@0 60
michael@0 61 bool SkAnimator::decodeMemory(const void* buffer, size_t size)
michael@0 62 {
michael@0 63 fMaker->fFileName.reset();
michael@0 64 SkDisplayXMLParser parser(*fMaker);
michael@0 65 return parser.parse((const char*)buffer, size);
michael@0 66 }
michael@0 67
michael@0 68 bool SkAnimator::decodeStream(SkStream* stream)
michael@0 69 {
michael@0 70 SkDisplayXMLParser parser(*fMaker);
michael@0 71 bool result = parser.parse(*stream);
michael@0 72 fMaker->setErrorString();
michael@0 73 return result;
michael@0 74 }
michael@0 75
michael@0 76 bool SkAnimator::decodeDOM(const SkDOM& dom, const SkDOMNode* node)
michael@0 77 {
michael@0 78 fMaker->fFileName.reset();
michael@0 79 SkDisplayXMLParser parser(*fMaker);
michael@0 80 return parser.parse(dom, node);
michael@0 81 }
michael@0 82
michael@0 83 bool SkAnimator::decodeURI(const char uri[]) {
michael@0 84 // SkDebugf("animator decode %s\n", uri);
michael@0 85
michael@0 86 // SkStream* stream = SkStream::GetURIStream(fMaker->fPrefix.c_str(), uri);
michael@0 87 SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(uri));
michael@0 88 if (stream.get()) {
michael@0 89 this->setURIBase(uri);
michael@0 90 return decodeStream(stream);
michael@0 91 } else {
michael@0 92 return false;
michael@0 93 }
michael@0 94 }
michael@0 95
michael@0 96 bool SkAnimator::doCharEvent(SkUnichar code) {
michael@0 97 if (code == 0)
michael@0 98 return false;
michael@0 99 struct SkEventState state;
michael@0 100 state.fCode = code;
michael@0 101 fMaker->fEnableTime = fMaker->getAppTime();
michael@0 102 bool result = fMaker->fEvents.doEvent(*fMaker, SkDisplayEvent::kKeyChar, &state);
michael@0 103 fMaker->notifyInval();
michael@0 104 return result;
michael@0 105 }
michael@0 106
michael@0 107 bool SkAnimator::doClickEvent(int clickState, SkScalar x, SkScalar y) {
michael@0 108 SkASSERT(clickState >= 0 && clickState <= 2);
michael@0 109 struct SkEventState state;
michael@0 110 state.fX = x;
michael@0 111 state.fY = y;
michael@0 112 fMaker->fEnableTime = fMaker->getAppTime();
michael@0 113 bool result = fMaker->fEvents.doEvent(*fMaker,
michael@0 114 clickState == 0 ? SkDisplayEvent::kMouseDown :
michael@0 115 clickState == 1 ? SkDisplayEvent::kMouseDrag :
michael@0 116 SkDisplayEvent::kMouseUp, &state);
michael@0 117 fMaker->notifyInval();
michael@0 118 return result;
michael@0 119 }
michael@0 120
michael@0 121 bool SkAnimator::doKeyEvent(SkKey code) {
michael@0 122 if (code == 0)
michael@0 123 return false;
michael@0 124 struct SkEventState state;
michael@0 125 state.fCode = code;
michael@0 126 fMaker->fEnableTime = fMaker->getAppTime();
michael@0 127 bool result = fMaker->fEvents.doEvent(*fMaker, SkDisplayEvent::kKeyPress, &state);
michael@0 128 fMaker->notifyInval();
michael@0 129 return result;
michael@0 130 }
michael@0 131
michael@0 132 bool SkAnimator::doKeyUpEvent(SkKey code) {
michael@0 133 if (code == 0)
michael@0 134 return false;
michael@0 135 struct SkEventState state;
michael@0 136 state.fCode = code;
michael@0 137 fMaker->fEnableTime = fMaker->getAppTime();
michael@0 138 bool result = fMaker->fEvents.doEvent(*fMaker, SkDisplayEvent::kKeyPressUp, &state);
michael@0 139 fMaker->notifyInval();
michael@0 140 return result;
michael@0 141 }
michael@0 142
michael@0 143 bool SkAnimator::doUserEvent(const SkEvent& evt) {
michael@0 144 fMaker->fEnableTime = fMaker->getAppTime();
michael@0 145 return onEvent(evt);
michael@0 146 }
michael@0 147
michael@0 148 SkAnimator::DifferenceType SkAnimator::draw(SkCanvas* canvas, SkPaint* paint, SkMSec time) {
michael@0 149 if (paint == NULL)
michael@0 150 return draw(canvas, time);
michael@0 151 fMaker->fScreenplay.time = time;
michael@0 152 fMaker->fCanvas = canvas;
michael@0 153 fMaker->fPaint = paint;
michael@0 154 fMaker->fDisplayList.fHasUnion = false;
michael@0 155 int result = fMaker->fDisplayList.draw(*fMaker, time);
michael@0 156 if (result)
michael@0 157 result += fMaker->fDisplayList.fHasUnion;
michael@0 158 return (DifferenceType) result;
michael@0 159 }
michael@0 160
michael@0 161 SkAnimator::DifferenceType SkAnimator::draw(SkCanvas* canvas, SkMSec time) {
michael@0 162 SkPaint paint;
michael@0 163 return draw(canvas, &paint, time);
michael@0 164 }
michael@0 165
michael@0 166 #ifdef SK_DEBUG
michael@0 167 void SkAnimator::eventDone(const SkEvent& ) {
michael@0 168 }
michael@0 169 #endif
michael@0 170
michael@0 171 bool SkAnimator::findClickEvent(SkScalar x, SkScalar y) {
michael@0 172 struct SkEventState state;
michael@0 173 state.fDisable = true;
michael@0 174 state.fX = x;
michael@0 175 state.fY = y;
michael@0 176 fMaker->fEnableTime = fMaker->getAppTime();
michael@0 177 bool result = fMaker->fEvents.doEvent(*fMaker, SkDisplayEvent::kMouseDown, &state);
michael@0 178 fMaker->notifyInval();
michael@0 179 return result;
michael@0 180 }
michael@0 181
michael@0 182 const SkAnimator* SkAnimator::getAnimator(const SkDisplayable* displayable) const {
michael@0 183 if (displayable->getType() != SkType_Movie)
michael@0 184 return NULL;
michael@0 185 const SkDisplayMovie* movie = (const SkDisplayMovie*) displayable;
michael@0 186 return movie->getAnimator();
michael@0 187 }
michael@0 188
michael@0 189 const SkDisplayable* SkAnimator::getElement(const char* id) {
michael@0 190 SkDisplayable* element;
michael@0 191 if (fMaker->find(id, &element) == false)
michael@0 192 return NULL;
michael@0 193 return (const SkDisplayable*) element;
michael@0 194 }
michael@0 195
michael@0 196 SkElementType SkAnimator::getElementType(const SkDisplayable* ae) {
michael@0 197 SkDisplayable* element = (SkDisplayable*) ae;
michael@0 198 const SkMemberInfo* info = SkDisplayType::GetMembers(fMaker, element->getType(), NULL);
michael@0 199 return (SkElementType) SkDisplayType::Find(fMaker, info);
michael@0 200 }
michael@0 201
michael@0 202 SkElementType SkAnimator::getElementType(const char* id) {
michael@0 203 const SkDisplayable* element = getElement(id);
michael@0 204 return getElementType(element);
michael@0 205 }
michael@0 206
michael@0 207 const SkMemberInfo* SkAnimator::getField(const SkDisplayable* ae, const char* field) {
michael@0 208 SkDisplayable* element = (SkDisplayable*) ae;
michael@0 209 const SkMemberInfo* info = element->getMember(field);
michael@0 210 return (const SkMemberInfo*) info;
michael@0 211 }
michael@0 212
michael@0 213 const SkMemberInfo* SkAnimator::getField(const char* elementID, const char* field) {
michael@0 214 const SkDisplayable* element = getElement(elementID);
michael@0 215 return getField(element, field);
michael@0 216 }
michael@0 217
michael@0 218 SkFieldType SkAnimator::getFieldType(const SkMemberInfo* ai) {
michael@0 219 const SkMemberInfo* info = (const SkMemberInfo*) ai;
michael@0 220 return (SkFieldType) info->getType();
michael@0 221 }
michael@0 222
michael@0 223 SkFieldType SkAnimator::getFieldType(const char* id, const char* fieldID) {
michael@0 224 const SkMemberInfo* field = getField(id, fieldID);
michael@0 225 return getFieldType(field);
michael@0 226 }
michael@0 227
michael@0 228 static bool getArrayCommon(const SkDisplayable* ae, const SkMemberInfo* ai,
michael@0 229 int index, SkOperand* operand) {
michael@0 230 const SkDisplayable* element = (const SkDisplayable*) ae;
michael@0 231 const SkMemberInfo* info = (const SkMemberInfo*) ai;
michael@0 232 SkASSERT(info->fType == SkType_Array);
michael@0 233 return info->getArrayValue(element, index, operand);
michael@0 234 }
michael@0 235
michael@0 236 int32_t SkAnimator::getArrayInt(const SkDisplayable* ae,
michael@0 237 const SkMemberInfo* ai, int index) {
michael@0 238 SkOperand operand;
michael@0 239 bool result = getArrayCommon(ae, ai, index, &operand);
michael@0 240 return result ? operand.fS32 : SK_NaN32;
michael@0 241 }
michael@0 242
michael@0 243 int32_t SkAnimator::getArrayInt(const char* id, const char* fieldID, int index) {
michael@0 244 const SkDisplayable* element = getElement(id);
michael@0 245 if (element == NULL)
michael@0 246 return SK_NaN32;
michael@0 247 const SkMemberInfo* field = getField(element, fieldID);
michael@0 248 if (field == NULL)
michael@0 249 return SK_NaN32;
michael@0 250 return getArrayInt(element, field, index);
michael@0 251 }
michael@0 252
michael@0 253 SkScalar SkAnimator::getArrayScalar(const SkDisplayable* ae,
michael@0 254 const SkMemberInfo* ai, int index) {
michael@0 255 SkOperand operand;
michael@0 256 bool result = getArrayCommon(ae, ai, index, &operand);
michael@0 257 return result ? operand.fScalar : SK_ScalarNaN;
michael@0 258 }
michael@0 259
michael@0 260 SkScalar SkAnimator::getArrayScalar(const char* id, const char* fieldID, int index) {
michael@0 261 const SkDisplayable* element = getElement(id);
michael@0 262 if (element == NULL)
michael@0 263 return SK_ScalarNaN;
michael@0 264 const SkMemberInfo* field = getField(element, fieldID);
michael@0 265 if (field == NULL)
michael@0 266 return SK_ScalarNaN;
michael@0 267 return getArrayScalar(element, field, index);
michael@0 268 }
michael@0 269
michael@0 270 const char* SkAnimator::getArrayString(const SkDisplayable* ae,
michael@0 271 const SkMemberInfo* ai, int index) {
michael@0 272 SkOperand operand;
michael@0 273 bool result = getArrayCommon(ae, ai, index, &operand);
michael@0 274 return result ? operand.fString->c_str() : NULL;
michael@0 275 }
michael@0 276
michael@0 277 const char* SkAnimator::getArrayString(const char* id, const char* fieldID, int index) {
michael@0 278 const SkDisplayable* element = getElement(id);
michael@0 279 if (element == NULL)
michael@0 280 return NULL;
michael@0 281 const SkMemberInfo* field = getField(element, fieldID);
michael@0 282 if (field == NULL)
michael@0 283 return NULL;
michael@0 284 return getArrayString(element, field, index);
michael@0 285 }
michael@0 286
michael@0 287 SkMSec SkAnimator::getInterval() {
michael@0 288 return fMaker->fMinimumInterval == (SkMSec) -1 ? 0 : fMaker->fMinimumInterval;
michael@0 289 }
michael@0 290
michael@0 291 void SkAnimator::getInvalBounds(SkRect* inval) {
michael@0 292 if (fMaker->fDisplayList.fHasUnion) {
michael@0 293 inval->fLeft = SkIntToScalar(fMaker->fDisplayList.fInvalBounds.fLeft);
michael@0 294 inval->fTop = SkIntToScalar(fMaker->fDisplayList.fInvalBounds.fTop);
michael@0 295 inval->fRight = SkIntToScalar(fMaker->fDisplayList.fInvalBounds.fRight);
michael@0 296 inval->fBottom = SkIntToScalar(fMaker->fDisplayList.fInvalBounds.fBottom);
michael@0 297 } else {
michael@0 298 inval->fLeft = inval->fTop = -SK_ScalarMax;
michael@0 299 inval->fRight = inval->fBottom = SK_ScalarMax;
michael@0 300 }
michael@0 301 }
michael@0 302
michael@0 303 const SkXMLParserError* SkAnimator::getParserError() {
michael@0 304 return &fMaker->fError;
michael@0 305 }
michael@0 306
michael@0 307 const char* SkAnimator::getParserErrorString() {
michael@0 308 if (fMaker->fErrorString.size() == 0 && fMaker->fError.hasError())
michael@0 309 fMaker->setErrorString();
michael@0 310 return fMaker->fErrorString.c_str();
michael@0 311 }
michael@0 312
michael@0 313 int32_t SkAnimator::getInt(const SkDisplayable* element, const SkMemberInfo* info) {
michael@0 314 if (info->fType != SkType_MemberProperty) {
michael@0 315 SkOperand operand;
michael@0 316 if (info->getType() == SkType_Int) {
michael@0 317 info->getValue(element, &operand, 1);
michael@0 318 return operand.fS32;
michael@0 319 }
michael@0 320 return SK_NaN32;
michael@0 321 }
michael@0 322 SkScriptValue scriptValue;
michael@0 323 bool success = element->getProperty(info->propertyIndex(), &scriptValue);
michael@0 324 if (success && scriptValue.fType == SkType_Int)
michael@0 325 return scriptValue.fOperand.fS32;
michael@0 326 return SK_NaN32;
michael@0 327 }
michael@0 328
michael@0 329 int32_t SkAnimator::getInt(const char* id, const char* fieldID) {
michael@0 330 const SkDisplayable* element = getElement(id);
michael@0 331 if (element == NULL)
michael@0 332 return SK_NaN32;
michael@0 333 const SkMemberInfo* field = getField(element, fieldID);
michael@0 334 if (field == NULL)
michael@0 335 return SK_NaN32;
michael@0 336 return getInt(element, field);
michael@0 337 }
michael@0 338
michael@0 339 SkScalar SkAnimator::getScalar(const SkDisplayable* element, const SkMemberInfo* info) {
michael@0 340 if (info->fType != SkType_MemberProperty) {
michael@0 341 SkOperand operand;
michael@0 342 if (info->getType() == SkType_Float) {
michael@0 343 info->getValue(element, &operand, 1);
michael@0 344 return operand.fScalar;
michael@0 345 }
michael@0 346 return SK_ScalarNaN;
michael@0 347 }
michael@0 348 SkScriptValue scriptValue;
michael@0 349 bool success = element->getProperty(info->propertyIndex(), &scriptValue);
michael@0 350 if (success && scriptValue.fType == SkType_Float)
michael@0 351 return scriptValue.fOperand.fScalar;
michael@0 352 return SK_ScalarNaN;
michael@0 353 }
michael@0 354
michael@0 355 SkScalar SkAnimator::getScalar(const char* id, const char* fieldID) {
michael@0 356 const SkDisplayable* element = getElement(id);
michael@0 357 if (element == NULL)
michael@0 358 return SK_ScalarNaN;
michael@0 359 const SkMemberInfo* field = getField(element, fieldID);
michael@0 360 if (field == NULL)
michael@0 361 return SK_ScalarNaN;
michael@0 362 return getScalar(element, field);
michael@0 363 }
michael@0 364
michael@0 365 const char* SkAnimator::getString(const SkDisplayable* ae,
michael@0 366 const SkMemberInfo* ai) {
michael@0 367 const SkDisplayable* element = (const SkDisplayable*) ae;
michael@0 368 const SkMemberInfo* info = (const SkMemberInfo*) ai;
michael@0 369 SkString* temp;
michael@0 370 info->getString(element, &temp);
michael@0 371 return temp->c_str();
michael@0 372 }
michael@0 373
michael@0 374 const char* SkAnimator::getString(const char* id, const char* fieldID) {
michael@0 375 const SkDisplayable* element = getElement(id);
michael@0 376 if (element == NULL)
michael@0 377 return NULL;
michael@0 378 const SkMemberInfo* field = getField(element, fieldID);
michael@0 379 if (field == NULL)
michael@0 380 return NULL;
michael@0 381 return getString(element, field);
michael@0 382 }
michael@0 383
michael@0 384 const char* SkAnimator::getURIBase() {
michael@0 385 return fMaker->fPrefix.c_str();
michael@0 386 }
michael@0 387
michael@0 388 void SkAnimator::initialize() {
michael@0 389 SkDELETE(fMaker);
michael@0 390 fMaker = SkNEW_ARGS(SkAnimateMaker, (this, NULL, NULL));
michael@0 391 decodeMemory(gMathPrimer, sizeof(gMathPrimer)-1);
michael@0 392 #ifdef SK_BUILD_FOR_ANDROID
michael@0 393 InitializeSkExtraPathEffects(this);
michael@0 394 #endif
michael@0 395 }
michael@0 396
michael@0 397
michael@0 398 #ifdef SK_DEBUG
michael@0 399 bool SkAnimator::isTrackingEvents() {
michael@0 400 return false;
michael@0 401 }
michael@0 402 #endif
michael@0 403
michael@0 404 bool SkAnimator::onEvent(const SkEvent& evt) {
michael@0 405 #ifdef SK_DEBUG
michael@0 406 SkAnimator* root = fMaker->getRoot();
michael@0 407 if (root == NULL)
michael@0 408 root = this;
michael@0 409 if (root->isTrackingEvents())
michael@0 410 root->eventDone(evt);
michael@0 411 #endif
michael@0 412 if (evt.isType(SK_EventType_OnEnd)) {
michael@0 413 SkEventState eventState;
michael@0 414 SkDEBUGCODE(bool success =) evt.findPtr("anim", (void**) &eventState.fDisplayable);
michael@0 415 SkASSERT(success);
michael@0 416 SkDEBUGCODE(success =) evt.findS32("time", (int32_t*) &fMaker->fEnableTime);
michael@0 417 SkASSERT(success);
michael@0 418 fMaker->fAdjustedStart = fMaker->getAppTime() - fMaker->fEnableTime;
michael@0 419 fMaker->fEvents.doEvent(*fMaker, SkDisplayEvent::kOnEnd, &eventState);
michael@0 420 fMaker->fAdjustedStart = 0;
michael@0 421 goto inval;
michael@0 422 }
michael@0 423 if (evt.isType(SK_EventType_Delay)) {
michael@0 424 fMaker->doDelayedEvent();
michael@0 425 goto inval;
michael@0 426 }
michael@0 427 {
michael@0 428 const char* id = evt.findString("id");
michael@0 429 if (id == NULL)
michael@0 430 return false;
michael@0 431 SkDisplayable** firstMovie = fMaker->fMovies.begin();
michael@0 432 SkDisplayable** endMovie = fMaker->fMovies.end();
michael@0 433 for (SkDisplayable** ptr = firstMovie; ptr < endMovie; ptr++) {
michael@0 434 SkDisplayMovie* movie = (SkDisplayMovie*) *ptr;
michael@0 435 movie->doEvent(evt);
michael@0 436 }
michael@0 437 {
michael@0 438 SkDisplayable* event;
michael@0 439 if (fMaker->find(id, &event) == false)
michael@0 440 return false;
michael@0 441 #if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
michael@0 442 SkString debugOut;
michael@0 443 SkMSec realTime = fMaker->getAppTime();
michael@0 444 debugOut.appendS32(realTime - fMaker->fDebugTimeBase);
michael@0 445 debugOut.append(" onEvent id=");
michael@0 446 debugOut.append(id);
michael@0 447 #endif
michael@0 448 SkMSec time = evt.getFast32();
michael@0 449 if (time != 0) {
michael@0 450 SkMSec app = fMaker->getAppTime();
michael@0 451 fMaker->setEnableTime(app, time);
michael@0 452 #if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
michael@0 453 debugOut.append(" time=");
michael@0 454 debugOut.appendS32(time - fMaker->fDebugTimeBase);
michael@0 455 debugOut.append(" adjust=");
michael@0 456 debugOut.appendS32(fMaker->fAdjustedStart);
michael@0 457 #endif
michael@0 458 }
michael@0 459 #if defined SK_DEBUG && defined SK_DEBUG_ANIMATION_TIMING
michael@0 460 SkDebugf("%s\n", debugOut.c_str());
michael@0 461 #endif
michael@0 462 SkASSERT(event->isEvent());
michael@0 463 SkDisplayEvent* displayEvent = (SkDisplayEvent*) event;
michael@0 464 displayEvent->populateInput(*fMaker, evt);
michael@0 465 displayEvent->enableEvent(*fMaker);
michael@0 466 }
michael@0 467 }
michael@0 468 inval:
michael@0 469 fMaker->notifyInval();
michael@0 470 return true;
michael@0 471 }
michael@0 472
michael@0 473 void SkAnimator::onEventPost(SkEvent* evt, SkEventSinkID sinkID)
michael@0 474 {
michael@0 475 #ifdef SK_DEBUG
michael@0 476 SkAnimator* root = fMaker->getRoot();
michael@0 477 if (root) {
michael@0 478 root->onEventPost(evt, sinkID);
michael@0 479 return;
michael@0 480 }
michael@0 481 #else
michael@0 482 SkASSERT(sinkID == this->getSinkID() || this->getHostEventSinkID() == sinkID);
michael@0 483 #endif
michael@0 484 evt->setTargetID(sinkID)->post();
michael@0 485 }
michael@0 486
michael@0 487 void SkAnimator::onEventPostTime(SkEvent* evt, SkEventSinkID sinkID, SkMSec time)
michael@0 488 {
michael@0 489 #ifdef SK_DEBUG
michael@0 490 SkAnimator* root = fMaker->getRoot();
michael@0 491 if (root) {
michael@0 492 root->onEventPostTime(evt, sinkID, time);
michael@0 493 return;
michael@0 494 }
michael@0 495 #else
michael@0 496 SkASSERT(sinkID == this->getSinkID() || this->getHostEventSinkID() == sinkID);
michael@0 497 #endif
michael@0 498 evt->setTargetID(sinkID)->postTime(time);
michael@0 499 }
michael@0 500
michael@0 501 void SkAnimator::reset() {
michael@0 502 fMaker->fDisplayList.reset();
michael@0 503 }
michael@0 504
michael@0 505 SkEventSinkID SkAnimator::getHostEventSinkID() const {
michael@0 506 return fMaker->fHostEventSinkID;
michael@0 507 }
michael@0 508
michael@0 509 void SkAnimator::setHostEventSinkID(SkEventSinkID target) {
michael@0 510 fMaker->fHostEventSinkID = target;
michael@0 511 }
michael@0 512
michael@0 513 void SkAnimator::onSetHostHandler(Handler ) {
michael@0 514 }
michael@0 515
michael@0 516 void SkAnimator::setJavaOwner(Handler ) {
michael@0 517 }
michael@0 518
michael@0 519 bool SkAnimator::setArrayString(const char* id, const char* fieldID, const char** array, int num)
michael@0 520 {
michael@0 521 SkTypedArray tArray(SkType_String);
michael@0 522 tArray.setCount(num);
michael@0 523 for (int i = 0; i < num; i++) {
michael@0 524 SkOperand op;
michael@0 525 op.fString = new SkString(array[i]);
michael@0 526 tArray[i] = op;
michael@0 527 }
michael@0 528 return setArray(id, fieldID, tArray);
michael@0 529 }
michael@0 530 bool SkAnimator::setArrayInt(const char* id, const char* fieldID, const int* array, int num)
michael@0 531 {
michael@0 532 SkTypedArray tArray(SkType_Int);
michael@0 533 tArray.setCount(num);
michael@0 534 for (int i = 0; i < num; i++) {
michael@0 535 SkOperand op;
michael@0 536 op.fS32 = array[i];
michael@0 537 tArray[i] = op;
michael@0 538 }
michael@0 539 return setArray(id, fieldID, tArray);
michael@0 540 }
michael@0 541
michael@0 542 bool SkAnimator::setArray(SkDisplayable* element, const SkMemberInfo* info, SkTypedArray array) {
michael@0 543 if (info->fType != SkType_Array)
michael@0 544 return false; //the field is not an array
michael@0 545 //i think we can handle the case where the displayable itself is an array differently from the
michael@0 546 //case where it has an array - for one thing, if it is an array, i think we can change its type
michael@0 547 //if it's not, we cannot
michael@0 548 SkDisplayTypes type = element->getType();
michael@0 549 if (type == SkType_Array) {
michael@0 550 SkDisplayArray* dispArray = (SkDisplayArray*) element;
michael@0 551 dispArray->values = array;
michael@0 552 return true;
michael@0 553 }
michael@0 554 else
michael@0 555 return false; //currently i don't care about this case
michael@0 556 }
michael@0 557
michael@0 558 bool SkAnimator::setArray(const char* id, const char* fieldID, SkTypedArray array) {
michael@0 559 SkDisplayable* element = (SkDisplayable*) getElement(id);
michael@0 560 //should I go ahead and change all 'NULL's to 'NULL'?
michael@0 561 if (element == NULL)
michael@0 562 return false;
michael@0 563 const SkMemberInfo* field = getField(element, fieldID);
michael@0 564 if (field == NULL)
michael@0 565 return false;
michael@0 566 return setArray(element, field, array);
michael@0 567 }
michael@0 568
michael@0 569 bool SkAnimator::setInt(SkDisplayable* element, const SkMemberInfo* info, int32_t s32) {
michael@0 570 if (info->fType != SkType_MemberProperty) {
michael@0 571 SkOperand operand;
michael@0 572 operand.fS32 = s32;
michael@0 573 SkASSERT(info->getType() == SkType_Int);
michael@0 574 info->setValue(element, &operand, 1);
michael@0 575 } else {
michael@0 576 SkScriptValue scriptValue;
michael@0 577 scriptValue.fType = SkType_Int;
michael@0 578 scriptValue.fOperand.fS32 = s32;
michael@0 579 element->setProperty(info->propertyIndex(), scriptValue);
michael@0 580 }
michael@0 581 return true;
michael@0 582 }
michael@0 583
michael@0 584 bool SkAnimator::setInt(const char* id, const char* fieldID, int32_t s32) {
michael@0 585 SkDisplayable* element = (SkDisplayable*) getElement(id);
michael@0 586 if (element == NULL)
michael@0 587 return false;
michael@0 588 const SkMemberInfo* field = getField(element, fieldID);
michael@0 589 if (field == NULL)
michael@0 590 return false;
michael@0 591 return setInt(element, field, s32);
michael@0 592 }
michael@0 593
michael@0 594 bool SkAnimator::setScalar(SkDisplayable* element, const SkMemberInfo* info, SkScalar scalar) {
michael@0 595 if (info->fType != SkType_MemberProperty) {
michael@0 596 SkOperand operand;
michael@0 597 operand.fScalar = scalar;
michael@0 598 SkASSERT(info->getType() == SkType_Float);
michael@0 599 info->setValue(element, &operand, 1);
michael@0 600 } else {
michael@0 601 SkScriptValue scriptValue;
michael@0 602 scriptValue.fType = SkType_Float;
michael@0 603 scriptValue.fOperand.fScalar = scalar;
michael@0 604 element->setProperty(info->propertyIndex(), scriptValue);
michael@0 605 }
michael@0 606 return true;
michael@0 607 }
michael@0 608
michael@0 609 bool SkAnimator::setScalar(const char* id, const char* fieldID, SkScalar scalar) {
michael@0 610 SkDisplayable* element = (SkDisplayable*) getElement(id);
michael@0 611 if (element == NULL)
michael@0 612 return false;
michael@0 613 const SkMemberInfo* field = getField(element, fieldID);
michael@0 614 if (field == NULL)
michael@0 615 return false;
michael@0 616 return setScalar(element, field, scalar);
michael@0 617 }
michael@0 618
michael@0 619 bool SkAnimator::setString(SkDisplayable* element,
michael@0 620 const SkMemberInfo* info, const char* str) {
michael@0 621 // !!! until this is fixed, can't call script with global references from here
michael@0 622 info->setValue(*fMaker, NULL, 0, info->fCount, element, info->getType(), str, strlen(str));
michael@0 623 return true;
michael@0 624 }
michael@0 625
michael@0 626 bool SkAnimator::setString(const char* id, const char* fieldID, const char* str) {
michael@0 627 SkDisplayable* element = (SkDisplayable*) getElement(id);
michael@0 628 if (element == NULL)
michael@0 629 return false;
michael@0 630 const SkMemberInfo* field = getField(element, fieldID);
michael@0 631 if (field == NULL)
michael@0 632 return false;
michael@0 633 return setString(element, field, str);
michael@0 634 }
michael@0 635
michael@0 636 void SkAnimator::setTimeline(const Timeline& timeline) {
michael@0 637 fMaker->fTimeline = &timeline;
michael@0 638 }
michael@0 639
michael@0 640 void SkAnimator::setURIBase(const char* uri) {
michael@0 641 if (uri)
michael@0 642 {
michael@0 643 const char* tail = strrchr(uri, '/');
michael@0 644 if (tail) {
michael@0 645 SkString prefix(uri, tail - uri + 1);
michael@0 646 if (uri[0] != '.' /*SkStream::IsAbsoluteURI(uri)*/)
michael@0 647 fMaker->fPrefix.reset();
michael@0 648 fMaker->fPrefix.append(prefix);
michael@0 649 fMaker->fFileName.set(tail + 1);
michael@0 650 } else
michael@0 651 fMaker->fFileName.set(uri);
michael@0 652 }
michael@0 653 }
michael@0 654
michael@0 655 #ifdef SK_DEBUG
michael@0 656 bool SkAnimator::NoLeaks() {
michael@0 657 #ifdef SK_BUILD_FOR_MAC
michael@0 658 if (SkDisplayable::fAllocations.count() == 0)
michael@0 659 return true;
michael@0 660 // return SkDisplayable::fAllocationCount == 0;
michael@0 661 SkDebugf("!!! leaked %d displayables:\n", SkDisplayable::fAllocations.count());
michael@0 662 for (SkDisplayable** leak = SkDisplayable::fAllocations.begin(); leak < SkDisplayable::fAllocations.end(); leak++)
michael@0 663 SkDebugf("%08x %s\n", *leak, (*leak)->id);
michael@0 664 #endif
michael@0 665 return false;
michael@0 666 }
michael@0 667 #endif
michael@0 668
michael@0 669 #ifdef SK_SUPPORT_UNITTEST
michael@0 670 #include "SkAnimatorScript.h"
michael@0 671 #include "SkBase64.h"
michael@0 672 #include "SkParse.h"
michael@0 673 #include "SkMemberInfo.h"
michael@0 674
michael@0 675 #define unittestline(type) { #type , type::UnitTest }
michael@0 676 #endif
michael@0 677
michael@0 678
michael@0 679 #ifdef SK_SUPPORT_UNITTEST
michael@0 680 void SkAnimator::Init(bool runUnitTests) {
michael@0 681 if (runUnitTests == false)
michael@0 682 return;
michael@0 683 static const struct {
michael@0 684 const char* fTypeName;
michael@0 685 void (*fUnitTest)( );
michael@0 686 } gUnitTests[] = {
michael@0 687 unittestline(SkBase64),
michael@0 688 unittestline(SkDisplayType),
michael@0 689 unittestline(SkParse),
michael@0 690 unittestline(SkScriptEngine),
michael@0 691 // unittestline(SkScriptEngine2), // compiled script experiment
michael@0 692 unittestline(SkAnimatorScript)
michael@0 693 };
michael@0 694 for (int i = 0; i < (int)SK_ARRAY_COUNT(gUnitTests); i++)
michael@0 695 {
michael@0 696 SkDebugf("SkAnimator: Running UnitTest for %s\n", gUnitTests[i].fTypeName);
michael@0 697 gUnitTests[i].fUnitTest();
michael@0 698 SkDebugf("SkAnimator: End UnitTest for %s\n", gUnitTests[i].fTypeName);
michael@0 699 }
michael@0 700 }
michael@0 701 #else
michael@0 702 void SkAnimator::Init(bool) {}
michael@0 703 #endif
michael@0 704
michael@0 705 void SkAnimator::Term() {
michael@0 706 }

mercurial