Closed fogti closed 4 years ago
Looks good so far.
Also I believe cleanup
can be optimized; right now we look for the lowest index, which is O(n), but if we keep track of the lowest index through peek
, add/remove_listener
then we can speed up that part of the cleanup process.
When we call cleanup
after every peek
, we can assume more about the state of the listeners
map.
Edit: ok. I tried it and ran it through the benchmarks. It doesn't improve the timings. code, better code
Another approach is to use BTreeMap
, it would reduce iter().min()
time from O(n) to O(log n).
I've branched the current code and I've split the code into a workspace in master. Namely I want to keep the original event implementation by default within the core package and have advanced events as a feature of the core package.
Another approach is to merge the listeners+events
, e.g. transform from Struct-of-Arrays
to Array-of-Structs
. Edit: Tested, worse timings.
I tested BTreeMap
. It is slower than SlotMap
.
P.S. rebase of #3 against #2 : zserik:count-down-action
Another thing which would be interesting: A more advanced usage of events would be filtered cascading, e.g. all events from Event
A
, such that predicate/Fn f
returns true are automatically cloned and pushed to Event
B (and maybe dropped from Event
A
).
Another use case would be waiting for one of serval event (queues) to become ready. I implemented a POC using crossbeam-channel
here
Edit: done.
I think rather than cascading events, there could be a specialized implementation of EventListen
based on multiple sub-listeners, where it listens to multiple events at one time, and when peek
is called it concatenates all the events from each of it's sub-listeners.
We should also be thinking about nonts
performance. The Rc/RefCell
has some overhead which may become noticeable in a very large UI.
ok, I opened a new draft PR.
another suggestion: maybe rename the derive(Widget)
to derive(WidgetChildren)
for better consistency?
Reference: https://www.reddit.com/r/rust/comments/dr04ce/reclutch_a_simple_rust_ui_foundation/f6e1bu2/
I think it is a good idea to split the reclutch sources into multiple independent parts, because the
Event
traits+structs have no dependencies with the widget+gfx backend.Additional notes regarding
reclutch-event
!Send, !Sync
implementation (nonts.rs
)Send + Sync
implementation (ts.rs
)HashMap
toSlotMap
, which fits this use case better, but benchmarking both might be required.Mutex
toRwLock
because a full lock is not always required.Rc<RefCell<>>
vsArc<RwLock<>>
(traits.rs:mod private
)That split is necessary to prevent the atomics+locking costs when the signal-handling only happens inside one thread (GUI-events often only happen inside one dedicated thread), and, on the other hand, allow cross-thread events (non-GUI-events often spread over various threads.
crossbeam-channel
is often preferred for simple thread communication via message-passing, but doesn't work (as far as I know) when multiple independent listeners need to listen on the same events (broadcasting)). It is neat to cover both inside a common interface. I tried experimenting witharchery
, but that won't really cover this use case neatly.