本页描述了如何通过 Lua 调用组件 API。简单来说,组件是一些方块或物品提供的 API,供与之相连的计算机上的Lua程序调用。
每个组件都会有一个地址。这个地址是一个UUID,即唯一标识符。大多数情况下都可以简写这些地址。例如,要从一个缩写的地址中获得完整的地址,你可以使用 component.get
。要得到任何方块的地址,你可以手持分析仪按住Ctrl右击方块。
要获得所有连接到你计算机的组件列表,你可以这样做:
Lua 5.2.3 Copyright (C) 1994-2013 Lua.org, PUC-Rio lua> local component = require("component") lua> for k,v in component.list() do print(k, v) end xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx keyboard xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx screen xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx gpu ...
注意,即使从计算机上拆下来,物品组件的地址通常也不会改变。因此,如果你移除一个硬盘再将其重新插入,它的地址会与之前的相同。而方块组件则不是这样,它们在被拆除再重新放置后总是会得到一个新的地址。
你可以选择像这样过滤组件列表:
这段代码会将每一个名称中包含 “adar” 的组件添加到表 radars 中,如 computronics 的雷达(computronicsRadar)或曲率驱动的雷达(warpdriveRadar)。
local component = require("component") local radars = {} for address, name in component.list("adar", false) do table.insert(radars, component.proxy(address)) end
这段代码只将所有连接的曲率驱动雷达(warpdriveRadar)添加到表 radars 中
local component = require("component") local radars = {} for address, name in component.list("warpdriveRadar", true) do table.insert(radars, component.proxy(address)) end
组件 API 为每种类型选择一个组件作为“主”组件进行跟踪。如果有多个相同类型的组件,哪一个被选为主组件是随机的。你可以通过 component.xxx
访问特定类型的主组件,其中 xxx
是类型,比如:
lua> =component.gpu.address xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
或者你也可以使用 component.getPrimary("xxx")
。切记,如果指定类型的主组件不存在,调用它会引起一个错误,你可能会希望先用 component.isAvailable("xxx")
进行检查。之所以选择直接引发错误而不是返回 nil,是因为相较于在后续代码中试图访问 nil 中的元素而产生错误,直接在这里抛出一个错误更能明确问题来源。
这个系统主要是为了让操作系统选择最初要输出的屏幕。
现在我们知道了如何获得组件地址,现在让我们看看如何与它们互动。有两种方法可以做到这一点。一种是调用 component.invoke(address, method, ...)
。例如:
local component = require("component") component.invoke(modemAddress, "broadcast", port, data)
而更优的方法通常是获取一个代理。代理是一个简单的 table,为每个 API 回调提供一个函数,以该回调命名。此外,每个代理还有两个字段:address
用来保存被包装的组件的地址,type
用来保存组件的类型。你可以这样获得一个代理:
local component = require("component") local proxy = component.proxy(address) -- 下面的调用是通过代理进行的: proxy.broadcast(port, data) -- 常见的代理字段: print(proxy.address) -- 传给上述 component.proxy 的地址 print(proxy.type) -- "modem"
通过 component.getPrimary
或 component.xxx
访问的所有主组件实际上都是一个代理。
一些组件的回调可以作为“直接调用”执行。直接调用是在计算机的工作线程中进行的,这意味着它们会立即返回。普通调用会被委托给主服务器线程,以避免竞争条件和其他线程问题,这也意味着普通调用最多需要一个 tick(即50ms)。这里明确一下:只有组件 API 会有这种情况。
与组件交互的一个重要部分是信号 。这些信号可以被组件推入队列,以通知计算机外部变化和事件。例如,用户的输入就是通过信号转发给计算机的。计算机也可以排队等待他们自己的信号,这有助于代码复用,或者只是异步通知你代码的其他部分。