Package com.mouseviator.fsuipc

# Class FSUIPC

java.lang.Object
com.mouseviator.fsuipc.FSUIPC

    public class FSUIPC
    extends java.lang.Object

## General description

This is another FSUIPC wrapper class... This one uses `FSUIPCWrapper` to perform stuff with FSUIPC, but sort of hides the low-level approach required by `FSUIPCWrapper` and hides it behind more object oriented Java approach - or at least, I tried to achieve that...

The `FSUIPCWrapper` uses native methods and therefore, needs a dll library to be loaded for it to work. But since the JVM can be 32bit, or 64bit, the library implementing the native functions must also be 32bit or 64bit. The `FSUIPCWrapper` will not load any library by itself. Therefore, it is up the programmer to do it before using any (actually some, but rather stick to all) functions from this (and therefore, the `FSUIPCWrapper` class) class. But you don't have to write them yourself, you can use `load()` function (which will try to detect platform by itself), or either one of `load32()` and `load64()` if you have your own mechanism on detecting platform, such as JNI.

This class is build upon a concept of data requests. Data requests simply are data that you want to read/write to/from the simulator via FSUIPC. Each data request is associated with the offset (what data you want to read/write, you know that from other programming with FSUIPC), has its type - READ or WRITE. For data request to be supported by this class, it must implement the `IDataRequest` interface. You can also use the `DataRequest` class as a foundation for building new data request object, or use any predefined ones from the `com.mouseviator.fsuipc.datarequest.primitives` package (which defines data request for all primitive data types supported by FSUIPC, such as byte, integer, string etc.).

Gathering data to/from the simulator via FSUIPC's inter process communication is time consuming, that is why it would be bad to do it each time we need i single information, like airspeed update. This class has two arrays (queues) for storing data requests. One is for one-time requests - the data, that you need to read/write once, since they do not change often, such as situation file. You can add requests to this queue using the `addOneTimeRequest(com.mouseviator.fsuipc.datarequest.IDataRequest)` function. Add multiple requests and then process them all via single FSUIPC inter process communication call using the `processRequestsOnce()` function. Note that if the processing is successful, the one-time queue will be emptied (you will need to add requests again for another data exchange).

The second type of queue is the one for continual data requests. For data, that you need to read/write continuously, such as airspeed. You can add requests to this queue using the `addContinualRequest(com.mouseviator.fsuipc.datarequest.IDataRequest)` function. The process them all using the `processRequests(int, boolean)` function. This function will start a thread that will trigger the FSUIPC inter process communication periodically in the interval specified when calling the function, and all registered data requests will be updated every time. If there are any request in the one-time queue, they will be processed to, so there is no need to call `processRequestsOnce()` after starting the processing thread using the `processRequests(int, boolean)` function. To stop the processing thread, call the `cancelRequestsProcessing()` function.

Well, I know it is nice that the processing thread updates the data, but how would you know that it actually happened? There is an event listener for this. Implement your own `IFSUIPCListener` and register it using the `addListener(com.mouseviator.fsuipc.IFSUIPCListener)` function. Then, FSUIPC class will call `IFSUIPCListener.onProcess(java.util.AbstractQueue)` function after each FSUIPC inter process communication requests are done (in another words, after each FSUIPC process() function call). See also another callback functions of the `IFSUIPCListener` interface. I think they are pretty self-explanatory

### Usage example

This is basic example on using this class. First of all, we need to get an instance of it.

      FSUIPC fsuipc = FSUIPC.getInstance();

Than we need to load the native library. In the code below, we do that using the `load()` function, which will try to determine whether to load 32 bit, or 64 bit library automatically. But you can also use `load32()` or `load64()` to load specific version if you have your own logic for determining JVM platform. When the library is loaded, we can connect to FSUIPC.

       byte result = FSUIPC.load();
       if (result != FSUIPC.LIB_LOAD_RESULT_OK) {
           System.out.println("Failed to load native library. Quiting...");
           return;
       }

       int ret = fsuipc.connect(FSUIPCWrapper.FSUIPCSimVersion.SIM_ANY);
       if (ret == 0) {
           System.out.println("Flight sim not found");
       } else {
           System.out.println("Flight Sim found!");
       }

