Split @Event Parameters Into @Polymorphic and @Property, Remove Marker Interfaces #5
Labels
No Label
1
13
2
21
3
34
5
55
8
bug
core
could have
duplicate
enhancement
help wanted
must have
proc
question
should have
wont have
L
M
S
XL
bug
bugfix
discussion
documentation
feature
maintenance
postponed
refactoring
wontfix
No Milestone
No Assignees
2 Participants
Notifications
Due Date
Dependencies
No dependencies set.
Reference: zdm/event-bus#5
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "f/new-annotations"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This pull request removes the parameters
includeSubtypes
andpriority
from theEvent
annotation in favor of the two annotations@Polymorphic
and@Priority
.Using separate annotations for optional parameters not only improves legibility, but also allows extensions of the event API without modifying the
@Event
annotation or evenevent-bus-core
for that matter.This is an essential step in the direction of sub-modules that integrate with frameworks like Swing and JavaFX and their respective event APIs.
Additionally, the marker interfaces
EventListener
andIEvent
have been removed as they serve no actual purpose and prevent Event Bus from directly interfacing with preexisting objects without their modification.Split @Event Parameters Into @Polymorphic and @Propertyto Split @Event Parameters Into @Polymorphic and @Property, Remove Market InterfacesSplit @Event Parameters Into @Polymorphic and @Property, Remove Market Interfacesto Split @Event Parameters Into @Polymorphic and @Property, Remove Marker Interfaces👍
@ -68,3 +68,3 @@
public void dispatch(IEvent event) {
public void dispatch(Object event) {
Objects.requireNonNull(event);
logger.log(Level.INFO, "Dispatching event {0}", event);
theoretically you can even save a line here by inlining
Objects.requireNonNull
I coould, but this would mix the actual logic of the method with the logging and bloat up the line.
@ -135,3 +135,3 @@
*/
public void registerListener(EventListener listener) throws EventBusException {
public void registerListener(Object listener) throws EventBusException {
Objects.requireNonNull(listener);
This line can again be inlined
Also something I noticed:
Maybe it wouldn't be a bad idea to use a
WeakReference
for referencing the object instead (or another one of these gc-able references).Otherwise, we might end up with a memory leak in Java as no object defined as event handler can ever be garbage collected, even if they would otherwise be garbage collected.
But isn't that what we want to achieve? A dedicated event listener would not necessarily be referenced from other classes apart from
EventBus
. Also,EventBus
allows the deletion of event listeners, so I don't see this as much of a problem.@kske Yes, but that assumes that a user manually unregisters any registered object that should be gc-able. But think to our own use cases: Did we ever use
removeListener
? I can't remember a single instance where we used that.And as we now no longer require EventListeners, which signify that the object is supposed to be long lasting, we can now declare anything as an event listener. So, what could potentially happen is that we register i.e. a list for a certain event, and then we swap out the list for another list. The only reason why this list will stay inside the memory is because of the reference from
EventBus
.Do you remember i.e. the edge cases in Envoy where we wanted to add an event listener on the content of a cell, but couldn't as it would lead to unpredictable results? Doing that would then be possible.
With swap I mean rereference (i.e.
eventBus.register(list);
list = new ArrayList<>()
eventBus.register(list);
).This would lead to a memory leak in the current implementation.
With the proposed mechanism this would be possible.
@ -173,3 +173,3 @@
public void removeListener(EventListener listener) {
public void removeListener(Object listener) {
Objects.requireNonNull(listener);
logger.log(Level.INFO, "Removing event listener {0}", listener.getClass().getName());
Isn't the
Objects.requireNonNull
unnecessary overhead? A null pointer exception will be thrown the momentgetClass()
gets called one line below.It would, but
Objects.requireNonNull
makes it immediately obvious to the caller that the parameter has to be non-null. I agree that it doesn't make much of the difference, but as it's handled like this in multiple methods I won't bother changing it for somethign equivalent.@ -72,3 +78,3 @@
@Override
public int compareTo(EventHandler other) {
int priority = other.annotation.priority() - annotation.priority();
int priority = other.priority - this.priority;
What about using
Integer.compare(this.priority, other.priority)
?Or is that too much overhead? 😉
Actually, yes I think so.
Integer.compare
callsInteger.valueOf
two times, generating two objects in the process just to execute a statement similar to the one I wrote.But, to your credit, I didn't even consider the possibility, to thanks for the suggestion :)
@ -90,3 +98,3 @@
* @since 0.0.1
*/
void execute(IEvent event) throws EventBusException {
void execute(Object event) throws EventBusException {
Why is that now an object instead of an event?
Because I got rid of the
IEvent
interface so that every object can be used as an event.be38c1fd02
to002180ed3b