SWIGJAVA: Remove the last JAVA ifdefs from src

Removed all references to #ifdef SWIGJAVA and JAVACALLBACK from the
library source.  All java-specific source code has been moved to the
corresponding library's .i file for java.

    * Update library source
    * Update examples where necessary
    * The function pointer methodology has been remove from libraries
      which provided callbacks as both a class and a function pointer
      implementation.  Examples were updated to use the class version
      of callbacks.
    * Updated documentation for SWIGJAVA

Signed-off-by: Noel Eck <noel.eck@intel.com>
This commit is contained in:
Noel Eck 2018-01-23 11:58:12 -08:00
parent d49ab2ac95
commit 666452e873
44 changed files with 280 additions and 509 deletions

View File

@ -33,66 +33,66 @@ As much as possible, avoid passing values/returning values through pointers give
#### Alternatives:
1. Functions that read data from a driver, return it through a pointer given as argument, and return a bool value, should be __replaced by__ functions that return the value directly and throw a std::runtime_error if a read error occurs. E.g.:
```c++
/*
* Function reads from sensor, places read value in variable bar and
* returns true if succesful. Function returns false if read failed.
*/
bool func(int *bar);
/*
* Function reads from sensor, places read value in variable bar and
* returns true if succesful. Function returns false if read failed.
*/
bool func(int *bar);
```
__Replaced by:__
```c++
/*
* Function reads from sensor and returns read value.
* Or throws std::runtime_error if a read error occurs
*/
int func();
/*
* Function reads from sensor and returns read value.
* Or throws std::runtime_error if a read error occurs
*/
int func();
```
2. Functions that return multiple values through pointers, that make sense to be grouped together into an array<sup>1</sup> (e.g. speed values, acceleration values), should be __replaced by__ functions that return a pointer to an array in which the elements are the returned values. Afterwards, [wrap the C array with a Java array](#wrapping-unbound-c-arrays-with-java-arrays-if-array-is-output). E.g.:
```c++
/*
* Function returns the acceleration on the three
* axis in the given variables.
*/
void getAccel(int *accelX, int *accelY, int *accelZ);
/*
* Function returns the acceleration on the three
* axis in the given variables.
*/
void getAccel(int *accelX, int *accelY, int *accelZ);
```
__Replaced by:__
__Replaced by:__
```c++
/*
* Function returns the acceleration on the three
* axis as elements of a 3-element array.
*/
int *getAccel();
/*
* Function returns the acceleration on the three
* axis as elements of a 3-element array.
*/
int *getAccel();
```
3. Functions that return N values through pointers, that do not make sense to grouped together (e.g. a general purpose function that returns both the light intensity and air pollution), should be __replaced by__ N functions (one for each value) that read only one specific value. E.g.:
```c++
/*
* Function returns the light intensity and air pollution
*/
void getData(int *light, int *air);
/*
* Function returns the light intensity and air pollution
*/
void getData(int *light, int *air);
```
__Replaced by:__
__Replaced by:__
```c++
int getLight();
int getAir();
int getLight();
int getAir();
```
4. Functions that return N values through pointers; values that do not make sense to be grouped together, but are time dependent, and make sense to be read at the same time. For example, a sensor that reads air humidity and temperature. A user may want to know the temperature value _temp_ read at the exact moment the humidity value _humid_ was read. These should be __replaced by__ N+1 functions: a _getData()_ function that reads all values at the same time and stores them in global variables; and N getter functions, one for each value. E.g.
```c++
/*
* Function returns the light intensity and air pollution
*/
void getData(int *temp, int *humid);
/*
* Function returns the light intensity and air pollution
*/
void getData(int *temp, int *humid);
```
__Replaced by:__
__Replaced by:__
```c++
void getData();
int getTemp();
int getHumid();
void getData();
int getTemp();
int getHumid();
```
<sup>1</sup>this depends on the interpretation of the returned data. For example, arguments that return the temperature and light intensity, don't make sense to be grouped into an array of size 2. But acceleration on the three axis can be grouped together in an array of size 3. where accelX is accel[0], accelY is accel[1], accelZ is accel[2].
@ -124,18 +124,18 @@ The exception.i library file provides support for creating language independent
```c++
// Language independent exception handler
%include exception.i
// Language independent exception handler
%include exception.i
%exception {
try {
$action
} catch(OutOfMemory) {
SWIG_exception(SWIG_MemoryError, "Out of memory");
} catch(...) {
SWIG_exception(SWIG_RuntimeError,"Unknown exception");
}
}
%exception {
try {
$action
} catch(OutOfMemory) {
SWIG_exception(SWIG_MemoryError, "Out of memory");
} catch(...) {
SWIG_exception(SWIG_RuntimeError,"Unknown exception");
}
}
```
In the upm library, the upm_exception.i interface file provides the functionality to catch common exceptions and propagate them through SWIG. It uses the exception.i library file and is language independent.
@ -157,15 +157,15 @@ The upm_exception.i interface file is included in the upm.i file, therefor SWIG
To throw a specific Java exception:
```c++
%exception {
try {
$action
} catch (std::out_of_range &e) {
jclass clazz = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(clazz, "Range error");
return $null;
}
}
%exception {
try {
$action
} catch (std::out_of_range &e) {
jclass clazz = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(clazz, "Range error");
return $null;
}
}
```
Where FindClass and ThrowNew are [JNI functions](http://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html).
@ -177,21 +177,21 @@ The C++ compiler does not force the code to catch any exception.
The %exception directive does not specify if a method throws a checked exception (does not add classes to the throws clause). For this, the %javaexception(classes) directive is used; where classes is a string containing one or more comma separated Java classes.
```c++
%javaexception("java.lang.Exception") {
try {
$action
} catch (std::out_of_range &e) {
jclass clazz = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(clazz, "Range error");
return $null;
}
}
%javaexception("java.lang.Exception") {
try {
$action
} catch (std::out_of_range &e) {
jclass clazz = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(clazz, "Range error");
return $null;
}
}
```
In the upm library, the java_exceptions.i library file provides the functionality to catch exceptions and propagate them through SWIG as Java checked exceptions. The file provides SWIG wrappers, in the form of macros, that can be applied to methods.E.g. use the __READDATA_EXCEPTION(function)__ macro for functions that read data from a sensor and throw a std::runtime_error in case of a read failure. This will result in:
```java
void function throws IOException ();
void function throws IOException ();
```
## Caveats & Challenges
@ -203,84 +203,73 @@ SWIG can wrap arrays in a more natural Java manner than the default by using the
Functions that return arrays, return a pointer to that array. E.g.:
```c++
/*
* Function returns the acceleration on the three
* axis as elements of a 3-element array.
*/
/*
* Function returns the acceleration on the three
* axis as elements of a 3-element array.
*/
int *getAccel();
int *getAccel();
```
__SWIG:__
__SWIG:__
```c++
%typemap(jni) int* "jintArray"
%typemap(jstype) int* "int[]"
%typemap(jtype) int* "int[]"
%typemap(jni) int* "jintArray"
%typemap(jstype) int* "int[]"
%typemap(jtype) int* "int[]"
%typemap(javaout) int* {
return $jnicall;
}
%typemap(javaout) int* {
return $jnicall;
}
%typemap(out) int *getAccel {
$result = JCALL1(NewIntArray, jenv, 3);
JCALL4(SetIntArrayRegion, jenv, $result, 0, 3, (const signed int*)$1);
}
%typemap(out) int *getAccel {
$result = JCALL1(NewIntArray, jenv, 3);
JCALL4(SetIntArrayRegion, jenv, $result, 0, 3, (const signed int*)$1);
}
```
### Wrapping unbound C arrays with Java arrays if array is input
In C, arrays are tipically passed as pointers, with an integer value representig the length of the array. In Java, the length of an array is always known, so the length argument is redundant. This example shows how to wrap the C array and also get rid the length argument. E.g.:
```c++
void func(uint8_t *buffer, int length);
void func(uint8_t *buffer, int length);
```
__SWIG:__
__SWIG:__
```c++
%typemap(jtype) (uint8_t *buffer, int length) "byte[]"
%typemap(jstype) (uint8_t *buffer, int length) "byte[]"
%typemap(jni) (uint8_t *buffer, int length) "jbyteArray"
%typemap(javain) (uint8_t *buffer, int length) "$javainput"
%typemap(jtype) (uint8_t *buffer, int length) "byte[]"
%typemap(jstype) (uint8_t *buffer, int length) "byte[]"
%typemap(jni) (uint8_t *buffer, int length) "jbyteArray"
%typemap(javain) (uint8_t *buffer, int length) "$javainput"
%typemap(in,numinputs=1) (uint8_t *buffer, int length) {
$1 = JCALL2(GetByteArrayElements, jenv, $input, NULL);
$2 = JCALL1(GetArrayLength, jenv, $input);
}
%typemap(in,numinputs=1) (uint8_t *buffer, int length) {
$1 = JCALL2(GetByteArrayElements, jenv, $input, NULL);
$2 = JCALL1(GetArrayLength, jenv, $input);
}
```
!!!! There is a difference between TYPE *name and TYPE * name in typemaps!!!!!
### Implementing callbacks in Java
Callbacks in the UPM Java library (as well as the MRAA Java library) make use of the _void mraa\_java\_isr\_callback(void\* data\)_ method from MRAA.
Callbacks in the UPM Java library (as well as the MRAA Java library) make use of the _void mraa\_java\_isr\_callback(void\* data\)_ method from MRAA.
__Callbacks in the UPM Java library are implemented as follows (we use the a110x Hall Effect sensors as example):__
We extend the sensor class with another method, _installISR\(jobject runnable\)_, which is a wrapper over the original _installISR\(void \(\*isr\)\(void \*\), void \*arg\)_ method. This will install the _mraa\_java\_isr\_callback\(\)_ method as the interrupt service routine \(ISR\) to be called, with _jobject runnable_ as argument.
SWIGJAVA is a symbol that is always defined by SWIG when using Java. We enclose the _installISR\(jobject runnable\)_ method in a _\#if defined(SWIGJAVA)_ check, to ensure the code only exists when creating a wrapper for Java.
Java callbacks are added at the SWIG interface level. For ease-of-use, a collection of macros are available in src/_upm.i.
src/a110x/javaupm_a110x.i:
```c++
#if defined(SWIGJAVA)
void A110X::installISR(jobject runnable)
{
installISR(mraa_java_isr_callback, runnable);
}
#endif
JAVA_ADD_INSTALLISR(upm::A110X)
```
We hide the underlying method, _installISR\(void \(\*isr\)\(void \*\), void \*arg\)_ , and expose only the _installISR\(jobject runnable\)_ to SWIG, through the use of the SWIGJAVA symbol. When SWIGJAVA is defined, we change the access modifier of the underlying method to private.
Will expand to the following SWIG wrapper code:
```c++
public:
#if defined(SWIGJAVA)
void installISR(jobject runnable);
#else
void installISR(void (*isr)(void *), void *arg);
#endif
private:
#if defined(SWIGJAVA)
void installISR(void (*isr)(void *), void *arg);
#endif
SWIGINTERN void upm_A110X_installISR__SWIG_1(upm::A110X *self,jobject runnable){
self->installISR(mraa_java_isr_callback, runnable);
}
```
To use callback in java, we create a ISR class, which implements the Java Runnable interface, and we override the _run\(\)_ method with the code to be executed when the interrupt is received. An example for the a110x Hall sensor that increments a counter each time an interrupt is received:
@ -288,13 +277,13 @@ To use callback in java, we create a ISR class, which implements the Java Runnab
```java
public class A110X_intrSample {
public static int counter=0;
public static void main(String[] args) throws InterruptedException {
upm_a110x.A110X hall = new upm_a110x.A110X(2);
A110XISR callback = new A110XISR();
hall.installISR(callback);
while(true){
System.out.println("Counter: " + counter);
Thread.sleep(1000);
@ -311,39 +300,3 @@ class A110XISR implements Runnable {
}
}
```
#### Issues with java callbacks and workarounds
__SWIGJAVA not defined at compile time__
Consider the following files:
* example.h - Header file for our source file
* example.cxx - Source file containing the class Example, for which we build java bindings
* example.i - The SWIG interface, that includes the example.h header file
The build process of a java module using SWIG is split into two steps:
1. Generating the intermediate files, from the SWIG interface file. This will produce the java class file (Example.java), the JNI file (exampleJNI.java) and wrapper file (example_wrap.cxx). The source file (example.cxx) is not needed in the first step.
```
swig -c++ -java example.i
```
2. Generating the shared library from the C++ sources and wrapper file
```
g++ -fPIC -c example.cxx example_wrap.cxx -I/usr/lib/jvm/java-1.8.0/include -I/usr/lib/jvm/java-1.8.0/include/linux
g++ -shared example_wrap.o sensor.o -o libexample.so
```
SWIGJAVA is always defined when SWIG parses the interface file, meaning it will be defined when it parses the header file (example.h) that is included in the interface file (example.i).
SWIG also adds the "#define SWIGJAVA" directive in the wrapper file (example_wrap.cxx).
However, in generating the shared library the SWIGJAVA symbol is only defined in the example_wrap.cxx file, because of the added "#define SWIGJAVA" directive. But we have also used the "#if defined(SWIGJAVA)" check in the source file (example.cxx), and thus need to define SWIGJAVA for it too. If we define the SWIGJAVA symbol as a compile flag, when compiling the source code to object code, the SWIGJAVA compile flag and #define SWIGJAVA" directive will clash and give a double definition warning (only a warning).
In this example it is simple to compile the two source codes separately, one with the compile flag, the other without, and then create the shared library (libexample.so).
But in a big automatic build like the java upm libraries, this may prove too hard or too complicated to do. A workaround to this would be to define a custom symbol (e.q. JAVACALLBACK in the upm library) and also test for it. In short, replace:
```c++
#if defined(SWIGJAVA)
```
by
```c++
#if defined(SWIGJAVA) || defined(JAVACALLBACK)
```

View File

@ -46,22 +46,33 @@ sig_handler(int signo)
}
//! [Interesting]
void
nrf_handler()
class mycb : public virtual Callback
{
std::cout << "Reciever :: " << *((uint32_t*) &(comm.m_rxBuffer[0])) << std::endl;
}
public:
mycb(upm::NRF24L01 *com) : _com(com) {}
virtual void run()
{
if (_com != NULL)
std::cout << "Reciever :: " << *((uint32_t*) &(_com->m_rxBuffer[0])) << std::endl;
else
std::cout << "Example callback!" << std::endl;
}
private:
upm::NRF24L01* _com;
};
int
main(int argc, char** argv)
{
mycb cb(&comm);
comm.setSourceAddress((uint8_t*) local_address);
comm.setDestinationAddress((uint8_t*) broadcast_address);
comm.setPayload(MAX_BUFFER);
comm.configure();
comm.setSpeedRate(upm::NRF_250KBPS);
comm.setChannel(99);
comm.setDataReceivedHandler(nrf_handler);
comm.setDataReceivedHandler(&cb);
signal(SIGINT, sig_handler);

View File

@ -46,10 +46,21 @@ sig_handler(int signo)
}
}
void
nrf_handler()
class mycb : public virtual Callback
{
}
public:
mycb(upm::NRF24L01 *com) : _com(com) {}
virtual void run()
{
if (_com != NULL)
std::cout << "Reciever :: " << *((uint32_t*) &(_com->m_rxBuffer[0])) << std::endl;
else
std::cout << "Example callback!" << std::endl;
}
private:
upm::NRF24L01* _com;
};
int
main(int argc, char** argv)
@ -57,12 +68,14 @@ main(int argc, char** argv)
//! [Interesting]
uint32_t dummyData = 0;
upm::NRF24L01 comm(7, 8);
mycb cb(&comm);
comm.setSourceAddress((uint8_t*) srcAddress);
comm.setDestinationAddress((uint8_t*) destAddress);
comm.setPayload(MAX_BUFFER);
comm.setChannel(99);
comm.configure();
comm.setDataReceivedHandler(nrf_handler);
comm.setDataReceivedHandler(&cb);
signal(SIGINT, sig_handler);

