On Thu, 23 Nov 2017 10:12:40 -0200 Gustavo Sverzut Barbieri
<[email protected]> said:

> 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.

something has to queue them to be handled later anyway... so it'd need that
"event queue" mechanism to use/build on.

> - broadcast events: use Eo as below:
> 
>    * no "event type", just event object (which as its Efl_Class, of course);

that was the idea. you allocate a new event type (get an int or handle). you
then GET the event type object from the loop, then listen to "event" callback
on it. same one on every event type object. the object "represents" the event
type. since events can be posted multiple times and are not one-off, futures
don't really apply.

>    * Future efl_loop_receive_once(loop, Efl_Class event_class); // or
> better name to "receive broadcast only once"

i don't think the event queue is the place for this. if you want a one-off call
for an action you do now in the future, then return that at the time you make
the call from the action. this may use the event queue underneath as an event
bus, but the only thing that is like this in ecore that builds on top of the
queue are jobs.

>    * 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);
> 

close to what i was thinking. i was more thinking:

// called once ever in an application:
Efl_Loop_Event_Type efl_loop_event_type_new(Eo *loop, MY_EVENT_INFO_CLASS);
// called to get the object representing that event type for that loop
Eo *efl_loop_event_get(Eo *loop, Efl_Loop_Event_Type type);

// to listen to an event:
event_type_obj = efl_loop_event_get(loop, event_type_id);
efl_event_callback_add(event_type_obj, EFL_LOOP_EVENT_TRIGGERED, mycall, data);

// to post an event:
Eo *event_obj = my_event_info_event_new(event_type_obj);
efl_event_type_post(event_type_obj, event_obj);

every event type want you to create a class to represent it (they all must
inherit a base event type class). the event type object is a factory that
produces event objects (this means it also can act as a cache for them via del
intercepts for example). the factory produces event objects of some specific
type based on the class you define. you can fill in the obj with appropriate
data at creation time, then when ready, post the event to the loop by the
standard "post" method that is in the event type class. since the event type
object knows what loop it belongs to, it will post to its owning loop. some
time later as this queue is processed, the triggered event callback will be
called per object in the queue.

> 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;

i dislike this for reasons above. the promises are really the domain of the
"action" to create and handle. the event queue is just s pub/sub bus. one-off's
are what jobs are for. we already have efl_loop_job's for just this and they
are promises/futures. they need some deferring/event queue mechanism to live on
top of. they currently depend on the legacy ecore jobs which depend on
the legacy event queue. that is the thing i need to replace. i consider jobs
(one-off events) a solved problem other than replacing the use of of the legacy
ecore event and job api's inside the code. :)

>    // 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".

eina value might be another option for the event object to be posted, but i
kind of leaned to the heavier eo objects... because i know it's what we do for
input events already and it can be optimized as above to be less costly.

> 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


-- 
------------- Codito, ergo sum - "I code, therefore I am" --------------
Carsten Haitzler - [email protected]


------------------------------------------------------------------------------
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