aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/animator/SkAnimator.h
blob: 9bb3642ca0b0d119695a4bb90b7e6c3f0fb46c3a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500

/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#ifndef SkAnimator_DEFINED
#define SkAnimator_DEFINED

#include "SkScalar.h"
#include "SkKey.h"
#include "SkEventSink.h"

class SkAnimateMaker;
class SkCanvas;
class SkDisplayable;
class SkEvent;
class SkExtras;
struct SkMemberInfo;
class SkPaint;
struct SkRect;
class SkStream;
class SkTypedArray;
class SkXMLParserError;
class SkDOM;
struct SkDOMNode;

/** SkElementType is the type of element: a rectangle, a color, an animator, and so on.
    This enum is incomplete and will be fleshed out in a future release */
enum SkElementType {
    kElementDummyType
};
/** SkFieldType is the type of field: a scalar, a string, an integer, a boolean, and so on.
    This enum is incomplete and will be fleshed out in a future release */
enum SkFieldType {
    kFieldDummyType
};

/** \class SkAnimator

    The SkAnimator class decodes an XML stream into a display list. The
    display list can be drawn statically as a picture, or can drawn
    different elements at different times to form a moving animation.

    SkAnimator does not read the system time on its own; it relies on the
    caller to pass the current time. The caller can pause, speed up, or
    reverse the animation by varying the time passed in.

    The XML describing the display list must conform to the schema
    described by SkAnimateSchema.xsd.

    The XML must contain an <event> element to draw. Usually, it contains
    an <event kind="onload" /> block to add some drawing elements to the
    display list when the document is first decoded.

    Here's an "Hello World" XML sample:

    <screenplay>
        <event kind="onload" >
            <text text="Hello World" y="20" />
        </event>
    </screenplay>

    To read and draw this sample:

        // choose one of these two
        SkAnimator animator; // declare an animator instance on the stack
    //  SkAnimator* animator = new SkAnimator() // or one could instantiate the class

        // choose one of these three
        animator.decodeMemory(buffer, size); // to read from RAM
        animator.decodeStream(stream); // to read from a user-defined stream (e.g., a zip file)
        animator.decodeURI(filename); // to read from a web location, or from a local text file

        // to draw to the current window:
        SkCanvas canvas(getBitmap()); // create a canvas
        animator.draw(canvas, &paint, 0); // draw the scene
*/
class SkAnimator : public SkEventSink {
public:
    SkAnimator();
    virtual ~SkAnimator();

    /** Add a drawable extension to the graphics engine. Experimental.
        @param extras A derived class that implements methods that identify and instantiate the class
    */
    void addExtras(SkExtras* extras);

    /** Read in XML from a stream, and append it to the current
        animator. Returns false if an error was encountered.
        Error diagnostics are stored in fErrorCode and fLineNumber.
        @param stream  The stream to append.
        @return true if the XML was parsed successfully.
    */
    bool appendStream(SkStream* stream);

    /** Read in XML from memory. Returns true if the file can be
        read without error. Returns false if an error was encountered.
        Error diagnostics are stored in fErrorCode and fLineNumber.
        @param buffer  The XML text as UTF-8 characters.
        @param size  The XML text length in bytes.
        @return true if the XML was parsed successfully.
    */
    bool decodeMemory(const void* buffer, size_t size);

    /** Read in XML from a stream. Returns true if the file can be
        read without error. Returns false if an error was encountered.
        Error diagnostics are stored in fErrorCode and fLineNumber.
        @param stream  The stream containg the XML text as UTF-8 characters.
        @return true if the XML was parsed successfully.
    */
    virtual bool decodeStream(SkStream* stream);

    /** Parse the DOM tree starting at the specified node. Returns true if it can be
        parsed without error. Returns false if an error was encountered.
        Error diagnostics are stored in fErrorCode and fLineNumber.
        @return true if the DOM was parsed successfully.
    */
    virtual bool decodeDOM(const SkDOM&, const SkDOMNode*);

    /** Read in XML from a URI. Returns true if the file can be
        read without error. Returns false if an error was encountered.
        Error diagnostics are stored in fErrorCode and fLineNumber.
        @param uri The complete url path to be read (either ftp, http or https).
        @return true if the XML was parsed successfully.
    */
    bool decodeURI(const char uri[]);

    /** Pass a char event, usually a keyboard symbol, to the animator.
        This triggers events of the form <event kind="keyChar" key="... />
        @param ch  The character to match against <event> element "key"
            attributes.
        @return true if the event was dispatched successfully.
    */
    bool doCharEvent(SkUnichar ch);

