@TestOnly public static void dispatchAllInvocationEventsInIdeEventQueue() throws InterruptedException { assert SwingUtilities.isEventDispatchThread() : Thread.currentThread(); final EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue(); while (true) { AWTEvent event = eventQueue.peekEvent(); if (event == null) break; AWTEvent event1 = eventQueue.getNextEvent(); if (event1 instanceof InvocationEvent) { IdeEventQueue.getInstance().dispatchEvent(event1); } } }
/** * Returns the next event in the queue that has the specified id without removing it from the * queue. This method will block until an event is available or until the thread is interrupted. * * @param id The event id to return. * @return The next event in the queue. * @specnote Does not block. Returns null if there are no matching events on the queue. */ public synchronized AWTEvent peekEvent(int id) { if (next != null) return next.peekEvent(id); AWTEvent evt = null; for (int i = 0; i < queues.length && evt == null; i++) { Queue q = queues[i]; evt = q.queueHead; while (evt != null && evt.id != id) evt = evt.queueNext; // At this point we either have found an event (evt != null -> exit // for loop), or we have found no event (evt == null -> search next // internal queue). } return evt; }
/** * 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; }
/** * Returns the next event in the queue without removing it from the queue. This method will block * until an event is available or until the thread is interrupted. * * @return The next event in the queue. * @specnote Does not block. Returns null if there are no events on the queue. */ public synchronized AWTEvent peekEvent() { if (next != null) return next.peekEvent(); return getNextEventImpl(false); }