Removing generics in EventHandler

I would like to move the getHandler() method from AbstractDetector upward in the EventDetector interface, were it really belongs. I have created issue 1016 for this.

As part of implementing this, I stumbled upon a problem that has some deep consequences. As the EventHandler interface is parameterized with the type of event detector, the signature of the getHandler method depends on the handler. So we get a circular dependency, with the handler depending on the detector and the detector depending on the handler. I tried several approaches to solve this and failed miserably. It became more and more complex with things like

   public interface EventDetector<D extends EventDetector<D, H>, H extends EventHandler<D, H>> {
      ...
   }

   public interface EventHandler<D extends EventDetector<D, H>, H extends EventHandler<D, H>> {
      ....
   }

   public abstract class AbstractDetector<T extends AbstractDetector<T, D, H>,
                                          D extends EventDetector<D, H>,
                                          H extends EventHandler<D, H>>
    implements EventDetector<D, H> {
      ...
   }

In some cases, at least in the tests, we sometime set up generic handlers (declared to implement EventHandler<EventDetector>) to specific detectors. This is probably the reason why in some methods we have to make use of super in the signature. At other places, we have a roughly reversed use case, with generic detectors that could wrap other detectors (boolean detectors, shifter…). We also have an EventMultipleHandler were one detector has several handlers.

I was not able to deal with all these uses cases and finally gave up.

Looking back at the root cause, it seems to be related to the event detector type in the signature of the init, eventOccurred and resetState in the handler. In fact, all cases I have ever encountered fall in two categories only:

  • general handlers that do not even use the detector passed as an argument
  • highly specific handlers that work only with exactly one type and already know this type

The current API is devoted to this second case, and enforces the type in the signature.

I am wondering if we could simplify the API and have EventHandler made non-generic and use just EventDetector in the signature of the methods, and let the implementation of the handler do a cast if required when it really needs to recover some data from the detector.

I have tried this and it works well. It simplifies also a lot the API, mainly for people having to implement the create method from AbstractDetector with its puzzling signature.

I have started a branch for this change: remove-generics-in-event-handler. For now, it contains only the change for double, I will do the field version later this evening and push it too.

I would like to have everyone’s opinion about this change, as it is a big change.

+1
Thanks @luc for this analysis. I’m very much in favor of this simplification of the EventHandler API and the upcoming release 12.0 is the opportunity for such a change.