| The API can be used to either interact with existing implementations in OpenComputers or to implement your own extensions for OpenComputers. |
| |
| Extending OpenComputers |
| ======================== |
| |
| Making a tile entity available as a component / peripheral |
| -------------------------------------------------- |
| If you simply wish to expose a couple of methods that can be called from a computer if your tile entity's block is 'connected' to the computer, you can use the `SimpleComponent` interface. This interface serves as a marker for OpenComputers to know it has to inject code that converts your tile entity into a component using its class transformer. It is an interface instead of an annotation to allow stripping it, removing any dependencies on OpenComputers. Here is an example implementation: |
| ```java |
| @Optional.Interface(iface = "li.cil.oc.api.network.SimpleComponent", modid = "OpenComputers") |
| public class TileEntityMyFancyThing extends TileEntity |
| implements SimpleComponent |
| { |
| @Override |
| public String getComponentName() { |
| return "fancy_thing"; |
| } |
| |
| @Callback |
| @Optional.Method(modid = "OpenComputers") |
| public Object[] greet(Context context, Arguments args) { |
| return new Object[]{String.format("Hello, %s!", args.checkString(0))}; |
| } |
| } |
| ``` |
| |
| The `getComponentName` determines with which name the tile entity will be available to computers. The `Callback` annotation tells OpenComputers to make the annotated method available to the computer. See the documentation on the `Callback` annotation for more information, in particular how it can be used to manipulate the call behavior (synchronized to the main thread vs. in the thread driving the calling computer). |
| |
| So to call the greeter method, in Lua you'd do this: |
| ```lua |
| print(component.fancy_thing.greet("Steve")) -- prints "Hello, Steve!" |
| ```` |
| |
| More control |
| ------------ |
| If you really need more control over how how your tile entity interacts with OpenComputer's internal network, you will have to implement the `Environment` interface on your tile entity. There's a basic implementation in the prefab package, named `TileEntityEnvironment`. Doing so will give you access to the `Node` that connects to the component network, and you must take care of the construction of the node itself (using the factory method in `api.Network`). This allows you to make the node a `Connector` node, which will allow you to draw internal power from OpenComputers or feed energy into it. You will also be able to send messages over the component network, see the `send...` methods in the `Node` interface. See the documentation on those interfaces to get a better idea on how they work together. |
| |
| Making a thrid-party block available as component / peripheral |
| -------------------------------------------------------------- |
| Blocks from other mods, i.e. blocks where you have no control over the tile entity implementation, can be accessed using the Adapter block as long as there is a driver available that supports the block. If there are multiple drivers they are automatically merged. Please see the [OpenComponents][] project for examples, and consider contributing any block drivers you write to it. Thank you. |
| |
| Making items available as components |
| ------------------------------------ |
| To make items usable as components in computers, such as cards or hard drives, you have to provide a driver for that item. This means you have to implement the `driver.Item` interface on a class and register an instance of it via the `api.Driver` registry. You can base your item drivers on the `DriverItem` prefab. Please see the example project on Github for a working example, and read the documentation of the driver interface for more information. |
| |
| FileSystem API |
| ============== |
| If you'd like to make some files/scripts you ship with your mod available to a computer, you can do so by wrapping those files using an OpenComputers file system. Use the factory methods in `api.FileSystem` to wrap the location your files are stored at in a file system, use the `asManagedEnvironment` methods to wrap it in a node that can be attached to the component network. For example, in an environment of a tile entity or created by an item driver you could do this in the `onConnect` method whenever a computer is connected (i.e. `node.host() instanceof Context`). Code-wise it may look something like this: |
| ```java |
| public class TileEntityWithFileSystem extends TileEntityEnvironment { |
| private final Node fileSystem; |
| |
| public TileEntityWithFileSystem() { |
| node = Network.newNode(this, Visibility.Network).create(); |
| fileSystem = FileSystem.asManagedEnvironment(FileSystem.fromClass(getClass, "yourmodid/lua"), "my_files"); |
| } |
| |
| @Override |
| public void onConnect(final Node node) { |
| if (node.host() instanceof Context) { |
| // Attach our file system to new computers we get connected to. |
| // Note that this is also called for all already present computers |
| // when we're added to an already existing network, so we don't |
| // have to loop through the existing nodes manually. |
| node.connect(fileSystem); |
| } |
| } |
| |
| @Override |
| public void onDisconnect(final Node node) { |
| if (node.host() instanceof Context) { |
| // Remove our file systems when we get disconnected from a |
| // computer. |
| node.disconnect(fileSystem); |
| } else if (node == this.node) { |
| // Remove the file system if we are disconnected, because in that |
| // case this method is only called once. |
| fileSystem.node.remove(); |
| } |
| } |
| } |
| ``` |
| |
| |
| [OpenComponents]: https://github.com/MightyPirates/OpenComponents |