Now, we can create some data request to read/write some data to/from simulator. In the code below, we create data request to read airspeed and register it for one time processing.

      //Helper for gathering aircraft data
      AircraftHelper aircraftHelper = new AircraftHelper();

      //Get IAS data request and register it for time processing
      FloatRequest ias = (FloatRequest) fsuipc.addOneTimeRequest(aircraftHelper.getIAS());

      //Let FSUIPC process all one-time requests
      int ret = fsuipc.processRequestsOnce();

      //Later on, print the requested data
      if (ret == FSUIPC.PROCESS_RESULT_OK) {
          System.out.println("Aircraft IAS: " + String.valueOf(ias.getValue()));
      }

Note that in the code above, we are using the helper method `AircraftHelper.getIAS()` to get the IAS data request. That helper provides modified request object, that will return the IAS in Kts as float value, even though that FSUIPC itself will return it as integer value * 128. The modified data request `IDataRequest.getValue()` will perform the calculation for us. The code above is the same as this:

      //Get IAS data request and register it for time processing
      IntRequest ias = new IntRequest(0x02BC);
      fsuipc.addOneTimeRequest(ias);

      //Let FSUIPC process all one-time requests
      int ret = fsuipc.processRequestsOnce();

      //Later on, print the requested data
      if (ret == FSUIPC.PROCESS_RESULT_OK) {
          System.out.println("Aircraft IAS (method 2): " + String.valueOf(ias.getValue() / 128.0f));
      }

