<commit_before>package openperipheral.adapter.peripheral;

import java.util.Arrays;
import java.util.concurrent.Callable;

import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import openperipheral.TickHandler;
import openperipheral.api.IWorldProvider;
import openperipheral.util.PrettyPrint;

import org.apache.commons.lang3.ArrayUtils;

import com.google.common.base.Preconditions;

import dan200.computer.api.IComputerAccess;
import dan200.computer.api.ILuaContext;

public abstract class ExecutionStrategy {
	public abstract Object[] execute(Object target, IComputerAccess computer, ILuaContext context, Callable<Object[]> callable) throws Exception;

	public boolean isAlwaysSafe() {
		return true;
	}

	private abstract static class OnTick<T> extends ExecutionStrategy {

		private static final String EVENT_SUCCESS = "openperipheral_success";
		private static final String EVENT_ERROR = "openperipheral_error";

		public abstract World getWorld(T target);

		@Override
		public Object[] execute(Object target, final IComputerAccess computer, ILuaContext context, final Callable<Object[]> callable) throws Exception {
			@SuppressWarnings("unchecked")
			World world = getWorld((T)target);
			Preconditions.checkNotNull(world, "Trying to execute OnTick method, but no available world");
			TickHandler.addTickCallback(world, new Runnable() {
				@Override
				public void run() {
					// on the tick, we execute the method, format the response,
					// then stick it into an event
					try {
						Object[] response = callable.call();
						computer.queueEvent(EVENT_SUCCESS, response);
					} catch (Throwable e) {
						computer.queueEvent(EVENT_ERROR, ArrayUtils.toArray(PrettyPrint.getMessageForThrowable(e)));
					}
				}
			});

			// while we don't have an OpenPeripheral event
			while (true) {
				Object[] event = context.pullEvent(null);
				String eventName = (String)event[0];
				if (eventName.equals(EVENT_ERROR)) throw new RuntimeException((String)event[1]);
				else if (eventName.equals(EVENT_SUCCESS)) return Arrays.copyOfRange(event, 1, event.length);
			}
		}
	}

	public static final ExecutionStrategy ASYNCHRONOUS = new ExecutionStrategy() {
		@Override
		public Object[] execute(Object target, IComputerAccess computer, ILuaContext context, Callable<Object[]> callable) throws Exception {
			return callable.call();
		}
	};

	private final static ExecutionStrategy ON_TICK_TILE_ENTITY = new OnTick<TileEntity>() {

		@Override
		public World getWorld(TileEntity target) {
			return target.worldObj;
		}

	};
<commit_msg>Trying to prevent crash on reset<commit_after>package openperipheral.adapter.peripheral;

import java.util.Arrays;
import java.util.concurrent.Callable;

import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import openmods.Log;
import openperipheral.TickHandler;
import openperipheral.api.IWorldProvider;
import openperipheral.util.PrettyPrint;

import com.google.common.base.Preconditions;

import dan200.computer.api.IComputerAccess;
import dan200.computer.api.ILuaContext;

public abstract class ExecutionStrategy {
	public abstract Object[] execute(Object target, IComputerAccess computer, ILuaContext context, Callable<Object[]> callable) throws Exception;

	public boolean isAlwaysSafe() {
		return true;
	}
	
	public static Object[] wrap(Object... args) {
		return args;
	}

	private static class Responder {
		private final IComputerAccess access;
		private boolean nobodyLovesMe;

		private Responder(IComputerAccess access) {
			this.access = access;
		}

		public synchronized void tooLate() {
			nobodyLovesMe = true;
		}

		public synchronized void queueEvent(String event, Object... args) {
			if (nobodyLovesMe) {
				Log.warn("Ignoring event '%s', args='%s'. (sob)", event, Arrays.toString(args));
			} else {
				try {
					access.queueEvent(event, args);
				} catch (Exception e) {
					Log.warn(e, "Failed to queue response '%s', args='%s'", event, Arrays.toString(args));
				}
			}
		}
	}

	private abstract static class OnTick<T> extends ExecutionStrategy {

		private static final String EVENT_SUCCESS = "openperipheral_success";
		private static final String EVENT_ERROR = "openperipheral_error";

		public abstract World getWorld(T target);

		@Override
		public Object[] execute(Object target, IComputerAccess computer, ILuaContext context, final Callable<Object[]> callable) throws Exception {
			@SuppressWarnings("unchecked")
			World world = getWorld((T)target);
			Preconditions.checkNotNull(world, "Trying to execute OnTick method, but no available world");

			final Responder responder = new Responder(computer);
			TickHandler.addTickCallback(world, new Runnable() {
				@Override
				public void run() {
					// on the tick, we execute the method, format the response,
					// then stick it into an event
					try {
						Object[] response = callable.call();
						responder.queueEvent(EVENT_SUCCESS, response);
					} catch (Throwable e) {
						responder.queueEvent(EVENT_ERROR, wrap(PrettyPrint.getMessageForThrowable(e)));
					}
				}
			});

			// while we don't have an OpenPeripheral event
			while (true) {
				try {
					Object[] event = context.pullEvent(null);
					String eventName = (String)event[0];
					if (eventName.equals(EVENT_ERROR)) throw new RuntimeException((String)event[1]);
					else if (eventName.equals(EVENT_SUCCESS)) return Arrays.copyOfRange(event, 1, event.length);
				} catch (InterruptedException e) {
					responder.tooLate();
					throw e;
				}
			}
		}
	}

	public static final ExecutionStrategy ASYNCHRONOUS = new ExecutionStrategy() {
		@Override
		public Object[] execute(Object target, IComputerAccess computer, ILuaContext context, Callable<Object[]> callable) throws Exception {
			return callable.call();
		}
	};

	private final static ExecutionStrategy ON_TICK_TILE_ENTITY = new OnTick<TileEntity>() {

		@Override
		public World getWorld(TileEntity target) {
			return target.worldObj;
		}

	};

{'fraction_non_alphanumeric': 0.09979939819458375, 'fraction_numerical': 0.0031761952524239387, 'mean_word_length': 4.524469067405356, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5525599', 'n_tokens_mistral': 2024, 'n_tokens_neox': 1711, 'n_words': 469}