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