diff --git a/src/main/java/li/cil/oc/api/network/Environment.java b/src/main/java/li/cil/oc/api/network/Environment.java
index 4340dbc57..cd2a48941 100644
--- a/src/main/java/li/cil/oc/api/network/Environment.java
+++ b/src/main/java/li/cil/oc/api/network/Environment.java
@@ -67,7 +67,7 @@ public interface Environment {
* it to query it for other nodes. Use this to perform initialization logic,
* such as building lists of nodes of a certain type in the network.
*
- * For example, if node C is added to a network with nodes A and B, these
+ * For example, if node A is added to a network with nodes B and C, these
* calls are made:
*
* - A.onConnect(A)
@@ -90,7 +90,7 @@ public interface Environment {
* Use this to perform clean-up logic such as removing references to the
* removed node.
*
- * For example, if node C is removed from a network with nodes A, B and C,
+ * For example, if node A is removed from a network with nodes A, B and C,
* these calls are made:
*
* - A.onDisconnect(A)
diff --git a/src/main/resources/assets/opencomputers/lua/kernel.lua b/src/main/resources/assets/opencomputers/lua/kernel.lua
index eb8a43aa8..c22002102 100644
--- a/src/main/resources/assets/opencomputers/lua/kernel.lua
+++ b/src/main/resources/assets/opencomputers/lua/kernel.lua
@@ -80,12 +80,19 @@ sandbox = {
setmetatable = function(t, mt)
local gc = rawget(mt, "__gc")
if type(gc) == "function" then
+ -- For all user __gc functions we enforce a much tighter deadline.
+ -- This is because these functions may be called from the main
+ -- thread under certain circumstanced (such as when saving the world),
+ -- which can lead to noticeable lag if the __gc function behaves badly.
rawset(mt, "__gc", function(self)
+ local oldDeadline, oldHitDeadline = deadline, hitDeadline
local co = coroutine.create(gc)
debug.sethook(co, checkDeadline, "", hookInterval)
+ deadline, hitDeadline = math.min(oldDeadline, computer.realTime() + 0.5), true
local result, reason = coroutine.resume(co, self)
debug.sethook(co)
checkDeadline()
+ deadline, hitDeadline = oldDeadline, oldHitDeadline
if not result then
error(reason, 0)
end
@@ -440,17 +447,18 @@ end
local libcomponent
+local proxyCache = setmetatable({}, {__mode="v"})
+local proxyDirectCache = setmetatable({}, {__mode="v"})
+
local componentCallback = {
__call = function(self, ...)
- return libcomponent.invoke(self.address, self.name, ...)
+ return invoke(component, not not proxyDirectCache[self], self.address, self.name, ...)
end,
__tostring = function(self)
return libcomponent.doc(self.address, self.name) or "function"
end
}
-local proxyCache = setmetatable({}, {__mode="v"})
-
libcomponent = {
doc = function(address, method)
checkArg(1, address, "string")
@@ -500,8 +508,9 @@ libcomponent = {
if not methods then
return nil, reason
end
- for method in pairs(methods) do
+ for method, direct in pairs(methods) do
proxy[method] = setmetatable({address=address,name=method}, componentCallback)
+ proxyDirectCache[proxy[method]] = direct
end
proxyCache[address] = proxy
return proxy
diff --git a/src/main/scala/li/cil/oc/common/inventory/ComponentInventory.scala b/src/main/scala/li/cil/oc/common/inventory/ComponentInventory.scala
index 825c476ad..1944550da 100644
--- a/src/main/scala/li/cil/oc/common/inventory/ComponentInventory.scala
+++ b/src/main/scala/li/cil/oc/common/inventory/ComponentInventory.scala
@@ -138,7 +138,7 @@ trait ComponentInventory extends Inventory with network.Environment {
def isComponentSlot(slot: Int) = true
protected def connectItemNode(node: Node) {
- if (node != null) {
+ if (this.node != null && node != null) {
this.node.connect(node)
}
}
diff --git a/src/main/scala/li/cil/oc/server/component/machine/NativeLuaArchitecture.scala b/src/main/scala/li/cil/oc/server/component/machine/NativeLuaArchitecture.scala
index 9b19d7fdc..7e29202dd 100644
--- a/src/main/scala/li/cil/oc/server/component/machine/NativeLuaArchitecture.scala
+++ b/src/main/scala/li/cil/oc/server/component/machine/NativeLuaArchitecture.scala
@@ -413,6 +413,9 @@ class NativeLuaArchitecture(val machine: api.machine.Machine) extends Architectu
case e: LuaRuntimeException =>
OpenComputers.log.warn("Could not persist computer.\n" + e.toString + (if (e.getLuaStackTrace.isEmpty) "" else "\tat " + e.getLuaStackTrace.mkString("\n\tat ")))
nbt.removeTag("state")
+ case e: LuaGcMetamethodException =>
+ OpenComputers.log.warning("Could not persist computer.\n" + e.toString)
+ nbt.removeTag("state")
}
// Limit memory again.