-
Notifications
You must be signed in to change notification settings - Fork 562
Default event handlers #2011
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Default event handlers #2011
Conversation
|
👋 Welcome back mstrauss! A progress list of the required criteria for merging this PR into |
|
❗ This change is not yet ready to be integrated. |
| * @throws IllegalStateException when event delivery has already been completed | ||
| * @since 26 | ||
| */ | ||
| public final <E extends Event> void ifUnconsumed(EventHandler<E> handler) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you choose to not simply register the default handlers on the event itself? If cloning of the list is a concern, then you may choose to not modify the list when a handler is added, but instead replace it with a new list. The clone (which will likely happen far more often) can then simply copy the pointer instead of the contents.
It seems to me that the locking mechanism, and the other restrictions can then simply be dropped. At the end of bubbling, you just ask for the list and proceed with processing these handlers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As an event can be transformed as it travels through the dispatch chain, we can't effectively enforce that it only ever be cloned or copyFor'ed so that its internal fields carry over to the next event instance. Attaching the default handlers to the invocation instead of the event seems to be the safer choice here.
The locking mechanism is also intended to alert users that they're using the API incorrectly, as it is explicitly intended that ifUnconsumed() is only ever called from the event handler of that particular event.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By transformed you mean converted to a different event type?
I feel the use of the accessor pattern here is overkill. It makes a pretty neutral class representing events permanently attached to FX framework internals, for IMHO a minor benefit.
I see in the test this the case we're talking about:
@Test
void cannotAddDefaultHandlerAfterDeliveryIsComplete() {
target2.addEventFilter(EmptyEvent.ANY, e -> {
e.ifUnconsumed(e2 -> {
// This call will fail with IllegalStateException:
e2.ifUnconsumed(_ -> {});
});
});
assertThrows(IllegalStateException.class, () -> EventUtil.fireEvent(target2, new EmptyEvent()));
}
I have the impression that you could probably prevent that in EventDispatchContext. When you start iterating over defaultHandlers you could set a flag just before to "lock" it. Then in addDefaultHandler you could only allow adding more handlers if we're not already doing callbacks on the list of default handlers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By transformed you mean converted to a different event type?
Yes, for example as it is done with DirectEvent and RedirectedEvent.
I feel the use of the accessor pattern here is overkill. It makes a pretty neutral class representing events permanently attached to FX framework internals, for IMHO a minor benefit.
You won't be able to use this class without at least bringing in javafx.base, and in that case you already have all the internals. What's the concern here? Do you imagine javafx.event.Event class be useful outside of JavaFX?
In any case, I've changed the implementation to not require an accessor for Event. The currently dispatched event will instead be tracked in EventDispatchContext, where we can check whether any of its methods is called with an unexpected event instance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, the refactor looks a lot cleaner and easier to reason about, with less mutable state on event itself that's magically accessible.
|
I've added registration methods for default handlers to
|
Implementation of default event handlers.
Progress
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.org/jfx.git pull/2011/head:pull/2011$ git checkout pull/2011Update a local copy of the PR:
$ git checkout pull/2011$ git pull https://git.openjdk.org/jfx.git pull/2011/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 2011View PR using the GUI difftool:
$ git pr show -t 2011Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jfx/pull/2011.diff