From f0f31f9fa9e4e4d683e2476712073cb92f4279c9 Mon Sep 17 00:00:00 2001 From: Kodos Atoz Date: Sun, 23 Aug 2015 16:28:06 -0500 Subject: [PATCH 1/3] Update greetings.txt Updated 'Switches' to Relays, fixed a misspelling. --- .../assets/opencomputers/loot/OpenOS/usr/misc/greetings.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/assets/opencomputers/loot/OpenOS/usr/misc/greetings.txt b/src/main/resources/assets/opencomputers/loot/OpenOS/usr/misc/greetings.txt index 041959f85..68d49726b 100644 --- a/src/main/resources/assets/opencomputers/loot/OpenOS/usr/misc/greetings.txt +++ b/src/main/resources/assets/opencomputers/loot/OpenOS/usr/misc/greetings.txt @@ -12,7 +12,7 @@ Most programs can be interrupted by pressing Ctrl+Alt+C. Paste the contents of the clipboard using the middle mouse button or a configurable key (default: insert). Computers will consume less power while idling - i.e. when os.sleep(n > 0.05) is called. Screens will consume more power the more lit characters they display. -Most blocks act as 'cables' - use switches and power distributers to create separate networks. +Most blocks act as 'cables' - use relays and power distributors to create separate networks. Welcome to the dark side - here, have some cookies. Screens can display Unicode - paste the special chars or use unicode.char. Run `help` or `man programname` for ingame help on programs shipped with OpenOS - start with `man man`. @@ -25,4 +25,4 @@ Have you tried turning it off and on again? To disable this greeting, install OpenOS to a writeable medium and delete `/etc/motd`. Did you know OpenComputers has a forum? No? Well, it's at http://oc.cil.li/. Please report bugs on the Github issue tracker, thank you! -Beware of cycles when building networks, or you may get duplicate messages! \ No newline at end of file +Beware of cycles when building networks, or you may get duplicate messages! From fdf5e334100dd5a61179dea76739a723ed549042 Mon Sep 17 00:00:00 2001 From: cyber01 Date: Mon, 24 Aug 2015 14:44:07 +0400 Subject: [PATCH 2/3] Added Relay Correction Correction2 --- .../opencomputers/doc/ru_RU/block/accessPoint.md | 2 ++ .../assets/opencomputers/doc/ru_RU/block/index.md | 1 + .../opencomputers/doc/ru_RU/block/netSplitter.md | 2 +- .../assets/opencomputers/doc/ru_RU/block/relay.md | 13 +++++++++++++ .../opencomputers/doc/ru_RU/block/serverRack.md | 2 +- .../assets/opencomputers/doc/ru_RU/block/switch.md | 2 ++ .../assets/opencomputers/doc/ru_RU/item/lanCard.md | 2 +- .../resources/assets/opencomputers/lang/ru_RU.lang | 6 ++++-- 8 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 src/main/resources/assets/opencomputers/doc/ru_RU/block/relay.md diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/accessPoint.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/accessPoint.md index 744abec69..faa4a62bf 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_RU/block/accessPoint.md +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/accessPoint.md @@ -2,6 +2,8 @@ ![AAA](oredict:oc:accessPoint) +*Этот блок устарел и будет удален в следующих версиях.* Замените его на [ретранслятор](relay.md). + Точки доступа, это беспроводные версии [коммутаторов](switch.md). Они могут быть использованы, когда требуется разделить подсети, чтобы устройства не видели [компоненты](../general/computer.md) в других сетях, однако сохраняя при этом возможность передачи сообщений между подсетями. В дополнение к этому, точки доступа могут использоваться как повторители: они могут перенаправлять сообщения из проводной линии другим устройствам; или беспроводные сообщения как проводные, так и беспроводные. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/index.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/index.md index a1e604531..ce0ebf1d9 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_RU/block/index.md +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/index.md @@ -39,6 +39,7 @@ * [Точка доступа](accessPoint.md) * [Кабель](cable.md) * [Сетевой переключатель](netSplitter.md) +* [Ретранслятор](relay.md) * [Коммутатор](switch.md) ## Управление питанием diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/netSplitter.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/netSplitter.md index 37e4bc296..e3725dcb5 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_RU/block/netSplitter.md +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/netSplitter.md @@ -2,6 +2,6 @@ ![*.net *.split](oredict:oc:netSplitter) -Сетевой переключатель позволяет контролировать соединение между подсетями. В отличие от [коммутатора](switch.md) или [конвертера энергии](powerConverter.md) позволяет непосредственно соединить подсети, делая при этом доступными все компоненты. Соединение каждой стороны переключается [ключем](../item/wrench.md). При подаче редстоун-сигнала все соединения инвертируются. +Сетевой переключатель позволяет контролировать соединение между подсетями. В отличие от [ретранслятора](relay.md) или [конвертера энергии](powerConverter.md) позволяет непосредственно соединить подсети, делая при этом доступными все компоненты. Соединение каждой стороны переключается [ключем](../item/wrench.md). При подаче редстоун-сигнала все соединения инвертируются. Таким образом, этот блок может быть использован для переключения соединения определенных компонентов сети. Используйте [редстоун-I/O](redstone.md) или [редстоун карты](../item/redstoneCard1.md) для автоматизации сетевого переключателя. \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/relay.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/relay.md new file mode 100644 index 000000000..64caecb9f --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/relay.md @@ -0,0 +1,13 @@ +# Ретранслятор + +![Строит мосты.](oredict:oc:relay) + +Ретранслятор используется для передачи сообщений между несколькими подсетями, изолируя компоненты [компьютеров](../general/computer.md) в других сетях. Сохранение компонентов, как правило, хорошая идея, что не позволяет [компьютерам](../general/computer.md) использовать неверный [монитор](screen1.md) или не позволяет перенагружать их (в результате чего [компьютеры](../general/computer.md) выключатся и отказываются загружаться). + +Может быть улучшен добавлением [беспроводной сетевой карты](../item/wlanCard.md), что позволит ретранслировать беспроводные сообщения. Сообщения, переданные по беспроводной линии могут быть получены или перенаправлены другими ретрансляторами или [компьютерами](../general/computer.md) с [беспроводной сетевой картой](../item/wlanCard.md). + +Также ретранслятор может быть улучшен с помощью [соединенной карты](../item/linkedCard.md). Это позволит передавать сообщения внутри туннеля, предоставленного картой, также; с обычными затратами энергии, поэтому убедитесь, что на ретранслятор поступает нужное количество энергии. + +Ретрансляторы *не* отслеживают, какие пакеты и куда они передали, поэтому для в сети могут образовываться петли или вы можете получать одно сообщение несколько раз. Из-за ограниченного буфера сообщений коммутатора, частое отправление сообщений приводит к их потере. Вы можете улучшить ретранслятор для увеличения скорости обработки сообщений, а также увеличения размера сообщений. + +Сообщения, могут перенаправлены всего несколько раз, поэтому цепочки с произвольным количеством ретрансляторов невозможны. По умолчанию, сообщение может быть перенаправлено пять раз. \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/serverRack.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/serverRack.md index 4a5af4ef2..850d739ed 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_RU/block/serverRack.md +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/serverRack.md @@ -6,4 +6,4 @@ Каждый [сервер](../item/server1.md) в серверной стойке может взаимодействовать только с одной "стороной" стойки или ни с какой. К какой стороне, какой [сервер](../item/server1.md) подключен, настраивается в интерфейсе стойки. Будьте внимательны, стороны считаются относительно самой стойки, например, если вы смотрите на стойку спереди, то `правая сторона` стойки для вас будет слева. -Серверные стойки взаимодействуют с [коммутаторами](switch.md) и [распределителями энергии](powerDistributor.md). Переключатель режимов работы стойки, может быть настроен в интерфейсе самой стойки, он имеет 2 режима: внешний и внутренний. Во внешнем режиме сервер будет работать как обычный [коммутатор](switch.md). Во внутреннем режиме, сообщения будут передаваться только к [серверам](../item/server1.md) в стойке и не будут автоматически связаны со сторонами стойки. [Серверы](../item/server1.md) все также будут иметь возможность передачи сообщений друг другу. Это позволяет использовать серверные стойки как продвинутые [коммутаторы](switch.md) для операций фильтрации и направления данных, например. +Серверные стойки взаимодействуют с [ретрансляторами](relay.md) и [распределителями энергии](powerDistributor.md). Переключатель режимов работы стойки, может быть настроен в интерфейсе самой стойки, он имеет 2 режима: внешний и внутренний. Во внешнем режиме сервер будет работать как обычный [ретранслятор](relay.md). Во внутреннем режиме, сообщения будут передаваться только к [серверам](../item/server1.md) в стойке и не будут автоматически связаны со сторонами стойки. [Серверы](../item/server1.md) все также будут иметь возможность передачи сообщений друг другу. Это позволяет использовать серверные стойки как продвинутые [ретрансляторы](relay.md) для операций фильтрации и направления данных, например. diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/block/switch.md b/src/main/resources/assets/opencomputers/doc/ru_RU/block/switch.md index 56445e17f..27b172988 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_RU/block/switch.md +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/block/switch.md @@ -2,6 +2,8 @@ ![Строит мосты.](oredict:oc:switch) +*Этот блок устарел и будет удален в следующих версиях.* Замените его на [ретранслятор](relay.md). + Коммутатор используется для передачи сообщений между несколькими подсетями, не используя компоненты [компьютеров](../general/computer.md) в других сетях. Сохранение компонентов, как правило, хорошая идея, что не позволяет [компьютерам](../general/computer.md) использовать неверный [монитор](screen1.md) или не позволяет перенагружать их (в результате чего [компьютеры](../general/computer.md) выключатся и отказываются загружаться). Также есть беспроводная версия коммутатора, называемая [точка доступа](accessPoint.md), с ее помощью сообщения передаются по беспроводной линии. Сообщения, переданные по беспроводной линии могут быть получены или перенаправлены другими [точками доступа](accessPoint.md) или [компьютерами](../general/computer.md) с [беспроводной сетевой картой](../item/wlanCard.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_RU/item/lanCard.md b/src/main/resources/assets/opencomputers/doc/ru_RU/item/lanCard.md index 7094ef65b..6a25e7b07 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_RU/item/lanCard.md +++ b/src/main/resources/assets/opencomputers/doc/ru_RU/item/lanCard.md @@ -2,4 +2,4 @@ ![Войди в сеть.](oredict:oc:lanCard) -Сетевая карта позволяет [компьютерам](../general/computer.md) отправлять и получать сетевые сообщения. Сообщения (или пакеты) будут отправлены всем принимающим устройствам в подсети или конкретной сетевой карте (после указания ее адреса). [Коммутаторы](../block/switch.md) и [точки доступа](../block/accessPoint.md) могут быть использованы для связи нескольких подсетей друг с другом, для передачи сообщений в них. Также возможно отправить письмо получателю, даже если он находится в другой подсети, если сеть подключена к одному или нескольким [коммутаторам](../block/switch.md). +Сетевая карта позволяет [компьютерам](../general/computer.md) отправлять и получать сетевые сообщения. Сообщения (или пакеты) будут отправлены всем принимающим устройствам в подсети или конкретной сетевой карте (при указании её адреса). [Ретрансляторы](../block/relay.md) могут быть использованы для связи нескольких подсетей друг с другом и передачи сообщений. Также возможно отправить письмо получателю, даже если он находится в другой подсети, если сеть подключена к одному или нескольким [ретрасляторами](../block/relay.md). diff --git a/src/main/resources/assets/opencomputers/lang/ru_RU.lang b/src/main/resources/assets/opencomputers/lang/ru_RU.lang index a1ab2d83f..85700e6ba 100644 --- a/src/main/resources/assets/opencomputers/lang/ru_RU.lang +++ b/src/main/resources/assets/opencomputers/lang/ru_RU.lang @@ -3,7 +3,7 @@ # Use [nl] to for a line break. # Blocks -tile.oc.accessPoint.name=Точка доступа +tile.oc.accessPoint.name=§cТочка доступа§7 tile.oc.adapter.name=Адаптер tile.oc.assembler.name=Сборщик роботов tile.oc.cable.name=Кабель @@ -35,7 +35,7 @@ tile.oc.screen1.name=Монитор (1-ый уровень) tile.oc.screen2.name=Монитор (2-ой уровень) tile.oc.screen3.name=Монитор (3-ий уровень) tile.oc.serverRack.name=Серверная стойка -tile.oc.switch.name=Коммутатор +tile.oc.switch.name=§cКоммутатор§7 tile.oc.netSplitter.name=Сетевой переключатель tile.oc.waypoint.name=Путевая точка @@ -229,6 +229,7 @@ oc:container.Disassembler=Разборщик oc:container.DiskDrive=Дисковод oc:container.Printer=Принтер oc:container.Raid=RAID +oc:container.Relay=Ретранслятор oc:container.Server=Сервер oc:container.ServerRack=Серверная стойка oc:container.Switch=Коммутатор @@ -319,6 +320,7 @@ oc:tooltip.RedstoneCard.RedNet=Мод §fRedNet§7 §aподдерживаетс oc:tooltip.RedstoneCard.WirelessCBE=Мод §fWireless Redstone (ChickenBones)§7 §aподдерживается§7. oc:tooltip.RedstoneCard.WirelessSV=Мод §fWireless Redstone (SlimeVoid)§7 §aподдерживается§7. oc:tooltip.RedstoneCard=Позволяет принимать и излучать сигналы красного камня вокруг компьютера или робота. +oc:tooltip.Relay=Позволяет соединять различные сети между собой. Передаются только сообщения, компоненты между сетями недоступны. Используйте его для разделения сетей с возможностью пересылать сообщения между ними. oc:tooltip.Robot=В отличие от компьютеров, роботы могут передвигаться и взаимодействовать с миром, как игрок.[nl] §cНе могут взаимодействовать с внешними компонентами.§7 # The underscore makes sure this isn't hidden with the rest of the tooltip. oc:tooltip.Robot_Level=§fУровень§7: §a%s§7. From 4e66556892a42973efb742fd77e4626b04e39795 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Tue, 25 Aug 2015 22:37:57 +0200 Subject: [PATCH 3/3] Added getter and setter for CPU architecture in computer API, closes #1390. Also potentially fixes a possible deadlock... maybe. Or breaks even more \o/ --- src/main/java/li/cil/oc/api/API.java | 2 +- .../oc/api/driver/item/MutableProcessor.java | 27 ++++++++++ .../assets/opencomputers/lua/machine.lua | 17 +++++++ src/main/scala/li/cil/oc/OpenComputers.scala | 2 +- .../cil/oc/common/item/traits/CPULike.scala | 45 ++++------------ .../integration/opencomputers/DriverCPU.scala | 22 +++++++- .../li/cil/oc/server/machine/Machine.scala | 8 +-- .../oc/server/machine/luac/ComputerAPI.scala | 51 +++++++++++++++++++ .../oc/server/machine/luaj/ComputerAPI.scala | 40 +++++++++++++++ 9 files changed, 170 insertions(+), 44 deletions(-) create mode 100644 src/main/java/li/cil/oc/api/driver/item/MutableProcessor.java diff --git a/src/main/java/li/cil/oc/api/API.java b/src/main/java/li/cil/oc/api/API.java index 051bcb5d8..471ef36e7 100644 --- a/src/main/java/li/cil/oc/api/API.java +++ b/src/main/java/li/cil/oc/api/API.java @@ -12,7 +12,7 @@ import li.cil.oc.api.detail.*; */ public class API { public static final String ID_OWNER = "OpenComputers|Core"; - public static final String VERSION = "5.5.3"; + public static final String VERSION = "5.5.4"; public static DriverAPI driver = null; public static FileSystemAPI fileSystem = null; diff --git a/src/main/java/li/cil/oc/api/driver/item/MutableProcessor.java b/src/main/java/li/cil/oc/api/driver/item/MutableProcessor.java new file mode 100644 index 000000000..04cc07634 --- /dev/null +++ b/src/main/java/li/cil/oc/api/driver/item/MutableProcessor.java @@ -0,0 +1,27 @@ +package li.cil.oc.api.driver.item; + +import li.cil.oc.api.machine.Architecture; +import net.minecraft.item.ItemStack; + +/** + * May be implemented in processor drivers of processors that can be reconfigured. + *

