renderer, example: implments shape animation
[platform/core/uifw/rive-tizen.git] / example / rive_viewer.cpp
1 #include <thread>
2 #include <Elementary.h>
3 #include <rive_tizen.hpp>
4
5 #include "animation/linear_animation_instance.hpp"
6 #include "artboard.hpp"
7 #include "file.hpp"
8 #include "thorvg_renderer.hpp"
9
10 using namespace std;
11
12 #define WIDTH 700
13 #define HEIGHT 700
14
15 static unique_ptr<tvg::SwCanvas> canvas;
16 static tvg::Canvas *renderCanvas;
17 static rive::File* file = nullptr;
18 static rive::Artboard* artboard = nullptr;
19 static rive::LinearAnimationInstance* animationInstance = nullptr;
20 static Ecore_Animator *animator = nullptr;
21 static Eo* view = nullptr;
22 static double lastTime;
23
24 static void deleteWindow(void *data, Evas_Object *obj, void *ev)
25 {
26    elm_exit();
27 }
28
29 static void drawToCanvas(void* data, Eo* obj)
30 {
31     if (canvas->draw() == tvg::Result::Success)
32     {
33         canvas->sync();
34     }
35 }
36
37 Eina_Bool animationLoop(void *data)
38 {
39     double currentTime = ecore_time_get();
40     float elapsed = currentTime - lastTime;
41     static float animationTime = 0;
42     lastTime = currentTime;
43
44     if (artboard != nullptr)
45     {
46        if (animationInstance != nullptr)
47        {
48           animationInstance->advance(elapsed);
49           animationInstance->apply(artboard);
50        }
51        artboard->advance(elapsed);
52
53        rive::TvgRenderer renderer(renderCanvas);
54        renderer.save();
55        artboard->draw(&renderer);
56        renderer.restore();
57     }
58
59     evas_object_image_pixels_dirty_set(view, EINA_TRUE);
60     evas_object_image_data_update_add(view, 0, 0, WIDTH, HEIGHT);
61
62     return ECORE_CALLBACK_RENEW;
63 }
64
65 static void runExample(uint32_t* buffer)
66 {
67     //Create a Canvas
68     canvas = tvg::SwCanvas::gen();
69     canvas->target(buffer, WIDTH, WIDTH, HEIGHT, tvg::SwCanvas::ARGB8888);
70     renderCanvas = canvas.get();
71
72     // Load Rive File
73     const char* filename = "../../example/shapes.riv";
74     FILE* fp = fopen(filename, "r");
75
76     fseek(fp, 0, SEEK_END);
77     size_t length = ftell(fp);
78     fseek(fp, 0, SEEK_SET);
79
80     uint8_t* bytes = new uint8_t[length];
81     if (fread(bytes, 1, length, fp) != length)
82     {
83        delete[] bytes;
84        fprintf(stderr, "failed to read all of %s\n", filename);
85        return;
86     }
87
88     auto reader = rive::BinaryReader(bytes, length);
89     auto result = rive::File::import(reader, &file);
90     if (result != rive::ImportResult::success)
91     {
92        delete[] bytes;
93        fprintf(stderr, "failed to import %s\n", filename);
94        return;
95     }
96
97     artboard = file->artboard();
98     artboard->advance(0.0f);
99
100     delete animationInstance;
101
102     auto animation = artboard->firstAnimation<rive::LinearAnimation>();
103     if (animation != nullptr)
104     {
105        animationInstance = new rive::LinearAnimationInstance(animation);
106     }
107     else
108     {
109        animationInstance = nullptr;
110     }
111
112     lastTime = ecore_time_get();
113     ecore_animator_frametime_set(1. / 60);
114     animator = ecore_animator_add(animationLoop, nullptr);
115
116     delete[] bytes;
117 }
118
119
120 static void cleanExample()
121 {
122     delete file;
123     delete animationInstance;
124 }
125
126
127 static void setupScreen(uint32_t* buffer)
128 {
129     Eo* win = elm_win_util_standard_add(NULL, "Rive Viewer");
130     evas_object_smart_callback_add(win, "delete,request", deleteWindow, 0);
131
132     view = evas_object_image_filled_add(evas_object_evas_get(win));
133     evas_object_image_size_set(view, WIDTH, HEIGHT);
134     evas_object_image_data_set(view, buffer);
135     evas_object_image_pixels_get_callback_set(view, drawToCanvas, nullptr);
136     evas_object_image_pixels_dirty_set(view, EINA_TRUE);
137     evas_object_image_data_update_add(view, 0, 0, WIDTH, HEIGHT);
138     evas_object_size_hint_weight_set(view, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
139     evas_object_show(view);
140
141     elm_win_resize_object_add(win, view);
142     evas_object_resize(win, WIDTH, HEIGHT);
143     evas_object_show(win);
144 }
145
146 int main(int argc, char **argv)
147 {
148     static uint32_t buffer[WIDTH * HEIGHT];
149
150     tvg::Initializer::init(tvg::CanvasEngine::Sw, thread::hardware_concurrency());
151
152     elm_init(argc, argv);
153
154     setupScreen(buffer);
155
156     runExample(buffer);
157
158     elm_run();
159
160     cleanExample();
161
162     elm_shutdown();
163
164     tvg::Initializer::term(tvg::CanvasEngine::Sw);
165
166     return 0;
167 }