diff --git a/li/cil/oc/api/Driver.java b/li/cil/oc/api/Driver.java index e0132d3e3..581e9bc13 100644 --- a/li/cil/oc/api/Driver.java +++ b/li/cil/oc/api/Driver.java @@ -8,7 +8,10 @@ import li.cil.oc.api.driver.Item; * This API allows registering new drivers with the mod. *

* Drivers are used to make items and third-party blocks available in the mod's - * component network, and optionally to Lua programs. + * component network, and optionally to Lua programs. If you implement a new + * block that should interact with the mod's component network it is enough to + * have it implement {@link li.cil.oc.api.network.Environment} - no driver is + * needed in that case. * * @see Network * @see Block diff --git a/li/cil/oc/api/FileSystem.java b/li/cil/oc/api/FileSystem.java index 11754d880..87bc28405 100644 --- a/li/cil/oc/api/FileSystem.java +++ b/li/cil/oc/api/FileSystem.java @@ -8,22 +8,27 @@ import li.cil.oc.api.network.ManagedEnvironment; /** * This class provides factory methods for creating file systems that are - * compatible with the built-in filesystem driver. + * compatible with the built-in file system driver. *

* File systems created this way and wrapped in a managed environment via - * {@link #asManagedEnvironment(li.cil.oc.api.fs.FileSystem)} will appear as - * filesystem components in the internal network. Note that the + * {@link #asManagedEnvironment} or its overloads will appear as + * filesystem components in the component network. Note that the * component's visibility is set to Neighbors per default. If you wish * to change the file system's visibility (e.g. like the disk drive does) you * must cast the environment's node to {@link li.cil.oc.api.network.Component} - * and set it accordingly. + * and set the visibility to the desired value. + *

+ * Note that these methods should not be called in the pre-init phase, + * since the {@link #instance} may not have been initialized at that time. Only + * start calling these methods in the init phase or later. */ public final class FileSystem { /** * Creates a new file system based on the location of a class. *

* This can be used to wrap a folder in the assets folder of your mod's JAR. - * The actual path is built like this: `"/assets/" + domain + "/" + root`. + * The actual path is built like this: + *

"/assets/" + domain + "/" + root
*

* If the class is located in a JAR file, this will create a read-only file * system based on that JAR file. If the class file is located in the native @@ -32,10 +37,10 @@ public final class FileSystem { * class path (i.e. it'll look for a path constructed as described above). *

* If the specified path cannot be located, the creation fails and this - * returns `None`. + * returns null. * * @param clazz the class whose containing JAR to wrap. - * @param domain the mod domain, usually its name. + * @param domain the domain, usually your mod's ID. * @param root an optional subdirectory. * @return a file system wrapping the specified folder. */ @@ -49,11 +54,11 @@ public final class FileSystem { *

* This will create a folder, if necessary, and create a writable virtual * file system based in that folder. The actual path is based in a sub- - * folder of the save folder. The actual path is e.g. built like this: - * "saves/" + WORLD_NAME + "/opencomputers/" + root. Where the first - * part may differ, in particular for servers. But you get the idea. + * folder of the save folder. The actual path is built like this: + *

"saves/" + WORLD_NAME + "/opencomputers/" + root
+ * The first part may differ, in particular for servers. *

- * Usually the name will be the name of the node used to represent the + * Usually the name will be the address of the node used to represent the * file system. *

* Note that by default file systems are "buffered", meaning that any @@ -86,12 +91,12 @@ public final class FileSystem { } /** - * Creates a new *writable* file system that resides in memory. + * Creates a new writable file system that resides in memory. *

* Any contents created and written on this file system will be lost when * the node is removed from the network. *

- * This is used for computers' `/tmp` mount, for example. + * This is used for computers' /tmp mount, for example. * * @param capacity the capacity of the file system. * @return a file system residing in memory. @@ -131,7 +136,7 @@ public final class FileSystem { * your own driver. Which will probably be most of the time. If you need * more control over the node, implement your own, and connect this one to * it. In that case you will have to forward any disk driver messages to the - * node, though, since it's visibility is neighbors only. + * node, though. * * @param fileSystem the file system to wrap. * @param label the label of the file system. @@ -143,8 +148,8 @@ public final class FileSystem { } /** - * Does the same thing {@link #asManagedEnvironment(li.cil.oc.api.fs.FileSystem, Label)} - * does, but creates a read-only label initialized to the specified value. + * Like {@link #asManagedEnvironment(li.cil.oc.api.fs.FileSystem, Label)}, + * but creates a read-only label initialized to the specified value. * * @param fileSystem the file system to wrap. * @param label the read-only label of the file system. @@ -156,9 +161,9 @@ public final class FileSystem { } /** - * Does the same thing {@link #asManagedEnvironment(li.cil.oc.api.fs.FileSystem, Label)} - * does, but creates an unlabeled file system (i.e. the label can neither - * be read nor written). + * Like {@link #asManagedEnvironment(li.cil.oc.api.fs.FileSystem, Label)}, + * but creates an unlabeled file system (i.e. the label can neither be read + * nor written). * * @param fileSystem the file system to wrap. * @return the network node wrapping the file system. diff --git a/li/cil/oc/api/Network.java b/li/cil/oc/api/Network.java index c35137082..e1a1ecf13 100644 --- a/li/cil/oc/api/Network.java +++ b/li/cil/oc/api/Network.java @@ -8,18 +8,36 @@ import li.cil.oc.api.network.Visibility; import net.minecraft.tileentity.TileEntity; /** - * This class provides factories networks and nodes. + * This class provides factories for networks and nodes. *

- * The two functions provided provided by this API are to allow existing - * environments - implemented in a tile entity - to join an existing network or - * create a new one, and to create nodes that may then be connected to an - * existing network. It is not possible to create networks that do not belong - * to at least one tile entity at this time. + * The first two functions provided provided by this API are to allow existing + * environments - implemented in a tile entity for example - to join an existing + * network or create new ones. The third one is used to create nodes that may + * then be connected to an existing network. It is not possible to create + * networks that do not belong to at least one tile entity or node. + *

+ * It is important to understand that component networks only exist on the + * server side. It is impossible to create nodes, and therefore networks, on + * the client side. This is to enforce a clear distinction of where the actual + * logic lies - since Lua only runs on the server. + *

+ * Note that these methods should not be called in the pre-init phase, + * since the {@link #instance} may not have been initialized at that time. Only + * start calling these methods in the init phase or later. */ public final class Network { /** - * Tries to add a tile entity network node at the specified coordinates to - * adjacent networks. + * Tries to add a tile entity's network node(s) at the specified coordinates + * to adjacent networks. + *

+ * If the tile entity implements {@link Environment} its one node will be + * connected to any existing adjacent tile entity nodes. If none exist a + * new network with the specified tile entity's node as its sole entry. + *

+ * If the tile entity is a {@link li.cil.oc.api.network.SidedEnvironment} + * the same rules as for simple environments apply, except that the + * respective for each side is used when connecting, and each side's node + * is added to its own new network, if necessary. * * @param tileEntity the tile entity to initialize. */ @@ -52,23 +70,34 @@ public final class Network { * Example use: *

      * class YourThing extends TileEntity implements Environment {
-     *     private ComponentConnector node_ = api.Network.newNode(this, Visibility.Network).
-     *         withComponent("your_thing").
-     *         withConnector(32).
-     *         create();
+     *     private ComponentConnector node_ =
+     *         api.Network.newNode(this, Visibility.Network).
+     *             withComponent("your_thing").
+     *             withConnector(32).
+     *             create();
      *
      *     public Node node() { return node_; }
      *
      *     // ...
      * }
      * 
+ *

+ * Note that the reachability specified here is the general + * availability of the created node to other nodes in the network. Special + * rules apply to components, which have a visibility that is used + * to control how they can be reached from Lua. For example, network cards + * have a reachability of Visibility.Network, to allow + * them to communicate with each other, but a visibility of + * Visibility.Neighbors to avoid other computers in the network + * to see the card (i.e. only the Lua programs running on the computer the + * card installed in can see interact with it). * - * @param host the environment the node is created for. - * @param visibility the visibility of the node. + * @param host the environment the node is created for. + * @param reachability the reachability of the node. * @return a new node builder. */ - public static Builder.NodeBuilder newNode(Environment host, Visibility visibility) { - if (instance != null) return instance.newNode(host, visibility); + public static Builder.NodeBuilder newNode(Environment host, Visibility reachability) { + if (instance != null) return instance.newNode(host, reachability); return null; } diff --git a/li/cil/oc/api/Persistable.java b/li/cil/oc/api/Persistable.java index 9cf2a67c4..8ad2b2a45 100644 --- a/li/cil/oc/api/Persistable.java +++ b/li/cil/oc/api/Persistable.java @@ -17,7 +17,7 @@ public interface Persistable { * Saves the current state of the object into the specified NBT tag. *

* This should write the state in such a way that it can be restored when - * `load` is called with that tag. + * {@link #load} is called with that tag. * * @param nbt the tag to save the state to. */ diff --git a/li/cil/oc/api/detail/Builder.java b/li/cil/oc/api/detail/Builder.java index af3cab79c..1dad00014 100644 --- a/li/cil/oc/api/detail/Builder.java +++ b/li/cil/oc/api/detail/Builder.java @@ -2,6 +2,11 @@ package li.cil.oc.api.detail; import li.cil.oc.api.network.*; +/** + * Used for building {@link Node}s via {@link li.cil.oc.api.Network#newNode}. + * + * @param the type of the node created by this builder. + */ public interface Builder { T create(); diff --git a/li/cil/oc/api/detail/NetworkAPI.java b/li/cil/oc/api/detail/NetworkAPI.java index 2501f750e..403cb8290 100644 --- a/li/cil/oc/api/detail/NetworkAPI.java +++ b/li/cil/oc/api/detail/NetworkAPI.java @@ -10,5 +10,5 @@ public interface NetworkAPI { void joinNewNetwork(Node node); - Builder.NodeBuilder newNode(Environment host, Visibility visibility); + Builder.NodeBuilder newNode(Environment host, Visibility reachability); } \ No newline at end of file diff --git a/li/cil/oc/api/driver/Block.java b/li/cil/oc/api/driver/Block.java index 9bef8f103..895a629bf 100644 --- a/li/cil/oc/api/driver/Block.java +++ b/li/cil/oc/api/driver/Block.java @@ -8,10 +8,14 @@ import net.minecraft.world.World; *

* This driver type is used for components that are blocks, i.e. that can be * placed in the world, but cannot be modified to or don't want to have their - * `TileEntities` implement `network.Node`. + * {@link net.minecraft.tileentity.TileEntity} implement one of the interfaces + * for environments ({@link li.cil.oc.api.network.Environment} or + * {@link li.cil.oc.api.network.SidedEnvironment}). *

- * A block driver is used by proxy blocks to check its neighbors and whether - * those neighbors should be treated as components or not. + * A block driver is used by Adapter blocks to check its neighbors and + * whether those neighbors should be treated as components or not. If a driver + * is present, it will be used to create a {@link ManagedEnvironment} that is + * managed by the adapter. *

* Note that it is possible to write one driver that supports as many different * blocks as you wish. I'd recommend writing one per device (type), though, to @@ -21,32 +25,38 @@ public interface Block { /** * Used to determine the block types this driver handles. *

- * This is used to determine which driver to use for a block placed next to a - * computer. Note that the return value should not change over time; if it - * does, though, an already installed component will not be ejected, since - * this value is only checked when adding components. + * This is used to determine which driver to use for a block placed next to + * an Adapter block. Note that the return value should not change + * over time; if it does, though, an already installed component will not + * be removed, since this value is only checked when scanning blocks. You + * can force this by sending a neighbor block change notification. * * @param world the world in which the block to check lives. * @param x the X coordinate of the block to check. * @param y the Y coordinate of the block to check. * @param z the Z coordinate of the block to check. - * @return true if the block is supported; false otherwise. + * @return true if the block is supported; false otherwise. */ boolean worksWith(World world, int x, int y, int z); /** - * Get a reference to the network node wrapping the specified block. + * Create a new managed environment interfacing the specified block. *

- * This is used to connect the component to the component network when it is - * detected next to a proxy. Components that are not part of the component - * network probably don't make much sense (can't think of any uses at this - * time), but you may still opt to not implement this. + * This is used to connect the component to the component network when it + * is detected next to an Adapter. Components that are not part of + * the component network probably don't make much sense (can't think of any + * uses at this time), but you may still opt to not implement this - i.e. + * it is safe to return null here. + *

+ * This is expected to return a new instance each time it is + * called. The created instance's life cycle is managed by the + * Adapter block that caused its creation. * - * @param world the world in which the block to get the node for lives. - * @param x the X coordinate of the block to get the node for. - * @param y the Y coordinate of the block to get the node for. - * @param z the Z coordinate of the block to get the node for. - * @return the network node for the block at that location. + * @param world the world containing the block to get the environment for. + * @param x the X coordinate of the block to get the environment for. + * @param y the Y coordinate of the block to get the environment for. + * @param z the Z coordinate of the block to get the environment for. + * @return the environment for the block at that location. */ ManagedEnvironment createEnvironment(World world, int x, int y, int z); } \ No newline at end of file diff --git a/li/cil/oc/api/driver/Item.java b/li/cil/oc/api/driver/Item.java index 2c5dfa351..937610e14 100644 --- a/li/cil/oc/api/driver/Item.java +++ b/li/cil/oc/api/driver/Item.java @@ -3,20 +3,21 @@ package li.cil.oc.api.driver; import li.cil.oc.api.network.ManagedEnvironment; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; /** * Interface for item component drivers. *

* This driver type is used for components that are items, i.e. that can be - * inserted into computers. An example for this are internal drives, memory and - * power supply units. + * inserted into computers and robots. An example for this are internal drives, + * memory and graphic cards. *

* When trying to add an item to a computer the list of registered drivers is - * queried using the drivers' `worksWith` functions. The first driver that - * replies positively and whose check against the slot type is successful, i.e. - * for which the `slot` matches the slot it should be inserted into, will be - * used as the component's driver and the component will be added. If no driver - * is found the item will be rejected and cannot be installed. + * queried using the drivers' worksWith functions. The first driver + * that replies positively and whose check against the slot type is successful, + * i.e. for which the slot matches the slot it should be inserted into, + * will be used as the component's driver and the component will be added. If no + * driver is found the item will be rejected and cannot be installed. *

* Note that it is possible to write one driver that supports as many different * items as you wish. I'd recommend writing one per device (type), though, to @@ -26,57 +27,71 @@ public interface Item { /** * Used to determine the item types this driver handles. *

- * This is used to determine which driver to use for an item when installed in - * a computer. Note that the return value should not change over time; if it - * does, though, an already installed component will not be ejected, since - * this value is only checked when adding components. + * This is used to determine which driver to use for an item when it should + * be installed in a computer. Note that the return value should not change + * over time; if it does, though, an already installed component will not + * be ejected, since this value is only checked when adding components. * * @param item the item to check. - * @return true if the item is supported; false otherwise. + * @return true if the item is supported; false otherwise. */ boolean worksWith(ItemStack item); /** - * Gets a reference to the network node interfacing the specified item. + * Create a new managed environment interfacing the specified item. *

* This is used to connect the component to the component network when it is - * added to a computer, for example. Components that are not part of the - * component network probably don't make much sense (can't think of any uses - * at this time), but you may still opt to not implement this. + * added to a computer, for example. The only kind of component that does + * not need to be connected to the component network is probably memory, and + * there's a built-in driver for that. You may still opt to not implement + * this - i.e. it is safe to return null here. *

- * This is expected to return a *new instance* each time it is called. + * Keep in mind that the tile entity's location may change if the owner is + * a robot. This is important if you cache the location somewhere. For + * example, the wireless network card checks in it's update whether its + * owner's position has changed to update the index structure used for + * receiver look-up. + *

+ * This is expected to return a new instance each time it is + * called. The created instance's life cycle is managed by the computer or + * other container that caused its creation. * - * @param item the item instance for which to get the node. - * @param container the container the environment will be managed by. This - * will usually be a tile entity. - * @return the network node for that item. + * @param stack the item stack for which to get the environment. + * @param container the tile entity the environment will be managed by. + * @return the environment for that item. */ - ManagedEnvironment createEnvironment(ItemStack item, Object container); + ManagedEnvironment createEnvironment(ItemStack stack, TileEntity container); /** * The slot type of the specified item this driver supports. *

- * This is used to determine into which slot of a computer the components this - * driver supports may go. This will only be called if a previous call to - * `worksWith` with the same item type returned true. + * This is used to determine into which slot of a computer the components + * this driver supports may go. This will only be called if a previous call + * to {@link #worksWith} with the same stack returned true. * - * @param item the item to get the slot type for. - * @return the component type of the specified item. + * @param stack the item stack to get the slot type for. + * @return the slot type of the specified item. */ - Slot slot(ItemStack item); + Slot slot(ItemStack stack); /** * Get the tag compound based on the item stack to use for persisting the - * environment and node associated with the specified item stack. + * environment associated with the specified item stack. *

* This is only used if the item has an environment. This must always be a - * child tag of the items own tag compound, it will not be saved otherwise. - * Use this in the unlikely case that the default name collides with - * something. The built-in components use a child tag-compound with the name - * "oc:node". + * child tag of the item stack's own tag compound, it will not be saved + * otherwise. Use this in the unlikely case that the default name collides + * with something. The built-in components use a child tag-compound with + * the name oc:data, which will also be used if this returns + * null. + *

+ * This tag will be passed to the environment's save and + * load methods when appropriate (world save / load and when + * removed from their hosting inventory). * - * @param item the item to get the child tag from. - * @return the tag to use for saving and loading. + * @param stack the item to get the child tag from. + * @return the tag to use for saving and loading, or null to use + * the default tag oc:data. */ - NBTTagCompound nbt(ItemStack item); + NBTTagCompound dataTag(ItemStack stack); } \ No newline at end of file diff --git a/li/cil/oc/api/driver/Memory.java b/li/cil/oc/api/driver/Memory.java index 950a88801..6f3bcd985 100644 --- a/li/cil/oc/api/driver/Memory.java +++ b/li/cil/oc/api/driver/Memory.java @@ -11,7 +11,7 @@ import net.minecraft.item.ItemStack; */ public interface Memory extends Item { /** - * The amount of RAM this component provides, in byte. + * The amount of RAM this component provides, in bytes. * * @param item the item to get the provided memory for. * @return the amount of memory the specified component provides. diff --git a/li/cil/oc/api/driver/Slot.java b/li/cil/oc/api/driver/Slot.java index 34436e6ea..2c7112c2b 100644 --- a/li/cil/oc/api/driver/Slot.java +++ b/li/cil/oc/api/driver/Slot.java @@ -4,26 +4,36 @@ package li.cil.oc.api.driver; * List of possible item component types. *

* This is used to determine which item components may go into which slots in - * a computer's and robot's inventory. + * a computer's or robot's inventory. */ public enum Slot { /** * Invalid slot type. + *

+ * Drivers should never return this, used internally. */ None, /** * Extension cards such as graphics cards or redstone cards. + *

+ * The primary means of adding new functionality to a computer or robot. */ Card, /** - * Floppy disks. These can be inserted into the Disk Drive block. + * Floppy disks. + *

+ * These can be inserted into the disk drive block, robots and tier three + * computer cases. They provide persistent storage cheaper than hard disk + * drives, but with much more limited capacity. */ Disk, /** - * Hard disk drives. These can be installed in computers. + * Hard disk drives. + *

+ * These can be installed in computers to provide persistent storage. */ HardDiskDrive, @@ -34,12 +44,17 @@ public enum Slot { /** * Tool slot in robots (equipment slot). + *

+ * Components should usually not implement this slot type, since this slot + * allows any kind of item. It is only used to define the background icon + * for the tool slot in robots. */ Tool, /** - * Upgrade slot for robots. For special robot upgrades such as internal - * engines and the like. + * Upgrade slot for robots. + *

+ * Used for special robot upgrades such as internal engines and the like. */ Upgrade } \ No newline at end of file diff --git a/li/cil/oc/api/fs/FileSystem.java b/li/cil/oc/api/fs/FileSystem.java index 84f851b55..365a65399 100644 --- a/li/cil/oc/api/fs/FileSystem.java +++ b/li/cil/oc/api/fs/FileSystem.java @@ -1,27 +1,18 @@ package li.cil.oc.api.fs; import li.cil.oc.api.Persistable; -import li.cil.oc.api.network.Network; import java.io.FileNotFoundException; /** * Interface for file system driver compatible file systems. *

- * To create a file system from a JAR file or folder (in read-only mode; for - * example the one containing your mod) use `Filesystem.fromClass`, providing - * a class from your mod as the first parameter. - *

- * To get a network node wrapping a file system and using the default file - * system driver, use `Filesystem.asNode`. - *

- * Alternatively to using the factory methods for file systems in `Filesystem` - * you are free to implement this interface yourself. + * See {@link li.cil.oc.api.FileSystem} for factory methods. *

* Note that all paths passed here are assumed to be absolute in the underlying * file system implementation, meaning they do not contain any "." or "..", and * are relative to the root of the file system. When wrapping a file system in - * a node with the provided factory function this is automatically ensured. If + * a node with the provided factory functions this is automatically ensured. If * you call any of the functions of a file system directly it is your * responsibility to ensure the path has been cleaned up. */ @@ -35,9 +26,6 @@ public interface FileSystem extends Persistable { * accordingly to enforce true read-only logic (i.e. {@link #open} should * not allow opening files in write or append mode, {@link #makeDirectory} * and such should do nothing/return false/throw an exception). - *

- * For file systems made available to the component {@link Network} will - * also use this flag to determine whether their label may be changed. */ boolean isReadOnly(); @@ -53,8 +41,6 @@ public interface FileSystem extends Persistable { /** * The used storage capacity of the file system, in bytes. - *

- * For read-only systems this should return zero. * * @return the used storage space of this file system. */ @@ -68,7 +54,8 @@ public interface FileSystem extends Persistable { * This function should never throw. * * @param path the path to check at. - * @return true if the path points to a file or directory; false otherwise. + * @return true if the path points to a file or directory; + * false otherwise. */ boolean exists(String path); @@ -117,19 +104,19 @@ public interface FileSystem extends Persistable { * Gets a list of all items in the specified folder. *

* This must return the actual object names in the specified parent folder, - * not their full path. For example, for a file at `/home/test`, when doing - * `list("/home/")` this should return `["test"]`, *not* `["/home/test"]`. + * not their full path. For example, for a file at /home/test, when + * doing list("/home/") this should return ["test"], + * not ["/home/test"]. *

* Sub-folders should be returned with a trailing slash, to indicate that - * they are folders. This is primarily intended to avoid Lua programs having - * to check which of the entries are folders via calling `isDirectory`, which - * would be excruciatingly slow (since each call takes one game tick). + * they are folders. *

* If the folder is empty this should return an empty array. * * @param path the path to the folder to get the contents of. - * @return an array with the names of all objects in that folder; `null` if - * the specified object does not exist or is not a folder. + * @return an array with the names of all objects in that folder; + * null if the specified object does not exist or is not a + * folder. */ String[] list(String path); @@ -139,26 +126,27 @@ public interface FileSystem extends Persistable { * Deletes a file or folder. *

* This only has to support deleting single files and empty folders. If a - * directory is non-empty this may return false. If the target object does - * not exists it should return false. + * directory is non-empty this may return false. If the target + * object does not exists it should return false. *

* This is only available for writable file systems. For read-only systems - * it should just always return false. + * it should always return false. * * @param path the path to the object to delete. - * @return true if the object was successfully deleted; false otherwise. + * @return true if the object was successfully deleted; + * false otherwise. */ boolean delete(String path); /** * Create the specified directory. *

- * This should always only create a single directory. If the parent directory - * does not exists it should return false. If the target object already - * exists it should also return false. + * This should always only create a single directory. If the parent + * directory does not exists it should return false. If the target + * object already exists it should also return false. *

* This is only available for writable file systems. For read-only systems - * it should just always return false. + * it should always return false. * * @param path the path to the directory to create. * @return true if the directory was created; false otherwise. @@ -169,11 +157,12 @@ public interface FileSystem extends Persistable { * Moves / renames a file or folder. *

* This is only available for writable file systems. For read-only systems - * it should just always return false. + * it should always return false. * * @param from the name of the file or folder to move. * @param to the location to move the file or folder to. - * @return true if the object was renamed; false otherwise. + * @return true if the object was renamed; + * false otherwise. * @throws FileNotFoundException if the source is not a file or folder. */ boolean rename(String from, String to) throws FileNotFoundException; @@ -185,10 +174,13 @@ public interface FileSystem extends Persistable { * intended to be used when initializing a file system to a set of known * modification times (for example, this is used when creating a virtual * file system from a set of real files). + *

+ * Read-only file systems may ignore this request. * * @param path the path of the object for which to set the modification time. * @param time the time the object was supposedly last modified. - * @return whether the modification time was adjusted. + * @return true if the modification time was adjusted; + * false otherwise. */ boolean setLastModified(String path, long time); @@ -199,8 +191,8 @@ public interface FileSystem extends Persistable { *

* This should create some internal handle to the file, based on the mode * specified. A unique ID corresponding to that handle should be returned. - * This ID can be used in `file` to get an abstract wrapper for the handle, - * and to allow interaction with the file. + * This ID can be used in {@link #getHandle} to get an abstract wrapper for + * the handle, and to allow interaction with the file. *

* It is the responsibility of the file system to restore all handles to * their previous state when it is reloaded (game loaded for example). @@ -215,20 +207,22 @@ public interface FileSystem extends Persistable { int open(String path, Mode mode) throws FileNotFoundException; /** - * Gets a wrapper for a file previously opened using `open`. + * Gets a wrapper for a file previously opened using {@link #open}. *

* The wrapper allows interaction with the underlying file (stream) based - * on the mode it was opened in. See the `File` interface for more details. + * on the mode it was opened in. See {@link Handle} for more details. *

- * If there is no such handle, this should return `None`, but never throw. + * If there is no such handle, this should return null, but never + * throw. * * @param handle the ID of the handle to get the wrapper for. - * @return the wrapper for that handle ID; None if the ID is invalid. + * @return the wrapper for that handle ID; null if there is no + * handle with the specified ID. */ Handle getHandle(int handle); /** - * Called when the file system is close. + * Called when the file system is destroyed. *

* This should close any open real file handles (e.g. all open I/O streams), * but keep any internal state that may have to be persisted, for example @@ -236,11 +230,11 @@ public interface FileSystem extends Persistable { * save any open handles). *

* When the filesystem is made available as a network node created via - * `FileSystem.asNode` this will be called whenever the node is disconnected - * from its network. If the node was used to represent an item (which will - * be the usual use-case, I imagine) this means the item was removed from - * its container (e.g. hard drive from a computer) or the container was - * unloaded. + * one of the factory functions in {@link li.cil.oc.api.FileSystem} this + * will be called whenever the node is disconnected from its network. If + * the node was used to represent an item (which will be the usual use-case, + * I imagine) this means the item was removed from its container (e.g. hard + * drive from a computer) or the container was unloaded. */ void close(); } \ No newline at end of file diff --git a/li/cil/oc/api/fs/Handle.java b/li/cil/oc/api/fs/Handle.java index 3df94c65a..759ebbfda 100644 --- a/li/cil/oc/api/fs/Handle.java +++ b/li/cil/oc/api/fs/Handle.java @@ -20,8 +20,8 @@ public interface Handle { * Closes the handle. *

* For example, if there is an underlying stream, this should close that - * stream. Any future calls to {@link #read} or {@link #write} should throw an - * IOException after this function was called. + * stream. Any future calls to {@link #read} or {@link #write} should throw + * an IOException after this function was called. */ void close(); diff --git a/li/cil/oc/api/fs/Label.java b/li/cil/oc/api/fs/Label.java index dd1bc8dbb..475d70bec 100644 --- a/li/cil/oc/api/fs/Label.java +++ b/li/cil/oc/api/fs/Label.java @@ -19,8 +19,11 @@ public interface Label { * Set the new value of this label. *

* May be set to null to clear the label. + *

+ * May throw an exception if the label is read-only. * * @param value the new label. + * @throws IllegalArgumentException if the label is read-only. */ void setLabel(String value); } diff --git a/li/cil/oc/common/tileentity/ComponentInventory.scala b/li/cil/oc/common/tileentity/ComponentInventory.scala index 25ae91e62..5126739a7 100644 --- a/li/cil/oc/common/tileentity/ComponentInventory.scala +++ b/li/cil/oc/common/tileentity/ComponentInventory.scala @@ -1,14 +1,18 @@ package li.cil.oc.common.tileentity import li.cil.oc.api.driver +import li.cil.oc.api.driver.{Item => ItemDriver} import li.cil.oc.api.network import li.cil.oc.api.network.{ManagedEnvironment, Node} import li.cil.oc.server.driver.Registry +import li.cil.oc.server.driver.item.Item import li.cil.oc.server.{PacketSender => ServerPacketSender} import net.minecraft.item.ItemStack import net.minecraft.nbt.NBTTagCompound +import net.minecraft.tileentity.{TileEntity => MCTileEntity} trait ComponentInventory extends Inventory with network.Environment { + self: MCTileEntity => protected lazy val components = Array.fill[Option[ManagedEnvironment]](getSizeInventory)(None) // ----------------------------------------------------------------------- // @@ -33,7 +37,7 @@ trait ComponentInventory extends Inventory with network.Environment { case Some(driver) => Option(driver.createEnvironment(stack, this)) match { case Some(environment) => - environment.load(driver.nbt(stack)) + environment.load(dataTag(driver, stack)) Some(environment) case _ => None } @@ -64,7 +68,7 @@ trait ComponentInventory extends Inventory with network.Environment { case (stack, slot) => components(slot) match { case Some(environment) => // We're guaranteed to have a driver for entries. - environment.save(Registry.driverFor(stack).get.nbt(stack)) + environment.save(dataTag(Registry.driverFor(stack).get, stack)) case _ => // Nothing special to save. } } @@ -80,9 +84,9 @@ trait ComponentInventory extends Inventory with network.Environment { case Some(driver) => Option(driver.createEnvironment(stack, this)) match { case Some(component) => components(slot) = Some(component) - component.load(driver.nbt(stack)) + component.load(dataTag(driver, stack)) connectItemNode(component.node) - component.save(driver.nbt(stack)) + component.save(dataTag(driver, stack)) ServerPacketSender.sendItemComponentAddress(this, slot, stack) case _ => // No environment (e.g. RAM). } @@ -101,7 +105,7 @@ trait ComponentInventory extends Inventory with network.Environment { components(slot) = None component.node.remove() Registry.driverFor(stack).foreach(driver => - component.save(driver.nbt(stack))) + component.save(dataTag(driver, stack))) case _ => // Nothing to do. } } @@ -111,4 +115,7 @@ trait ComponentInventory extends Inventory with network.Environment { protected def connectItemNode(node: Node) { this.node.connect(node) } + + private def dataTag(driver: ItemDriver, stack: ItemStack) = + Option(driver.dataTag(stack)).getOrElse(Item.dataTag(stack)) } \ No newline at end of file diff --git a/li/cil/oc/common/tileentity/Robot.scala b/li/cil/oc/common/tileentity/Robot.scala index 75bf54701..1aa711d27 100644 --- a/li/cil/oc/common/tileentity/Robot.scala +++ b/li/cil/oc/common/tileentity/Robot.scala @@ -3,7 +3,6 @@ package li.cil.oc.common.tileentity import cpw.mods.fml.relauncher.{SideOnly, Side} import li.cil.oc.api.driver.Slot import li.cil.oc.api.network._ -import li.cil.oc.client.{PacketSender => ClientPacketSender} import li.cil.oc.common.block.Delegator import li.cil.oc.server.component.GraphicsCard import li.cil.oc.server.component.robot.Player diff --git a/li/cil/oc/server/driver/item/FileSystem.scala b/li/cil/oc/server/driver/item/FileSystem.scala index 0a19bb8fe..82efb0ec4 100644 --- a/li/cil/oc/server/driver/item/FileSystem.scala +++ b/li/cil/oc/server/driver/item/FileSystem.scala @@ -5,21 +5,22 @@ import li.cil.oc import li.cil.oc.api.driver.Slot import li.cil.oc.api.fs.Label import li.cil.oc.common.item.{Disk, HardDiskDrive} -import li.cil.oc.common.tileentity.DiskDrive +import li.cil.oc.common.tileentity.TileEntity import li.cil.oc.util.mods.ComputerCraft import li.cil.oc.{Settings, Items} import net.minecraft.item.ItemStack import net.minecraft.nbt.NBTTagCompound +import net.minecraft.tileentity.{TileEntity => MCTileEntity} object FileSystem extends Item { override def worksWith(stack: ItemStack) = isOneOf(stack, Items.hdd1, Items.hdd2, Items.hdd3, Items.disk) || ComputerCraft.isDisk(stack) - override def createEnvironment(stack: ItemStack, container: AnyRef) = + override def createEnvironment(stack: ItemStack, container: MCTileEntity) = if (ComputerCraft.isDisk(stack)) { container match { - case diskDrive: DiskDrive => - val address = addressFromTag(nbt(stack)) - val mount = ComputerCraft.createDiskMount(stack, diskDrive.world) + case tileEntity: TileEntity => + val address = addressFromTag(dataTag(stack)) + val mount = ComputerCraft.createDiskMount(stack, tileEntity.world) Option(oc.api.FileSystem.asManagedEnvironment(mount, new ComputerCraftLabel(stack))) match { case Some(environment) => environment.node.asInstanceOf[oc.server.network.Node].address = address @@ -46,7 +47,7 @@ object FileSystem extends Item { // We have a bit of a chicken-egg problem here, because we want to use the // node's address as the folder name... so we generate the address here, // if necessary. No one will know, right? Right!? - val address = addressFromTag(nbt(stack)) + val address = addressFromTag(dataTag(stack)) Option(oc.api.FileSystem.asManagedEnvironment(oc.api.FileSystem. fromSaveDirectory(address, capacity, Settings.get.bufferChanges), new ItemLabel(stack))) match { case Some(environment) => @@ -74,12 +75,12 @@ object FileSystem extends Item { private class ItemLabel(val stack: ItemStack) extends Label { def getLabel = - if (nbt(stack).hasKey(Settings.namespace + "fs.label")) - nbt(stack).getString(Settings.namespace + "fs.label") + if (dataTag(stack).hasKey(Settings.namespace + "fs.label")) + dataTag(stack).getString(Settings.namespace + "fs.label") else null def setLabel(value: String) { - nbt(stack).setString(Settings.namespace + "fs.label", + dataTag(stack).setString(Settings.namespace + "fs.label", if (value.length > 16) value.substring(0, 16) else value) } } diff --git a/li/cil/oc/server/driver/item/Generator.scala b/li/cil/oc/server/driver/item/Generator.scala index d814a8671..5910ba32d 100644 --- a/li/cil/oc/server/driver/item/Generator.scala +++ b/li/cil/oc/server/driver/item/Generator.scala @@ -4,11 +4,12 @@ import li.cil.oc.Items import li.cil.oc.api.driver.Slot import li.cil.oc.server.component import net.minecraft.item.ItemStack +import net.minecraft.tileentity.{TileEntity => MCTileEntity} object Generator extends Item { override def worksWith(stack: ItemStack) = isOneOf(stack, Items.generator) - override def createEnvironment(stack: ItemStack, container: AnyRef) = new component.Generator() + override def createEnvironment(stack: ItemStack, container: MCTileEntity) = new component.Generator() override def slot(stack: ItemStack) = Slot.Upgrade } diff --git a/li/cil/oc/server/driver/item/GraphicsCard.scala b/li/cil/oc/server/driver/item/GraphicsCard.scala index cf2569fa7..909f65936 100644 --- a/li/cil/oc/server/driver/item/GraphicsCard.scala +++ b/li/cil/oc/server/driver/item/GraphicsCard.scala @@ -5,11 +5,12 @@ import li.cil.oc.api.driver.Slot import li.cil.oc.common import li.cil.oc.server.component import net.minecraft.item.ItemStack +import net.minecraft.tileentity.{TileEntity => MCTileEntity} object GraphicsCard extends Item { override def worksWith(stack: ItemStack) = isOneOf(stack, Items.gpu1, Items.gpu2, Items.gpu3) - override def createEnvironment(stack: ItemStack, container: AnyRef) = + override def createEnvironment(stack: ItemStack, container: MCTileEntity) = Items.multi.subItem(stack) match { case Some(gpu: common.item.GraphicsCard) => gpu.tier match { case 0 => new component.GraphicsCard.Tier1() diff --git a/li/cil/oc/server/driver/item/Item.scala b/li/cil/oc/server/driver/item/Item.scala index 2f6a96f57..705672a3d 100644 --- a/li/cil/oc/server/driver/item/Item.scala +++ b/li/cil/oc/server/driver/item/Item.scala @@ -6,7 +6,17 @@ import net.minecraft.item.ItemStack import net.minecraft.nbt.NBTTagCompound trait Item extends api.driver.Item { - def nbt(stack: ItemStack) = { + def dataTag(stack: ItemStack) = Item.dataTag(stack) + + protected def isOneOf(stack: ItemStack, items: common.item.Delegate*) = + stack.getItem == Items.multi && (Items.multi.subItem(stack) match { + case None => false + case Some(subItem) => items.contains(subItem) + }) +} + +object Item { + def dataTag(stack: ItemStack) = { if (!stack.hasTagCompound) { stack.setTagCompound(new NBTTagCompound("tag")) } @@ -16,10 +26,4 @@ trait Item extends api.driver.Item { } nbt.getCompoundTag(Settings.namespace + "data") } - - protected def isOneOf(stack: ItemStack, items: common.item.Delegate*) = - stack.getItem == Items.multi && (Items.multi.subItem(stack) match { - case None => false - case Some(subItem) => items.contains(subItem) - }) -} +} \ No newline at end of file diff --git a/li/cil/oc/server/driver/item/Memory.scala b/li/cil/oc/server/driver/item/Memory.scala index b7c6b0086..8a8fd2d09 100644 --- a/li/cil/oc/server/driver/item/Memory.scala +++ b/li/cil/oc/server/driver/item/Memory.scala @@ -4,6 +4,7 @@ import li.cil.oc.Items import li.cil.oc.api.driver import li.cil.oc.api.driver.Slot import net.minecraft.item.ItemStack +import net.minecraft.tileentity.{TileEntity => MCTileEntity} object Memory extends Item with driver.Memory { def amount(stack: ItemStack) = if (stack.getItem == Items.multi) Items.multi.subItem(stack) match { @@ -13,7 +14,7 @@ object Memory extends Item with driver.Memory { def worksWith(stack: ItemStack) = isOneOf(stack, Items.ram3, Items.ram1, Items.ram2) - def createEnvironment(stack: ItemStack, container: AnyRef) = null + def createEnvironment(stack: ItemStack, container: MCTileEntity) = null def slot(stack: ItemStack) = Slot.Memory } diff --git a/li/cil/oc/server/driver/item/NetworkCard.scala b/li/cil/oc/server/driver/item/NetworkCard.scala index 87ec08005..07b12a7bc 100644 --- a/li/cil/oc/server/driver/item/NetworkCard.scala +++ b/li/cil/oc/server/driver/item/NetworkCard.scala @@ -4,11 +4,12 @@ import li.cil.oc.Items import li.cil.oc.api.driver.Slot import li.cil.oc.server.component import net.minecraft.item.ItemStack +import net.minecraft.tileentity.{TileEntity => MCTileEntity} object NetworkCard extends Item { def worksWith(stack: ItemStack) = isOneOf(stack, Items.lan) - override def createEnvironment(stack: ItemStack, container: AnyRef) = new component.NetworkCard() + override def createEnvironment(stack: ItemStack, container: MCTileEntity) = new component.NetworkCard() def slot(stack: ItemStack) = Slot.Card } diff --git a/li/cil/oc/server/driver/item/RedstoneCard.scala b/li/cil/oc/server/driver/item/RedstoneCard.scala index 153d0db8a..900d2603e 100644 --- a/li/cil/oc/server/driver/item/RedstoneCard.scala +++ b/li/cil/oc/server/driver/item/RedstoneCard.scala @@ -6,11 +6,12 @@ import li.cil.oc.api.driver.Slot import li.cil.oc.common.tileentity.{BundledRedstone, Redstone} import li.cil.oc.server.component import net.minecraft.item.ItemStack +import net.minecraft.tileentity.{TileEntity => MCTileEntity} object RedstoneCard extends Item { override def worksWith(stack: ItemStack) = isOneOf(stack, Items.rs) - override def createEnvironment(stack: ItemStack, container: AnyRef) = + override def createEnvironment(stack: ItemStack, container: MCTileEntity) = container match { case redstone: BundledRedstone if isBundledRedstoneModAvailable => new component.BundledRedstoneCard(redstone) case redstone: Redstone => new component.RedstoneCard(redstone) diff --git a/li/cil/oc/server/driver/item/WirelessNetworkCard.scala b/li/cil/oc/server/driver/item/WirelessNetworkCard.scala index bc7247fe9..0515cd20b 100644 --- a/li/cil/oc/server/driver/item/WirelessNetworkCard.scala +++ b/li/cil/oc/server/driver/item/WirelessNetworkCard.scala @@ -4,16 +4,13 @@ import li.cil.oc.Items import li.cil.oc.api.driver.Slot import li.cil.oc.server.component import net.minecraft.item.ItemStack -import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.{TileEntity => MCTileEntity} object WirelessNetworkCard extends Item { def worksWith(stack: ItemStack) = isOneOf(stack, Items.wlan) - override def createEnvironment(stack: ItemStack, container: AnyRef) = - container match { - case owner: TileEntity => new component.WirelessNetworkCard(owner) - case _ => null - } + override def createEnvironment(stack: ItemStack, container: MCTileEntity) = + if (container != null) new component.WirelessNetworkCard(container) else null def slot(stack: ItemStack) = Slot.Card } diff --git a/li/cil/oc/server/fs/FileSystem.scala b/li/cil/oc/server/fs/FileSystem.scala index ca5531ac3..95853d1b5 100644 --- a/li/cil/oc/server/fs/FileSystem.scala +++ b/li/cil/oc/server/fs/FileSystem.scala @@ -66,7 +66,7 @@ object FileSystem extends api.detail.FileSystemAPI { asManagedEnvironment(fileSystem, null: Label) private class ReadOnlyLabel(val label: String) extends Label { - def setLabel(value: String) = throw new Exception("label is read only") + def setLabel(value: String) = throw new IllegalArgumentException("label is read only") def getLabel = label }