001// Copyright (c) FIRST and other WPILib contributors. 002// Open Source Software; you can modify and/or share it under the terms of 003// the WPILib BSD license file in the root directory of this project. 004 005package edu.wpi.first.util; 006 007import java.io.IOException; 008import java.nio.ByteBuffer; 009import java.util.concurrent.atomic.AtomicBoolean; 010 011/** WPIUtil JNI. */ 012public class WPIUtilJNI { 013 static boolean libraryLoaded = false; 014 static RuntimeLoader<WPIUtilJNI> loader = null; 015 016 /** Sets whether JNI should be loaded in the static block. */ 017 public static class Helper { 018 private static AtomicBoolean extractOnStaticLoad = new AtomicBoolean(true); 019 020 /** 021 * Returns true if the JNI should be loaded in the static block. 022 * 023 * @return True if the JNI should be loaded in the static block. 024 */ 025 public static boolean getExtractOnStaticLoad() { 026 return extractOnStaticLoad.get(); 027 } 028 029 /** 030 * Sets whether the JNI should be loaded in the static block. 031 * 032 * @param load Whether the JNI should be loaded in the static block. 033 */ 034 public static void setExtractOnStaticLoad(boolean load) { 035 extractOnStaticLoad.set(load); 036 } 037 038 /** Utility class. */ 039 private Helper() {} 040 } 041 042 static { 043 if (Helper.getExtractOnStaticLoad()) { 044 try { 045 loader = 046 new RuntimeLoader<>( 047 "wpiutiljni", RuntimeLoader.getDefaultExtractionRoot(), WPIUtilJNI.class); 048 loader.loadLibrary(); 049 } catch (IOException ex) { 050 ex.printStackTrace(); 051 System.exit(1); 052 } 053 libraryLoaded = true; 054 } 055 } 056 057 /** 058 * Force load the library. 059 * 060 * @throws IOException if the library failed to load 061 */ 062 public static synchronized void forceLoad() throws IOException { 063 if (libraryLoaded) { 064 return; 065 } 066 loader = 067 new RuntimeLoader<>( 068 "wpiutiljni", RuntimeLoader.getDefaultExtractionRoot(), WPIUtilJNI.class); 069 loader.loadLibrary(); 070 libraryLoaded = true; 071 } 072 073 /** 074 * Write the given string to stderr. 075 * 076 * @param str String to write. 077 */ 078 public static native void writeStderr(String str); 079 080 /** Enable mock time. */ 081 public static native void enableMockTime(); 082 083 /** Disable mock time. */ 084 public static native void disableMockTime(); 085 086 /** 087 * Set mock time. 088 * 089 * @param time The desired time in microseconds. 090 */ 091 public static native void setMockTime(long time); 092 093 /** 094 * Returns the time. 095 * 096 * @return The time. 097 */ 098 public static native long now(); 099 100 /** 101 * Returns the system time. 102 * 103 * @return The system time. 104 */ 105 public static native long getSystemTime(); 106 107 /** 108 * Creates an event. Events have binary state (signaled or not signaled) and may be either 109 * automatically reset or manually reset. Automatic-reset events go to non-signaled state when a 110 * WaitForObject is woken up by the event; manual-reset events require ResetEvent() to be called 111 * to set the event to non-signaled state; if ResetEvent() is not called, any waiter on that event 112 * will immediately wake when called. 113 * 114 * @param manualReset true for manual reset, false for automatic reset 115 * @param initialState true to make the event initially in signaled state 116 * @return Event handle 117 */ 118 public static native int createEvent(boolean manualReset, boolean initialState); 119 120 /** 121 * Destroys an event. Destruction wakes up any waiters. 122 * 123 * @param eventHandle event handle 124 */ 125 public static native void destroyEvent(int eventHandle); 126 127 /** 128 * Sets an event to signaled state. 129 * 130 * @param eventHandle event handle 131 */ 132 public static native void setEvent(int eventHandle); 133 134 /** 135 * Sets an event to non-signaled state. 136 * 137 * @param eventHandle event handle 138 */ 139 public static native void resetEvent(int eventHandle); 140 141 /** 142 * Creates a semaphore. Semaphores keep an internal counter. Releasing the semaphore increases the 143 * count. A semaphore with a non-zero count is considered signaled. When a waiter wakes up it 144 * atomically decrements the count by 1. This is generally useful in a single-supplier, 145 * multiple-consumer scenario. 146 * 147 * @param initialCount initial value for the semaphore's internal counter 148 * @param maximumCount maximum value for the samephore's internal counter 149 * @return Semaphore handle 150 */ 151 public static native int createSemaphore(int initialCount, int maximumCount); 152 153 /** 154 * Destroys a semaphore. Destruction wakes up any waiters. 155 * 156 * @param semHandle semaphore handle 157 */ 158 public static native void destroySemaphore(int semHandle); 159 160 /** 161 * Releases N counts of a semaphore. 162 * 163 * @param semHandle semaphore handle 164 * @param releaseCount amount to add to semaphore's internal counter; must be positive 165 * @return True on successful release, false on failure (e.g. release count would exceed maximum 166 * value, or handle invalid) 167 */ 168 public static native boolean releaseSemaphore(int semHandle, int releaseCount); 169 170 static native long allocateRawFrame(); 171 172 static native void freeRawFrame(long frame); 173 174 static native long getRawFrameDataPtr(long frame); 175 176 static native void setRawFrameData( 177 long frame, ByteBuffer data, int size, int width, int height, int stride, int pixelFormat); 178 179 static native void setRawFrameInfo( 180 long frame, int size, int width, int height, int stride, int pixelFormat); 181 182 /** 183 * Waits for a handle to be signaled. 184 * 185 * @param handle handle to wait on 186 * @throws InterruptedException on failure (e.g. object was destroyed) 187 */ 188 public static native void waitForObject(int handle) throws InterruptedException; 189 190 /** 191 * Waits for a handle to be signaled, with timeout. 192 * 193 * @param handle handle to wait on 194 * @param timeout timeout in seconds 195 * @return True if timeout reached without handle being signaled 196 * @throws InterruptedException on failure (e.g. object was destroyed) 197 */ 198 public static native boolean waitForObjectTimeout(int handle, double timeout) 199 throws InterruptedException; 200 201 /** 202 * Waits for one or more handles to be signaled. 203 * 204 * <p>Invalid handles are treated as signaled; the returned array will have the handle error bit 205 * set for any invalid handles. 206 * 207 * @param handles array of handles to wait on 208 * @return array of signaled handles 209 * @throws InterruptedException on failure (e.g. no objects were signaled) 210 */ 211 public static native int[] waitForObjects(int[] handles) throws InterruptedException; 212 213 /** 214 * Waits for one or more handles to be signaled, with timeout. 215 * 216 * <p>Invalid handles are treated as signaled; the returned array will have the handle error bit 217 * set for any invalid handles. 218 * 219 * @param handles array of handles to wait on 220 * @param timeout timeout in seconds 221 * @return array of signaled handles; empty if timeout reached without any handle being signaled 222 * @throws InterruptedException on failure (e.g. no objects were signaled and no timeout) 223 */ 224 public static native int[] waitForObjectsTimeout(int[] handles, double timeout) 225 throws InterruptedException; 226 227 /** Utility class. */ 228 protected WPIUtilJNI() {} 229}