If we want to monitor the airspeed continuously, we would register it with `addContinualRequest(com.mouseviator.fsuipc.datarequest.IDataRequest)` rather than with `addOneTimeRequest(com.mouseviator.fsuipc.datarequest.IDataRequest)`. In this case, it would also be nice to define the listener so that we know when processing happened. Note that the example uses logger variable, which is for logging messages (if you don't know about logging in Java, just ignore it) - kind of instead of System.out.println... Also notice, that inside the `IFSUIPCListener.onProcess(java.util.AbstractQueue)` callback we use `SwingUtilities.invokeLater`. This is because the processing happens in FSUIPC class processing thread - NOT EDT thread... and all GUI updates should happen on EDT thread...that is how to do it. The last line of code in this example, that cancels the requests processing, is not really needed. The FSUIPC class check the last result code after each to call to FSUIPC's processing function and it will cancel the processing thread once it finds out that FSUIPC connection to sim has been lost. But you can of course call it if you want to stop the processing for any reason.

     //Helper for gathering aircraft data
     AircraftHelper aircraftHelper = new AircraftHelper();

     //Get IAS data request and register it for time processing
     FloatRequest ias = (FloatRequest) fsuipc.addContinualRequest(aircraftHelper.getIAS());

     //We will get results from continual request processing using the listener
     IFSUIPCListener fsuipcListener = new IFSUIPCListener() {
           @Override
           public void onConnected() {
              logger.info("FSUIPC connected!");
           }

           @Override
           public void onDisconnected() {
              logger.info("FSUIPC disconnected!");
           }

           @Override
           public void onProcess(AbstractQueue<IDataRequest> arRequests) {
              System.out.println("FSUIPC continual request processing callback!");

              //GUI updates on EDT thread
              SwingUtilities.invokeLater(new Runnable() {
                  @Override
                  public void run() {
                      lblIAS.setText(String.format("%d Kts", (int) Math.ceil(ias.getValue())));
                  }
              }
           }

           @Override
           public void onFail(int lastResult) {
               logger.log(Level.INFO, "Last FSUIPC function call ended with error code: {0}, message: {1}",
                     new Object[]{lastResult,
                        FSUIPC.FSUIPC_ERROR_MESSAGES.get(FSUIPCWrapper.FSUIPCResult.get(lastResult))});
           }
     }

     //Add our listener to FSUIPC
     fsuipc.addListener(fsuipcListener);

     //Start continual processing, every 250 miliseconds
     fsuipc.processRequests(250, true);

     .
     .
     .
     .

     //Later, stop processing
     fsuipc.cancelRequestsProcessing();

When we are finished, we should disconnect the FSUIPC (this will also release used resources).

      fsuipc.disconnect();

Author:
  Mouseviator

- ## Field Summary

  Fields
  Modifier and Type | Field | Description
  --- | --- | ---
  `static java.util.HashMap<FSUIPCWrapper.FSUIPCResult,​java.lang.String>` | `FSUIPC_ERROR_MESSAGES` | A has map with error messages, giving some explanation to FSUIPC result values.
  `static java.util.HashMap<FSUIPCWrapper.FSUIPCSimVersion,​java.lang.String>` | `FSUIPC_SIM_VERSION_TEXT` | A has map with simulator names, giving some explanation to FSUIPC supported simulator values.
  `static byte` | `LIB_LOAD_RESULT_ALREADY_LOADED` | This result is returned by `load()`, `load32()` and `load64()` if native library is already loaded when calling these functions.
  `static byte` | `LIB_LOAD_RESULT_FAILED` | This result is returned by `load()`, `load32()` and `load64()` if loading of native library fails.
  `static byte` | `LIB_LOAD_RESULT_OK` | This result is returned by `load()`, `load32()` and `load64()` if loading of native library succeeds.
  `static java.lang.String` | `LIBRARY_NAME32` | Name of 32 bit library implementation
  `static java.lang.String` | `LIBRARY_NAME64` | Name of 64 bit library implementation
  `static int` | `PROCESS_RESULT_FAILED_TO_CANCEL_THREAD` | A code returned by `processRequests(int, boolean)` if it fails to cancel already running processing thread.
  `static int` | `PROCESS_RESULT_FAILTED_TO_START_THREAD` | A code returned by `processRequests(int, boolean)` if it fails to start processing thread.
  `static int` | `PROCESS_RESULT_OK` | A code returned by `processRequests(int, boolean)`, `process()` or `processRequestsOnce()` if FSUIPC process function return no errors.
  `static int` | `PROCESS_RESULT_REQUESTS_EMPTY` | A code returned by `processRequests(int, boolean)` or `processRequestsOnce()` if no requests have been registered.
  `static int` | `PROCESS_RESULT_REQUESTS_PROCESS_FAILED` | A code returned by `process()` if FSUIPC process function returns any other value than OK.
  `static int` | `PROCESS_RESULT_REQUESTS_STORE_FAILED` | A code returned by `processRequests(int, boolean)` or `processRequestsOnce()` if FSUIPC fails to register any of data request.
  `static int` | `PROCESS_RESULT_THREAD_ALREADY_RUNNING` | A code returned by `processRequests(int, boolean)` if processing thread is already running and you did not specify to stop it when calling the function.

- ## Constructor Summary

  Constructors
  Constructor | Description
  --- | ---
  `FSUIPC()` |

- ## Method Summary

  Modifier and Type | Method | Description
  --- | --- | ---
  `IDataRequest` | `addContinualRequest​(IDataRequest dataRequest)` | This method will add data request to the continual requests array.
  `boolean` | `addListener​(IFSUIPCListener listener)` | This will add listener.
  `IDataRequest` | `addOneTimeRequest​(IDataRequest dataRequest)` | This method will add data request to the one-time requests array.This array will be emptied once successfully processed via the `processRequestsOnce()` function.
  `boolean` | `cancelRequestsProcessing()` | This function will cancel the thread that is running the continual request processing.
  `boolean` | `clearContinualRequests()` | This will clear an array of continual requests and stop continual request processing thread.
  `int` | `connect​(FSUIPCWrapper.FSUIPCSimVersion simVersion)` | Open FSUIPC connection to selected simulator version.
  `void` | `disconnect()` | Closes connection to FSUIPC.
  `java.lang.String` | `getFSVersion()` | This function will return one text from `FSUIPC_SIM_VERSION_TEXT` based on the result of the call of the function `FSUIPCWrapper.getFSVersion()`.
  `java.lang.String` | `getFSVersion​(FSUIPCWrapper.FSUIPCSimVersion simVersion)` | This function will return one text from `FSUIPC_SIM_VERSION_TEXT` based on the result of the call of the function `FSUIPCWrapper.getFSVersion()`.If it fails to convert result of function `FSUIPCWrapper.getFSVersion()` to `FSUIPCWrapper.FSUIPCSimVersion`, the returned value will be an empty string.
  `static FSUIPC` | `getInstance()` |
  `java.lang.String` | `getLastErrorMessage()` | This function will return a message from `FSUIPC_ERROR_MESSAGES` for the last FSUIPC function call.
  `long` | `getLastProcessingTime()` | Returns the time in nanoseconds that the last call to FSUIPC process function took.
  `FSUIPCWrapper.FSUIPCResult` | `getLastResult()` | Return the last result from last FSUIPC operation.
  `java.lang.String` | `getLibVersion()` | Returns string representation of FSUIPC library version.
  `java.util.AbstractQueue<IDataRequest>` | `getOneTimeRequests()` | This function returns an array of one time data requests.
  `java.lang.String` | `getVersion()` | Returns string representation of FSUIPC version.
  `boolean` | `isConnected()` | Will return the value of the internal `AtomicBoolean` variable that is being updated when FSUIPC is connected/disconnected.
  `static byte` | `load()` | This function will try to load the 32bit/64bit native library that implements this wrapper native methods.
  `static byte` | `load32()` | This function will try to load 32bit version of native library that implements this wrapper native methods.
  `static byte` | `load64()` | This function will try to load 64bit version of native library that implements this wrapper native methods.
  `int` | `processRequests​(int repeatPeriod, boolean cancelRunning)` | This function will start thread for continual processing of FSUIPC data requests.
  `int` | `processRequestsOnce()` | This function will process all stored one-time data requests.
  `void` | `removeAllListeners()` | This will remove all listeners
  `boolean` | `removeContinualRequest​(IDataRequest dataRequest)` | This function will remove data request from continual requests array.
  `boolean` | `removeListener​(IFSUIPCListener listener)` | This will remove registered listener.
  `boolean` | `waitForConnection​(FSUIPCWrapper.FSUIPCSimVersion simVersion, int repeatPeriod)` | This method will init thread that will continuously try to connect to simulator via FSUIPC till success.

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Field Details

  - ### PROCESS_RESULT_REQUESTS_EMPTY

    public static final int PROCESS_RESULT_REQUESTS_EMPTY
    A code returned by `processRequests(int, boolean)` or `processRequestsOnce()` if no requests have been registered.
    See Also:
      Constant Field Values

  - ### PROCESS_RESULT_REQUESTS_STORE_FAILED

    public static final int PROCESS_RESULT_REQUESTS_STORE_FAILED
    A code returned by `processRequests(int, boolean)` or `processRequestsOnce()` if FSUIPC fails to register any of data request.
    See Also:
      Constant Field Values

  - ### PROCESS_RESULT_REQUESTS_PROCESS_FAILED

    public static final int PROCESS_RESULT_REQUESTS_PROCESS_FAILED
    A code returned by `process()` if FSUIPC process function returns any other value than OK.
    See Also:
      Constant Field Values

  - ### PROCESS_RESULT_OK

    public static final int PROCESS_RESULT_OK
    A code returned by `processRequests(int, boolean)`, `process()` or `processRequestsOnce()` if FSUIPC process function return no errors.
    See Also:
      Constant Field Values

  - ### PROCESS_RESULT_FAILED_TO_CANCEL_THREAD

    public static final int PROCESS_RESULT_FAILED_TO_CANCEL_THREAD
    A code returned by `processRequests(int, boolean)` if it fails to cancel already running processing thread.
    See Also:
      Constant Field Values

  - ### PROCESS_RESULT_FAILTED_TO_START_THREAD

    public static final int PROCESS_RESULT_FAILTED_TO_START_THREAD
    A code returned by `processRequests(int, boolean)` if it fails to start processing thread.
    See Also:
      Constant Field Values

  - ### PROCESS_RESULT_THREAD_ALREADY_RUNNING

    public static final int PROCESS_RESULT_THREAD_ALREADY_RUNNING
    A code returned by `processRequests(int, boolean)` if processing thread is already running and you did not specify to stop it when calling the function.
    See Also:
      Constant Field Values

  - ### LIBRARY_NAME64

    public static final java.lang.String LIBRARY_NAME64
    Name of 64 bit library implementation
    See Also:
      Constant Field Values

  - ### LIBRARY_NAME32

    public static final java.lang.String LIBRARY_NAME32
    Name of 32 bit library implementation
    See Also:
      Constant Field Values

  - ### LIB_LOAD_RESULT_OK

    public static final byte LIB_LOAD_RESULT_OK
    This result is returned by `load()`, `load32()` and `load64()` if loading of native library succeeds.
    See Also:
      Constant Field Values

  - ### LIB_LOAD_RESULT_FAILED

    public static final byte LIB_LOAD_RESULT_FAILED
    This result is returned by `load()`, `load32()` and `load64()` if loading of native library fails.
    See Also:
      Constant Field Values

  - ### LIB_LOAD_RESULT_ALREADY_LOADED

    public static final byte LIB_LOAD_RESULT_ALREADY_LOADED
    This result is returned by `load()`, `load32()` and `load64()` if native library is already loaded when calling these functions.
    See Also:
      Constant Field Values

  - ### FSUIPC_ERROR_MESSAGES

    public static final java.util.HashMap<FSUIPCWrapper.FSUIPCResult,​java.lang.String> FSUIPC_ERROR_MESSAGES
    A has map with error messages, giving some explanation to FSUIPC result values. There is a maessage for each value of `FSUIPCWrapper.FSUIPCResult`

  - ### FSUIPC_SIM_VERSION_TEXT

    public static final java.util.HashMap<FSUIPCWrapper.FSUIPCSimVersion,​java.lang.String> FSUIPC_SIM_VERSION_TEXT
    A has map with simulator names, giving some explanation to FSUIPC supported simulator values. There is a message for each value of `FSUIPCWrapper.FSUIPCSimVersion`

- ## Constructor Details

  - ### FSUIPC

    public FSUIPC()

- ## Method Details

  - ### getInstance

    public static FSUIPC getInstance()
    Returns:
      Instance of FSUIPC.

  - ### load

    public static byte load()
    This function will try to load the 32bit/64bit native library that implements this wrapper native methods. Note that it tries to determine the architecture by reading the "sun.arch.data.model" system property and then call `load32()` or `load64()` based on result. The result can also be "unknown", by that case non of the functions will be called. Note that this is not bulletproof, if you ae using JNI or similar API, use it and call 32/64 bit load function by yourself.
    Returns:
      Will return `LIB_LOAD_RESULT_OK` if the library is successfully loaded, `LIB_LOAD_RESULT_FAILED` if the loading of the library fails and `LIB_LOAD_RESULT_ALREADY_LOADED` if the library is already loaded (either 32 or 64 bit one)

  - ### load32

    public static byte load32()
    This function will try to load 32bit version of native library that implements this wrapper native methods.
    Returns:
      Will return `LIB_LOAD_RESULT_OK` if the library is successfully loaded, `LIB_LOAD_RESULT_FAILED` if the loading of the library fails and `LIB_LOAD_RESULT_ALREADY_LOADED` if the library is already loaded (either 32 or 64 bit one)

  - ### load64

    public static byte load64()
    This function will try to load 64bit version of native library that implements this wrapper native methods.
    Returns:
      Will return `LIB_LOAD_RESULT_OK` if the library is successfully loaded, `LIB_LOAD_RESULT_FAILED` if the loading of the library fails and `LIB_LOAD_RESULT_ALREADY_LOADED` if the library is already loaded (either 32 or 64 bit one)

  - ### addListener

    public boolean addListener​(IFSUIPCListener listener)
    This will add listener. If the listener is already present, it will not be added.
    Parameters:
      `listener` - A listener to add.
    Returns:
      True if listener was added, false otherwise (you passed null, or what `Collection.add(java.lang.Object)` returns.).

  - ### removeListener

    public boolean removeListener​(IFSUIPCListener listener)
    This will remove registered listener.
    Parameters:
      `listener` - A listener to remove.
    Returns:
      True if listener was removed, false otherwise (you passed null, or what `Collection.remove(java.lang.Object)` returns.).

  - ### removeAllListeners

    public void removeAllListeners()
    This will remove all listeners

  - ### connect

    public int connect​(FSUIPCWrapper.FSUIPCSimVersion simVersion)
    Open FSUIPC connection to selected simulator version.
    Parameters:
      `simVersion` - A simulator to connect to.
    Returns:
      0 if not connected, 1 (or non-zero) when successfully connected.

  - ### isConnected

    public boolean isConnected()
    Will return the value of the internal `AtomicBoolean` variable that is being updated when FSUIPC is connected/disconnected.
    Returns:
      True if FSUIPC is connected, false otherwise.

  - ### waitForConnection

    public boolean waitForConnection​(FSUIPCWrapper.FSUIPCSimVersion simVersion, int repeatPeriod)
    This method will init thread that will continuously try to connect to simulator via FSUIPC till success. WARNING: This functions will first try to stop any currently running waiting thread. This might take some time - thus may block the current thread! Should not be called from main EDT thread.
    Parameters:
      `simVersion` - A simulator version to which to connect.
      `repeatPeriod` - A time in seconds to repeat the connection attempts.
    Returns:
      True if thread is successfully started, false otherwise.

  - ### cancelRequestsProcessing

    public boolean cancelRequestsProcessing()
    This function will cancel the thread that is running the continual request processing. WARNING: This functions will try to stop any currently running processing thread. This might take some time - thus may block the current thread! Should not be called from main EDT thread.
    Returns:
      True if thread was canceled, false if there was some problem (exception).

  - ### disconnect

    public void disconnect()
    Closes connection to FSUIPC.

  - ### getLastResult

    public FSUIPCWrapper.FSUIPCResult getLastResult() throws java.security.InvalidParameterException
    Return the last result from last FSUIPC operation. This should be one from `FSUIPCWrapper.FSUIPCResult`
    Returns:
      `FSUIPCWrapper.FSUIPCResult` of last FSUIPC function call.
    Throws:
      `java.security.InvalidParameterException` - if `FSUIPCWrapper.getResult()` return value not supported by `FSUIPCWrapper.FSUIPCResult`. That would mean this library is outdated!

  - ### getLastErrorMessage

    public java.lang.String getLastErrorMessage() throws java.security.InvalidParameterException
    This function will return a message from `FSUIPC_ERROR_MESSAGES` for the last FSUIPC function call. It will call `getLastResult()` internally to get the last result code.
    Returns:
      A string error message for the last FSUIPC function call.
    Throws:
      `java.security.InvalidParameterException` - if `getLastResult()` throws the same Exception.

  - ### getFSVersion

    public java.lang.String getFSVersion()
    This function will return one text from `FSUIPC_SIM_VERSION_TEXT` based on the result of the call of the function `FSUIPCWrapper.getFSVersion()`. If it fails to convert result of function `FSUIPCWrapper.getFSVersion()` to `FSUIPCWrapper.FSUIPCSimVersion`, the returned value will be an empty string.
    Returns:
      String value.

  - ### getFSVersion

    public java.lang.String getFSVersion​(FSUIPCWrapper.FSUIPCSimVersion simVersion)
    This function will return one text from `FSUIPC_SIM_VERSION_TEXT` based on the result of the call of the function `FSUIPCWrapper.getFSVersion()`.If it fails to convert result of function `FSUIPCWrapper.getFSVersion()` to `FSUIPCWrapper.FSUIPCSimVersion`, the returned value will be an empty string.
    Parameters:
      `simVersion` - A sim version to get string representation for.
    Returns:
      String value.

  - ### getVersion

    public java.lang.String getVersion()
    Returns string representation of FSUIPC version. Calls `FSUIPCWrapper.getVersion()` to get FSUIPC version as number first.
    Returns:
      String representation of FSUIPC version.

  - ### getLibVersion

    public java.lang.String getLibVersion()
    Returns string representation of FSUIPC library version. Calls `FSUIPCWrapper.getVersion()` to get FSUIPC version as number first. Note that this version number is hard-coded in FSUIPC C lib and was not updated for years :)
    Returns:
      String representation of FSUIPC library version.

  - ### addOneTimeRequest

    public IDataRequest addOneTimeRequest​(IDataRequest dataRequest)
    This method will add data request to the one-time requests array.This array will be emptied once successfully processed via the `processRequestsOnce()` function.
    Parameters:
      `dataRequest` - Read or Write data request.
    Returns:
      The passed dataRequest if not null, otherwise null.

  - ### addContinualRequest

    public IDataRequest addContinualRequest​(IDataRequest dataRequest)
    This method will add data request to the continual requests array.
    Parameters:
      `dataRequest` - Read or Write data request.
    Returns:
      The passed dataRequest if not null, otherwise null.

  - ### removeContinualRequest

    public boolean removeContinualRequest​(IDataRequest dataRequest)
    This function will remove data request from continual requests array.
    Parameters:
      `dataRequest` - A data request to remove.
    Returns:
      True if continual requests array changed (the request was removed).

  - ### clearContinualRequests

    public boolean clearContinualRequests()
    This will clear an array of continual requests and stop continual request processing thread.
    Returns:
      The result of call to `cancelRequestsProcessing()`, which is done before the requests array is cleared.

  - ### getOneTimeRequests

    public java.util.AbstractQueue<IDataRequest> getOneTimeRequests()
    This function returns an array of one time data requests.
    Returns:
      The queue of one-time requests.

  - ### processRequestsOnce

    public int processRequestsOnce()
    This function will process all stored one-time data requests. To store one time data request to the queue, use `addContinualRequest(com.mouseviator.fsuipc.datarequest.IDataRequest)` method.
    Returns:
      This function will return `PROCESS_RESULT_OK` if everything went Ok. It will return `PROCESS_RESULT_REQUESTS_EMPTY` if the one-time requests array was empty before calling this function - ie. nothing to process. The `PROCESS_RESULT_REQUESTS_STORE_FAILED` will be returned if it failed to store any of the request to FSUIPC (`FSUIPCWrapper.read(int, int, byte[])` and `FSUIPCWrapper.write(int, int, byte[])` is being called in the background based on request type). And lastly, the `PROCESS_RESULT_REQUESTS_PROCESS_FAILED` if the call to `FSUIPCWrapper.process()` returned error. In the case of last two scenarios, use `FSUIPCWrapper.getResult()` to find out what did not work.

  - ### processRequests

    public int processRequests​(int repeatPeriod, boolean cancelRunning)
    This function will start thread for continual processing of FSUIPC data requests. Specify time period in milliseconds of how often to process requests. This will process all requests, either the ones stored via the `addOneTimeRequest(com.mouseviator.fsuipc.datarequest.IDataRequest)` or `addContinualRequest(com.mouseviator.fsuipc.datarequest.IDataRequest)` functions. If processing is completed without errors, the "one time" requests array will be cleared. WARNING: This function will try to stop any currently running processing thread (if cancelRunning is true). This might take some time - thus may block the current thread! Should not be called from main EDT thread.
    Parameters:
      `repeatPeriod` - How often to process the requests. Milliseconds.
      `cancelRunning` - Whether to cancel the task if currently running and start a new one.
    Returns:
      This function will return `PROCESS_RESULT_OK` if thread is successfully started. It will return `PROCESS_RESULT_FAILED_TO_CANCEL_THREAD` if the thread is already running, the cancelRunning parameter was true and it failed to cancel the currently running thread. If the thread is already running and the cancelRunning parameter is false, `PROCESS_RESULT_THREAD_ALREADY_RUNNING` will be returned. The `PROCESS_RESULT_FAILTED_TO_START_THREAD` will be returned if it fails to start new thread.

  - ### getLastProcessingTime

    public long getLastProcessingTime()
    Returns the time in nanoseconds that the last call to FSUIPC process function took. It will be updated by `processRequests(int, boolean)` and `processRequestsOnce()` functions.
    Returns:
      Time in milliseconds.