| package li.cil.oc.api.machine; |
| |
| import net.minecraft.item.ItemStack; |
| import net.minecraft.nbt.NBTTagCompound; |
| |
| import java.lang.annotation.ElementType; |
| import java.lang.annotation.Retention; |
| import java.lang.annotation.RetentionPolicy; |
| import java.lang.annotation.Target; |
| |
| /** |
| * This interface abstracts away any language specific details for the Machine. |
| * <p/> |
| * This allows the introduction of other languages, e.g. computers that run |
| * assembly or some other language interpreter. The two architectures included |
| * in OpenComputers are the native Lua architecture (using native LuaC) and the |
| * Java Lua architecture (using LuaJ). |
| */ |
| public interface Architecture { |
| /** |
| * Used to check if the machine is fully initialized. If this is false no |
| * signals for detected components will be generated. Avoids duplicate |
| * signals if <tt>component_added</tt> signals are generated in the |
| * language's startup script, for already present components (see Lua's |
| * init.lua script). |
| * <p/> |
| * This is also used to check whether limits on direct calls should be |
| * enforced or not - this allows a quick boot phase in the language's |
| * kernel logic before switching to business-as-usual. |
| * |
| * @return whether the machine is fully initialized. |
| */ |
| boolean isInitialized(); |
| |
| /** |
| * This is called when the amount of memory in the machine may have changed. |
| * This is usually triggered by the owner when its composition changes. For |
| * example this is called from computer cases' onInventoryChanged method. |
| * <p/> |
| * The amount of memory should be computed from the list of components given. |
| * The architecture should immediately apply the new memory size |
| * |
| * @param components the components to use for computing the total memory. |
| * @return whether any memory is present at all. |
| */ |
| boolean recomputeMemory(Iterable<ItemStack> components); |
| |
| /** |
| * Called when a machine starts up. Used to (re-)initialize the underlying |
| * architecture logic. For example, for Lua this creates a new Lua state. |
| * <p/> |
| * This also sets up any built-in APIs for the underlying language, such as |
| * querying available memory, listing and interacting with components and so |
| * on. If this returns <tt>false</tt> the machine fails to start. |
| * <p/> |
| * Note that the owning machine has not necessarily been connected to a |
| * network when this is called, in case this is called from the machine's |
| * load logic. Use {@link #onConnect()} for additional initialization that |
| * depends on a node network (such as connecting a ROM file system). |
| * |
| * @return whether the architecture was initialized successfully. |
| */ |
| boolean initialize(); |
| |
| /** |
| * Called when a machine stopped. Used to clean up any handles, memory and |
| * so on. For example, for Lua this destroys the Lua state. |
| */ |
| void close(); |
| |
| /** |
| * Performs a synchronized call initialized in a previous call to |
| * {@link #runThreaded(boolean)}. |
| * <p/> |
| * This method is invoked from the main server thread, meaning it is safe |
| * to interact with the world without having to perform manual |
| * synchronization. |
| * <p/> |
| * This method is expected to leave the architecture in a state so it is |
| * prepared to next be called with <tt>runThreaded(true)</tt>. For example, |
| * the Lua architecture will leave the results of the synchronized call on |
| * the stack so they can be further processed in the next call to |
| * <tt>runThreaded</tt>. |
| */ |
| void runSynchronized(); |
| |
| /** |
| * Continues execution of the machine. The first call may be used to |
| * initialize the machine (e.g. for Lua we load the libraries in the first |
| * call so that the computers boot faster). After that the architecture |
| * <em>should</em> return <tt>true</tt> from {@link #isInitialized()}. |
| * <p/> |
| * The resumed state is either a return from a synchronized call, when a |
| * synchronized call has been completed (via <tt>runSynchronized</tt>), or |
| * a normal yield in all other cases (sleep, interrupt, boot, ...). |
| * <p/> |
| * This is expected to return within a very short time, usually. For example, |
| * in Lua this returns as soon as the state yields, and returns at the latest |
| * when the Settings.timeout is reached (in which case it forces the state |
| * to crash). |
| * <p/> |
| * This is expected to consume a single signal if one is present and return. |
| * If returning from a synchronized call this should consume no signal. |
| * |
| * @param isSynchronizedReturn whether the architecture is resumed from an |
| * earlier synchronized call. In the case of |
| * Lua this means the results of the call are |
| * now on the stack, for example. |
| * @return the result of the execution. Used to determine the new state. |
| */ |
| ExecutionResult runThreaded(boolean isSynchronizedReturn); |
| |
| /** |
| * Called when the owning machine was connected to the component network. |
| * <p/> |
| * This can be useful for connecting custom file systems (read only memory) |
| * in case {@link #initialize()} was called from the machine's load logic |
| * (where it was not yet connected to the network). |
| */ |
| void onConnect(); |
| |
| /** |
| * Restores the state of this architecture as previously saved in |
| * {@link #save(NBTTagCompound)}. The architecture should be in the same |
| * state it was when it was saved after this, so it can be resumed from |
| * whatever state the owning machine was in when it was saved. |
| * |
| * @param nbt the tag compound to save to. |
| */ |
| void load(NBTTagCompound nbt); |
| |
| /** |
| * Saves the architecture for later restoration, e.g. across games or chunk |
| * unloads. Used to persist a machine's execution state. For native Lua this |
| * uses the Eris library to persist the main coroutine, for example. |
| * <p/> |
| * Note that the tag compound is shared with the Machine. |
| * |
| * @param nbt the tag compound to save to. |
| */ |
| void save(NBTTagCompound nbt); |
| |
| /** |
| * Architectures can be annotated with this to provide a nice display name. |
| * <p/> |
| * This is used when the name of an architecture has to be displayed to the |
| * user, such as when cycling architectures on a CPU. |
| */ |
| @Retention(RetentionPolicy.RUNTIME) |
| @Target(ElementType.TYPE) |
| @interface Name { |
| String value(); |
| } |
| |
| /** |
| * Architectures flagged with this annotation can potentially run without |
| * any additional memory installed in the computer. |
| * <p/> |
| * Use this to allow assembly of devices such as microcontrollers without |
| * any memory being installed in them while your architecture is being |
| * used by the CPU being installed. Note to actually make the machine |
| * start up you only need to always return <tt>true</tt> from |
| * {@link #recomputeMemory}. |
| */ |
| @Retention(RetentionPolicy.RUNTIME) |
| @Target(ElementType.TYPE) |
| @interface NoMemoryRequirements { |
| } |
| } |