    /** Experimental:
        Pass a mouse click event along with the mouse coordinates to
        the animator. This triggers events of the form <event kind="mouseDown" ... />
        and other mouse events.
        @param state The mouse state, described by SkView::Click::State : values are
        down == 0, moved == 1, up == 2
        @param x    The x-position of the mouse
        @param y The y-position of the mouse
        @return true if the event was dispatched successfully.
    */
    bool doClickEvent(int state, SkScalar x, SkScalar y);

    /** Pass a meta-key event, such as an arrow , to the animator.
        This triggers events of the form <event kind="keyPress" code="... />
        @param code  The key to match against <event> element "code"
            attributes.
        @return true if the event was dispatched successfully.
    */
    bool doKeyEvent(SkKey code);
    bool doKeyUpEvent(SkKey code);

    /** Send an event to the animator. The animator's clock is set
        relative to the current time.
        @return true if the event was dispatched successfully.
    */
    bool doUserEvent(const SkEvent& evt);

    /** The possible results from the draw function.
    */
    enum DifferenceType {
        kNotDifferent,
        kDifferent,
        kPartiallyDifferent
    };
    /** Draws one frame of the animation. The first call to draw always
        draws the initial frame of the animation. Subsequent calls draw
        the offset into the animation by
        subtracting the initial time from the current time.
        @param canvas  The canvas to draw into.
        @param paint     The paint to draw with.
        @param time  The offset into the current animation.
        @return kNotDifferent if there are no active animations; kDifferent if there are active animations; and
        kPartiallyDifferent if the document contains an active <bounds> element that specifies a minimal
        redraw area.
    */
    DifferenceType draw(SkCanvas* canvas, SkPaint* paint, SkMSec time);

    /** Draws one frame of the animation, using a new Paint each time.
        The first call to draw always
        draws the initial frame of the animation. Subsequent calls draw
        the offset into the animation by
        subtracting the initial time from the current time.
        @param canvas  The canvas to draw into.
        @param time  The offset into the current animation.
        @return kNotDifferent if there are no active animations; kDifferent if there are active animations; and
        kPartiallyDifferent if the document contains an active <bounds> element that specifies a minimal
        redraw area.
    */
    DifferenceType draw(SkCanvas* canvas, SkMSec time);

    /** Experimental:
        Helper to choose whether to return a SkView::Click handler.
        @param x ignored
        @param y ignored
        @return true if a mouseDown event handler is enabled.
    */
    bool findClickEvent(SkScalar x, SkScalar y);


    /** Get the nested animator associated with this element, if any.
        Use this to access a movie's event sink, to send events to movies.
        @param element the value returned by getElement
        @return the internal animator.
    */
    const SkAnimator* getAnimator(const SkDisplayable* element) const;

    /** Returns the scalar value of the specified element's attribute[index]
        @param element the value returned by getElement
        @param field the value returned by getField
        @param index the array entry
        @return the integer value to retrieve, or SK_NaN32 if unsuccessful
    */
    int32_t getArrayInt(const SkDisplayable* element, const SkMemberInfo* field, int index);

    /** Returns the scalar value of the specified element's attribute[index]
        @param elementID is the value of the id attribute in the XML of this element
        @param fieldName specifies the name of the attribute
        @param index the array entry
        @return the integer value to retrieve, or SK_NaN32 if unsuccessful
    */
    int32_t getArrayInt(const char* elementID, const char* fieldName, int index);

    /** Returns the scalar value of the specified element's attribute[index]
        @param element the value returned by getElement
        @param field the value returned by getField
        @param index the array entry
        @return the scalar value to retrieve, or SK_ScalarNaN if unsuccessful
    */
    SkScalar getArrayScalar(const SkDisplayable* element, const SkMemberInfo* field, int index);

    /** Returns the scalar value of the specified element's attribute[index]
        @param elementID is the value of the id attribute in the XML of this element
        @param fieldName specifies the name of the attribute
        @param index the array entry
        @return the scalar value to retrieve, or SK_ScalarNaN if unsuccessful
    */
    SkScalar getArrayScalar(const char* elementID, const char* fieldName, int index);

    /** Returns the string value of the specified element's attribute[index]
        @param element is a value returned by getElement
        @param field is a value returned by getField
        @param index the array entry
        @return the string value to retrieve, or null if unsuccessful
    */
    const char* getArrayString(const SkDisplayable* element, const SkMemberInfo* field, int index);

