This example demonstrates how to manage the idle state of the main loop.

Once a program knows that the main loop is going to enter in idle state, it could start doing some processing until getting out of this state.

To exemplify this, we also add events and a timer to this program, so we can see the idle exiter callback being called before processing the event and/or timer, the event/timer callback being called (processed), then the idle enterer being called before entering in idle state again. Once in idle, the main loop keeps calling the idler callback continuously until a new event or timer is received.

First, we declare a struct that will be used as context to be passed to every callback. It's not useful everywhere, since this example is very simple and doesn't do anything other than printing messages, but using this context will make it a little bit more real. Our context will be used to delete the timer, idler, idle enterer and exiter, and the event handler, and also to count how many times the idler was called.

Then we start declaring callbacks for the idle enterer, idle exiter and the idler itself. Idle enterer and exiter callbacks just print a message saying that they were called, while the idler, in addition to printing a message too, also sends an event every 10 times that it is called, incrementing the context count variable. This event will be used to make the main loop exit the idle state and call the event callback.

These callbacks return \hyperlink{group__Ecore__Main__Loop__Group_ga1ee9db07f9a46a8b20fb83e1c6dbed09}{E\+C\+O\+R\+E\+\_\+\+C\+A\+L\+L\+B\+A\+C\+K\+\_\+\+R\+E\+N\+E\+W}, since we want them to keep being called every time the main loop changes to/from idle state. Otherwise, if we didn't want them to be called again, they should return \hyperlink{group__Ecore__Main__Loop__Group_gae0c653baad8836232c0dc27f91f875d6}{E\+C\+O\+R\+E\+\_\+\+C\+A\+L\+L\+B\+A\+C\+K\+\_\+\+C\+A\+N\+C\+E\+L}.

The next function declared is the event callback {\ttfamily \+\_\+event\+\_\+handler\+\_\+cb}. It will check if the idler was called more than 100 times already {\ttfamily }(ctxt-\/$>$count $>$ 100), and will delete the idler, idle enterer and exiter, the timer (if it still exists), and request that the main loop stop running. Then it returns \hyperlink{group__Ecore__Main__Loop__Group_ga780091d7d49a4bb6cb753f12e1a3b19d}{E\+C\+O\+R\+E\+\_\+\+C\+A\+L\+L\+B\+A\+C\+K\+\_\+\+D\+O\+N\+E} to indicate that the event shouldn't be handled by any other callback.

Finally, we add a callback to the timer, that will just print a message when it is called, and this will happen only once (\hyperlink{group__Ecore__Main__Loop__Group_gae0c653baad8836232c0dc27f91f875d6}{E\+C\+O\+R\+E\+\_\+\+C\+A\+L\+L\+B\+A\+C\+K\+\_\+\+C\+A\+N\+C\+E\+L} is being returned). This timer callback is just here to show that the main loop gets out of idle state when processing timers too.

The {\bfseries main} function is simple, just creates a new type of event that we will use to demonstrate the event handling together with the idle state, adds the callbacks that we declared so far, fill the context struct, and starts running the main loop.

\begin{DoxyNote}{Note}
We use timer and event callbacks to demonstrate the idle state changing, but it also happens for file descriptor handlers, pipe handlers, etc.
\end{DoxyNote}

