tizen 2.3 release
[framework/uifw/elementary.git] / src / examples / efl_thread_6.c
1 //Compile with:
2 //gcc -o efl_thread_6 efl_thread_6.c -g `pkg-config --cflags --libs elementary`
3 #include <Elementary.h>
4
5 static Evas_Object *win = NULL;
6
7 struct info
8 {
9    Evas_Object *obj;
10    int *pix;
11 };
12
13 // BEGIN - code running in my custom thread instance
14 //
15 static void
16 mandel(int *pix, int w, int h)
17 {
18    double x, xx, y, cx, cy, cox, coy;
19    int iteration, hx, hy, val, r, g, b, rr, gg, bb;
20    int itermax = 10000;
21    double magnify = 0.02;
22
23    // this mandel calc is run in the worker threads so it's here. it is
24    // just here to calculate something and consume cpu to demonstrate the
25    // ecore thread worker queue. don't pay much attention to the below code
26    magnify += ((double)(rand() % 100) / 100.0) / 4.0;
27    cox = (double)(rand() % 100) / 100.0;
28    coy = (double)(rand() % 100) / 100.0;
29    cox /= (magnify * 3.0);
30    r = rand() % 255; g = rand() % 255; b = rand() % 255;
31    for (hy = 0; hy < h; hy++)
32      {
33         for (hx = 0; hx < w; hx++)
34           {
35              cx = (((float)hx) / ((float)w) - 0.5) / (magnify * 3.0);
36              cy = (((float)hy) / ((float)h) - 0.5) / (magnify * 3.0);
37              cx += cox;
38              cy += coy;
39              x = 0.0;
40              y = 0.0;
41              for (iteration = 1; iteration < itermax; iteration++)
42                {
43                   xx = (x * x) - (y * y) + cx;
44                   y = (2.0 * x * y) + cy;
45                   x = xx;
46                   if (((x * x) + (y * y)) > 100.0) iteration = 999999;
47                }
48              val = (((x * x) + (y * y)) * 2.55) / 100.0;
49              if (val > 255) val = 255;
50              if (iteration >= 99999)
51                {
52                   rr = (r * val) / 255;
53                   gg = (g * val) / 255;
54                   bb = (b * val) / 255;
55                   pix[(hy * w) + hx] =
56                      (val  << 24) | (rr << 16) | (gg << 8) | (bb);
57                }
58              else
59                 pix[(hy * w) + hx] = 0xffffffff;
60           }
61      }
62 }
63
64 static void
65 th_do(void *data, Ecore_Thread *th)
66 {
67    struct info *inf = data;
68    // CANNOT TOUCH inf->obj here! just inf->pix which is 256x256 @ 32bpp
69    // quick and dirty to consume some cpu - do a mandelbrot calc
70    mandel(inf->pix, 256, 256);
71 }
72 //
73 // END - code running in my custom thread instance
74
75 static void // thread job finished - collect results and put in img obj
76 th_end(void *data, Ecore_Thread *th)
77 {
78    struct info *inf = data;
79
80    // copy data to object, free calculated data and info struc
81    evas_object_image_data_copy_set(inf->obj, inf->pix);
82    evas_object_show(inf->obj);
83    free(inf->pix);
84    free(inf);
85 }
86
87 static void // if the thread is cancelled - free pix, keep obj tho
88 th_cancel(void *data, Ecore_Thread *th)
89 {
90    struct info *inf = data;
91
92    // just free pixel data and info struct
93    free(inf->pix);
94    free(inf);
95 }
96
97 static Eina_Bool // animate the objects so you see all the madels move
98 anim(void *data)
99 {
100    Evas_Object *o = data;
101    double t, z;
102    int w, h, v;
103    Evas_Coord x, y;
104
105    // just calculate some position using the pointer value of the object as
106    // a seed value to make different objects go into different places over time
107    v = ((int)o) & 0xff;
108    t = ecore_loop_time_get();
109    w = 100 + ((v * 100) >> 8);
110    h = 100 + ((v * 100) >> 8);
111    z = (double)(v) / 100.0;
112    x = (w * sin(t));
113    y = (h * cos(t + z));
114    // do the actual move
115    evas_object_move(o, 200 + x - 128, 200 + y - 128);
116    // keep looping - return true
117    return EINA_TRUE;
118 }
119
120 EAPI_MAIN int
121 elm_main(int argc, char **argv)
122 {
123    Evas_Object *o, *bg;
124    int i;
125
126    win = elm_win_add(NULL, "efl-thread-6", ELM_WIN_BASIC);
127    elm_win_title_set(win, "EFL Thread 6");
128    elm_win_autodel_set(win, EINA_TRUE);
129    elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
130    evas_object_resize(win, 400, 400);
131    evas_object_show(win);
132
133    bg = elm_bg_add(win);
134    evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
135    elm_win_resize_object_add(win, bg);
136    evas_object_show(bg);
137
138    // queue up 64 mandel generation thread jobs
139    for (i = 0; i < 64; i++)
140      {
141         struct info *inf;
142
143         // create ecore thread to do some threaded job inside the worker pool
144         inf = malloc(sizeof(struct info));
145         if (inf)
146           {
147              o = evas_object_image_filled_add(evas_object_evas_get(win));
148              evas_object_image_size_set(o, 256, 256);
149              evas_object_image_alpha_set(o, EINA_TRUE);
150              evas_object_resize(o, 256, 256);
151              inf->obj = o;
152              inf->pix = malloc(256 * 256 * sizeof(int));
153              ecore_thread_run(th_do, th_end, th_cancel, inf);
154              // bonus - slide the objects around all the time with an
155              // animator that ticks off every frame.
156              ecore_animator_add(anim, o);
157           }
158      }
159
160    elm_run();
161    elm_shutdown();
162
163    return 0;
164 }
165 ELM_MAIN()