    /** Returns the string value of the specified element's attribute[index]
        @param elementID is the value of the id attribute in the XML of this element
        @param fieldName specifies the name of the attribute
        @param index the array entry
        @return the string value to retrieve, or null if unsuccessful
    */
    const char* getArrayString(const char* elementID, const char* fieldName, int index);

    /** Returns the XML element corresponding to the given ID.
        @param elementID is the value of the id attribute in the XML of this element
        @return the element matching the ID, or null if the element can't be found
    */
    const SkDisplayable* getElement(const char* elementID);

    /** Returns the element type corresponding to the XML element.
        The element type matches the element name; for instance, <line> returns kElement_LineType
        @param element is a value returned by getElement
        @return element type, or 0 if the element can't be found
    */
    SkElementType getElementType(const SkDisplayable* element);

    /** Returns the element type corresponding to the given ID.
        @param elementID is the value of the id attribute in the XML of this element
        @return element type, or 0 if the element can't be found
    */
    SkElementType getElementType(const char* elementID);

    /** Returns the XML field of the named attribute in the XML element.
        @param element is a value returned by getElement
        @param fieldName is the attribute to return
        @return the attribute matching the fieldName, or null if the element can't be found
    */
    const SkMemberInfo* getField(const SkDisplayable* element, const char* fieldName);

    /** Returns the XML field of the named attribute in the XML element matching the elementID.
        @param elementID is the value of the id attribute in the XML of this element
        @param fieldName is the attribute to return
        @return the attribute matching the fieldName, or null if the element can't be found
    */
    const SkMemberInfo* getField(const char* elementID, const char* fieldName);

    /** Returns the value type coresponding to the element's attribute.
        The value type matches the XML schema: and may be kField_BooleanType, kField_ScalarType, etc.
        @param field is a value returned by getField
        @return the attribute type, or 0 if the element can't be found
    */
    SkFieldType getFieldType(const SkMemberInfo* field);

    /** Returns the value type coresponding to the element's attribute.
        @param elementID is the value of the id attribute in the XML of this element
        @param fieldName specifies the name of the attribute
        @return the attribute type, or 0 if the element can't be found
    */
    SkFieldType getFieldType(const char* elementID, const char* fieldName);

    /** Returns the recommended animation interval. Returns zero if no
        interval is specified.
    */
    SkMSec getInterval();

    /** Returns the partial rectangle to invalidate after drawing. Call after draw() returns
    kIsPartiallyDifferent to do a mimimal inval(). */
    void getInvalBounds(SkRect* inval);

    /** Returns the details of any error encountered while parsing the XML.
    */
    const SkXMLParserError* getParserError();

    /** Returns the details of any error encountered while parsing the XML as string.
    */
    const char* getParserErrorString();

    /** Returns the scalar value of the specified element's attribute
        @param element is a value returned by getElement
        @param field is a value returned by getField
        @return the integer value to retrieve, or SK_NaN32 if not found
    */
    int32_t getInt(const SkDisplayable* element, const SkMemberInfo* field);

    /** Returns the scalar value of the specified element's attribute
        @param elementID is the value of the id attribute in the XML of this element
        @param fieldName specifies the name of the attribute
        @return the integer value to retrieve, or SK_NaN32 if not found
    */
    int32_t getInt(const char* elementID, const char* fieldName);

    /** Returns the scalar value of the specified element's attribute
        @param element is a value returned by getElement
        @param field is a value returned by getField
        @return the scalar value to retrieve, or SK_ScalarNaN if not found
    */
    SkScalar getScalar(const SkDisplayable* element, const SkMemberInfo* field);

    /** Returns the scalar value of the specified element's attribute
        @param elementID is the value of the id attribute in the XML of this element
        @param fieldName specifies the name of the attribute
        @return the scalar value to retrieve, or SK_ScalarNaN if not found
    */
    SkScalar getScalar(const char* elementID, const char* fieldName);

    /** Returns the string value of the specified element's attribute
        @param element is a value returned by getElement
        @param field is a value returned by getField
        @return the string value to retrieve, or null if not found
    */
    const char* getString(const SkDisplayable* element, const SkMemberInfo* field);

    /** Returns the string value of the specified element's attribute
        @param elementID is the value of the id attribute in the XML of this element
        @param fieldName specifies the name of the attribute
        @return the string value to retrieve, or null if not found
    */
    const char* getString(const char* elementID, const char* fieldName);

