Skip to content

Commit

Permalink
[wpiutil] jni_util: Add JSpan and CriticalJSpan (#5554)
Browse files Browse the repository at this point in the history
These replace JArrayRef et al and support statically sized arrays similar to std::span.
  • Loading branch information
KangarooKoala authored Aug 24, 2023
1 parent 8f3d6a1 commit 2e4ad35
Show file tree
Hide file tree
Showing 19 changed files with 324 additions and 308 deletions.
21 changes: 8 additions & 13 deletions apriltag/src/main/native/cpp/jni/AprilTagJNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -504,15 +504,14 @@ Java_edu_wpi_first_apriltag_jni_AprilTagJNI_estimatePoseHomography
nullPointerEx.Throw(env, "homography cannot be null");
return nullptr;
}
JDoubleArrayRef harr{env, homography};
JSpan<const jdouble, 9> harr{env, homography};
if (harr.size() != 9) {
illegalArgEx.Throw(env, "homography array must be size 9");
return nullptr;
}

AprilTagPoseEstimator estimator({units::meter_t{tagSize}, fx, fy, cx, cy});
return MakeJObject(env, estimator.EstimateHomography(
std::span<const double, 9>{harr.array()}));
return MakeJObject(env, estimator.EstimateHomography(harr));
}

/*
Expand All @@ -530,7 +529,7 @@ Java_edu_wpi_first_apriltag_jni_AprilTagJNI_estimatePoseOrthogonalIteration
nullPointerEx.Throw(env, "homography cannot be null");
return nullptr;
}
JDoubleArrayRef harr{env, homography};
JSpan<const jdouble, 9> harr{env, homography};
if (harr.size() != 9) {
illegalArgEx.Throw(env, "homography array must be size 9");
return nullptr;
Expand All @@ -541,17 +540,15 @@ Java_edu_wpi_first_apriltag_jni_AprilTagJNI_estimatePoseOrthogonalIteration
nullPointerEx.Throw(env, "corners cannot be null");
return nullptr;
}
JDoubleArrayRef carr{env, corners};
JSpan<const jdouble, 8> carr{env, corners};
if (carr.size() != 8) {
illegalArgEx.Throw(env, "corners array must be size 8");
return nullptr;
}

AprilTagPoseEstimator estimator({units::meter_t{tagSize}, fx, fy, cx, cy});
return MakeJObject(env,
estimator.EstimateOrthogonalIteration(
std::span<const double, 9>{harr.array()},
std::span<const double, 8>{carr.array()}, nIters));
estimator.EstimateOrthogonalIteration(harr, carr, nIters));
}

/*
Expand All @@ -569,7 +566,7 @@ Java_edu_wpi_first_apriltag_jni_AprilTagJNI_estimatePose
nullPointerEx.Throw(env, "homography cannot be null");
return nullptr;
}
JDoubleArrayRef harr{env, homography};
JSpan<const jdouble, 9> harr{env, homography};
if (harr.size() != 9) {
illegalArgEx.Throw(env, "homography array must be size 9");
return nullptr;
Expand All @@ -580,16 +577,14 @@ Java_edu_wpi_first_apriltag_jni_AprilTagJNI_estimatePose
nullPointerEx.Throw(env, "corners cannot be null");
return nullptr;
}
JDoubleArrayRef carr{env, corners};
JSpan<const jdouble, 8> carr{env, corners};
if (carr.size() != 8) {
illegalArgEx.Throw(env, "corners array must be size 8");
return nullptr;
}

AprilTagPoseEstimator estimator({units::meter_t{tagSize}, fx, fy, cx, cy});
return MakeJObject(
env, estimator.Estimate(std::span<const double, 9>{harr.array()},
std::span<const double, 8>{carr.array()}));
return MakeJObject(env, estimator.Estimate(harr, carr));
}

} // extern "C"
7 changes: 3 additions & 4 deletions hal/src/main/native/cpp/jni/AddressableLEDJNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,11 @@ Java_edu_wpi_first_hal_AddressableLEDJNI_setData
(JNIEnv* env, jclass, jint handle, jbyteArray arr)
{
int32_t status = 0;
JByteArrayRef jArrRef{env, arr};
auto arrRef = jArrRef.array();
JSpan<const jbyte> jArrRef{env, arr};
HAL_WriteAddressableLEDData(
static_cast<HAL_AddressableLEDHandle>(handle),
reinterpret_cast<const HAL_AddressableLEDData*>(arrRef.data()),
arrRef.size() / 4, &status);
reinterpret_cast<const HAL_AddressableLEDData*>(jArrRef.data()),
jArrRef.size() / 4, &status);
CheckStatus(env, status);
}

Expand Down
28 changes: 12 additions & 16 deletions hal/src/main/native/cpp/jni/CANAPIJNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,10 @@ Java_edu_wpi_first_hal_CANAPIJNI_writeCANPacket
(JNIEnv* env, jclass, jint handle, jbyteArray data, jint apiId)
{
auto halHandle = static_cast<HAL_CANHandle>(handle);
JByteArrayRef arr{env, data};
auto arrRef = arr.array();
JSpan<const jbyte> arr{env, data};
int32_t status = 0;
HAL_WriteCANPacket(halHandle, reinterpret_cast<const uint8_t*>(arrRef.data()),
arrRef.size(), apiId, &status);
HAL_WriteCANPacket(halHandle, reinterpret_cast<const uint8_t*>(arr.data()),
arr.size(), apiId, &status);
CheckStatus(env, status);
}

Expand All @@ -90,12 +89,11 @@ Java_edu_wpi_first_hal_CANAPIJNI_writeCANPacketRepeating
jint timeoutMs)
{
auto halHandle = static_cast<HAL_CANHandle>(handle);
JByteArrayRef arr{env, data};
auto arrRef = arr.array();
JSpan<const jbyte> arr{env, data};
int32_t status = 0;
HAL_WriteCANPacketRepeating(halHandle,
reinterpret_cast<const uint8_t*>(arrRef.data()),
arrRef.size(), apiId, timeoutMs, &status);
reinterpret_cast<const uint8_t*>(arr.data()),
arr.size(), apiId, timeoutMs, &status);
CheckStatus(env, status);
}

Expand Down Expand Up @@ -124,11 +122,10 @@ Java_edu_wpi_first_hal_CANAPIJNI_writeCANPacketNoThrow
(JNIEnv* env, jclass, jint handle, jbyteArray data, jint apiId)
{
auto halHandle = static_cast<HAL_CANHandle>(handle);
JByteArrayRef arr{env, data};
auto arrRef = arr.array();
JSpan<const jbyte> arr{env, data};
int32_t status = 0;
HAL_WriteCANPacket(halHandle, reinterpret_cast<const uint8_t*>(arrRef.data()),
arrRef.size(), apiId, &status);
HAL_WriteCANPacket(halHandle, reinterpret_cast<const uint8_t*>(arr.data()),
arr.size(), apiId, &status);
return status;
}

Expand All @@ -143,12 +140,11 @@ Java_edu_wpi_first_hal_CANAPIJNI_writeCANPacketRepeatingNoThrow
jint timeoutMs)
{
auto halHandle = static_cast<HAL_CANHandle>(handle);
JByteArrayRef arr{env, data};
auto arrRef = arr.array();
JSpan<const jbyte> arr{env, data};
int32_t status = 0;
HAL_WriteCANPacketRepeating(halHandle,
reinterpret_cast<const uint8_t*>(arrRef.data()),
arrRef.size(), apiId, timeoutMs, &status);
reinterpret_cast<const uint8_t*>(arr.data()),
arr.size(), apiId, timeoutMs, &status);
return status;
}

Expand Down
6 changes: 3 additions & 3 deletions hal/src/main/native/cpp/jni/CANJNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_can_CANJNI_FRCNetCommCANSessionMuxSendMessage
(JNIEnv* env, jclass, jint messageID, jbyteArray data, jint periodMs)
{
JByteArrayRef dataArray{env, data};
JSpan<const jbyte> dataArray{env, data};

const uint8_t* dataBuffer =
reinterpret_cast<const uint8_t*>(dataArray.array().data());
uint8_t dataSize = dataArray.array().size();
reinterpret_cast<const uint8_t*>(dataArray.data());
uint8_t dataSize = dataArray.size();

int32_t status = 0;
HAL_CAN_SendMessage(messageID, dataBuffer, dataSize, periodMs, &status);
Expand Down
10 changes: 5 additions & 5 deletions hal/src/main/native/cpp/jni/DMAJNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@
#include <algorithm>
#include <cstring>

#include <wpi/jni_util.h>

#include "HALUtil.h"
#include "edu_wpi_first_hal_DMAJNI.h"
#include "hal/DMA.h"
#include "hal/handles/HandlesInternal.h"

using namespace hal;
using namespace wpi::java;

namespace hal {
bool GetEncoderBaseHandle(HAL_EncoderHandle handle,
Expand Down Expand Up @@ -312,20 +315,17 @@ Java_edu_wpi_first_hal_DMAJNI_readDMA
env->SetIntArrayRegion(buf, 0, dmaSample.captureSize,
reinterpret_cast<jint*>(dmaSample.readBuffer));

int32_t* nativeArr =
static_cast<int32_t*>(env->GetPrimitiveArrayCritical(store, nullptr));
CriticalJSpan<jint> nativeArr{env, store};

std::copy_n(
dmaSample.channelOffsets,
sizeof(dmaSample.channelOffsets) / sizeof(dmaSample.channelOffsets[0]),
nativeArr);
nativeArr.data());
nativeArr[22] = static_cast<int32_t>(dmaSample.captureSize);
nativeArr[23] = static_cast<int32_t>(dmaSample.triggerChannels);
nativeArr[24] = remaining;
nativeArr[25] = readStatus;

env->ReleasePrimitiveArrayCritical(store, nativeArr, JNI_ABORT);

return dmaSample.timeStamp;
}

Expand Down
8 changes: 4 additions & 4 deletions hal/src/main/native/cpp/jni/DriverStationJNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,10 @@ Java_edu_wpi_first_hal_DriverStationJNI_getAllJoystickData

HAL_GetAllJoystickData(axes, povs, buttons);

CriticalJFloatArrayRef jAxes(env, axesArray);
CriticalJByteArrayRef jRawAxes(env, rawAxesArray);
CriticalJShortArrayRef jPovs(env, povsArray);
CriticalJLongArrayRef jButtons(env, buttonsAndMetadataArray);
CriticalJSpan<jfloat> jAxes(env, axesArray);
CriticalJSpan<jbyte> jRawAxes(env, rawAxesArray);
CriticalJSpan<jshort> jPovs(env, povsArray);
CriticalJSpan<jlong> jButtons(env, buttonsAndMetadataArray);

static_assert(sizeof(jAxes[0]) == sizeof(axes[0].axes[0]));
static_assert(sizeof(jRawAxes[0]) == sizeof(axes[0].raw[0]));
Expand Down
4 changes: 2 additions & 2 deletions hal/src/main/native/cpp/jni/I2CJNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ Java_edu_wpi_first_hal_I2CJNI_i2CTransactionB
jint returnValue =
HAL_TransactionI2C(static_cast<HAL_I2CPort>(port), address,
reinterpret_cast<const uint8_t*>(
JByteArrayRef(env, dataToSend).array().data()),
JSpan<const jbyte>(env, dataToSend).data()),
sendSize, recvBuf.data(), receiveSize);
env->SetByteArrayRegion(dataReceived, 0, receiveSize,
reinterpret_cast<const jbyte*>(recvBuf.data()));
Expand Down Expand Up @@ -120,7 +120,7 @@ Java_edu_wpi_first_hal_I2CJNI_i2CWriteB
jint returnValue =
HAL_WriteI2C(static_cast<HAL_I2CPort>(port), address,
reinterpret_cast<const uint8_t*>(
JByteArrayRef(env, dataToSend).array().data()),
JSpan<const jbyte>(env, dataToSend).data()),
sendSize);
return returnValue;
}
Expand Down
13 changes: 6 additions & 7 deletions hal/src/main/native/cpp/jni/SPIJNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ Java_edu_wpi_first_hal_SPIJNI_spiTransactionB
jint retVal =
HAL_TransactionSPI(static_cast<HAL_SPIPort>(port),
reinterpret_cast<const uint8_t*>(
JByteArrayRef(env, dataToSend).array().data()),
JSpan<const jbyte>(env, dataToSend).data()),
recvBuf.data(), size);
env->SetByteArrayRegion(dataReceived, 0, size,
reinterpret_cast<const jbyte*>(recvBuf.data()));
Expand Down Expand Up @@ -131,7 +131,7 @@ Java_edu_wpi_first_hal_SPIJNI_spiWriteB
{
jint retVal = HAL_WriteSPI(static_cast<HAL_SPIPort>(port),
reinterpret_cast<const uint8_t*>(
JByteArrayRef(env, dataToSend).array().data()),
JSpan<const jbyte>(env, dataToSend).data()),
size);
return retVal;
}
Expand Down Expand Up @@ -356,12 +356,11 @@ JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_SPIJNI_spiSetAutoTransmitData
(JNIEnv* env, jclass, jint port, jbyteArray dataToSend, jint zeroSize)
{
JByteArrayRef jarr(env, dataToSend);
JSpan<const jbyte> jarr(env, dataToSend);
int32_t status = 0;
HAL_SetSPIAutoTransmitData(
static_cast<HAL_SPIPort>(port),
reinterpret_cast<const uint8_t*>(jarr.array().data()),
jarr.array().size(), zeroSize, &status);
HAL_SetSPIAutoTransmitData(static_cast<HAL_SPIPort>(port),
reinterpret_cast<const uint8_t*>(jarr.data()),
jarr.size(), zeroSize, &status);
CheckStatus(env, status);
}

Expand Down
9 changes: 4 additions & 5 deletions hal/src/main/native/cpp/jni/SerialPortJNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,11 +261,10 @@ Java_edu_wpi_first_hal_SerialPortJNI_serialWrite
(JNIEnv* env, jclass, jint handle, jbyteArray dataToSend, jint size)
{
int32_t status = 0;
jint retVal =
HAL_WriteSerial(static_cast<HAL_SerialPortHandle>(handle),
reinterpret_cast<const char*>(
JByteArrayRef(env, dataToSend).array().data()),
size, &status);
jint retVal = HAL_WriteSerial(
static_cast<HAL_SerialPortHandle>(handle),
reinterpret_cast<const char*>(JSpan<const jbyte>(env, dataToSend).data()),
size, &status);
CheckStatus(env, status);
return retVal;
}
Expand Down
2 changes: 1 addition & 1 deletion hal/src/main/native/cpp/jni/SimDeviceJNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ Java_edu_wpi_first_hal_SimDeviceJNI_createSimValueEnumDouble
}
return HAL_CreateSimValueEnumDouble(
device, JStringRef{env, name}.c_str(), direction, len, carr.data(),
JDoubleArrayRef{env, optionValues}.array().data(), initialValue);
JSpan<const jdouble>{env, optionValues}.data(), initialValue);
}

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_AddressableLEDDataJNI_setData
(JNIEnv* env, jclass, jint index, jbyteArray arr)
{
JByteArrayRef jArrRef{env, arr};
JSpan<const jbyte> jArrRef{env, arr};
auto arrRef = jArrRef.array();
HALSIM_SetAddressableLEDData(
index, reinterpret_cast<const HAL_AddressableLEDData*>(arrRef.data()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ Java_edu_wpi_first_hal_simulation_DriverStationDataJNI_setJoystickAxes
{
HAL_JoystickAxes axes;
{
wpi::java::JFloatArrayRef jArrayRef(env, axesArray);
JSpan<const jfloat> jArrayRef(env, axesArray);
auto arrayRef = jArrayRef.array();
auto arraySize = arrayRef.size();
int maxCount =
Expand All @@ -461,7 +461,7 @@ Java_edu_wpi_first_hal_simulation_DriverStationDataJNI_setJoystickPOVs
{
HAL_JoystickPOVs povs;
{
wpi::java::JShortArrayRef jArrayRef(env, povsArray);
JSpan<const jshort> jArrayRef(env, povsArray);
auto arrayRef = jArrayRef.array();
auto arraySize = arrayRef.size();
int maxCount =
Expand Down
10 changes: 5 additions & 5 deletions ntcore/src/generate/cpp/jni/types_jni.cpp.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ void JNI_UnloadTypes(JNIEnv* env) {
} // namespace nt

static std::vector<int> FromJavaBooleanArray(JNIEnv* env, jbooleanArray jarr) {
CriticalJBooleanArrayRef ref{env, jarr};
CriticalJSpan<const jboolean> ref{env, jarr};
if (!ref) {
return {};
}
Expand Down Expand Up @@ -214,7 +214,7 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_setRaw
indexOobEx.Throw(env, "len must be >= 0");
return false;
}
CriticalJByteArrayRef cvalue{env, value};
CriticalJSpan<const jbyte> cvalue{env, value};
if (static_cast<unsigned int>(start + len) > cvalue.size()) {
indexOobEx.Throw(env, "start + len must be smaller than array length");
return false;
Expand Down Expand Up @@ -243,7 +243,7 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_setRawBuffer
indexOobEx.Throw(env, "len must be >= 0");
return false;
}
JByteArrayRef cvalue{env, value, start + len};
JSpan<const jbyte> cvalue{env, value, static_cast<size_t>(start + len)};
if (!cvalue) {
illegalArgEx.Throw(env, "value must be a native ByteBuffer");
return false;
Expand Down Expand Up @@ -310,7 +310,7 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_setDefaultRaw
indexOobEx.Throw(env, "len must be >= 0");
return false;
}
CriticalJByteArrayRef cvalue{env, defaultValue};
CriticalJSpan<const jbyte> cvalue{env, defaultValue};
if (static_cast<unsigned int>(start + len) > cvalue.size()) {
indexOobEx.Throw(env, "start + len must be smaller than array length");
return false;
Expand Down Expand Up @@ -339,7 +339,7 @@ Java_edu_wpi_first_networktables_NetworkTablesJNI_setDefaultRawBuffer
indexOobEx.Throw(env, "len must be >= 0");
return false;
}
JByteArrayRef cvalue{env, defaultValue, start + len};
JSpan<const jbyte> cvalue{env, defaultValue, static_cast<size_t>(start + len)};
if (!cvalue) {
illegalArgEx.Throw(env, "value must be a native ByteBuffer");
return false;
Expand Down
Loading

0 comments on commit 2e4ad35

Please sign in to comment.