Beispiel #1
0
    @Override
    public Object[] returningFeval(String functionName, int nargout, Object... args)
        throws MatlabInvocationException {
      // Functions with no arguments should be passed null, not an empty array
      if (args != null && args.length == 0) {
        args = null;
      }

      try {
        Object matlabResult = Matlab.mtFevalConsoleOutput(functionName, args, nargout);

        Object[] resultArray;
        if (nargout == 0) {
          resultArray = new Object[0];
        } else if (nargout == 1) {
          resultArray = new Object[] {matlabResult};
        }
        // If multiple return values then an Object[] should have been returned
        else {
          if (matlabResult == null) {
            String errorMsg =
                "Expected " + nargout + " return arguments, instead null was returned";
            throw MatlabInvocationException.Reason.NARGOUT_MISMATCH.asException(errorMsg);
          } else if (!matlabResult.getClass().equals(Object[].class)) {
            String errorMsg =
                "Expected " + nargout + " return arguments, instead 1 argument was returned";
            throw MatlabInvocationException.Reason.NARGOUT_MISMATCH.asException(errorMsg);
          }

          resultArray = (Object[]) matlabResult;

          if (nargout != resultArray.length) {
            String errorMsg =
                "Expected "
                    + nargout
                    + " return arguments, instead "
                    + resultArray.length
                    + (resultArray.length == 1 ? " argument was" : " arguments were")
                    + " returned";
            throw MatlabInvocationException.Reason.NARGOUT_MISMATCH.asException(errorMsg);
          }
        }

        return resultArray;
      } catch (Exception e) {
        throw MatlabInvocationException.Reason.INTERNAL_EXCEPTION.asException(
            new ThrowableWrapper(e));
      }
    }
Beispiel #2
0
  /**
   * Exits MATLAB without waiting for MATLAB to return, because MATLAB will not return when exiting.
   *
   * @throws MatlabInvocationException
   */
  static void exit() {
    Runnable runnable =
        new Runnable() {
          @Override
          public void run() {
            try {
              Matlab.mtFevalConsoleOutput("exit", null, 0);
            }
            // This should never fail, and if it does there is no way to consistently report it back
            // to the caller
            // because this method does not block
            catch (Exception e) {
            }
          }
        };

    if (NativeMatlab.nativeIsMatlabThread()) {
      runnable.run();
    } else {
      Matlab.whenMatlabIdle(runnable);
    }
  }
Beispiel #3
0
  /**
   * Invokes the {@code callable} on the main MATLAB thread and waits for the computation to be
   * completed.
   *
   * @param <T>
   * @param callable
   * @return
   * @throws MatlabInvocationException
   */
  static <T> T invokeAndWait(final MatlabThreadCallable<T> callable)
      throws MatlabInvocationException {
    T result;

    if (NativeMatlab.nativeIsMatlabThread()) {
      try {
        result = callable.call(THREAD_OPERATIONS);
      } catch (RuntimeException e) {
        ThrowableWrapper cause = new ThrowableWrapper(e);
        throw MatlabInvocationException.Reason.RUNTIME_EXCEPTION.asException(cause);
      }
    } else if (EventQueue.isDispatchThread()) {
      final AtomicReference<MatlabReturn<T>> returnRef = new AtomicReference<MatlabReturn<T>>();

      Matlab.whenMatlabIdle(
          new Runnable() {
            @Override
            public void run() {
              MatlabReturn<T> matlabReturn;

              try {
                matlabReturn = new MatlabReturn<T>(callable.call(THREAD_OPERATIONS));
              } catch (MatlabInvocationException e) {
                matlabReturn = new MatlabReturn<T>(e);
              } catch (RuntimeException e) {
                ThrowableWrapper cause = new ThrowableWrapper(e);
                MatlabInvocationException userCausedException =
                    MatlabInvocationException.Reason.RUNTIME_EXCEPTION.asException(cause);
                matlabReturn = new MatlabReturn<T>(userCausedException);
              }

              returnRef.set(matlabReturn);
            }
          });

      // Pump event queue while waiting for MATLAB to complete the computation
      try {
        while (returnRef.get() == null) {
          if (EVENT_QUEUE.peekEvent() != null) {
            EVENT_QUEUE_DISPATCH_METHOD.invoke(EVENT_QUEUE, EVENT_QUEUE.getNextEvent());
          }
        }
      } catch (InterruptedException e) {
        throw MatlabInvocationException.Reason.EVENT_DISPATCH_THREAD.asException(e);
      } catch (IllegalAccessException e) {
        throw MatlabInvocationException.Reason.EVENT_DISPATCH_THREAD.asException(e);
      } catch (InvocationTargetException e) {
        throw MatlabInvocationException.Reason.EVENT_DISPATCH_THREAD.asException(e);
      }

      // Process return
      MatlabReturn<T> matlabReturn = returnRef.get();

      // If exception was thrown, rethrow it
      if (matlabReturn.exception != null) {
        throw matlabReturn.exception;
      }
      // Return data computed by MATLAB
      else {
        result = matlabReturn.data;
      }
    } else {
      // Used to block the calling thread while waiting for MATLAB to finish computing
      final ArrayBlockingQueue<MatlabReturn<T>> returnQueue =
          new ArrayBlockingQueue<MatlabReturn<T>>(1);

      Matlab.whenMatlabIdle(
          new Runnable() {
            @Override
            public void run() {
              MatlabReturn<T> matlabReturn;

              try {
                matlabReturn = new MatlabReturn<T>(callable.call(THREAD_OPERATIONS));
              } catch (MatlabInvocationException e) {
                matlabReturn = new MatlabReturn<T>(e);
              } catch (RuntimeException e) {
                ThrowableWrapper cause = new ThrowableWrapper(e);
                MatlabInvocationException userCausedException =
                    MatlabInvocationException.Reason.RUNTIME_EXCEPTION.asException(cause);
                matlabReturn = new MatlabReturn<T>(userCausedException);
              }

              returnQueue.add(matlabReturn);
            }
          });

      try {
        // Wait for MATLAB's main thread to finish computation
        MatlabReturn<T> matlabReturn = returnQueue.take();

        // If exception was thrown, rethrow it
        if (matlabReturn.exception != null) {
          throw matlabReturn.exception;
        }
        // Return data computed by MATLAB
        else {
          result = matlabReturn.data;
        }
      } catch (InterruptedException e) {
        throw MatlabInvocationException.Reason.INTERRRUPTED.asException(e);
      }
    }

    return result;
  }