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