mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-26 22:43:40 -04:00
Merge branch 'master' of github.com:MightyPirates/OpenComputers into MC1.7
Conflicts: src/main/scala/li/cil/oc/OpenComputers.scala src/main/scala/li/cil/oc/server/fs/CC15FileSystem.scala
This commit is contained in:
commit
0025fc19b0
34
src/api/java/stargatetech2/api/IStackManager.java
Normal file
34
src/api/java/stargatetech2/api/IStackManager.java
Normal file
@ -0,0 +1,34 @@
|
||||
package stargatetech2.api;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
/**
|
||||
* The way to get ItemStacks added to the game by StargateTech 2
|
||||
*
|
||||
* @author LordFokas
|
||||
*/
|
||||
public interface IStackManager {
|
||||
/**
|
||||
* Used to fetch an ItemStack by it's name, with a default size of 1.
|
||||
*
|
||||
* @param stack The stack we want to fetch.
|
||||
* @return The stack, or null if none was found.
|
||||
*/
|
||||
public ItemStack get(String stack);
|
||||
|
||||
/**
|
||||
* Used to fetch an ItemStack by it's name with a given size.
|
||||
*
|
||||
* @param stack The stack we want to fetch.
|
||||
* @param size The size the stack comes with. Must be in the range 1 - 64.
|
||||
* @return The stack, or null if none was found.
|
||||
*/
|
||||
public ItemStack get(String stack, int size);
|
||||
|
||||
/**
|
||||
* @return A list with the names of all the existing stacks.
|
||||
*/
|
||||
public Collection<String> getAllStacks();
|
||||
}
|
@ -24,4 +24,9 @@ public interface IStargateTechAPI {
|
||||
* @return The current IFactory instance.
|
||||
*/
|
||||
public IFactory getFactory();
|
||||
|
||||
/**
|
||||
* @return The current IStackManager instance.
|
||||
*/
|
||||
public IStackManager getStackManager();
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package stargatetech2.api.shields;
|
||||
|
||||
/**
|
||||
* Implemented by the Shield Controller TileEntities.
|
||||
*
|
||||
* @author LordFokas
|
||||
*/
|
||||
public interface IShieldController {
|
||||
/**
|
||||
* Given the way shield emitters work together, you cannot
|
||||
* directly access their ShieldPermissions object.
|
||||
* This means you cannot use this method to change
|
||||
* permissions on a shield.
|
||||
*
|
||||
* @return A deep clone of the ShieldPermissions object that
|
||||
* defines this controller's shield behavior.
|
||||
*/
|
||||
public ShieldPermissions getPermissions();
|
||||
|
||||
/**
|
||||
* @return True if the shield is activated, false otherwise.
|
||||
*/
|
||||
public boolean isShieldOn();
|
||||
|
||||
/**
|
||||
* @return The name of the player who owns this Shield Controller.
|
||||
*/
|
||||
public String getOwner();
|
||||
|
||||
/**
|
||||
* Checks if a player can access this device.
|
||||
*
|
||||
* @param player The player's name.
|
||||
* @return Whether or not this player can access this device.
|
||||
*/
|
||||
public boolean hasAccess(String player);
|
||||
}
|
@ -10,16 +10,16 @@ import net.minecraft.world.World;
|
||||
public interface IShieldable {
|
||||
/**
|
||||
* Called by shield emitters to make blocks raise their shields.
|
||||
* The block on {px, py, pz} contains an ITileShieldEmitter from which
|
||||
* you can get the current ShieldPermissions object.
|
||||
* The block on {px, py, pz} contains an IShieldController from
|
||||
* which you can get the current ShieldPermissions object.
|
||||
*
|
||||
* @param world The world this IShieldable is on.
|
||||
* @param x This IShieldable's X Coordinate.
|
||||
* @param y This IShieldable's Y Coordinate.
|
||||
* @param z This IShieldable's Z Coordinate.
|
||||
* @param px The X Coordinate of the shield emitter raising a shield on this block.
|
||||
* @param py The Y Coordinate of the shield emitter raising a shield on this block.
|
||||
* @param pz The Z Coordinate of the shield emitter raising a shield on this block.
|
||||
* @param px The X Coordinate of the shield controller in charge of the shield on this block.
|
||||
* @param py The Y Coordinate of the shield controller in charge of the shield on this block.
|
||||
* @param pz The Z Coordinate of the shield controller in charge of the shield on this block.
|
||||
*/
|
||||
public void onShield(World world, int x, int y, int z, int px, int py, int pz);
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package stargatetech2.api.shields;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.EntityMinecart;
|
||||
@ -13,21 +14,22 @@ import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
public class ShieldPermissions {
|
||||
// Permission Flags
|
||||
public static final int PERM_PLAYER = 0x01;
|
||||
public static final int PERM_VILLAGER = 0x02;
|
||||
public static final int PERM_ANIMAL = 0x04;
|
||||
public static final int PERM_MONSTER = 0x08;
|
||||
public static final int PERM_MINECART = 0x10;
|
||||
public static final int PERM_FRIEND = 0x01;
|
||||
public static final int PERM_PLAYER = 0x02;
|
||||
public static final int PERM_VILLAGER = 0x04;
|
||||
public static final int PERM_ANIMAL = 0x08;
|
||||
public static final int PERM_MONSTER = 0x10;
|
||||
public static final int PERM_VESSEL = 0x20;
|
||||
|
||||
private int permValue = 0;
|
||||
private ArrayList<String> playerExceptions = new ArrayList<String>();
|
||||
private LinkedList<String> playerExceptions = new LinkedList<String>();
|
||||
|
||||
/**
|
||||
* @return A default ShieldPermissions object.
|
||||
*/
|
||||
public static ShieldPermissions getDefault(){
|
||||
ShieldPermissions perm = new ShieldPermissions();
|
||||
perm.allow(PERM_PLAYER);
|
||||
perm.allow(PERM_FRIEND | PERM_PLAYER);
|
||||
return perm;
|
||||
}
|
||||
|
||||
@ -68,7 +70,7 @@ public class ShieldPermissions {
|
||||
* @return A list of strings containing the names of all the players
|
||||
* who currently are exceptions to the player permission setting.
|
||||
*/
|
||||
public ArrayList<String> getExceptionList(){
|
||||
public List<String> getExceptionList(){
|
||||
return playerExceptions;
|
||||
}
|
||||
|
||||
@ -96,7 +98,7 @@ public class ShieldPermissions {
|
||||
}else if(entity instanceof EntityMob){
|
||||
allow = hasBit(PERM_MONSTER);
|
||||
}else if(entity instanceof EntityMinecart){
|
||||
allow = hasBit(PERM_MINECART);
|
||||
allow = hasBit(PERM_VESSEL);
|
||||
}
|
||||
if(allow && entity.riddenByEntity != null && doDismount && entity.worldObj.isRemote == false){
|
||||
if(!isEntityAllowed(entity.riddenByEntity, true)){
|
||||
@ -141,7 +143,7 @@ public class ShieldPermissions {
|
||||
if(nbt != null){
|
||||
int exceptions = nbt.getInteger("exceptions");
|
||||
permissions.permValue = nbt.getInteger("permValue");
|
||||
permissions.playerExceptions = new ArrayList<String>(exceptions);
|
||||
permissions.playerExceptions = new LinkedList<String>();
|
||||
for(int i = 0; i < exceptions; i++){
|
||||
permissions.setPlayerException(nbt.getString("pex" + i));
|
||||
}
|
||||
|
@ -1,8 +1,13 @@
|
||||
local hookInterval = 100
|
||||
local deadline = math.huge
|
||||
local hitDeadline = false
|
||||
local function checkDeadline()
|
||||
if computer.realTime() > deadline then
|
||||
debug.sethook(coroutine.running(), checkDeadline, "", 1)
|
||||
if not hitDeadline then
|
||||
deadline = deadline + 0.5
|
||||
end
|
||||
hitDeadline = true
|
||||
error("too long without yielding", 0)
|
||||
end
|
||||
end
|
||||
@ -570,6 +575,7 @@ local function main()
|
||||
|
||||
while true do
|
||||
deadline = computer.realTime() + timeout -- timeout global is set by host
|
||||
hitDeadline = false
|
||||
debug.sethook(co, checkDeadline, "", hookInterval)
|
||||
local result = table.pack(coroutine.resume(co, table.unpack(args, 1, args.n)))
|
||||
if not result[1] then
|
||||
|
@ -130,7 +130,7 @@ if #args == 0 and (io.input() == io.stdin or options.i) and not options.c then
|
||||
end
|
||||
else
|
||||
-- execute command.
|
||||
local result = table.pack(execute(table.unpack(args)))
|
||||
local result = table.pack(execute(...))
|
||||
if not result[1] then
|
||||
error(result[2])
|
||||
end
|
||||
|
@ -34,6 +34,8 @@ Skynet
|
||||
Terminator T-1000
|
||||
Terminator T-800
|
||||
Wheatley
|
||||
Rosie
|
||||
Uniblab
|
||||
|
||||
# Perry Rhodan Robots, definitly not all...
|
||||
Anson Argyris
|
||||
|
@ -4,7 +4,6 @@ import li.cil.oc.client.Textures
|
||||
import li.cil.oc.util.{RenderState, PackedColor}
|
||||
import li.cil.oc.{OpenComputers, Settings}
|
||||
import net.minecraft.client.renderer.GLAllocation
|
||||
import net.minecraft.client.renderer.Tessellator
|
||||
import net.minecraft.client.renderer.texture.TextureManager
|
||||
import org.lwjgl.opengl.GL11
|
||||
import scala.io.Source
|
||||
@ -46,7 +45,6 @@ object MonospaceFontRenderer {
|
||||
val s = Settings.get.fontCharScale
|
||||
val dw = charWidth * s - charWidth
|
||||
val dh = charHeight * s - charHeight
|
||||
val t = Tessellator.instance
|
||||
// Now create lists for all printable chars.
|
||||
for (index <- 1 until 0xFF) {
|
||||
val x = (index - 1) % cols
|
||||
@ -54,12 +52,16 @@ object MonospaceFontRenderer {
|
||||
val u = x * uStep
|
||||
val v = y * vStep
|
||||
GL11.glNewList(charLists + index, GL11.GL_COMPILE)
|
||||
t.startDrawingQuads()
|
||||
t.addVertexWithUV(-dw, charHeight * s, 0, u, v + vSize)
|
||||
t.addVertexWithUV(charWidth * s, charHeight * s, 0, u + uSize, v + vSize)
|
||||
t.addVertexWithUV(charWidth * s, -dh, 0, u + uSize, v)
|
||||
t.addVertexWithUV(-dw, -dh, 0, u, v)
|
||||
t.draw()
|
||||
GL11.glBegin(GL11.GL_QUADS)
|
||||
GL11.glTexCoord2d(u, v + vSize)
|
||||
GL11.glVertex3d(-dw, charHeight * s, 0)
|
||||
GL11.glTexCoord2d(u + uSize, v + vSize)
|
||||
GL11.glVertex3d(charWidth * s, charHeight * s, 0)
|
||||
GL11.glTexCoord2d(u + uSize, v)
|
||||
GL11.glVertex3d(charWidth * s, -dh, 0)
|
||||
GL11.glTexCoord2d(u, v)
|
||||
GL11.glVertex3d(-dw, -dh, 0)
|
||||
GL11.glEnd()
|
||||
GL11.glTranslatef(charWidth, 0, 0)
|
||||
GL11.glEndList()
|
||||
}
|
||||
|
@ -86,13 +86,12 @@ class ClassTransformer extends IClassTransformer {
|
||||
|
||||
def ensureStargateTechCompatibility(basicClass: Array[Byte]): Array[Byte] = {
|
||||
if (!Mods.StargateTech2.isAvailable) {
|
||||
return basicClass
|
||||
// No SGT2 or version is too old, abstract bus API doesn't exist.
|
||||
val classNode = newClassNode(basicClass)
|
||||
classNode.interfaces.remove("stargatetech2/api/bus/IBusDevice")
|
||||
writeClass(classNode)
|
||||
}
|
||||
|
||||
// Version of SGT2 is too old, abstract bus API doesn't exist.
|
||||
val classNode = newClassNode(basicClass)
|
||||
classNode.interfaces.remove("stargatetech2/api/bus/IBusDevice")
|
||||
writeClass(classNode)
|
||||
else basicClass
|
||||
}
|
||||
|
||||
def injectEnvironmentImplementation(classNode: ClassNode, basicClass: Array[Byte]): Array[Byte] = {
|
||||
|
@ -319,7 +319,7 @@ class Player(val robot: tileentity.Robot) extends EntityPlayer(robot.world, Play
|
||||
})
|
||||
}
|
||||
|
||||
private def isItemUseAllowed(stack: ItemStack) = {
|
||||
private def isItemUseAllowed(stack: ItemStack) = stack == null || {
|
||||
(Settings.get.allowUseItemsWithDuration || stack.getMaxItemUseDuration <= 0) &&
|
||||
(!PortalGun.isPortalGun(stack) || PortalGun.isStandardPortalGun(stack)) &&
|
||||
!stack.isItemEqual(new ItemStack(Items.lead))
|
||||
|
@ -233,7 +233,8 @@ class Robot(val robot: tileentity.Robot) extends ManagedComponent {
|
||||
Iterable(checkSideForFace(args, 1, facing))
|
||||
}
|
||||
else {
|
||||
ForgeDirection.VALID_DIRECTIONS.filter(_ != facing.getOpposite).toIterable
|
||||
// Always try the direction we're looking first.
|
||||
Iterable(facing) ++ ForgeDirection.VALID_DIRECTIONS.filter(side => side != facing && side != facing.getOpposite).toIterable
|
||||
}
|
||||
val sneaky = args.isBoolean(2) && args.checkBoolean(2)
|
||||
val stack = player.robotInventory.selectedItemStack
|
||||
@ -339,7 +340,8 @@ class Robot(val robot: tileentity.Robot) extends ManagedComponent {
|
||||
Iterable(checkSideForFace(args, 1, facing))
|
||||
}
|
||||
else {
|
||||
ForgeDirection.VALID_DIRECTIONS.filter(_ != facing.getOpposite).toIterable
|
||||
// Always try the direction we're looking first.
|
||||
Iterable(facing) ++ ForgeDirection.VALID_DIRECTIONS.filter(side => side != facing && side != facing.getOpposite).toIterable
|
||||
}
|
||||
val sneaky = args.isBoolean(2) && args.checkBoolean(2)
|
||||
|
||||
@ -420,7 +422,8 @@ class Robot(val robot: tileentity.Robot) extends ManagedComponent {
|
||||
Iterable(checkSideForFace(args, 1, facing))
|
||||
}
|
||||
else {
|
||||
ForgeDirection.VALID_DIRECTIONS.filter(_ != facing.getOpposite).toIterable
|
||||
// Always try the direction we're looking first.
|
||||
Iterable(facing) ++ ForgeDirection.VALID_DIRECTIONS.filter(side => side != facing && side != facing.getOpposite).toIterable
|
||||
}
|
||||
val sneaky = args.isBoolean(2) && args.checkBoolean(2)
|
||||
val duration =
|
||||
|
@ -5,13 +5,13 @@ import li.cil.oc.api.driver.Slot
|
||||
import li.cil.oc.server.component
|
||||
import li.cil.oc.util.mods.Mods
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.tileentity.{TileEntity => MCTileEntity}
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
import stargatetech2.api.bus.IBusDevice
|
||||
|
||||
object AbstractBusCard extends Item {
|
||||
override def worksWith(stack: ItemStack) = isOneOf(stack, Items.abstractBus)
|
||||
|
||||
override def createEnvironment(stack: ItemStack, container: MCTileEntity) = if (Mods.StargateTech2.isAvailable) container match {
|
||||
override def createEnvironment(stack: ItemStack, container: TileEntity) = if (Mods.StargateTech2.isAvailable) container match {
|
||||
case device: IBusDevice => new component.AbstractBus(device)
|
||||
case _ => null
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ trait Buffered extends OutputStreamFileSystem {
|
||||
FileUtils.deleteQuietly(childFile)
|
||||
childFile.createNewFile()
|
||||
val out = new io.FileOutputStream(childFile).getChannel
|
||||
val in = java.nio.channels.Channels.newChannel(openInputStream(childPath).get)
|
||||
val in = openInputChannel(childPath).get
|
||||
out.transferFrom(in, 0, Long.MaxValue)
|
||||
out.close()
|
||||
in.close()
|
||||
|
@ -35,16 +35,26 @@ class CompositeReadOnlyFileSystem(factories: mutable.LinkedHashMap[String, Calla
|
||||
|
||||
override def lastModified(path: String) = findFileSystem(path).fold(0L)(_.lastModified(path))
|
||||
|
||||
override def list(path: String) = parts.values.foldLeft(Array.empty[String])((acc, fs) => {
|
||||
if (fs.exists(path)) try {
|
||||
val l = fs.list(path)
|
||||
if (l != null) acc ++ l else acc
|
||||
}
|
||||
catch {
|
||||
case _: Throwable => acc
|
||||
}
|
||||
else acc
|
||||
})
|
||||
override def list(path: String) = if (isDirectory(path)) {
|
||||
parts.values.foldLeft(mutable.Set.empty[String])((acc, fs) => {
|
||||
if (fs.exists(path)) try {
|
||||
val l = fs.list(path)
|
||||
if (l != null) for (e <- l) {
|
||||
val f = e.stripSuffix("/")
|
||||
val d = f + "/"
|
||||
// Avoid duplicates and always only use the latest entry.
|
||||
acc -= f
|
||||
acc -= d
|
||||
acc += e
|
||||
}
|
||||
}
|
||||
catch {
|
||||
case _: Throwable =>
|
||||
}
|
||||
acc
|
||||
}).toArray
|
||||
}
|
||||
else null
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
|
@ -25,8 +25,8 @@ class ComputerCraftFileSystem(val mount: IMount) extends InputStreamFileSystem {
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
protected def openInputStream(path: String) = try {
|
||||
Some(mount.openForRead(path))
|
||||
protected def openInputChannel(path: String) = try {
|
||||
Some(new InputStreamChannel(mount.openForRead(path)))
|
||||
} catch {
|
||||
case _: Throwable => None
|
||||
}
|
||||
|
@ -43,6 +43,23 @@ trait FileInputStreamFileSystem extends InputStreamFileSystem {
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override protected def openInputStream(path: String): Option[io.InputStream] =
|
||||
Some(new io.FileInputStream(new io.File(root, path)))
|
||||
override protected def openInputChannel(path: String) = Some(new FileChannel(new io.File(root, path)))
|
||||
|
||||
protected class FileChannel(file: io.File) extends InputChannel {
|
||||
val channel = new io.RandomAccessFile(file, "r").getChannel
|
||||
|
||||
override def position(newPosition: Long) = {
|
||||
channel.position(newPosition)
|
||||
channel.position
|
||||
}
|
||||
|
||||
override def position = channel.position
|
||||
|
||||
override def close() = channel.close()
|
||||
|
||||
override def isOpen = channel.isOpen
|
||||
|
||||
override def read(dst: Array[Byte]) = channel.read(java.nio.ByteBuffer.wrap(dst))
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,11 +1,13 @@
|
||||
package li.cil.oc.server.fs
|
||||
|
||||
import java.io.{FileNotFoundException, IOException, InputStream}
|
||||
import java.io.{FileNotFoundException, IOException}
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.fs.Mode
|
||||
import net.minecraft.nbt.{NBTTagList, NBTTagCompound}
|
||||
import net.minecraftforge.common.util.Constants.NBT
|
||||
import scala.collection.mutable
|
||||
import java.nio.channels.ReadableByteChannel
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
trait InputStreamFileSystem extends api.fs.FileSystem {
|
||||
private val handles = mutable.Map.empty[Int, Handle]
|
||||
@ -26,9 +28,9 @@ trait InputStreamFileSystem extends api.fs.FileSystem {
|
||||
|
||||
override def open(path: String, mode: Mode) = this.synchronized(if (mode == Mode.Read && exists(path) && !isDirectory(path)) {
|
||||
val handle = Iterator.continually((Math.random() * Int.MaxValue).toInt + 1).filterNot(handles.contains).next()
|
||||
openInputStream(path) match {
|
||||
case Some(stream) =>
|
||||
handles += handle -> new Handle(this, handle, path, stream)
|
||||
openInputChannel(path) match {
|
||||
case Some(channel) =>
|
||||
handles += handle -> new Handle(this, handle, path, channel)
|
||||
handle
|
||||
case _ => throw new FileNotFoundException()
|
||||
}
|
||||
@ -50,10 +52,10 @@ trait InputStreamFileSystem extends api.fs.FileSystem {
|
||||
val handle = handleNbt.getInteger("handle")
|
||||
val path = handleNbt.getString("path")
|
||||
val position = handleNbt.getLong("position")
|
||||
openInputStream(path) match {
|
||||
case Some(stream) =>
|
||||
val fileHandle = new Handle(this, handle, path, stream)
|
||||
fileHandle.position = stream.skip(position) // May be != position if the file changed since we saved.
|
||||
openInputChannel(path) match {
|
||||
case Some(channel) =>
|
||||
val fileHandle = new Handle(this, handle, path, channel)
|
||||
channel.position(position)
|
||||
handles += handle -> fileHandle
|
||||
case _ => // The source file seems to have disappeared since last time.
|
||||
}
|
||||
@ -63,7 +65,7 @@ trait InputStreamFileSystem extends api.fs.FileSystem {
|
||||
override def save(nbt: NBTTagCompound) = this.synchronized {
|
||||
val handlesNbt = new NBTTagList()
|
||||
for (file <- handles.values) {
|
||||
assert(!file.isClosed)
|
||||
assert(file.channel.isOpen)
|
||||
val handleNbt = new NBTTagCompound()
|
||||
handleNbt.setInteger("handle", file.handle)
|
||||
handleNbt.setString("path", file.path)
|
||||
@ -75,34 +77,73 @@ trait InputStreamFileSystem extends api.fs.FileSystem {
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
protected def openInputStream(path: String): Option[InputStream]
|
||||
protected def openInputChannel(path: String): Option[InputChannel]
|
||||
|
||||
protected trait InputChannel extends ReadableByteChannel {
|
||||
def isOpen: Boolean
|
||||
|
||||
def close()
|
||||
|
||||
def position: Long
|
||||
|
||||
def position(newPosition: Long): Long
|
||||
|
||||
def read(dst: Array[Byte]): Int
|
||||
|
||||
override def read(dst: ByteBuffer) = {
|
||||
if (dst.hasArray) {
|
||||
read(dst.array())
|
||||
}
|
||||
else {
|
||||
val count = dst.limit - dst.position
|
||||
val buffer = new Array[Byte](count)
|
||||
val n = read(buffer)
|
||||
dst.put(buffer, 0, n)
|
||||
n
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected class InputStreamChannel(val inputStream: java.io.InputStream) extends InputChannel {
|
||||
var isOpen = true
|
||||
|
||||
private var position_ = 0L
|
||||
|
||||
override def close() = if (isOpen) {
|
||||
isOpen = false
|
||||
inputStream.close()
|
||||
}
|
||||
|
||||
override def position = position_
|
||||
|
||||
override def position(newPosition: Long) = {
|
||||
inputStream.reset()
|
||||
position_ = inputStream.skip(newPosition)
|
||||
position_
|
||||
}
|
||||
|
||||
override def read(dst: Array[Byte]) = {
|
||||
val read = inputStream.read(dst)
|
||||
position_ += read
|
||||
read
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
private class Handle(val owner: InputStreamFileSystem, val handle: Int, val path: String, val stream: InputStream) extends api.fs.Handle {
|
||||
var isClosed = false
|
||||
var position = 0L
|
||||
private class Handle(val owner: InputStreamFileSystem, val handle: Int, val path: String, val channel: InputChannel) extends api.fs.Handle {
|
||||
override def position = channel.position
|
||||
|
||||
override def length = owner.size(path)
|
||||
|
||||
override def close() = if (!isClosed) {
|
||||
isClosed = true
|
||||
override def close() = if (channel.isOpen) {
|
||||
owner.handles -= handle
|
||||
stream.close()
|
||||
channel.close()
|
||||
}
|
||||
|
||||
override def read(into: Array[Byte]) = {
|
||||
val read = stream.read(into)
|
||||
if (read >= 0)
|
||||
position += read
|
||||
read
|
||||
}
|
||||
override def read(into: Array[Byte]) = channel.read(into)
|
||||
|
||||
override def seek(to: Long) = {
|
||||
stream.reset()
|
||||
position = stream.skip(to)
|
||||
position
|
||||
}
|
||||
override def seek(to: Long) = channel.position(to)
|
||||
|
||||
override def write(value: Array[Byte]) = throw new IOException("bad file descriptor")
|
||||
}
|
||||
|
@ -98,9 +98,9 @@ trait VirtualFileSystem extends OutputStreamFileSystem {
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
protected def openInputStream(path: String) =
|
||||
protected def openInputChannel(path: String) =
|
||||
root.get(segments(path)) match {
|
||||
case Some(obj: VirtualFile) => obj.openInputStream()
|
||||
case Some(obj: VirtualFile) => obj.openInputStream().map(new InputStreamChannel(_))
|
||||
case _ => None
|
||||
}
|
||||
|
||||
|
@ -58,8 +58,8 @@ class ZipFileInputStreamFileSystem(private val archive: ArchiveDirectory) extend
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override protected def openInputStream(path: String) = ZipFileInputStreamFileSystem.synchronized {
|
||||
entry(path).map(_.openStream())
|
||||
override protected def openInputChannel(path: String) = ZipFileInputStreamFileSystem.synchronized {
|
||||
entry(path).map(entry => new InputStreamChannel(entry.openStream()))
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
@ -220,12 +220,12 @@ object LuaStateFactory {
|
||||
case 0 => lua.pushNumber(random.nextDouble())
|
||||
case 1 =>
|
||||
val u = lua.checkNumber(1).toInt
|
||||
lua.checkArg(1, 1 < u, "interval is empty")
|
||||
lua.checkArg(1, 1 <= u, "interval is empty")
|
||||
lua.pushInteger(1 + random.nextInt(u))
|
||||
case 2 =>
|
||||
val l = lua.checkNumber(1).toInt
|
||||
val u = lua.checkNumber(2).toInt
|
||||
lua.checkArg(1, l < u, "interval is empty")
|
||||
lua.checkArg(1, l <= u, "interval is empty")
|
||||
lua.pushInteger(l + random.nextInt(u - (l - 1)))
|
||||
case _ => throw new IllegalArgumentException("wrong number of arguments")
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user