I have a misunderstanding about a certain Clojure/Java interop.
I'm using the Pi4J library and I want to get a listener on a GPIO Pin.
The usage documentation: https://pi4j.com/1.2/usage.html (under "Listen for Pin Changes") gives the following example:
public static class GpioUsageExampleListener implements GpioPinListenerDigital {
@Override
public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
// display pin state on console
System.out.println(" --> GPIO PIN STATE CHANGE: " + event.getPin() + " = "
+ event.getState());
}
}
// create and register gpio pin listener
myButton.addListener(new GpioUsageExampleListener());
There is also an example application: https://pi4j.com/1.2/example/listener.html
Which has:
myButton.addListener(new GpioPinListenerDigital() {
@Override
public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
// display pin state on console
System.out.println(" --> GPIO PIN STATE CHANGE: " + event.getPin() + " = " + event.getState());
}
});
So, I'm trying the following bit of Clojure code:
(import [com.pi4j.io.gpio GpioFactory GpioPinDigitalInput PinPullResistance RaspiPin]
[com.pi4j.io.gpio.event GpioPinListenerDigital])
(def gpio (GpioFactory/getInstance))
(def mybutton (.provisionDigitalInputPin gpio RaspiPin/GPIO_02 PinPullResistance/PULL_DOWN))
(def gpio-listener (reify GpioPinListenerDigital
(handleGpioPinDigitalStateChangeEvent [this event]
(println "GPIO Event Occured"))))
(.addListener mybutton gpio-listener)
But I get:
No matching method addListener found taking 1 args for class com.pi4j.io.gpio.impl.GpioPinImpl
Using reflection, I have a look at the methods available to the mybutton instance, and I can see the method is there:
(clojure.reflect/reflect mybutton)
:members
#{{
;;; Stuff trimmed
{:name addListener,
:return-type void,
:declaring-class com.pi4j.io.gpio.impl.GpioPinImpl,
:parameter-types [java.util.List],
:exception-types [],
:flags #{:public :synchronized}}
{:name addListener,
:return-type void,
:declaring-class com.pi4j.io.gpio.impl.GpioPinImpl,
:parameter-types [com.pi4j.io.gpio.event.GpioPinListener<>],
:exception-types [],
:flags #{:varargs :public :synchronized}}}}
I've checked the type of gpio-listener against GpioPinListener with success.
(cast com.pi4j.io.gpio.event.GpioPinListener gpio-listener)
#object[user$reify__7404 0x11251bd "user$reify__7404@11251bd"]
I tried type hinting the parameter to GpioPinListener, but I get the same result.
My lack of Clojure and Java knowledge is failing me here, so I'm a little lost where to look next, but I'm sure it's something really basic.