Closed edwinyzh closed 4 years ago
I believe - with the new interface-typed event, you can freely add returned value in user-defined interface-typed event.
I didn't get it to be honest @edwinyzh . The return type of post would be the same of the passed one? https://github.com/spinettaro/delphi-flux-seed satisfies your request?
I didn't get it to be honest @edwinyzh . The return type of post would be the same of the passed one? https://github.com/spinettaro/delphi-flux-seed satisfies your request?
The requirement is simple - turn the eventbus from unidirectional to bi-directional.
@edwinyzh
You can make it "bi-directional" with the latest interface-typed event. You can delegate the callback to the event emitter via a designated user-defined interface event method. Is that what you are looking for?
Overall, bidirectional communication would make the work flow hard to manage. It is just like the infamous "GOTO" of procedural languages.
In a one-to-many publisher/subscriber setting while in thread mode other than TThreadMode.Posting, DIRECTLY returning a value from IEventBus.Post does NOT make any sense. Pointless in my eyes. It unnecessarily complicates the design of delphi_event_bus, which is intended (as I see it) to be a lightweight and flexible Event Bus framework.
@wxinix,
You explained it very well! I'm convinced ;) You are right, it seems that directly returning a value by in a 1-to-many eventBus system doesn't make much sense and make things complicated as well!
Actually I can/already achieved bidirectional communication by sending back something like TEventReceivedYourReuqest
;)
I'll check the new interface-typed event, but I'm current hesitant to upgrade because I'm using a customized TEventBus
, maybe sometime later.
Thank you for all you guys' contribution to the EventBus lib!
@edwinyzh The latest delphi_event_bus framework makes use of interface-typed event, instead of TObject in previous version. This means - when routing an event from the event emitter to subscriber methods, there is no longer internal copying of the event object --- the emitter and subscription methods are now dealing with the same event object.
Thanks to @spinettaro , for this new framework design, which is very neat and greatly improves on previous versions.
This allows us to implement a "bidirectional communication" like below:
TOnEventReceived = reference to procedure(AMessage: string); // You can use anonymous methods, or method ptrs
IMyFunkyEvent = inteface
['{3522E1C5-547F-4AB6-A799-5B3D3574D2FA}']
procedure Set_OnEventReceived(AValue: TOnEventReceived);
function Get_OnEventReceived: TOnEventReceived;
property OnEventReceived: TOnEventReceived read Get_OnEventReceived write Set_OnEventReceived;
end;
Then from the subscriber method (assuming Posting thread mode), you can callback the emitter:
[Subscribe]
procedure OnMyFunkyEvent(AEvent: IMyFunkyEvent);
begin
// manage the event
if Assigned(AEvent.OnEventReceived) then
AEvent.OnEventReceived(); // Calling back the emitter here to send back stuff
end;
Thus you see, a "bidirectional communication" is easily accomplished via this new interface-typed event, which should meet your requirement.
@wxinix,
Thanks for the demonstration, It's VERY GOOD! GREAT! In my experience I believe cloning of the event objects with the slow Extended RTTI has been the bottleneck of performance in some situations!
I should have checked the updated readme file for DEB 2.0 ;)
One side effect of the 2.0 change - for each event you'll have to define an object and an interface ;)
thanks @wxinix for the explanation :) . @edwinyzh pay attention with the bidirectional communication as we have seen in other frameworks, ie Flux from Facebook, having a unidirectional flow is much better in term of readability, maintainability and troubleshooting sessions...
My stupid question is: finally, EventBus is freeing any Event object after replying?
Also, I believe the above example should exist also in the frontpage readme file of EventBus
Now the events are interfaces. So we are relying on the reference counting mechanism for interfaces. MM is not required anymore.
Is it reasonable to make the
TEventBus.Post
method be able to return a value (can be any type of value, a TObject or TValue? not sure)?The idea is like the `SendMessage' winapi.
It's very necessary, in case we use an event to represent an action (a concept borrowed from Redux action.
That being said, I want to achieve an application architecture, where:
the modification of the model is centralized in a single module (which will subscribe events from other modules - including, but not limited to the UI),
and the other modules will not modify the model directly, but only post through the EventBus "action events" to describe what they desire the model to change.
And it must come in handy if the event posting would be able to return values when posting to the same thread.
Not sure if I have described it clearly, but I mainly have inspired by Redux Framework.
I hope this makes sense.
And this stackoverflow question might help understanding my suggestion: React.js - flux vs global event bus