**This is an old revision of the document!**

组件访问

本篇文章的部分/全部内容还没有进行翻译。

本页描述了如何通过 Lua 访问组件 API。简单来讲:组件是一些块或物品提供的 API,以供其可以在与之相连的计算机内的 Lua 程序上运行。

地址

所有的组件都有地址。地址是一个 UUID,即唯一标识符。大多数情况下都可以简写这些地址。例如,为了从一个缩写的地址中获得完整的地址,你可以使用 component.get。要获得任何一个块的详细地址,你可以手持分析仪按住Shitf键右键该方块。

要获得所有连接到你的计算机的组件的列表,你可以这样做:

snippet.lua
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” 的组件,如 computronics radar 或 warpDrive radar,添加到表 radars 内

snippet.lua
local component = require("component")
local radars = {}
for address, name in component.list("adar", false) do
  table.insert(radars, component.proxy(address))
end

这段代码只会讲所有连接的 warpDrive radars 添加到表 radars 内

snippet.lua
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 是类型名。比如:

snippet.lua
lua> =component.gpu.address
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

或者你也可以使用 component.getPrimary("xxx")。切记,如果没有指定类型的组件,这么做会引发一个错误,所以你可能会希望先用 component.isAvailable("xxx") 进行检查。因为抛出一个错误通常比以后得到一个 nil 更清晰。

这个系统主要是为了让操作系统能够选择最初输出到的屏幕。

Proxies

So now that we know how to get the address of components, let's see how we can interact with them. There are two ways to go about this. One is to call component.invoke(address, method, ...). For example:

snippet.lua
local component = require("component")
component.invoke(modemAddress, "broadcast", port, data)

The preferred way will usually be to get a proxy, however. A proxy is simply a table that provides one function for each API callback, named after that callback. In addition, each proxy has two fields: address, which holds the address of the wrapped component, and type, which holds the type of the component. You can get a proxy like this:

snippet.lua
local component = require("component")
local proxy = component.proxy(address)
 
-- The call above using the proxy:
proxy.broadcast(port, data)
 
-- The common proxy fields:
print(proxy.address) -- address passed to component.proxy above
print(proxy.type) -- "modem"

Note that each primary component you access via component.getPrimary or component.xxx is in fact a proxy.

Direct Calls

Some component callbacks can be performed as “direct calls”. Direct calls are performed in the computer's worker thread, meaning they will return instantly. Normal calls are delegated to the main server thread, to avoid race conditions and other threading issues, which also means that normal calls will take up to one tick (i.e. 50 ms). Just to be clear: this only applies to component APIs.

Signals

An important part of interacting with components are Signals. These can be queued by components to notify computers of external changes and events. For example, user input is forwarded to computers via signals. Computers can also queue their own signals, which can be useful for code-reuse, or just notifying other parts of your code asynchronously.

目录