\begin{DoxyCodeInclude}
\textcolor{comment}{//Compile with:}
\textcolor{comment}{// gcc -o ecore\_idler\_example ecore\_idler\_example.c `pkg-config --libs --cflags ecore eo`}

\textcolor{preprocessor}{#ifdef HAVE\_CONFIG\_H}
\textcolor{preprocessor}{# include <config.h>}
\textcolor{preprocessor}{#endif}

\textcolor{preprocessor}{#include <Ecore.h>}
\textcolor{preprocessor}{#include <Eo.h>}
\textcolor{preprocessor}{#include <unistd.h>}

\textcolor{keyword}{struct }context   \textcolor{comment}{// helper struct to give some context to the callbacks}
\{
   \textcolor{keywordtype}{int}                  count;
   \hyperlink{group__Ecore__Idle__Group_ga361e0801c2d510e54e92b54968863ca3}{Ecore\_Idle\_Enterer}  *enterer;
   \hyperlink{group__Ecore__Idle__Group_ga2cc50b0957bf0eaf0c024a7c053fa1dc}{Ecore\_Idler}         *idler;
   \hyperlink{group__Ecore__Idle__Group_ga0481e5c5dda1fa73f4e0296ef069692b}{Ecore\_Idle\_Exiter}   *exiter;
   \hyperlink{group__Ecore__Event__Group_ga252a2566c9c7c9094964ab8e157f0521}{Ecore\_Event\_Handler} *handler;
   \hyperlink{group__Ecore__Timer__Group_gaf96ffb609956658ec038e54bd39f46f0}{Ecore\_Timer}         *timer;
\};

\textcolor{keyword}{static} \textcolor{keywordtype}{int} \_event\_type = 0; \textcolor{comment}{// a new type of event will be defined and stored here}

\textcolor{keyword}{static} \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\_Bool}
\_enterer\_cb(\textcolor{keywordtype}{void} *data EINA\_UNUSED) \textcolor{comment}{// the idle enterer callback}
\{
   printf(\textcolor{stringliteral}{"IDLE ENTERER: Ecore entering in idle state.\(\backslash\)n"});

   \textcolor{keywordflow}{return} \hyperlink{group__Ecore__Main__Loop__Group_ga1ee9db07f9a46a8b20fb83e1c6dbed09}{ECORE\_CALLBACK\_RENEW}; \textcolor{comment}{// same as EINA\_TRUE}
\}

\textcolor{keyword}{static} \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\_Bool}
\_exiter\_cb(\textcolor{keywordtype}{void} *data EINA\_UNUSED) \textcolor{comment}{// the idle exiter callback}
\{
   printf(\textcolor{stringliteral}{"IDLE EXITER: Ecore exiting idle state.\(\backslash\)n"});

   \textcolor{keywordflow}{return} \hyperlink{group__Ecore__Main__Loop__Group_ga1ee9db07f9a46a8b20fb83e1c6dbed09}{ECORE\_CALLBACK\_RENEW}; \textcolor{comment}{// same as EINA\_TRUE}
\}

\textcolor{keyword}{static} \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\_Bool}
\_idler\_cb(\textcolor{keywordtype}{void} *data) \textcolor{comment}{// the idler callback - ran while the mainloop is idle}
\{
   \textcolor{keyword}{struct }context *ctxt = data;
   printf(\textcolor{stringliteral}{"IDLER: executing idler callback while in idle state.\(\backslash\)n"});

   ctxt->count++;

   \textcolor{comment}{/* each 10 times that the callback gets called, generate an event that}
\textcolor{comment}{    * will wake up the main loop, triggering idle enterers, exiters, etc. */}
   \textcolor{keywordflow}{if} ((ctxt->count % 10) == 0)
     \hyperlink{group__Ecore__Event__Group_gacea6a144774958a7188274b79c91ee1f}{ecore\_event\_add}(\_event\_type, NULL, NULL, NULL);

   \textcolor{keywordflow}{return} \hyperlink{group__Ecore__Main__Loop__Group_ga1ee9db07f9a46a8b20fb83e1c6dbed09}{ECORE\_CALLBACK\_RENEW}; \textcolor{comment}{// same as EINA\_TRUE}
\}

\textcolor{keyword}{static} \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\_Bool}
\_event\_handler\_cb(\textcolor{keywordtype}{void} *data, \textcolor{keywordtype}{int} type EINA\_UNUSED, \textcolor{keywordtype}{void} *event EINA\_UNUSED) \textcolor{comment}{// event callback}
\{
   \textcolor{keyword}{struct }context *ctxt = data;

   printf(\textcolor{stringliteral}{"EVENT: processing callback for the event received.\(\backslash\)n"});

   \textcolor{keywordflow}{if} (ctxt->count > 100)
     \{
        \hyperlink{group__Ecore__Idle__Group_ga7e1106729c49d0cd714ef58e0343470c}{ecore\_idle\_enterer\_del}(ctxt->enterer);
        \hyperlink{group__Ecore__Idle__Group_ga89b7d6e94230fcbc331258f7aedf6010}{ecore\_idle\_exiter\_del}(ctxt->exiter);
\textcolor{comment}{//        ecore\_idler\_del(ctxt->idler);}
        eo\_unref(ctxt->idler);

        ctxt->enterer = NULL;
        ctxt->exiter = NULL;
        ctxt->idler = NULL;

        \textcolor{keywordflow}{if} (ctxt->timer)
          \{
             \hyperlink{group__Ecore__Timer__Group_gaba2b599c7aabe3ab664dc3d47f62a33a}{ecore\_timer\_del}(ctxt->timer);
             ctxt->timer = NULL;
          \}

        \hyperlink{group__Ecore__Main__Loop__Group_ga95cf8e97dff0716433c2c5474d606a98}{ecore\_main\_loop\_quit}();
     \}

   \textcolor{keywordflow}{return} \hyperlink{group__Ecore__Main__Loop__Group_ga780091d7d49a4bb6cb753f12e1a3b19d}{ECORE\_CALLBACK\_DONE}; \textcolor{comment}{// same as EINA\_FALSE}
\}

\textcolor{keyword}{static} \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\_Bool}
\_timer\_cb(\textcolor{keywordtype}{void} *data)
\{
   \textcolor{keyword}{struct }context *ctxt = data;
   printf(\textcolor{stringliteral}{"TIMER: timer callback called.\(\backslash\)n"});

   \textcolor{keywordflow}{if} (ctxt->timer)
     ctxt->timer = NULL;

   \textcolor{keywordflow}{return} \hyperlink{group__Ecore__Main__Loop__Group_gae0c653baad8836232c0dc27f91f875d6}{ECORE\_CALLBACK\_CANCEL}; \textcolor{comment}{// same as EINA\_FALSE}
\}

\textcolor{keywordtype}{int}
main(\textcolor{keywordtype}{void})
\{
   \textcolor{keyword}{struct }context ctxt = \{0\};

   \textcolor{keywordflow}{if} (!\hyperlink{group__Ecore__Init__Group_ga77757609684a2c922dc5ec398274751b}{ecore\_init}())
     \{
        printf(\textcolor{stringliteral}{"ERROR: Cannot init Ecore!\(\backslash\)n"});
        \textcolor{keywordflow}{return} -1;
     \}

   \_event\_type = \hyperlink{group__Ecore__Event__Group_ga3fad8d8bfe3776c69d33aff1f056ba89}{ecore\_event\_type\_new}();

   ctxt.enterer = \hyperlink{group__Ecore__Idle__Group_ga0805b9840716bd08ae44956dba8de3e6}{ecore\_idle\_enterer\_add}(\_enterer\_cb, &ctxt);
   ctxt.exiter = \hyperlink{group__Ecore__Idle__Group_ga4bbd02660dd2b36a2da262a9bda3dfb4}{ecore\_idle\_exiter\_add}(\_exiter\_cb, &ctxt);
   ctxt.idler = \hyperlink{group__Ecore__Idle__Group_ga048ed35688c416f1f495912a900e9297}{ecore\_idler\_add}(\_idler\_cb, &ctxt);
\textcolor{comment}{//   ctxt.idler = eo\_add(ECORE\_IDLER\_CLASS, NULL, ecore\_idler\_constructor(\_idler\_cb, &ctxt));}
   ctxt.handler = \hyperlink{group__Ecore__Event__Group_gae75b0b1b2c50e73b8e42afc628b00a62}{ecore\_event\_handler\_add}(\_event\_type,
                                          \_event\_handler\_cb,
                                          &ctxt);
   ctxt.timer = ecore\_timer\_add(0.0005, \_timer\_cb, &ctxt);

   \hyperlink{group__Ecore__Main__Loop__Group_gaf103b9f668bb3e4fed12e52c6180132d}{ecore\_main\_loop\_begin}();
   \hyperlink{group__Ecore__Init__Group_ga768298b932f18d7e7593a447493e5cde}{ecore\_shutdown}();

   \textcolor{keywordflow}{return} 0;
\}

\end{DoxyCodeInclude}
 