View File

@ -42,17 +42,24 @@ sig_handler(int signo)
}
}
void
handler(clbk_data data)
//! [Interesting]
class mycb : public virtual Callback
{
printf("callback data (%d)\n", data.is_heart_beat);
}
public:
virtual void run(clbk_data arg)
{
printf("callback data (%d)\n", arg.is_heart_beat);
}
};
int
main(int argc, char** argv)
{
mycb cb;
//! [Interesting]
Pulsensor sensor(handler);
Pulsensor sensor(&cb);
sensor.start_sampler();
while (!doWork) {

View File

@ -23,12 +23,14 @@
*/
//NOT TESTED!!!
import java.util.AbstractList;
import java.lang.Float;
public class H3LIS331DLSample {
public static void main(String[] args) throws InterruptedException {
//! [Interesting]
int[] val;
float[] accel;
// Instantiate an H3LIS331DL on I2C bus 0
upm_h3lis331dl.H3LIS331DL sensor = new upm_h3lis331dl.H3LIS331DL(0);
@ -39,14 +41,14 @@ public class H3LIS331DLSample {
while(true){
sensor.update();
val = sensor.getRawXYZ();
System.out.println( "Raw: X: " + val[0] + " Y: " + val[1] + " Z: " + val[2] );
upm_h3lis331dl.IntVector val = sensor.getRawXYZ();
System.out.println( "Raw: X: " + val.get(0) + " Y: " + val.get(1) + " Z: " + val.get(2) );
accel = sensor.getAcceleration();
System.out.println( "Acceleration: X: " + accel[0] + " Y: " + accel[1] + " Z: " + accel[2] );
upm_h3lis331dl.FloatVector accel = sensor.getAcceleration();
System.out.println( "Acceleration: X: " + accel.get(0) + " Y: " + accel.get(1) + " Z: " + accel.get(2) );
Thread.sleep(1000);
}
//! [Interesting]
}
}
}

View File

@ -28,15 +28,14 @@ public class MMA7455Sample {
public static void main(String[] args) throws InterruptedException {
// ! [Interesting]
upm_mma7455.MMA7455 sensor = new upm_mma7455.MMA7455(0);
short[] val;
while (true) {
val = sensor.readData();
System.out.println("Accelerometer X: " + val[0] + ", Y: " + val[1] + ", Z: " + val[2]);
upm_mma7455.ShortVector val = sensor.readData();
System.out.println("Accelerometer X: " + val.get(0) + ", Y: " + val.get(1) + ", Z: " + val.get(2));
Thread.sleep(1000);
}
// ! [Interesting]
}
}
}

View File

@ -44,13 +44,13 @@ public class MMA7660Sample
while (true)
{
float acceleration[] = accel.getAcceleration();
upm_mma7660.FloatVector acceleration = accel.getAcceleration();
System.out.println("Acceleration: x = "
+ acceleration[0]
+ acceleration.get(0)
+ " y = "
+ acceleration[1]
+ acceleration.get(1)
+ " x = "
+ acceleration[2]);
+ acceleration.get(2));
System.out.println();

View File

@ -43,9 +43,8 @@ public class MPU9150Sample {
// System.out.println("Gryoscope: " + "GX: " + gyro[0] + " GY: " + gyro[1] + " GZ: "
// + gyro[2]);
float[] magn = sensor.getMagnetometer();
System.out.println("Magnetometer: " + "MX: " + magn[0] + " MY: " + magn[1] + " MZ: "
+ magn[2]);
upm_mpu9150.FloatVector magn = sensor.getMagnetometer();
System.out.println("Magnetometer: " + "MX: " + magn.get(0) + " MY: " + magn.get(1) + " MZ: " + magn.get(2));
Thread.sleep(1000);
}

View File

@ -461,7 +461,7 @@ function(upm_swig_java)
${DEPEND_DIRS}
)
set_target_properties (javaupm_${libname} PROPERTIES
COMPILE_FLAGS "-fpermissive -DJAVACALLBACK -DSWIGJAVA"
COMPILE_FLAGS "-fpermissive"
PREFIX "lib"
SUFFIX ".so"
)