+ * This is the case for OC's built-in CPUs, for example, which can be reconfigured + * to any registered architecture. It a CPU has such a driver, it may also be + * reconfigured by the machine it is running in (e.g. in the Lua case via + * computer.setArchitecture). + */ +public interface MutableProcessor extends Processor { + /** + * Get a list of all architectures supported by this processor. + */ + java.util.Collection> allArchitectures(); + + /** + * Set the architecture to use for the specified processor. + * + * @param stack the processor to set the architecture for. + * @param architecture the architecture to use on the processor. + */ + void setArchitecture(ItemStack stack, Class architecture); +} diff --git a/src/main/resources/assets/opencomputers/lua/machine.lua b/src/main/resources/assets/opencomputers/lua/machine.lua index 56e79e3c0..238fd4f51 100644 --- a/src/main/resources/assets/opencomputers/lua/machine.lua +++ b/src/main/resources/assets/opencomputers/lua/machine.lua @@ -1320,6 +1320,23 @@ local libcomputer = { beep = function(...) libcomponent.invoke(computer.address(), "beep", ...) + end, + + getArchitectures = function(...) + return spcall(computer.getArchitectures, ...) + end, + getArchitecture = function(...) + return spcall(computer.getArchitecture, ...) + end, + setArchitecture = function(...) + local result, reason = spcall(computer.setArchitecture, ...) + if not result then + if reason then + return result, reason + end + else + coroutine.yield(true) -- reboot + end end } sandbox.computer = libcomputer diff --git a/src/main/scala/li/cil/oc/OpenComputers.scala b/src/main/scala/li/cil/oc/OpenComputers.scala index 2749f0993..4f6aae03e 100644 --- a/src/main/scala/li/cil/oc/OpenComputers.scala +++ b/src/main/scala/li/cil/oc/OpenComputers.scala @@ -19,7 +19,7 @@ object OpenComputers { final val Name = "OpenComputers" - final val Version = "1.5.16" + final val Version = "@VERSION@" var log = LogManager.getLogger(Name) diff --git a/src/main/scala/li/cil/oc/common/item/traits/CPULike.scala b/src/main/scala/li/cil/oc/common/item/traits/CPULike.scala index 31d20a765..4b26ca417 100644 --- a/src/main/scala/li/cil/oc/common/item/traits/CPULike.scala +++ b/src/main/scala/li/cil/oc/common/item/traits/CPULike.scala @@ -3,12 +3,10 @@ package li.cil.oc.common.item.traits import java.util import li.cil.oc.Settings -import li.cil.oc.api -import li.cil.oc.api.machine.Architecture +import li.cil.oc.integration.opencomputers.DriverCPU import li.cil.oc.util.Tooltip import net.minecraft.entity.player.EntityPlayer import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound import net.minecraft.util.ChatComponentTranslation import net.minecraft.world.World @@ -21,37 +19,19 @@ trait CPULike extends Delegate { override protected def tooltipData: Seq[Any] = Seq(Settings.get.cpuComponentSupport(cpuTier)) override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[String]) { - (if (stack.hasTagCompound) { - Option(stack.getTagCompound.getString(Settings.namespace + "archName")) - } - else { - val architectures = allArchitectures - architectures.headOption.map(_._2) - }) match { - case Some(archName) if !archName.isEmpty => tooltip.addAll(Tooltip.get("CPU.Architecture", archName)) - case _ => allArchitectures.headOption.collect { - case ((_, name)) => tooltip.addAll(Tooltip.get("CPU.Architecture", name)) - } - } + tooltip.addAll(Tooltip.get("CPU.Architecture", DriverCPU.getArchitectureName(DriverCPU.architecture(stack)))) } override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer) = { if (player.isSneaking) { if (!world.isRemote) { - val architectures = allArchitectures - if (architectures.length > 0) { - val currentIndex = if (stack.hasTagCompound) { - val currentArch = stack.getTagCompound.getString(Settings.namespace + "archClass") - architectures.indexWhere(_._1.getName == currentArch) - } - else { - stack.setTagCompound(new NBTTagCompound()) - -1 - } - val index = (currentIndex + 1) % architectures.length - val (archClass, archName) = architectures(index) - stack.getTagCompound.setString(Settings.namespace + "archClass", archClass.getName) - stack.getTagCompound.setString(Settings.namespace + "archName", archName) + val architectures = DriverCPU.allArchitectures.toList + if (architectures.nonEmpty) { + val currentIndex = architectures.indexOf(DriverCPU.architecture(stack)) + val newIndex = (currentIndex + 1) % architectures.length + val archClass = architectures(newIndex) + val archName = DriverCPU.getArchitectureName(archClass) + DriverCPU.setArchitecture(stack, archClass) player.addChatMessage(new ChatComponentTranslation(Settings.namespace + "tooltip.CPU.Architecture", archName)) } player.swingItem() @@ -59,11 +39,4 @@ trait CPULike extends Delegate { } stack } - - private def allArchitectures = api.Machine.architectures.map { arch => - arch.getAnnotation(classOf[Architecture.Name]) match { - case annotation: Architecture.Name => (arch, annotation.value) - case _ => (arch, arch.getSimpleName) - } - }.toArray } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverCPU.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverCPU.scala index 14db12664..62e8557d3 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverCPU.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverCPU.scala @@ -5,7 +5,7 @@ import li.cil.oc.OpenComputers import li.cil.oc.Settings import li.cil.oc.api import li.cil.oc.api.driver.EnvironmentHost -import li.cil.oc.api.driver.item.Processor +import li.cil.oc.api.driver.item.MutableProcessor import li.cil.oc.api.machine.Architecture import li.cil.oc.api.network.ManagedEnvironment import li.cil.oc.common.Slot @@ -14,12 +14,14 @@ import li.cil.oc.common.item import li.cil.oc.common.item.Delegator import li.cil.oc.server.machine.luac.NativeLuaArchitecture import net.minecraft.item.ItemStack +import net.minecraft.nbt.NBTTagCompound +import scala.collection.convert.WrapAsJava._ import scala.collection.convert.WrapAsScala._ object DriverCPU extends DriverCPU -abstract class DriverCPU extends Item with Processor { +abstract class DriverCPU extends Item with MutableProcessor { override def worksWith(stack: ItemStack) = isOneOf(stack, api.Items.get(Constants.ItemName.CPUTier1), api.Items.get(Constants.ItemName.CPUTier2), @@ -39,6 +41,8 @@ abstract class DriverCPU extends Item with Processor { override def supportedComponents(stack: ItemStack) = Settings.get.cpuComponentSupport(cpuTier(stack)) + override def allArchitectures = api.Machine.architectures.toList + override def architecture(stack: ItemStack): Class[_ <: Architecture] = { if (stack.hasTagCompound) { val archClass = stack.getTagCompound.getString(Settings.namespace + "archClass") match { @@ -57,4 +61,18 @@ abstract class DriverCPU extends Item with Processor { } api.Machine.architectures.headOption.orNull } + + override def setArchitecture(stack: ItemStack, architecture: Class[_ <: Architecture]): Unit = { + if (!worksWith(stack)) throw new IllegalArgumentException("Unsupported processor type.") + if (!stack.hasTagCompound) stack.setTagCompound(new NBTTagCompound()) + stack.getTagCompound.setString(Settings.namespace + "archClass", architecture.getName) + stack.getTagCompound.setString(Settings.namespace + "archName", getArchitectureName(architecture)) + } + + // TODO Move to Machine API in 1.6 + def getArchitectureName(architecture: Class[_ <: Architecture]) = + architecture.getAnnotation(classOf[Architecture.Name]) match { + case annotation: Architecture.Name => annotation.value + case _ => architecture.getSimpleName + } } diff --git a/src/main/scala/li/cil/oc/server/machine/Machine.scala b/src/main/scala/li/cil/oc/server/machine/Machine.scala index 0118a25b3..0b5a256e7 100644 --- a/src/main/scala/li/cil/oc/server/machine/Machine.scala +++ b/src/main/scala/li/cil/oc/server/machine/Machine.scala @@ -478,7 +478,7 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach // Check if we should switch states. These are all the states in which we're // guaranteed that the executor thread isn't running anymore. - state.synchronized(state.top match { + state.synchronized(state.top) match { // Booting up. case Machine.State.Starting => verifyComponents() @@ -539,10 +539,8 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach finally { inSynchronizedCall = false } - - assert(!isExecuting) case _ => // Nothing special to do, just avoid match errors. - }) + } // Finally check if we should stop the computer. We cannot lock the state // because we may have to wait for the executor thread to finish, which @@ -946,6 +944,8 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach case Machine.State.Stopping => state.clear() state.push(Machine.State.Stopping) + case Machine.State.Restarting => + // Nothing to do! case _ => throw new AssertionError("Invalid state in executor post-processing.") } assert(!isExecuting) diff --git a/src/main/scala/li/cil/oc/server/machine/luac/ComputerAPI.scala b/src/main/scala/li/cil/oc/server/machine/luac/ComputerAPI.scala index cf3b18f37..c92ea091b 100644 --- a/src/main/scala/li/cil/oc/server/machine/luac/ComputerAPI.scala +++ b/src/main/scala/li/cil/oc/server/machine/luac/ComputerAPI.scala @@ -1,9 +1,15 @@ package li.cil.oc.server.machine.luac import li.cil.oc.Settings +import li.cil.oc.api +import li.cil.oc.api.driver.item.MutableProcessor +import li.cil.oc.api.driver.item.Processor import li.cil.oc.api.network.Connector +import li.cil.oc.integration.opencomputers.DriverCPU import li.cil.oc.util.ExtendedLuaState.extendLuaState +import scala.collection.convert.WrapAsScala._ + class ComputerAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) { def initialize() { // Computer API, stuff that kinda belongs to os, but we don't want to @@ -105,6 +111,51 @@ class ComputerAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) { }) lua.setField(-2, "maxEnergy") + lua.pushScalaFunction(lua => { + machine.host.internalComponents.map(stack => (stack, api.Driver.driverFor(stack))).collectFirst { + case (stack, processor: MutableProcessor) => processor.allArchitectures.toSeq + case (stack, processor: Processor) => Seq(processor.architecture(stack)) + } match { + case Some(architectures) => + lua.pushValue(architectures.map(DriverCPU.getArchitectureName)) + case _ => + lua.newTable() + } + 1 + }) + lua.setField(-2, "getArchitectures") + + lua.pushScalaFunction(lua => { + machine.host.internalComponents.map(stack => (stack, api.Driver.driverFor(stack))).collectFirst { + case (stack, processor: Processor) => + lua.pushString(DriverCPU.getArchitectureName(processor.architecture(stack))) + 1 + }.getOrElse(0) + }) + lua.setField(-2, "getArchitecture") + + lua.pushScalaFunction(lua => { + val archName = lua.checkString(1) + machine.host.internalComponents.map(stack => (stack, api.Driver.driverFor(stack))).collectFirst { + case (stack, processor: MutableProcessor) => processor.allArchitectures.find(arch => DriverCPU.getArchitectureName(arch) == archName) match { + case Some(archClass) => + if (archClass != processor.architecture(stack)) { + processor.setArchitecture(stack, archClass) + lua.pushBoolean(true) + } + else { + lua.pushBoolean(false) + } + 1 + case _ => + lua.pushNil() + lua.pushString("unknown architecture") + 2 + } + }.getOrElse(0) + }) + lua.setField(-2, "setArchitecture") + // Set the computer table. lua.setGlobal("computer") } diff --git a/src/main/scala/li/cil/oc/server/machine/luaj/ComputerAPI.scala b/src/main/scala/li/cil/oc/server/machine/luaj/ComputerAPI.scala index d27b826cb..cb87c1180 100644 --- a/src/main/scala/li/cil/oc/server/machine/luaj/ComputerAPI.scala +++ b/src/main/scala/li/cil/oc/server/machine/luaj/ComputerAPI.scala @@ -1,11 +1,17 @@ package li.cil.oc.server.machine.luaj import li.cil.oc.Settings +import li.cil.oc.api +import li.cil.oc.api.driver.item.MutableProcessor +import li.cil.oc.api.driver.item.Processor import li.cil.oc.api.network.Connector +import li.cil.oc.integration.opencomputers.DriverCPU import li.cil.oc.util.ScalaClosure._ import li.cil.repack.org.luaj.vm2.LuaValue import li.cil.repack.org.luaj.vm2.Varargs +import scala.collection.convert.WrapAsScala._ + class ComputerAPI(owner: LuaJLuaArchitecture) extends LuaJAPI(owner) { override def initialize() { // Computer API, stuff that kinda belongs to os, but we don't want to @@ -54,6 +60,40 @@ class ComputerAPI(owner: LuaJLuaArchitecture) extends LuaJAPI(owner) { computer.set("maxEnergy", (_: Varargs) => LuaValue.valueOf(node.asInstanceOf[Connector].globalBufferSize)) + computer.set("getArchitectures", (args: Varargs) => { + machine.host.internalComponents.map(stack => (stack, api.Driver.driverFor(stack))).collectFirst { + case (stack, processor: MutableProcessor) => processor.allArchitectures.toSeq + case (stack, processor: Processor) => Seq(processor.architecture(stack)) + } match { + case Some(architectures) => LuaValue.listOf(architectures.map(DriverCPU.getArchitectureName).map(LuaValue.valueOf).toArray) + case _ => LuaValue.tableOf() + } + }) + + computer.set("getArchitecture", (args: Varargs) => { + machine.host.internalComponents.map(stack => (stack, api.Driver.driverFor(stack))).collectFirst { + case (stack, processor: Processor) => LuaValue.valueOf(DriverCPU.getArchitectureName(processor.architecture(stack))) + }.getOrElse(LuaValue.NONE) + }) + + computer.set("setArchitecture", (args: Varargs) => { + val archName = args.checkjstring(1) + machine.host.internalComponents.map(stack => (stack, api.Driver.driverFor(stack))).collectFirst { + case (stack, processor: MutableProcessor) => processor.allArchitectures.find(arch => DriverCPU.getArchitectureName(arch) == archName) match { + case Some(archClass) => + if (archClass != processor.architecture(stack)) { + processor.setArchitecture(stack, archClass) + LuaValue.TRUE + } + else { + LuaValue.FALSE + } + case _ => + LuaValue.varargsOf(LuaValue.NIL, LuaValue.valueOf("unknown architecture")) + } + }.getOrElse(LuaValue.NONE) + }) + // Set the computer table. lua.set("computer", computer) }