
\begin{DoxyCodeInclude}
\textcolor{comment}{//Compile with:}
\textcolor{comment}{//gcc -o efl\_thread\_6 efl\_thread\_6.c -g `pkg-config --cflags --libs elementary`}
\textcolor{preprocessor}{#include <Elementary.h>}

\textcolor{keyword}{static} Evas\_Object *win = NULL;
\textcolor{keyword}{static} Eina\_List *threads;

\textcolor{keyword}{struct }info
\{
   Evas\_Object *obj;
   \textcolor{keywordtype}{int} *pix;
\};

\textcolor{comment}{// BEGIN - code running in my custom thread instance}
\textcolor{comment}{//}
\textcolor{keyword}{static} \textcolor{keywordtype}{void}
mandel(Ecore\_Thread *th, \textcolor{keywordtype}{int} *pix, \textcolor{keywordtype}{int} w, \textcolor{keywordtype}{int} h)
\{
   \textcolor{keywordtype}{double} x, xx, y, cx, cy, cox, coy;
   \textcolor{keywordtype}{int} iteration, hx, hy, val, r, g, b, rr, gg, bb;
   \textcolor{keywordtype}{int} itermax = 10000;
   \textcolor{keywordtype}{double} magnify = 0.02;

   \textcolor{comment}{// this mandel calc is run in the worker threads so it's here. it is}
   \textcolor{comment}{// just here to calculate something and consume cpu to demonstrate the}
   \textcolor{comment}{// ecore thread worker queue. don't pay much attention to the below code}
   magnify += ((double)(rand() % 100) / 100.0) / 4.0;
   cox = (double)(rand() % 100) / 100.0;
   coy = (double)(rand() % 100) / 100.0;
   cox /= (magnify * 3.0);
   r = rand() % 255; g = rand() % 255; b = rand() % 255;
   \textcolor{keywordflow}{for} (hy = 0; hy < h; hy++)
     \{
        \textcolor{comment}{// every line check if thread has been cancelled to return early}
        \textcolor{keywordflow}{if} (ecore\_thread\_check(th)) \textcolor{keywordflow}{return};
        \textcolor{keywordflow}{for} (hx = 0; hx < w; hx++)
          \{
             cx = (((float)hx) / ((float)w) - 0.5) / (magnify * 3.0);
             cy = (((float)hy) / ((float)h) - 0.5) / (magnify * 3.0);
             cx += cox;
             cy += coy;
             x = 0.0;
             y = 0.0;
             \textcolor{keywordflow}{for} (iteration = 1; iteration < itermax; iteration++)
               \{
                  xx = (x * x) - (y * y) + cx;
                  y = (2.0 * x * y) + cy;
                  x = xx;
                  \textcolor{keywordflow}{if} (((x * x) + (y * y)) > 100.0) iteration = 999999;
               \}
             val = (((x * x) + (y * y)) * 2.55) / 100.0;
             \textcolor{keywordflow}{if} (val > 255) val = 255;
             \textcolor{keywordflow}{if} (iteration >= 99999)
               \{
                  rr = (r * val) / 255;
                  gg = (g * val) / 255;
                  bb = (b * val) / 255;
                  pix[(hy * w) + hx] =
                     (val  << 24) | (rr << 16) | (gg << 8) | (bb);
               \}
             \textcolor{keywordflow}{else}
               pix[(hy * w) + hx] = 0xffffffff;
          \}
     \}
\}

\textcolor{keyword}{static} \textcolor{keywordtype}{void}
th\_do(\textcolor{keywordtype}{void} *data, Ecore\_Thread *th)
\{
   \textcolor{keyword}{struct }info *inf = data;
   \textcolor{comment}{// CANNOT TOUCH inf->obj here! just inf->pix which is 256x256 @ 32bpp}
   \textcolor{comment}{// quick and dirty to consume some cpu - do a mandelbrot calc}
   mandel(th, inf->pix, 256, 256);
\}
\textcolor{comment}{//}
\textcolor{comment}{// END - code running in my custom thread instance}

\textcolor{keyword}{static} \textcolor{keywordtype}{void} \textcolor{comment}{// thread job finished - collect results and put in img obj}
th\_end(\textcolor{keywordtype}{void} *data, Ecore\_Thread *th)
\{
   \textcolor{keyword}{struct }info *inf = data;

   \textcolor{comment}{// copy data to object, free calculated data and info struc}
   evas\_object\_image\_data\_copy\_set(inf->obj, inf->pix);
   evas\_object\_show(inf->obj);
   free(inf->pix);
   free(inf);
   threads = eina\_list\_remove(threads, th);
\}

\textcolor{keyword}{static} \textcolor{keywordtype}{void} \textcolor{comment}{// if the thread is cancelled - free pix, keep obj tho}
th\_cancel(\textcolor{keywordtype}{void} *data, Ecore\_Thread *th)
\{
   \textcolor{keyword}{struct }info *inf = data;

   \textcolor{comment}{// just free pixel data and info struct}
   free(inf->pix);
   free(inf);
\}

\textcolor{keyword}{static} Eina\_Bool \textcolor{comment}{// animate the objects so you see all the madels move}
anim(\textcolor{keywordtype}{void} *data)
\{
   Evas\_Object *o = data;
   \textcolor{keywordtype}{double} t, z;
   \textcolor{keywordtype}{int} w, h, v;
   Evas\_Coord x, y;

   \textcolor{comment}{// just calculate some position using the pointer value of the object as}
   \textcolor{comment}{// a seed value to make different objects go into different places over time}
   v = ((int)(uintptr\_t)o) & 0xff;
   t = ecore\_loop\_time\_get();
   w = 100 + ((v * 100) >> 8);
   h = 100 + ((v * 100) >> 8);
   z = (double)(v) / 100.0;
   x = (w * sin(t));
   y = (h * cos(t + z));
   \textcolor{comment}{// do the actual move}
   evas\_object\_move(o, 200 + x - 128, 200 + y - 128);
   \textcolor{comment}{// keep looping - return true}
   \textcolor{keywordflow}{return} EINA\_TRUE;
\}

EAPI\_MAIN \textcolor{keywordtype}{int}
elm\_main(\textcolor{keywordtype}{int} argc, \textcolor{keywordtype}{char} **argv)
\{
   Evas\_Object *o;
   Ecore\_Thread *th;
   \textcolor{keywordtype}{int} i;

   elm_policy_set(ELM\_POLICY\_QUIT, ELM\_POLICY\_QUIT\_LAST\_WINDOW\_CLOSED);

   win = elm_win_util_standard_add(\textcolor{stringliteral}{"efl-thread-6"}, \textcolor{stringliteral}{"EFL Thread 6"});
   elm_win_autodel_set(win, EINA\_TRUE);

   \textcolor{comment}{// queue up 64 mandel generation thread jobs}
   \textcolor{keywordflow}{for} (i = 0; i < 64; i++)
     \{
        \textcolor{keyword}{struct }info *inf;

        \textcolor{comment}{// create ecore thread to do some threaded job inside the worker pool}
        inf = malloc(\textcolor{keyword}{sizeof}(\textcolor{keyword}{struct} info));
        \textcolor{keywordflow}{if} (inf)
          \{
             o = evas\_object\_image\_filled\_add(evas\_object\_evas\_get(win));
             evas\_object\_image\_size\_set(o, 256, 256);
             evas\_object\_image\_alpha\_set(o, EINA\_TRUE);
             evas\_object\_resize(o, 256, 256);
             inf->obj = o;
             inf->pix = malloc(256 * 256 * \textcolor{keyword}{sizeof}(\textcolor{keywordtype}{int}));
             th = ecore\_thread\_run(th\_do, th\_end, th\_cancel, inf);
             threads = eina\_list\_append(threads, th);
             \textcolor{comment}{// bonus - slide the objects around all the time with an}
             \textcolor{comment}{// animator that ticks off every frame.}
             ecore\_animator\_add(anim, o);
          \}
     \}

   evas\_object\_resize(win, 400, 400);
   evas\_object\_show(win);

   elm_run();

   \textcolor{comment}{// if some threads are still running - cancel them}
   EINA\_LIST\_FREE(threads, th) ecore\_thread\_cancel(th);


   \textcolor{keywordflow}{return} 0;
\}
ELM_MAIN()
\end{DoxyCodeInclude}
 