View File

@ -77,14 +77,12 @@ void ADXL335::values(int *xVal, int *yVal, int *zVal)
*zVal = mraa_aio_read(m_aioZ);
}
#ifdef SWIGJAVA
int *ADXL335::values()
std::vector<int> ADXL335::values()
{
int *v = new int[3];
std::vector<int> v(3);
values(&v[0], &v[1], &v[2]);
return v;
}
#endif
void ADXL335::acceleration(float *xAccel, float *yAccel, float *zAccel)
{
@ -101,14 +99,12 @@ void ADXL335::acceleration(float *xAccel, float *yAccel, float *zAccel)
*zAccel = (zVolts - m_zeroZ) / ADXL335_SENSITIVITY;
}
#ifdef SWIGJAVA
float *ADXL335::acceleration()
std::vector<float> ADXL335::acceleration()
{
float *v = new float[3];
std::vector<float> v(3);
acceleration(&v[0], &v[1], &v[2]);
return v;
}
#endif
void ADXL335::calibrate()
{

View File

@ -27,6 +27,7 @@
#pragma once
#include <string>
#include <vector>
#include <mraa/aio.h>
#define ADXL335_DEFAULT_AREF 5.0
@ -106,14 +107,12 @@ namespace upm {
*/
void values(int *xVal, int *yVal, int *zVal);
#ifdef SWIGJAVA
/**
* Gets the analog values for the 3 axes
*
* @return Array containing value of X, Y, Z axes
* @return std::vector of x, y, z analog acceleration values
*/
int *values();
#endif
std::vector<int> values();
/**
* Gets the acceleration along all 3 axes
@ -124,14 +123,12 @@ namespace upm {
*/
void acceleration(float *xAccel, float *yAccel, float *zAccel);
#ifdef SWIGJAVA
/**
* Gets the acceleration along all 3 axes
*
* @return Array containing acceleration on X, Y, Z axes
* @return std::vector of x, y, z acceleration values
*/
float *acceleration();
#endif
std::vector<float> acceleration();
/**
* While the sensor is still, measures the X-axis, Y-axis, and Z-axis

View File

@ -167,14 +167,12 @@ void BMA220::getAccelerometer(float *x, float *y, float *z)
*z = m_accelZ / m_accelScale;
}
#ifdef JAVACALLBACK
float *BMA220::getAccelerometer()
std::vector<float> BMA220::getAccelerometer()
{
float *v = new float[3];
std::vector<float> v(3);
getAccelerometer(&v[0], &v[1], &v[2]);
return v;
}
#endif
uint8_t BMA220::getChipID()
{

View File

@ -24,6 +24,7 @@
#pragma once
#include <string>
#include <vector>
#include <mraa/common.hpp>
#include <mraa/i2c.hpp>
#include <mraa/gpio.hpp>
@ -539,14 +540,12 @@ namespace upm {
*/
void getAccelerometer(float *x, float *y, float *z);
#if defined(SWIGJAVA) || defined(JAVACALLBACK)
/**
* get the accelerometer values in gravities
*
* @return Array containing X, Y, Z acceleration values
* @return std::vector containing X, Y, Z acceleration values
*/
float *getAccelerometer();
#endif
std::vector<float> getAccelerometer();
/**
* set the filtering configuration

View File

@ -59,13 +59,6 @@ int Button::value()
return mraa_gpio_read(m_gpio);
}
/*#ifdef JAVACALLBACK
void Button::installISR(mraa::Edge level, jobject runnable)
{
installISR(level, mraa_java_isr_callback, runnable);
}
#endif*/
void Button::installISR(mraa::Edge level, void (*isr)(void *), void *arg)
{
if (m_isrInstalled)

View File

@ -87,11 +87,8 @@ class Button{
* @param arg Pointer to an object to be supplied as an
* argument to the ISR.
*/
/*#if defined(SWIGJAVA) || defined(JAVACALLBACK)
void installISR(mraa::Edge level, jobject runnable);
#else*/
void installISR(mraa::Edge level, void (*isr)(void *), void *arg);
//#endif
/**
* Uninstalls the previously installed ISR
*

View File

@ -31,5 +31,3 @@
$1 = reinterpret_cast< uint16_t * >(argp);
}
#endif
//#elsif (SWIGJAVA)

View File

@ -52,5 +52,3 @@
}
}
#endif
//#elsif (SWIGJAVA)

View File

@ -31,5 +31,3 @@
$1 = reinterpret_cast< uint8_t * >(argp);
}
#endif
//#elsif (SWIGJAVA)

View File

@ -58,13 +58,6 @@ int GroveButton::value()
return mraa_gpio_read(m_gpio);
}
/*#ifdef JAVACALLBACK
void GroveButton::installISR(mraa::Edge level, jobject runnable)
{
installISR(level, mraa_java_isr_callback, runnable);
}
#endif*/
void GroveButton::installISR(mraa::Edge level, void (*isr)(void *), void *arg)
{
if (m_isrInstalled)

View File

@ -84,11 +84,8 @@ class GroveButton: public Grove {
* @param arg Pointer to an object to be supplied as an
* argument to the ISR.
*/
//#if defined(SWIGJAVA) || defined(JAVACALLBACK)
// void installISR(mraa::Edge level, jobject runnable);
//#else
void installISR(mraa::Edge level, void (*isr)(void *), void *arg);
//#endif
/**
* Uninstalls the previously installed ISR
*

View File

@ -600,25 +600,23 @@ void H3LIS331DL::getXYZ(int *x, int *y, int*z)
*z = (m_rawZ - m_adjZ);
}
#ifdef SWIGJAVA
float *H3LIS331DL::getAcceleration()
std::vector<float> H3LIS331DL::getAcceleration()
{
float *v = new float[3];
std::vector<float> v(3);
getAcceleration(&v[0], &v[1], &v[2]);
return v;
}
int *H3LIS331DL::getRawXYZ()
std::vector<int> H3LIS331DL::getRawXYZ()
{
int *v = new int[3];
std::vector<int> v(3);
getRawXYZ(&v[0], &v[1], &v[2]);
return v;
}
int *H3LIS331DL::getXYZ()
std::vector<int> H3LIS331DL::getXYZ()
{
int *v = new int[3];
std::vector<int> v(3);
getXYZ(&v[0], &v[1], &v[2]);
return v;
}
#endif

View File

@ -24,6 +24,7 @@
#pragma once
#include <string>
#include <vector>
#include <mraa/common.hpp>
#include <mraa/i2c.hpp>
@ -594,29 +595,26 @@ namespace upm {
*/
void getXYZ(int *x, int *y, int *z);
#ifdef SWIGJAVA
/**
* Gets acceleration values for each of the axes
*
* @return Array containing X, Y, Z acceleration values
* @return std::vector containing X, Y, Z acceleration values
*/
float *getAcceleration();
std::vector<float> getAcceleration();
/**
* Gets raw axis values
*
* @return Array containing X, Y, Z raw values
* @return std::vector containing X, Y, Z raw values
*/
int *getRawXYZ();
std::vector<int> getRawXYZ();
/**
* Gets adjusted axis values
*
* @return Array containing X, Y, Z adjusted axis values
* @return std::vector containing X, Y, Z adjusted axis values
*/
int *getXYZ();
#endif
std::vector<int> getXYZ();
/**
* Provides public access to the MRAA I2C context of the class for

View File

@ -2,6 +2,10 @@
%include "../upm.i"
%include "cpointer.i"
%include "typemaps.i"
%include "std_vector.i"
%template(IntVector) std::vector<int>;
%template(FloatVector) std::vector<float>;
%apply int *OUTPUT { int *x, int *y, int*z };
%apply float *OUTPUT { float *aX, float *aY, float *aZ };
@ -9,45 +13,8 @@
%ignore i2cContext;
%{
#include "h3lis331dl.hpp"
#include "h3lis331dl.hpp"
%}
%typemap(jni) float* "jfloatArray"
%typemap(jstype) float* "float[]"
%typemap(jtype) float* "float[]"
%typemap(javaout) float* {
return $jnicall;
}
%typemap(out) float *getAcceleration {
$result = JCALL1(NewFloatArray, jenv, 3);
JCALL4(SetFloatArrayRegion, jenv, $result, 0, 3, $1);
delete [] $1;
}
%typemap(jni) int* "jintArray"
%typemap(jstype) int* "int[]"
%typemap(jtype) int* "int[]"
%typemap(javaout) int* {
return $jnicall;
}
%typemap(out) int *getRawXYZ {
$result = JCALL1(NewIntArray, jenv, 3);
JCALL4(SetIntArrayRegion, jenv, $result, 0, 3, (const int*)$1);
}
%typemap(out) int *getXYZ {
$result = JCALL1(NewIntArray, jenv, 3);
JCALL4(SetIntArrayRegion, jenv, $result, 0, 3, (const int*)$1);
}
%ignore getRawXYZ(int *, int *, int *);
%ignore getXYZ(int *, int *, int *);
%ignore getAcceleration(float *, float *, float *);
%include "h3lis331dl.hpp"
JAVA_JNI_LOADLIBRARY(javaupm_h3lis331dl)
JAVA_JNI_LOADLIBRARY(javaupm_h3lis331dl)

View File

@ -26,6 +26,7 @@
#include <iostream>
#include <stdexcept>
#include <string.h>
#include <vector>
#include "lsm9ds0.hpp"
@ -621,28 +622,26 @@ void LSM9DS0::getMagnetometer(float *x, float *y, float *z)
*z = (m_magZ * m_magScale) / 1000.0;
}
#ifdef JAVACALLBACK
float *LSM9DS0::getAccelerometer()
std::vector<float> LSM9DS0::getAccelerometer()
{
float *v = new float[3];
std::vector<float> v(3);
getAccelerometer(&v[0], &v[1], &v[2]);
return v;
}
float *LSM9DS0::getGyroscope()
std::vector<float> LSM9DS0::getGyroscope()
{
float *v = new float[3];
std::vector<float> v(3);
getGyroscope(&v[0], &v[1], &v[2]);
return v;
}
float *LSM9DS0::getMagnetometer()
std::vector<float> LSM9DS0::getMagnetometer()
{
float *v = new float[3];
std::vector<float> v(3);
getMagnetometer(&v[0], &v[1], &v[2]);
return v;
}
#endif
float LSM9DS0::getTemperature()
{

View File

@ -24,6 +24,7 @@
#pragma once
#include <string>
#include <vector>
#include <mraa/common.hpp>
#include <mraa/i2c.hpp>
@ -1266,28 +1267,26 @@ namespace upm {
*/
void getMagnetometer(float *x, float *y, float *z);
#if defined(SWIGJAVA) || defined(JAVACALLBACK)
/**
* get the accelerometer values in gravities
*
* @return Array containing X, Y, Z acceleration values
* @return std::vector containing X, Y, Z acceleration values
*/
float *getAccelerometer();
std::vector<float> getAccelerometer();
/**
* get the gyroscope values in degrees per second
*
* @return Array containing X, Y, Z gyroscope values
* @return std::vector containing X, Y, Z gyroscope values
*/
float *getGyroscope();
std::vector<float> getGyroscope();
/**
* get the magnetometer values in gauss
*
* @return Array containing X, Y, Z magnetometer values
* @return std::vector containing X, Y, Z magnetometer values
*/
float *getMagnetometer();
#endif
std::vector<float> getMagnetometer();
/**
* get the temperature value. Unfortunately the datasheet does

View File

@ -3,29 +3,15 @@
%include "typemaps.i"
%include "arrays_java.i";
%include "../java_buffer.i"
%include "std_vector.i"
%template(ShortVector) std::vector<short>;
%apply short *OUTPUT { short * ptrX, short * ptrY, short * ptrZ };
%typemap(jni) short* "jshortArray"
%typemap(jstype) short* "short[]"
%typemap(jtype) short* "short[]"
%typemap(javaout) short* {
return $jnicall;
}
%typemap(out) short *readData {
$result = JCALL1(NewShortArray, jenv, 3);
JCALL4(SetShortArrayRegion, jenv, $result, 0, 3, (const signed short*)$1);
delete [] $1;
}
%ignore readData(short *, short *, short *);
%{
#include "mma7455.hpp"
#include "mma7455.hpp"
%}
%include "mma7455.hpp"
JAVA_JNI_LOADLIBRARY(javaupm_mma7455)
JAVA_JNI_LOADLIBRARY(javaupm_mma7455)

View File

@ -26,6 +26,7 @@
#include <string>
#include <stdexcept>
#include <unistd.h>
#include <vector>
#include <stdlib.h>
#include <string.h>
#include <math.h>
@ -133,13 +134,11 @@ MMA7455::readData (short * ptrX, short * ptrY, short * ptrZ) {
return mraa::SUCCESS;
}
#ifdef SWIGJAVA
short *MMA7455::readData() {
short *v = new short[3];
std::vector<short> MMA7455::readData() {
std::vector<short> v(3);
readData(&v[0], &v[1], &v[2]);
return v;
}
#endif
int
MMA7455::i2cReadReg (unsigned char reg, uint8_t *buffer, int len) {

View File

@ -24,6 +24,7 @@
#pragma once
#include <string>
#include <vector>
#include <mraa/i2c.hpp>
#define ADDR 0x1D // device address
@ -208,14 +209,13 @@ class MMA7455 {
*/
mraa::Result readData (short * ptrX, short * ptrY, short * ptrZ);
#ifdef SWIGJAVA
/**
* Reads X-axis, Y-axis, and Z-axis acceleration data
*
* @return Array containing X, Y, Z acceleration data
* @return std::vector containing X, Y, Z acceleration data
*/
short *readData ();
#endif
std::vector<short> readData ();
/**
* Internal function for reading I2C data
*

View File

@ -4,44 +4,17 @@
%include "typemaps.i"
%include "arrays_java.i";
%include "../java_buffer.i"
%include "std_vector.i"
%template(IntVector) std::vector<int>;
%template(FloatVector) std::vector<float>;
%apply int *OUTPUT { int *x, int *y, int *z };
%apply float *OUTPUT { float *ax, float *ay, float *az };
%typemap(jni) float* "jfloatArray"
%typemap(jstype) float* "float[]"
%typemap(jtype) float* "float[]"
%typemap(javaout) float* {
return $jnicall;
}
%typemap(out) float *getAcceleration {
$result = JCALL1(NewFloatArray, jenv, 3);
JCALL4(SetFloatArrayRegion, jenv, $result, 0, 3, $1);
}
%typemap(jni) int* "jintArray"
%typemap(jstype) int* "int[]"
%typemap(jtype) int* "int[]"
%typemap(javaout) int* {
return $jnicall;
}
%typemap(out) int *getRawValues {
$result = JCALL1(NewIntArray, jenv, 3);
JCALL4(SetIntArrayRegion, jenv, $result, 0, 3, (const signed int*)$1);
}
%ignore getRawValues(int *, int *, int *);
%ignore getAcceleration(float *, float *, float *);
%{
#include "mma7660.hpp"
#include "mma7660_regs.h"
#include "mma7660.hpp"
#include "mma7660_regs.h"
%}
%include "mma7660_regs.h"
%include "mma7660.hpp"

View File

@ -23,7 +23,9 @@
*/
#pragma once
#include <mma7660.h>
#include <vector>
#include "mma7660.h"
namespace upm {
@ -197,17 +199,16 @@ namespace upm {
*/
bool setSampleRate(MMA7660_AUTOSLEEP_T sr);
#if defined(SWIGJAVA) || defined(JAVACALLBACK)
/**
* Reads the current acceleration values. The returned memory
* is statically allocated and will be overwritten on each
* call.
*
* @return Array containing x, y, z.
* @return std::vector containing x, y, z.
*/
float *getAcceleration()
std::vector<float> getAcceleration()
{
static float values[3];
std::vector<float> values(3);
getAcceleration(&values[0], &values[1], &values[2]);
return values;
}
@ -217,15 +218,15 @@ namespace upm {
* is statically allocated and will be overwritten on each
* call.
*
* @return Array containing x, y, z.
* @return std::vector containing x, y, z.
*/
int *getRawValues()
std::vector<int> getRawValues()
{
static int values[3];
std::vector<int> values(3);
getRawValues(&values[0], &values[1], &values[2]);
return values;
}
#endif
/**
* Installs an interrupt service routine (ISR) to be called when
* an interrupt occurs

View File

@ -3,40 +3,22 @@
%include "typemaps.i"
%include "arrays_java.i"
%include "../java_buffer.i"
%include "std_vector.i"
%template(FloatVector) std::vector<float>;
%apply int {mraa::Edge};
%{
#include "mpu60x0.hpp"
#include "mpu9150.hpp"
#include "mpu60x0.hpp"
#include "mpu9150.hpp"
%}
%typemap(jni) float * "jfloatArray"
%typemap(jstype) float * "float[]"
%typemap(jtype) float * "float[]"
%typemap(javaout) float * {
return $jnicall;
}
%typemap(out) float * {
$result = JCALL1(NewFloatArray, jenv, 3);
JCALL4(SetFloatArrayRegion, jenv, $result, 0, 3, $1);
delete [] $1;
}
%ignore getAccelerometer(float *, float *, float *);
%ignore getGyroscope(float *, float *, float *);
%ignore getMagnetometer(float *, float *, float *);
%include "mpu60x0.hpp"
%include "mpu9150.hpp"
%ignore installISR(int , mraa::Edge , void *, void *);
%define GETTER get_gpioIRQ()
%enddef
JAVA_ADD_INSTALLISR_GPIO(upm::MPU60X0)
JAVA_JNI_LOADLIBRARY(javaupm_mpu9150)

View File

@ -109,11 +109,9 @@ void MPU9150::getMagnetometer(float *x, float *y, float *z)
*z = mz;
}
#ifdef SWIGJAVA
float *MPU9150::getMagnetometer()
std::vector<float> MPU9150::getMagnetometer()
{
float *v = new float[3];
std::vector<float> v(3);
getMagnetometer(&v[0], &v[1], &v[2]);
return v;
}
#endif

View File

@ -23,6 +23,7 @@
*/
#pragma once
#include <vector>
#include "mpu60x0.hpp"
#include "ak8975.hpp"
@ -108,17 +109,13 @@ namespace upm {
*/
void getMagnetometer(float *x, float *y, float *z);
#ifdef SWIGJAVA
/**
* Return the compensated values for the x, y, and z axes. The
* unit of measurement is in micro-teslas (uT).
*
* @return Array containing X, Y, Z magnetometer values
* @return std::vector containing X, Y, Z magnetometer values
*/
float *getMagnetometer();
#endif
std::vector<float> getMagnetometer();
protected:
// magnetometer instance

View File

@ -1,6 +1,5 @@
#pragma once
#if defined(SWIGJAVA) || defined(JAVACALLBACK)
class Callback
{
public:
@ -13,10 +12,9 @@ class Callback
};
static void generic_callback (Callback* callback)
void generic_callback (Callback* callback)
{
if (callback == NULL)
return;
callback->run();
}
#endif

View File

@ -134,20 +134,12 @@ NRF24L01::setPayload (uint8_t payload) {
m_payload = payload;
}
#ifdef JAVACALLBACK
void
NRF24L01::setDataReceivedHandler (Callback *call_obj)
{
callback_obj = call_obj;
dataReceivedHandler = &generic_callback;
}
#else
void
NRF24L01::setDataReceivedHandler (funcPtrVoidVoid handler)
{
dataReceivedHandler = handler;
}
#endif
bool
NRF24L01::dataReady () {
@ -316,11 +308,8 @@ void
NRF24L01::pollListener() {
if (dataReady()) {
getData (m_rxBuffer);
#ifdef JAVACALLBACK
dataReceivedHandler (callback_obj); /* let know that data arrived */
#else
dataReceivedHandler (); /* let know that data arrived */
#endif
}
}

View File

@ -33,9 +33,7 @@
#include <mraa/spi.hpp>
#include <cstring>
#if defined(SWIGJAVA) || defined(JAVACALLBACK)
#include "Callback.hpp"
#endif
/* Memory Map */
#define CONFIG 0x00
@ -142,11 +140,7 @@
namespace upm {
#if defined(SWIGJAVA) || defined(JAVACALLBACK)
typedef void (* funcPtrVoidVoid) (Callback *);
#else
typedef void (* funcPtrVoidVoid) ();
#endif
typedef enum {
NRF_250KBPS = 0,
@ -257,21 +251,13 @@ class NRF24L01 {
*/
void setPayload (uint8_t load);
#if defined(SWIGJAVA) || defined(JAVACALLBACK)
/**
* Sets the handler to be called when data has been
* received
* @param call_obj Object used for callback - Java
*/
void setDataReceivedHandler (Callback *call_obj);
#else
/**
* Sets the handler to be called when data has been
* received
* @param handler Handler used for callback
*/
void setDataReceivedHandler (funcPtrVoidVoid handler);
#endif
/**
* Checks if the data has arrived
*/
@ -374,11 +360,12 @@ class NRF24L01 {
uint8_t m_bleBuffer [32]; /**< BLE buffer */
private:
#if defined(SWIGJAVA) || defined(JAVACALLBACK)
/**< Callback object to use for setting the handler from Java */
/* Callback object to use for setting the handler from Java */
Callback *callback_obj;
#endif
funcPtrVoidVoid dataReceivedHandler; /**< Data arrived handler */
/** Data arrived handler */
funcPtrVoidVoid dataReceivedHandler;
/**
* Writes bytes to an SPI device

View File

@ -32,10 +32,6 @@
#include <string>
#include <stdexcept>
#ifdef JAVACALLBACK
#undef JAVACALLBACK
#endif
#include "pn532.hpp"
using namespace upm;

View File

@ -1,6 +1,5 @@
#pragma once
#if defined(SWIGJAVA) || defined(JAVACALLBACK)
class Callback
{
public:
@ -11,5 +10,3 @@ class Callback
{ /* empty, overloaded in Java*/
}
};
#endif

View File

@ -32,7 +32,6 @@
using namespace upm;
#if defined(JAVACALLBACK)
Pulsensor::Pulsensor (Callback *obj_call) : pin_ctx(0)
{
obj_callback = obj_call;
@ -49,24 +48,6 @@ Pulsensor::Pulsensor (Callback *obj_call) : pin_ctx(0)
qs = FALSE;
apmlitude = 100;
}
#else
Pulsensor::Pulsensor (callback_handler handler) : pin_ctx(0)
{
callback = handler;
sample_counter = 0;
last_beat_time = 0;
threshold = 512;
ibi = 600;
trough = 512;
peak = 512;
is_pulse = FALSE;
ret = FALSE;
bpm = 0;
qs = FALSE;
apmlitude = 100;
}
#endif
void Pulsensor::start_sampler ()
{
@ -114,11 +95,8 @@ void *Pulsensor::do_sample (void *arg) {
(pulsensor->is_pulse == FALSE) &&
(N > (pulsensor->ibi / 5)* 3) ) {
pulsensor->is_pulse = callback_data.is_heart_beat = TRUE;
#if defined(JAVACALLBACK)
pulsensor->obj_callback->run(callback_data);
#else
pulsensor->callback(callback_data);
#endif
pulsensor->ibi = pulsensor->sample_counter - pulsensor->last_beat_time;
pulsensor->last_beat_time = pulsensor->sample_counter;
@ -156,11 +134,9 @@ void *Pulsensor::do_sample (void *arg) {
if (data_from_sensor < pulsensor->threshold &&
pulsensor->is_pulse == TRUE) {
pulsensor->is_pulse = callback_data.is_heart_beat = FALSE;
#if defined(JAVACALLBACK)
pulsensor->obj_callback->run(callback_data);
#else
pulsensor->callback(callback_data);
#endif
pulsensor->is_pulse = FALSE;
pulsensor->apmlitude = pulsensor->peak - pulsensor->trough;
pulsensor->threshold = pulsensor->apmlitude / 2 + pulsensor->trough;

View File

@ -47,11 +47,7 @@ struct clbk_data {
int is_heart_beat; /**< heartbeat check */
};
#if defined(SWIGJAVA) || defined(JAVACALLBACK)
#include "Callback.hpp"
#else
typedef void (* callback_handler) (clbk_data);
#endif
namespace upm {
/**
@ -80,11 +76,8 @@ namespace upm {
class Pulsensor {
public:
#if defined(SWIGJAVA) || defined(JAVACALLBACK)
Pulsensor(Callback *callback);
#else
Pulsensor(callback_handler handler);
#endif
void start_sampler();
void stop_sampler();
@ -106,11 +99,8 @@ private:
uint8_t second_beat; /**< Second heartbeat */
uint8_t ret; /**< Return value */
mraa::Aio pin_ctx; /**< The pin context */
#if defined(SWIGJAVA) || defined(JAVACALLBACK)
Callback *obj_callback; /**< The callback object */
#else
callback_handler callback; /**< The callback function */
#endif
volatile uint16_t ctx_counter;
};
}

View File

@ -24,9 +24,6 @@
#include <iostream>
#ifdef JAVACALLBACK
#undef JAVACALLBACK
#endif
#include "rgbringcoder.hpp"
using namespace std;

View File

@ -29,10 +29,6 @@
#include <string>
#include <string.h>
#ifdef JAVACALLBACK
#undef JAVACALLBACK
#endif
#include "sx1276.hpp"
using namespace upm;

View File

@ -2,6 +2,7 @@
%include "stdint.i"
%include "upm_exception.i"
/* Import additional SWIG helps (not exposed in wrapper) */
%import _upm.i
%{
@ -16,19 +17,21 @@
#if (SWIG_JAVASCRIPT_V8)
%{
// Because there's no guarantee that v8 will ever call garbage collection,
// we're adding a function that will allow a user to call it manually
void cleanUp()
{
// Call the v8 garbage collector as long as there is memory to clean up
// See https://codereview.chromium.org/412163003 for this API change
/* Because there's no guarantee that v8 will ever call garbage collection,
* we're adding a function that will allow a user to call it manually
*/
void cleanUp()
{
/* Call the v8 garbage collector as long as there is memory to clean up
* See https://codereview.chromium.org/412163003 for this API change
*/
#if (SWIG_V8_VERSION < 0x032838)
while (!v8::V8::IdleNotification())
while (!v8::V8::IdleNotification())
#else
while (!v8::Isolate::GetCurrent()->IdleNotification(1000))
while (!v8::Isolate::GetCurrent()->IdleNotification(1000))
#endif
{;}
}
{;}
}
%}
void cleanUp();
#endif

View File

@ -24,9 +24,6 @@
#include <iostream>
#ifdef JAVACALLBACK
#undef JAVACALLBACK
#endif
#include "wheelencoder.hpp"
using namespace upm;