2020-12-26 14:12:05 -08:00
|
|
|
// Copyright (c) FIRST and other WPILib contributors.
|
|
|
|
|
// Open Source Software; you can modify and/or share it under the terms of
|
|
|
|
|
// the WPILib BSD license file in the root directory of this project.
|
2019-09-26 22:53:21 -07:00
|
|
|
|
2021-06-12 01:17:09 -07:00
|
|
|
package edu.wpi.first.util;
|
2019-09-26 22:53:21 -07:00
|
|
|
|
|
|
|
|
import java.io.IOException;
|
2023-12-26 20:05:02 -08:00
|
|
|
import java.nio.ByteBuffer;
|
2019-09-26 22:53:21 -07:00
|
|
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
|
|
|
|
2024-01-01 22:56:23 -08:00
|
|
|
/** WPIUtil JNI. */
|
2020-03-21 20:43:34 -07:00
|
|
|
public class WPIUtilJNI {
|
2019-09-26 22:53:21 -07:00
|
|
|
static boolean libraryLoaded = false;
|
|
|
|
|
|
2024-01-01 22:56:23 -08:00
|
|
|
/** Sets whether JNI should be loaded in the static block. */
|
2019-09-26 22:53:21 -07:00
|
|
|
public static class Helper {
|
|
|
|
|
private static AtomicBoolean extractOnStaticLoad = new AtomicBoolean(true);
|
|
|
|
|
|
2024-01-01 22:56:23 -08:00
|
|
|
/**
|
|
|
|
|
* Returns true if the JNI should be loaded in the static block.
|
|
|
|
|
*
|
|
|
|
|
* @return True if the JNI should be loaded in the static block.
|
|
|
|
|
*/
|
2019-09-26 22:53:21 -07:00
|
|
|
public static boolean getExtractOnStaticLoad() {
|
|
|
|
|
return extractOnStaticLoad.get();
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-01 22:56:23 -08:00
|
|
|
/**
|
|
|
|
|
* Sets whether the JNI should be loaded in the static block.
|
|
|
|
|
*
|
|
|
|
|
* @param load Whether the JNI should be loaded in the static block.
|
|
|
|
|
*/
|
2019-09-26 22:53:21 -07:00
|
|
|
public static void setExtractOnStaticLoad(boolean load) {
|
|
|
|
|
extractOnStaticLoad.set(load);
|
|
|
|
|
}
|
2024-01-01 22:56:23 -08:00
|
|
|
|
|
|
|
|
/** Utility class. */
|
|
|
|
|
private Helper() {}
|
2019-09-26 22:53:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static {
|
|
|
|
|
if (Helper.getExtractOnStaticLoad()) {
|
|
|
|
|
try {
|
2024-05-25 01:48:59 +08:00
|
|
|
RuntimeLoader.loadLibrary("wpiutiljni");
|
|
|
|
|
} catch (Exception ex) {
|
2019-09-26 22:53:21 -07:00
|
|
|
ex.printStackTrace();
|
|
|
|
|
System.exit(1);
|
|
|
|
|
}
|
|
|
|
|
libraryLoaded = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-10 20:46:47 -07:00
|
|
|
/**
|
|
|
|
|
* Force load the library.
|
|
|
|
|
*
|
|
|
|
|
* @throws IOException if the library failed to load
|
|
|
|
|
*/
|
2019-09-26 22:53:21 -07:00
|
|
|
public static synchronized void forceLoad() throws IOException {
|
|
|
|
|
if (libraryLoaded) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-05-25 01:48:59 +08:00
|
|
|
RuntimeLoader.loadLibrary("wpiutiljni");
|
2019-09-26 22:53:21 -07:00
|
|
|
libraryLoaded = true;
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-05 08:51:48 -08:00
|
|
|
/** Checks if the MSVC runtime is valid. Throws a runtime exception if not. */
|
|
|
|
|
public static native void checkMsvcRuntime();
|
|
|
|
|
|
2024-01-04 08:38:06 -08:00
|
|
|
/**
|
|
|
|
|
* Write the given string to stderr.
|
|
|
|
|
*
|
|
|
|
|
* @param str String to write.
|
|
|
|
|
*/
|
2022-08-30 20:40:16 -07:00
|
|
|
public static native void writeStderr(String str);
|
|
|
|
|
|
2024-01-04 08:38:06 -08:00
|
|
|
/** Enable mock time. */
|
2021-05-31 10:35:54 -07:00
|
|
|
public static native void enableMockTime();
|
|
|
|
|
|
2024-01-04 08:38:06 -08:00
|
|
|
/** Disable mock time. */
|
2021-12-27 11:51:32 -06:00
|
|
|
public static native void disableMockTime();
|
|
|
|
|
|
2024-01-04 08:38:06 -08:00
|
|
|
/**
|
|
|
|
|
* Set mock time.
|
|
|
|
|
*
|
|
|
|
|
* @param time The desired time in microseconds.
|
|
|
|
|
*/
|
2021-05-31 10:35:54 -07:00
|
|
|
public static native void setMockTime(long time);
|
|
|
|
|
|
2024-01-04 08:38:06 -08:00
|
|
|
/**
|
|
|
|
|
* Returns the time.
|
|
|
|
|
*
|
|
|
|
|
* @return The time.
|
|
|
|
|
*/
|
2020-08-06 21:37:38 -07:00
|
|
|
public static native long now();
|
|
|
|
|
|
2024-01-04 08:38:06 -08:00
|
|
|
/**
|
|
|
|
|
* Returns the system time.
|
|
|
|
|
*
|
|
|
|
|
* @return The system time.
|
|
|
|
|
*/
|
2021-12-28 01:06:31 -06:00
|
|
|
public static native long getSystemTime();
|
|
|
|
|
|
2024-01-02 23:13:46 -05:00
|
|
|
/**
|
|
|
|
|
* Creates an event. Events have binary state (signaled or not signaled) and may be either
|
|
|
|
|
* automatically reset or manually reset. Automatic-reset events go to non-signaled state when a
|
|
|
|
|
* WaitForObject is woken up by the event; manual-reset events require ResetEvent() to be called
|
|
|
|
|
* to set the event to non-signaled state; if ResetEvent() is not called, any waiter on that event
|
|
|
|
|
* will immediately wake when called.
|
|
|
|
|
*
|
|
|
|
|
* @param manualReset true for manual reset, false for automatic reset
|
|
|
|
|
* @param initialState true to make the event initially in signaled state
|
|
|
|
|
* @return Event handle
|
|
|
|
|
*/
|
2021-08-03 00:05:47 -07:00
|
|
|
public static native int createEvent(boolean manualReset, boolean initialState);
|
|
|
|
|
|
2024-01-02 23:13:46 -05:00
|
|
|
/**
|
|
|
|
|
* Destroys an event. Destruction wakes up any waiters.
|
|
|
|
|
*
|
|
|
|
|
* @param eventHandle event handle
|
|
|
|
|
*/
|
2021-08-03 00:05:47 -07:00
|
|
|
public static native void destroyEvent(int eventHandle);
|
|
|
|
|
|
2024-01-02 23:13:46 -05:00
|
|
|
/**
|
|
|
|
|
* Sets an event to signaled state.
|
|
|
|
|
*
|
|
|
|
|
* @param eventHandle event handle
|
|
|
|
|
*/
|
2021-08-03 00:05:47 -07:00
|
|
|
public static native void setEvent(int eventHandle);
|
|
|
|
|
|
2024-01-02 23:13:46 -05:00
|
|
|
/**
|
|
|
|
|
* Sets an event to non-signaled state.
|
|
|
|
|
*
|
|
|
|
|
* @param eventHandle event handle
|
|
|
|
|
*/
|
2021-08-03 00:05:47 -07:00
|
|
|
public static native void resetEvent(int eventHandle);
|
|
|
|
|
|
2024-01-02 23:13:46 -05:00
|
|
|
/**
|
|
|
|
|
* Creates a semaphore. Semaphores keep an internal counter. Releasing the semaphore increases the
|
|
|
|
|
* count. A semaphore with a non-zero count is considered signaled. When a waiter wakes up it
|
|
|
|
|
* atomically decrements the count by 1. This is generally useful in a single-supplier,
|
|
|
|
|
* multiple-consumer scenario.
|
|
|
|
|
*
|
|
|
|
|
* @param initialCount initial value for the semaphore's internal counter
|
2024-08-17 10:44:34 -04:00
|
|
|
* @param maximumCount maximum value for the semaphore's internal counter
|
2024-01-02 23:13:46 -05:00
|
|
|
* @return Semaphore handle
|
|
|
|
|
*/
|
2021-08-03 00:05:47 -07:00
|
|
|
public static native int createSemaphore(int initialCount, int maximumCount);
|
|
|
|
|
|
2024-01-02 23:13:46 -05:00
|
|
|
/**
|
|
|
|
|
* Destroys a semaphore. Destruction wakes up any waiters.
|
|
|
|
|
*
|
|
|
|
|
* @param semHandle semaphore handle
|
|
|
|
|
*/
|
2021-08-03 00:05:47 -07:00
|
|
|
public static native void destroySemaphore(int semHandle);
|
|
|
|
|
|
2024-01-02 23:13:46 -05:00
|
|
|
/**
|
|
|
|
|
* Releases N counts of a semaphore.
|
|
|
|
|
*
|
|
|
|
|
* @param semHandle semaphore handle
|
|
|
|
|
* @param releaseCount amount to add to semaphore's internal counter; must be positive
|
|
|
|
|
* @return True on successful release, false on failure (e.g. release count would exceed maximum
|
|
|
|
|
* value, or handle invalid)
|
|
|
|
|
*/
|
2021-08-03 00:05:47 -07:00
|
|
|
public static native boolean releaseSemaphore(int semHandle, int releaseCount);
|
|
|
|
|
|
2023-12-26 20:05:02 -08:00
|
|
|
static native long allocateRawFrame();
|
2023-11-23 13:55:10 -05:00
|
|
|
|
2023-12-26 20:05:02 -08:00
|
|
|
static native void freeRawFrame(long frame);
|
|
|
|
|
|
|
|
|
|
static native long getRawFrameDataPtr(long frame);
|
|
|
|
|
|
|
|
|
|
static native void setRawFrameData(
|
|
|
|
|
long frame, ByteBuffer data, int size, int width, int height, int stride, int pixelFormat);
|
|
|
|
|
|
|
|
|
|
static native void setRawFrameInfo(
|
|
|
|
|
long frame, int size, int width, int height, int stride, int pixelFormat);
|
2023-11-23 13:55:10 -05:00
|
|
|
|
2025-01-07 09:33:20 -07:00
|
|
|
static native void setRawFrameTime(long frame, long timestamp, int timeSource);
|
|
|
|
|
|
2021-08-03 00:05:47 -07:00
|
|
|
/**
|
2022-12-26 14:32:13 -05:00
|
|
|
* Waits for a handle to be signaled.
|
2021-08-03 00:05:47 -07:00
|
|
|
*
|
|
|
|
|
* @param handle handle to wait on
|
|
|
|
|
* @throws InterruptedException on failure (e.g. object was destroyed)
|
|
|
|
|
*/
|
|
|
|
|
public static native void waitForObject(int handle) throws InterruptedException;
|
|
|
|
|
|
|
|
|
|
/**
|
2022-12-26 14:32:13 -05:00
|
|
|
* Waits for a handle to be signaled, with timeout.
|
2021-08-03 00:05:47 -07:00
|
|
|
*
|
|
|
|
|
* @param handle handle to wait on
|
|
|
|
|
* @param timeout timeout in seconds
|
|
|
|
|
* @return True if timeout reached without handle being signaled
|
|
|
|
|
* @throws InterruptedException on failure (e.g. object was destroyed)
|
|
|
|
|
*/
|
|
|
|
|
public static native boolean waitForObjectTimeout(int handle, double timeout)
|
|
|
|
|
throws InterruptedException;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Waits for one or more handles to be signaled.
|
|
|
|
|
*
|
|
|
|
|
* <p>Invalid handles are treated as signaled; the returned array will have the handle error bit
|
|
|
|
|
* set for any invalid handles.
|
|
|
|
|
*
|
|
|
|
|
* @param handles array of handles to wait on
|
|
|
|
|
* @return array of signaled handles
|
|
|
|
|
* @throws InterruptedException on failure (e.g. no objects were signaled)
|
|
|
|
|
*/
|
|
|
|
|
public static native int[] waitForObjects(int[] handles) throws InterruptedException;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Waits for one or more handles to be signaled, with timeout.
|
|
|
|
|
*
|
|
|
|
|
* <p>Invalid handles are treated as signaled; the returned array will have the handle error bit
|
|
|
|
|
* set for any invalid handles.
|
|
|
|
|
*
|
|
|
|
|
* @param handles array of handles to wait on
|
|
|
|
|
* @param timeout timeout in seconds
|
|
|
|
|
* @return array of signaled handles; empty if timeout reached without any handle being signaled
|
|
|
|
|
* @throws InterruptedException on failure (e.g. no objects were signaled and no timeout)
|
|
|
|
|
*/
|
|
|
|
|
public static native int[] waitForObjectsTimeout(int[] handles, double timeout)
|
|
|
|
|
throws InterruptedException;
|
2024-01-01 22:56:23 -08:00
|
|
|
|
2024-09-13 01:13:06 -04:00
|
|
|
/**
|
|
|
|
|
* Create a native FileLogger. When the specified file is modified, appended data will be appended
|
|
|
|
|
* to the specified data log.
|
|
|
|
|
*
|
|
|
|
|
* @param file path to the file
|
|
|
|
|
* @param log data log implementation handle
|
|
|
|
|
* @param key log key to append data to
|
|
|
|
|
* @return The FileLogger handle.
|
|
|
|
|
*/
|
|
|
|
|
public static native long createFileLogger(String file, long log, String key);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Free a native FileLogger. This causes the FileLogger to stop appending data to the log.
|
|
|
|
|
*
|
|
|
|
|
* @param fileTail The FileLogger handle.
|
|
|
|
|
*/
|
|
|
|
|
public static native void freeFileLogger(long fileTail);
|
|
|
|
|
|
2024-01-01 22:56:23 -08:00
|
|
|
/** Utility class. */
|
|
|
|
|
protected WPIUtilJNI() {}
|
2019-09-26 22:53:21 -07:00
|
|
|
}
|