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