src/main/java/me/senseiwells/arucas/api/ArucasThreadHandler.java
public Value runOnMainThreadAndWait(Context context, String fileName, String fileContent) throws CodeError {
		// Make sure that this handler belongs to the provided context
		// Cannot have two main threads for the same program
		if (context.getThreadHandler() != this) {
			throw new IllegalStateException("Wrong context passed in");
		}
		if (this.isRunning()) {
			throw new IllegalStateException("Main thread is already running");
		}

		this.currentFileContent = fileContent;
		this.hasError = false;
		this.isRunning = true;

		CompletableFuture<Throwable> futureThrowable = new CompletableFuture<>();
		CompletableFuture<Value> futureValue = new CompletableFuture<>();

		new ArucasThread(this.arucasThreadGroup, () -> {
			Value value;
			try {
				value = Run.run(context, fileName, fileContent);
			}
			catch (Throwable throwable) {
				futureThrowable.complete(throwable);
				value = null;
			}
			this.stop();
			futureValue.complete(value);
		}, "Arucas Main Thread").start(context);

		Value value = ExceptionUtils.catchAsNull(futureValue::get);
		if (value != null) {
			return value;
		}
		if (futureThrowable.isDone()) {
			Throwable throwable = ExceptionUtils.catchAsNull(futureThrowable::get);
			if (throwable == null) {
				throw new NullPointerException("Throwable was null");
			}
			if (throwable instanceof CodeError codeError) {
				throw codeError;
			}
			throw new RuntimeException(throwable);
		}
		throw new IllegalStateException("Result was neither an error or a value");
	}
/**
	 * This method runs a script on a Main thread and
	 * will wait for the thread to finish returning the
	 * correct value and throwing any errors that the
	 * script would have thrown on the Main Thread
	 *
	 * @param context     the base context
	 * @param fileName    the name of the file you are running from
	 * @param fileContent the Arucas code you want to execute
	 */
This method runs a script on a Main thread and
will wait for the thread to finish returning the
correct value and throwing any errors that the
script would have thrown on the Main Thread

@param context     the base context
@param fileName    the name of the file you are running from
@param fileContent the Arucas code you want to execute
This method runs a script on a Main thread and will wait for the thread to finish returning the correct value and throwing any errors that the script would have thrown on the Main Thread @param context the base context @param fileName the name of the file you are running from @param fileContent the Arucas code you want to execute
public Value runOnMainThreadAndWait(Context context, String fileName, String fileContent) throws CodeError {
		if (context.getThreadHandler() != this) {
			throw new IllegalStateException("Wrong context passed in");
		}
		if (this.isRunning()) {
			throw new IllegalStateException("Main thread is already running");
		}
		this.currentFileContent = fileContent;
		this.hasError = false;
		this.isRunning = true;
		CompletableFuture<Throwable> futureThrowable = new CompletableFuture<>();
		CompletableFuture<Value> futureValue = new CompletableFuture<>();
		new ArucasThread(this.arucasThreadGroup, () -> {
			Value value;
			try {
				value = Run.run(context, fileName, fileContent);
			}
			catch (Throwable throwable) {
				futureThrowable.complete(throwable);
				value = null;
			}
			this.stop();
			futureValue.complete(value);
		}, "Arucas Main Thread").start(context);
		Value value = ExceptionUtils.catchAsNull(futureValue::get);
		if (value != null) {
			return value;
		}
		if (futureThrowable.isDone()) {
			Throwable throwable = ExceptionUtils.catchAsNull(futureThrowable::get);
			if (throwable == null) {
				throw new NullPointerException("Throwable was null");
			}
			if (throwable instanceof CodeError codeError) {
				throw codeError;
			}
			throw new RuntimeException(throwable);
		}
		throw new IllegalStateException("Result was neither an error or a value");
	}
public Value runOnMainThreadAndWait ( Context context , String fileName , String fileContent ) throws CodeError { if ( context . getThreadHandler ( ) != this ) { throw new IllegalStateException ( "Wrong context passed in" ) ; } if ( this . isRunning ( ) ) { throw new IllegalStateException ( "Main thread is already running" ) ; } this . currentFileContent = fileContent ; this . hasError = false ; this . isRunning = true ; CompletableFuture < Throwable > futureThrowable = new CompletableFuture < > ( ) ; CompletableFuture < Value > futureValue = new CompletableFuture < > ( ) ; new ArucasThread ( this . arucasThreadGroup , ( ) -> { Value value ; try { value = Run . run ( context , fileName , fileContent ) ; } catch ( Throwable throwable ) { futureThrowable . complete ( throwable ) ; value = null ; } this . stop ( ) ; futureValue . complete ( value ) ; } , "Arucas Main Thread" ) . start ( context ) ; Value value = ExceptionUtils . catchAsNull ( futureValue :: get ) ; if ( value != null ) { return value ; } if ( futureThrowable . isDone ( ) ) { Throwable throwable = ExceptionUtils . catchAsNull ( futureThrowable :: get ) ; if ( throwable == null ) { throw new NullPointerException ( "Throwable was null" ) ; } if ( throwable instanceof CodeError codeError ) { throw codeError ; } throw new RuntimeException ( throwable ) ; } throw new IllegalStateException ( "Result was neither an error or a value" ) ; }
This method runs a script on a Main thread and
 will wait for the thread to finish returning the
 correct value and throwing any errors that the
 script would have thrown on the Main Thread
This method runs a script on a Main thread and will wait for the thread to finish returning the correct value and throwing any errors that the script would have thrown on the Main Thread
// Make sure that this handler belongs to the provided context // Cannot have two main threads for the same program