/* * This file is part of the public ComputerCraft API - http://www.computercraft.info * Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only. * For help using the API, and posting your mods, visit the forums at computercraft.info. */ package dan200.computercraft.api.lua; import javax.annotation.Nonnull; import javax.annotation.Nullable; /** * An interface passed to peripherals and {@link ILuaObject}s by computers or turtles, providing methods * that allow the peripheral call to wait for events before returning, just like in lua. This is very useful if you need * to signal work to be performed on the main thread, and don't want to return until the work has been completed. */ public interface ILuaContext { /** * Wait for an event to occur on the computer, suspending the thread until it arises. This method is exactly * equivalent to {@code os.pullEvent()} in lua. * * @param filter A specific event to wait for, or null to wait for any event. * @return An object array containing the name of the event that occurred, and any event parameters. * @throws LuaException If the user presses CTRL+T to terminate the current program while pullEvent() is * waiting for an event, a "Terminated" exception will be thrown here. * * Do not attempt to catch this exception. You should use {@link #pullEventRaw(String)} * should you wish to disable termination. * @throws InterruptedException If the user shuts down or reboots the computer while pullEvent() is waiting for an * event, InterruptedException will be thrown. This exception must not be caught or * intercepted, or the computer will leak memory and end up in a broken state. */ @Nonnull default Object[] pullEvent( @Nullable String filter ) throws LuaException, InterruptedException { Object[] results = pullEventRaw( filter ); if( results.length >= 1 && results[0].equals( "terminate" ) ) throw new LuaException( "Terminated", 0 ); return results; } /** * The same as {@link #pullEvent(String)}, except "terminated" events are ignored. Only use this if you want to * prevent program termination, which is not recommended. This method is exactly equivalent to * {@code os.pullEventRaw()} in lua. * * @param filter A specific event to wait for, or null to wait for any event. * @return An object array containing the name of the event that occurred, and any event parameters. * @throws InterruptedException If the user shuts down or reboots the computer while pullEventRaw() is waiting for * an event, InterruptedException will be thrown. This exception must not be caught or * intercepted, or the computer will leak memory and end up in a broken state. * @see #pullEvent(String) */ @Nonnull default Object[] pullEventRaw( @Nullable String filter ) throws InterruptedException { return yield( new Object[] { filter } ); } /** * Yield the current coroutine with some arguments until it is resumed. This method is exactly equivalent to * {@code coroutine.yield()} in lua. Use {@code pullEvent()} if you wish to wait for events. * * @param arguments An object array containing the arguments to pass to coroutine.yield() * @return An object array containing the return values from coroutine.yield() * @throws InterruptedException If the user shuts down or reboots the computer the coroutine is suspended, * InterruptedException will be thrown. This exception must not be caught or * intercepted, or the computer will leak memory and end up in a broken state. * @see #pullEvent(String) */ @Nonnull Object[] yield( @Nullable Object[] arguments ) throws InterruptedException; /** * Queue a task to be executed on the main server thread at the beginning of next tick, waiting for it to complete. * This should be used when you need to interact with the world in a thread-safe manner. * * Note that the return values of your task are handled as events, meaning more complex objects such as maps or * {@link ILuaObject} will not preserve their identities. * * @param task The task to execute on the main thread. * @return The objects returned by {@code task}. * @throws LuaException If the task could not be queued, or if the task threw an exception. * @throws InterruptedException If the user shuts down or reboots the computer the coroutine is suspended, * InterruptedException will be thrown. This exception must not be caught or * intercepted, or the computer will leak memory and end up in a broken state. */ @Nullable Object[] executeMainThreadTask( @Nonnull ILuaTask task ) throws LuaException, InterruptedException; /** * Queue a task to be executed on the main server thread at the beginning of next tick, but do not wait for it to * complete. This should be used when you need to interact with the world in a thread-safe manner but do not care * about the result or you wish to run asynchronously. * * When the task has finished, it will enqueue a {@code task_completed} event, which takes the task id, a success * value and the return values, or an error message if it failed. If you need to wait on this event, it may be * better to use {@link #executeMainThreadTask(ILuaTask)}. * * @param task The task to execute on the main thread. * @return The "id" of the task. This will be the first argument to the {@code task_completed} event. * @throws LuaException If the task could not be queued. */ long issueMainThreadTask( @Nonnull ILuaTask task ) throws LuaException; }