my proposal on this whole topic is a bit different and hopefully simpler:

- one time, single shot (ecore jobs): reimplement as promises/future.
currently they are done on top of events (to avoid changing the
ecore_main.c), of course this needs to be reversed. Simple and clean.
Just need core changes, since efl_loop_job() returns a future already.

- broadcast events: use Eo as below:

   * no "event type", just event object (which as its Efl_Class, of course);

   * Future efl_loop_receive_once(loop, Efl_Class event_class); // or
better name to "receive broadcast only once"
   * efl_loop_receiver_add(loop, Efl_Class event_class, cb, data); //
or better name to "add broadcast receiver, like event cb"
   * efl_loop_receiver_del(loop, Efl_Class event_class, cb, data); //
or better name to "del broadcast receiver, like event cb"

   * efl_loop_broadcast(loop, event_object);

Then internally:


   // efl_loop_receive_once()
   loop->receivers[event_class]:  hash class -> array of promises to resolve.
   promise = eina_promise_new(...);
   future = efl_future_then(loop, eina_future_new(promise)); // use
efl variant to auto-delete future if loop dies!
   loop->receivers[event_class].append(promise);
   return future;


   // efl_loop_broadcast()
   event_class = efl_class_get(event);
   foreach promise of loop->receivers[event_class] {
      eina_promise_resolve(promise, eina_value_object_init(event)); //
auto-refs!
   }
   loop->receivers[event_class].clear(); // empty array. recurring
will re_schedule



   // efl_loop_receiver_add()
   future = efl_loop_receive_once(...); // use same core

   // keep info to re-schedule and "del" (unregister)
   ctx = alloc({ .event_class = event_class, .cb = cb, .data = data });
   loop->receivers.append(ctx); // or loop->receivers[event_class].append(ctx);

   future2 = eina_future_then(future, re_schedule, ctx); // future
chain that auto re-schedules and calls user
   ctx->future = future2;


  // efl_loop_receiver_del()
  foreach ctx of loop->receivers {  // or loop->receivers[event_class]
     if (ctx->event_class == event_class && ctx->cb == cb && ctx->data
== data) {
        efl_future_cancel(ctx->future);
        loop->receivers.remove(ctx);
        free(ctx);
        return true;
     }
  }
  return false; // not found


Advantages:

  - very simple to implement, basically invert Promise/Future <->
Ecore_Event handling in existing main loop;

 - Job is natively handled (since it's a promise/future in the new api);

 - single shot events are the core, very easy to manage

 - recurring events are done on top of single shot, adds one more cb,
but no big deal in performance (if it's, just reverse the structures)

 - events as proper Eo objects: give us many possibilities without
need to implement extras, like references, methods (getters, protected
setters)...

I'd not go with Eina_Value as events. It could be done, would work
exactly the same but offers less flexibility (needs copy intead of ref
count, no way to protect members). But if Eo is considered too heavy
or cumbersome, it could be used. (cumbersome: remember eolian should
help!)

For Eina_Value_Type, special care would be needed for structures...
I'm not expecting users to create new Eina_Value_Type for each event,
rather just use EINA_VALUE_TYPE_STRUCT or similar. In these cases,
"subtype" is needed, that describes the structure itself (it can be
used as event_class). Or impose it's always a structure and in this
case pass the Eina_Value_Struct_Desc instead of Eina_Value_Type as
"event_class".




On Wed, Nov 22, 2017 at 5:38 AM, Jean-Philippe André <[email protected]> wrote:
> Hi,
>
> I talked to raster for clarification.
>
> 2017-11-22 14:57 GMT+09:00 Carsten Haitzler <[email protected]>:
>
>> So we had a partly done move to efl_loop. it still was all built on top of
>> the
>> main loop globals. If this is all done right then we can have multiple
>> loops
>> (e.g. one per thread) and that is a good thing.
>>
>> So I've been fixing that. I've done just about all the globals in ecore
>> EXCEPT
>> ecore events. I now have to think about how to do this in eo/interfaces
>> with
>> efl loop objects and so on. I'm mulling how to do it.
>>
>> We still have some need for a deferred event bus/queue. A lot of things
>> that
>> are ecore events should be callbacks on objects directly and that's being
>> fixed, but an event queue + types is still needed.
>>
>> So there are a few aspects to this.
>>
>> 1. Creating of new event types at runtime (and allocating a unique
>> identifier
>> for them).
>> 2. Being able to submit them to a queue to be "processed later"
>> 3. Being able to call callbacks that are listening for that type of event
>> and
>> hand them the deferred event data.
>>
>> This is used as the backing for ecore_jobs and pretty much every i/o thing
>> (input events, i/o and more) as well as in-process custom event bus+events.
>>
>> My current thought is this.
>>
>> 1. event types are still ints with a single global shared backing table of
>> all
>> event types (allocated once ever much like atoms in x).
>> 2. event event is an eo object on the queue (of some type).
>> 3. some event object "factory" on the loop that creates and "deletes"
>> (caches
>> then) these event objects for recycling.
>>
>> Does anyone have better ideas? I considered the event type being an object
>> itself and also doubling as a factory per event type but due to multiple
>> threads you'd probably be creating an object then per thread per event
>> type and
>> I do not like that.
>
>
>
> Basically we have two base EO types:
>
>  - "ecore event type" EO class:
> singleton per loop, it's a handle
> you can request the loop for the handle  given the UUID
> contains the read-only UUID, maybe a string description, and an EO event
> "received" or whatever
> created and managed by the Efl.Loop (each Loop would need to create their
> own handles)
> listeners add an EO callback for "received" to that handle, this keeps the
> listeners list per loop
> the loop has a special function to send an event
>
>  - "ecore event info" EO class:
> an ecore event that carries no info could even use null
> event info is a base class with a link to its type
> the loop creates and manages these temporary objects as events are being
> processed
>
>
> This is consistent with input events (info type are EO objects with a
> common base class).
> I see no major issue with this design, besides extra memory requirements.
>
> --
> Jean-Philippe André
> ------------------------------------------------------------------------------
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, Slashdot.org! http://sdm.link/slashdot
> _______________________________________________
> enlightenment-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/enlightenment-devel



-- 
Gustavo Sverzut Barbieri
--------------------------------------
Mobile: +55 (16) 99354-9890

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to