bilus / om-event-bus

Simple event handling for om components.
Eclipse Public License 1.0
30 stars 1 forks source link

What's the advantage of om-event-bus compared with give an async/chan to :shared #2

Closed xfsnowind closed 1 year ago

xfsnowind commented 9 years ago

Hi, These days we are using om-event-bus in our project and it works quite well. But when I was re-evaluating our project, I found if we give a core.async/chan in :shared field of om's function root, all the children node are able to get it simply by get-shared. What it needs is just owner.

So it's quite easy and simple to put value in this channel in the children nodes and get them out of the root element. That is almost same behavior with when om-event-bus doing bubbling. And the same to trickling. The only thing that om's :shared functionality cannot do is maybe the xform thing, It may be a little bit harder. I haven't think about it. Otherwise, from the user story, I didn't find any advantage to use om-event-up than just channel in :shared.

Forgive my english and maybe I didn't deeply understand the requirements or other functionalities, can you explain?

bilus commented 9 years ago

Good point indeed. You can certainly use :shared except you need to use mult etc. so an event can be consumed by more than one component (components peek at events to see if they're interested). This means you have to pass a mult via :shared but also manage tapping and untapping when components are mounted/unmounted. I created the library because I was fed up with doing this manually. In the essence it's all it does: for any component that implements one of the three 'got-event' protocols, it subscribes them to a mult while at the same ensuring events are delivered in the correct order (which isn't the case with a mult being just passed around).

The interesting bits are here: https://github.com/bilus/om-event-bus/blob/master/src/cljx/om_event_bus/impl.cljx They are platform-agnostic you could even use them in Clojure to build event buses like this.

With Om, you can use event buses to create 're-frame' implemented in Om (to send events to handlers). https://github.com/Day8/re-frame

Having said that, using too many events definitely goes against the grain of how things 'should be done' in Om so I wouldn't overuse it. On the other hand, it's better to have a structure of orderly event buses instead of a spaghetti of ad-hoc channels passed arounds. The latter requires more effort to build a mental model.

I hope it answers your question. :)

xfsnowind commented 9 years ago

Thanks for your reply!

What om-event-bus provides is just a way for every component to communicate with one another, no matter directions. And that's also what om's root function's option :shared can offer. I don't think we need to pass a mult to :shared, a chan is enough. I have changed to use :shared in our project and it works as before, which is nice. But it's impressive that you implement this functionality manually.

Actually, I tried to read the impl code, it's awesome. But unfortunately, I didn't have too much experience in protocol and reify to understand how this leg function is implemented before being called.

bilus commented 9 years ago

The scenario I had in mind when I said you cannot use a chan is when you want to send messages from one component to multiple child/parent components. With one-to-one communication certainly a single chan is exactly what you need. With one-to-many you need a broadcast mechanism.

The code is pretty complex and I wouldn't been able to get it right without a battery of tests (https://github.com/bilus/om-event-bus/blob/master/test/clj/om_event_bus/impl_test.clj). :) As a side note, protocols are awesome. It's amazing how you don't need inheritance etc. when you user protocols and multimethods.

xfsnowind commented 9 years ago

Yes, you are right. In this scenario, a broadcast is needed.

As you recommended, maybe I should tried to write sth with protocols. Anyway, Thanks for your reply!