    /** Gets the file default directory of the URL base path set explicitly or by reading the last URL. */
    const char* getURIBase();

    /** Resets the animator to a newly created state with no animation data. */
    void initialize();

    /** Experimental. Resets any active animations so that the next time passed is treated as
        time zero. */
    void reset();

    /** Sets the scalar value of the specified element's attribute
        @param elementID is the value of the id attribute in the XML of this element
        @param fieldName specifies the name of the attribute
        @param array is the c-style array of integers
        @param count is the length of the array
        @return true if the value was set successfully
    */
    bool setArrayInt(const char* elementID, const char* fieldName, const int* array, int count);

    /** Sets the scalar value of the specified element's attribute
        @param elementID is the value of the id attribute in the XML of this element
        @param fieldName specifies the name of the attribute
        @param array is the c-style array of strings
        @param count is the length of the array
        @return true if the value was set successfully
    */
    bool setArrayString(const char* elementID, const char* fieldName, const char** array, int count);

    /** Sets the scalar value of the specified element's attribute
        @param elementID is the value of the id attribute in the XML of this element
        @param fieldName specifies the name of the attribute
        @param data the integer value to set
        @return true if the value was set successfully
    */
    bool setInt(const char* elementID, const char* fieldName, int32_t data);

    /** Sets the scalar value of the specified element's attribute
        @param elementID is the value of the id attribute in the XML of this element
        @param fieldName specifies the name of the attribute
        @param data the scalar value to set
        @return true if the value was set successfully
    */
    bool setScalar(const char* elementID, const char* fieldName, SkScalar data);

    /** Sets the string value of the specified element's attribute
        @param elementID is the value of the id attribute in the XML of this element
        @param fieldName specifies the name of the attribute
        @param data the string value to set
        @return true if the value was set successfully
    */
    bool setString(const char* elementID, const char* fieldName, const char* data);

    /** Sets the file default directory of the URL base path
        @param path the directory path
    */
    void setURIBase(const char* path);

    typedef void* Handler;
    // This guy needs to be exported to java, so don't make it virtual
    void setHostHandler(Handler handler) {
        this->onSetHostHandler(handler);
    }

    /** \class Timeline
    Returns current time to animator. To return a custom timeline, create a child
    class and override the getMSecs method.
    */
    class Timeline {
    public:
        virtual ~Timeline() {}

        /** Returns the current time in milliseconds */
        virtual SkMSec getMSecs() const = 0;
    };

    /** Sets a user class to return the current time to the animator.
        Optional; if not called, the system clock will be used by calling SkTime::GetMSecs instead.
        @param callBack the time function
    */
    void setTimeline(const Timeline& );

    static void Init(bool runUnitTests);
    static void Term();

    /** The event sink events generated by the animation are posted to.
        Screenplay also posts an inval event to this event sink after processing an
        event to force a redraw.
        @param target the event sink id
    */
    void setHostEventSinkID(SkEventSinkID hostID);
    SkEventSinkID getHostEventSinkID() const;

    // helper
    void setHostEventSink(SkEventSink* sink) {
        this->setHostEventSinkID(sink ? sink->getSinkID() : 0);
    }

    virtual void setJavaOwner(Handler owner);

#ifdef SK_DEBUG
    virtual void eventDone(const SkEvent& evt);
    virtual bool isTrackingEvents();
    static bool NoLeaks();
#endif

protected:
    virtual void onSetHostHandler(Handler handler);
    virtual void onEventPost(SkEvent*, SkEventSinkID);
    virtual void onEventPostTime(SkEvent*, SkEventSinkID, SkMSec time);

private:
// helper functions for setters
    bool setArray(SkDisplayable* element, const SkMemberInfo* field, SkTypedArray array);
    bool setArray(const char* elementID, const char* fieldName, SkTypedArray array);
    bool setInt(SkDisplayable* element, const SkMemberInfo* field, int32_t data);
    bool setScalar(SkDisplayable* element, const SkMemberInfo* field, SkScalar data);
    bool setString(SkDisplayable* element, const SkMemberInfo* field, const char* data);

    virtual bool onEvent(const SkEvent&);
    SkAnimateMaker* fMaker;
    friend class SkAnimateMaker;
    friend class SkAnimatorScript;
    friend class SkAnimatorScript2;
    friend class SkApply;
    friend class SkDisplayMovie;
    friend class SkDisplayType;
    friend class SkPost;
    friend class SkXMLAnimatorWriter;
};

#endif