mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-01-05 15:00:29 +00:00
An initial stab at documentation generation (#360)
This adds documentation comments to many of CC's Lua APIs, and a couple of the Java ones, through the use of stubs. We then export these to HTML using illuaminate [1] and upload them to our documentation site [2]. Uploads currently occur on pushes to master and any release/tag. The site is entirely static - there is no way to switch between versions, etc... but hopefully we can improve this in the future. [1]: github.com/SquidDev/illuaminate/ [2]: https://tweaked.cc/
This commit is contained in:
parent
1ccd687c00
commit
ef8da8054f
@ -14,5 +14,9 @@ trim_trailing_whitespace = false
|
||||
[*.sexp]
|
||||
indent_size = 2
|
||||
|
||||
[*.yml]
|
||||
indent_size = 2
|
||||
|
||||
|
||||
[*.properties]
|
||||
insert_final_newline = false
|
||||
|
16
.github/workflows/make-doc.sh
vendored
Executable file
16
.github/workflows/make-doc.sh
vendored
Executable file
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -eu
|
||||
|
||||
DEST="${GITHUB_REF#refs/*/}"
|
||||
echo "Uploading docs to https://tweaked.cc/$DEST"
|
||||
|
||||
# Setup ssh key
|
||||
mkdir -p "$HOME/.ssh/"
|
||||
echo "$SSH_KEY" > "$HOME/.ssh/key"
|
||||
chmod 600 "$HOME/.ssh/key"
|
||||
|
||||
# And upload
|
||||
rsync -avc -e "ssh -i $HOME/.ssh/key -o StrictHostKeyChecking=no -p $SSH_PORT" \
|
||||
"$GITHUB_WORKSPACE/doc/" \
|
||||
"$SSH_USER@$SSH_HOST:/var/www/tweaked.cc/$DEST"
|
29
.github/workflows/make-doc.yml
vendored
Normal file
29
.github/workflows/make-doc.yml
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
name: Build documentation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
tags:
|
||||
|
||||
jobs:
|
||||
make_doc:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
||||
- name: Build documentation
|
||||
run: |
|
||||
test -d bin || mkdir bin
|
||||
test -f bin/illuaminate || wget -q -Obin/illuaminate https://squiddev.cc/illuaminate/linux-x86-64/illuaminate
|
||||
chmod +x bin/illuaminate
|
||||
bin/illuaminate doc-gen
|
||||
|
||||
- name: Upload documentation
|
||||
run: .github/workflows/make-doc.sh 2> /dev/null
|
||||
env:
|
||||
SSH_KEY: ${{ secrets.SSH_KEY }}
|
||||
SSH_USER: ${{ secrets.SSH_USER }}
|
||||
SSH_HOST: ${{ secrets.SSH_HOST }}
|
||||
SSH_PORT: ${{ secrets.SSH_PORT }}
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,6 +3,7 @@
|
||||
/logs
|
||||
/build
|
||||
/out
|
||||
/doc/**/*.html
|
||||
|
||||
# Runtime directories
|
||||
/run
|
||||
|
@ -1,4 +1,4 @@
|
||||
# ![CC: Tweaked](logo.png)
|
||||
# ![CC: Tweaked](doc/logo.png)
|
||||
[![Current build status](https://github.com/SquidDev-CC/CC-Tweaked/workflows/Build/badge.svg)](https://github.com/SquidDev-CC/CC-Tweaked/actions "Current build status") [![Download CC: Tweaked on CurseForge](http://cf.way2muchnoise.eu/title/cc-tweaked.svg)](https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked on CurseForge")
|
||||
|
||||
CC: Tweaked is a fork of [ComputerCraft](https://github.com/dan200/ComputerCraft), adding programmable computers,
|
||||
|
13
doc/index.md
Normal file
13
doc/index.md
Normal file
@ -0,0 +1,13 @@
|
||||
# CC: Tweaked
|
||||
|
||||
This is a small website to test documentation generation from Lua source code.
|
||||
|
||||
This is still very much in the proof-of-concept stage. We've rolled own own documentation
|
||||
generation tool, and there's a couple of missing features. Furthermore, Java-based APIs
|
||||
(such as Lua builtins, or @{os}) are not documented.
|
||||
|
||||
For more information, please check out [the GitHub issue][gh_issue] and [the
|
||||
documented source][gh_branch].
|
||||
|
||||
[gh_issue]: https://github.com/SquidDev-CC/CC-Tweaked/issues/133
|
||||
[gh_branch]: https://github.com/SquidDev-CC/CC-Tweaked/tree/feature/doc-gen
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
6
doc/stub/commands.lua
Normal file
6
doc/stub/commands.lua
Normal file
@ -0,0 +1,6 @@
|
||||
function exec(command) end
|
||||
function execAsync(commad) end
|
||||
function list() end
|
||||
function getBlockPosition() end
|
||||
function getBlockInfos(min_x, min_y, min_z, max_x, max_y, max_z) end
|
||||
function getBlockInfo(x, y, z) end
|
42
doc/stub/fs.lua
Normal file
42
doc/stub/fs.lua
Normal file
@ -0,0 +1,42 @@
|
||||
--- The FS API allows you to manipulate files and the filesystem.
|
||||
--
|
||||
-- @module fs
|
||||
|
||||
function list(path) end
|
||||
function combine(base, child) end
|
||||
function getName(path) end
|
||||
function getSize(path) end
|
||||
function exists(path) end
|
||||
function isDir(path) end
|
||||
function isReadOnly(path) end
|
||||
function makeDir(path) end
|
||||
function move(from, to) end
|
||||
function copy(from, to) end
|
||||
function delete(path) end
|
||||
function open(path, mode) end
|
||||
function getDrive(path) end
|
||||
function getFreeSpace(path) end
|
||||
function find(pattern) end
|
||||
function getDir(path) end
|
||||
|
||||
--- A file handle which can be read from.
|
||||
--
|
||||
-- @type ReadHandle
|
||||
-- @see fs.open
|
||||
local ReadHandle = {}
|
||||
function ReadHandle.read(count) end
|
||||
function ReadHandle.readAll() end
|
||||
function ReadHandle.readLine(with_trailing) end
|
||||
function ReadHandle.seek(whence, offset) end
|
||||
function ReadHandle.close() end
|
||||
|
||||
--- A file handle which can be written to.
|
||||
--
|
||||
-- @type WriteHandle
|
||||
-- @see fs.open
|
||||
local WriteHandle = {}
|
||||
function WriteHandle.write(text) end
|
||||
function WriteHandle.writeLine(text) end
|
||||
function WriteHandle.flush(text) end
|
||||
function WriteHandle.seek(whence, offset) end
|
||||
function WriteHandle.close() end
|
213
doc/stub/http.lua
Normal file
213
doc/stub/http.lua
Normal file
@ -0,0 +1,213 @@
|
||||
--- The http library allows communicating with web servers, sending and
|
||||
-- receiving data from them.
|
||||
--
|
||||
-- #### `http_check` event
|
||||
--
|
||||
-- @module http
|
||||
|
||||
--- Asynchronously make a HTTP request to the given url.
|
||||
--
|
||||
-- This returns immediately, a [`http_success`](#http-success-event) or
|
||||
-- [`http_failure`](#http-failure-event) will be queued once the request has
|
||||
-- completed.
|
||||
--
|
||||
-- @tparam string url The url to request
|
||||
-- @tparam[opt] string body An optional string containing the body of the
|
||||
-- request. If specified, a `POST` request will be made instead.
|
||||
-- @tparam[opt] { [string] = string } headers Additional headers to send as part
|
||||
-- of this request.
|
||||
-- @tparam[opt] boolean binary Whether to make a binary HTTP request. If true,
|
||||
-- the body will not be UTF-8 encoded, and the received response will not be
|
||||
-- decoded.
|
||||
--
|
||||
-- @tparam[2] {
|
||||
-- url = string, body? = string, headers? = { [string] = string },
|
||||
-- binary? = boolean, method? = string, redirect? = boolean,
|
||||
-- } request Options for the request.
|
||||
--
|
||||
-- This table form is an expanded version of the previous syntax. All arguments
|
||||
-- from above are passed in as fields instead (for instance,
|
||||
-- `http.request("https://example.com")` becomes `http.request { url =
|
||||
-- "https://example.com" }`).
|
||||
--
|
||||
-- This table also accepts several additional options:
|
||||
--
|
||||
-- - `method`: Which HTTP method to use, for instance `"PATCH"` or `"DELETE"`.
|
||||
-- - `redirect`: Whether to follow HTTP redirects. Defaults to true.
|
||||
--
|
||||
-- @see http.get For a synchronous way to make GET requests.
|
||||
-- @see http.post For a synchronous way to make POST requests.
|
||||
function request(...) end
|
||||
|
||||
--- Make a HTTP GET request to the given url.
|
||||
--
|
||||
-- @tparam string url The url to request
|
||||
-- @tparam[opt] { [string] = string } headers Additional headers to send as part
|
||||
-- of this request.
|
||||
-- @tparam[opt] boolean binary Whether to make a binary HTTP request. If true,
|
||||
-- the body will not be UTF-8 encoded, and the received response will not be
|
||||
-- decoded.
|
||||
--
|
||||
-- @tparam[2] {
|
||||
-- url = string, headers? = { [string] = string },
|
||||
-- binary? = boolean, method? = string, redirect? = boolean,
|
||||
-- } request Options for the request. See @{http.request} for details on how
|
||||
-- these options behave.
|
||||
--
|
||||
-- @treturn Response The resulting http response, which can be read from.
|
||||
-- @treturn[2] nil When the http request failed, such as in the event of a 404
|
||||
-- error or connection timeout.
|
||||
-- @treturn string A message detailing why the request failed.
|
||||
-- @treturn Response|nil The failing http response, if available.
|
||||
--
|
||||
-- @usage Make a request to [example.computercraft.cc](https://example.computercraft.cc),
|
||||
-- and print the returned page.
|
||||
-- ```lua
|
||||
-- local request = http.get("https://example.computercraft.cc")
|
||||
-- print(request.readAll())
|
||||
-- -- => HTTP is working!
|
||||
-- request.close()
|
||||
-- ```
|
||||
function get(...) end
|
||||
|
||||
--- Make a HTTP POST request to the given url.
|
||||
--
|
||||
-- @tparam string url The url to request
|
||||
-- @tparam string body The body of the POST request.
|
||||
-- @tparam[opt] { [string] = string } headers Additional headers to send as part
|
||||
-- of this request.
|
||||
-- @tparam[opt] boolean binary Whether to make a binary HTTP request. If true,
|
||||
-- the body will not be UTF-8 encoded, and the received response will not be
|
||||
-- decoded.
|
||||
--
|
||||
-- @tparam[2] {
|
||||
-- url = string, body? = string, headers? = { [string] = string },
|
||||
-- binary? = boolean, method? = string, redirect? = boolean,
|
||||
-- } request Options for the request. See @{http.request} for details on how
|
||||
-- these options behave.
|
||||
--
|
||||
-- @treturn Response The resulting http response, which can be read from.
|
||||
-- @treturn[2] nil When the http request failed, such as in the event of a 404
|
||||
-- error or connection timeout.
|
||||
-- @treturn string A message detailing why the request failed.
|
||||
-- @treturn Response|nil The failing http response, if available.
|
||||
function post(...) end
|
||||
|
||||
--- A http response. This acts very much like a @{fs.ReadHandle|file}, though
|
||||
-- provides some http specific methods.
|
||||
--
|
||||
-- #### `http_success` event
|
||||
-- #### `http_failure` event
|
||||
--
|
||||
-- @type Response
|
||||
-- @see http.request On how to make a http request.
|
||||
local Response = {}
|
||||
|
||||
--- Returns the response code and response message returned by the server
|
||||
--
|
||||
-- @treturn number The response code (i.e. 200)
|
||||
-- @treturn string The response message (i.e. "OK")
|
||||
function Response.getResponseCode() end
|
||||
|
||||
--- Get a table containing the response's headers, in a format similar to that
|
||||
-- required by @{http.request}. If multiple headers are sent with the same
|
||||
-- name, they will be combined with a comma.
|
||||
--
|
||||
-- @treturn { [string]=string } The response's headers.
|
||||
-- Make a request to [example.computercraft.cc](https://example.computercraft.cc),
|
||||
-- and print the returned headers.
|
||||
-- ```lua
|
||||
-- local request = http.get("https://example.computercraft.cc")
|
||||
-- print(textutils.serialize(request.getResponseHeaders()))
|
||||
-- -- => {
|
||||
-- -- [ "Content-Type" ] = "text/plain; charset=utf8",
|
||||
-- -- [ "content-length" ] = 17,
|
||||
-- -- ...
|
||||
-- -- }
|
||||
-- request.close()
|
||||
-- ```
|
||||
function Response.getResponseHeaders() end
|
||||
|
||||
function Response.read(count) end
|
||||
function Response.readAll() end
|
||||
function Response.readLine(with_trailing) end
|
||||
function Response.seek(whence, offset) end
|
||||
function Response.close() end
|
||||
|
||||
--- Asynchronously determine whether a URL can be requested.
|
||||
--
|
||||
-- If this returns `true`, one should also listen for [`http_check`
|
||||
-- events](#http-check-event) which will container further information about
|
||||
-- whether the URL is allowed or not.
|
||||
--
|
||||
-- @tparam string url The URL to check.
|
||||
-- @treturn true When this url is not invalid. This does not imply that it is
|
||||
-- allowed - see the comment above.
|
||||
-- @treturn[2] false When this url is invalid.
|
||||
-- @treturn string A reason why this URL is not valid (for instance, if it is
|
||||
-- malformed, or blocked).
|
||||
--
|
||||
-- @see http.checkURL For a synchronous version.
|
||||
function checkURLAsync(url) end
|
||||
|
||||
--- Determine whether a URL can be requested.
|
||||
--
|
||||
-- If this returns `true`, one should also listen for [`http_check`
|
||||
-- events](#http-check-event) which will container further information about
|
||||
-- whether the URL is allowed or not.
|
||||
--
|
||||
-- @tparam string url The URL to check.
|
||||
-- @treturn true When this url is valid and can be requested via @{http.request}.
|
||||
-- @treturn[2] false When this url is invalid.
|
||||
-- @treturn string A reason why this URL is not valid (for instance, if it is
|
||||
-- malformed, or blocked).
|
||||
--
|
||||
-- @see http.checkURLAsync For an asynchronous version.
|
||||
--
|
||||
-- @usage
|
||||
-- ```lua
|
||||
-- print(http.checkURL("https://example.computercraft.cc/"))
|
||||
-- -- => true
|
||||
-- print(http.checkURL("http://localhost/"))
|
||||
-- -- => false Domain not permitted
|
||||
-- print(http.checkURL("not a url"))
|
||||
-- -- => false URL malformed
|
||||
-- ```
|
||||
function checkURL(url) end
|
||||
|
||||
--- Open a websocket.
|
||||
--
|
||||
-- @tparam string url The websocket url to connect to. This should have the
|
||||
-- `ws://` or `wss://` protocol.
|
||||
-- @tparam[opt] { [string] = string } headers Additional headers to send as part
|
||||
-- of the initial websocket connection.
|
||||
--
|
||||
-- @treturn Websocket The websocket connection.
|
||||
-- @treturn[2] false If the websocket connection failed.
|
||||
-- @treturn string An error message describing why the connection failed.
|
||||
function websocket(url, headers) end
|
||||
|
||||
--- Asynchronously open a websocket.
|
||||
--
|
||||
-- This returns immediately, a [`websocket_success`](#websocket-success-event)
|
||||
-- or [`websocket_failure`](#websocket-failure-event) will be queued once the
|
||||
-- request has completed.
|
||||
--
|
||||
-- @tparam string url The websocket url to connect to. This should have the
|
||||
-- `ws://` or `wss://` protocol.
|
||||
-- @tparam[opt] { [string] = string } headers Additional headers to send as part
|
||||
-- of the initial websocket connection.
|
||||
function websocketAsync(url, headers) end
|
||||
|
||||
|
||||
|
||||
--- A websocket, which can be used to send an receive messages with a web
|
||||
-- server.
|
||||
--
|
||||
-- @type Websocket
|
||||
-- @see http.websocket On how to open a websocket.
|
||||
local Websocket = {}
|
||||
|
||||
function Websocket.send(message, binary) end
|
||||
function Websocket.receive() end
|
||||
function Websocket.close() end
|
17
doc/stub/os.lua
Normal file
17
doc/stub/os.lua
Normal file
@ -0,0 +1,17 @@
|
||||
function queueEvent(event, ...) end
|
||||
function startTimer(delay) end
|
||||
function setAlarm(time) end
|
||||
function shutdown() end
|
||||
function reboot() end
|
||||
function getComputerID() end
|
||||
computerID = getComputerID
|
||||
function setComputerLabel(label) end
|
||||
function getComputerLabel() end
|
||||
computerLabel = getComputerLabel
|
||||
function clock() end
|
||||
function time(timezone) end
|
||||
function day(timezone) end
|
||||
function cancelTimer(id) end
|
||||
function cancelAlarm(id) end
|
||||
function epoch(timezone) end
|
||||
function date(format, time) end
|
14
doc/stub/redstone.lua
Normal file
14
doc/stub/redstone.lua
Normal file
@ -0,0 +1,14 @@
|
||||
function getSides() end
|
||||
function setOutput(side, on) end
|
||||
function getOutput(side) end
|
||||
function getInput(side) end
|
||||
function setBundledOutput(side, output) end
|
||||
function getBundledOutput(side) end
|
||||
function getBundledInput(side) end
|
||||
function testBundledInput(side, mask) end
|
||||
function setAnalogOutput(side, value) end
|
||||
setAnalogueOutput = setAnalogOutput
|
||||
function getAnalogOutput(sid) end
|
||||
getAnalogueOutput = getAnalogOutput
|
||||
function getAnalogInput(side) end
|
||||
getAnalogueInput = getAnaloguInput
|
52
doc/stub/term.lua
Normal file
52
doc/stub/term.lua
Normal file
@ -0,0 +1,52 @@
|
||||
function write(text) end
|
||||
function scroll(lines) end
|
||||
function setCursorPos(x, y) end
|
||||
function setCursorBlink(blink) end
|
||||
function getCursorPos() end
|
||||
function getSize() end
|
||||
function clear() end
|
||||
function clearLine() end
|
||||
function setTextColour(colour) end
|
||||
setTextColor = setTextColour
|
||||
function setBackgroundColour(colour) end
|
||||
setBackgroundColor = setBackgroundColour
|
||||
function isColour() end
|
||||
isColor = isColour
|
||||
function getTextColour() end
|
||||
getTextColor = getTextColor
|
||||
function getBackgroundColour() end
|
||||
getBackgroundColour = getBackgroundColour
|
||||
function blit(text, text_colours, background_colours) end
|
||||
function setPaletteColour(colour, ...) end
|
||||
setPaletteColour = setPaletteColour
|
||||
function getPaletteColour(colour, ...) end
|
||||
getPaletteColour = getPaletteColour
|
||||
function nativePaletteColour(colour) end
|
||||
nativePaletteColour = nativePaletteColour
|
||||
|
||||
--- @type Redirect
|
||||
local Redirect = {}
|
||||
|
||||
Redirect.write = write
|
||||
Redirect.scroll = scroll
|
||||
Redirect.setCursorPos = setCursorPos
|
||||
Redirect.setCursorBlink = setCursorBlink
|
||||
Redirect.getCursorPos = getCursorPos
|
||||
Redirect.getSize = getSize
|
||||
Redirect.clear = clear
|
||||
Redirect.clearLine = clearLine
|
||||
Redirect.setTextColour = setTextColour
|
||||
Redirect.setTextColor = setTextColor
|
||||
Redirect.setBackgroundColour = setBackgroundColour
|
||||
Redirect.setBackgroundColor = setBackgroundColor
|
||||
Redirect.isColour = isColour
|
||||
Redirect.isColor = isColor
|
||||
Redirect.getTextColour = getTextColour
|
||||
Redirect.getTextColor = getTextColor
|
||||
Redirect.getBackgroundColour = getBackgroundColour
|
||||
Redirect.getBackgroundColor = getBackgroundColor
|
||||
Redirect.blit = blit
|
||||
Redirect.setPaletteColour = setPaletteColour
|
||||
Redirect.setPaletteColor = setPaletteColor
|
||||
Redirect.getPaletteColour = getPaletteColour
|
||||
Redirect.getPaletteColor = getPaletteColor
|
42
doc/stub/turtle.lua
Normal file
42
doc/stub/turtle.lua
Normal file
@ -0,0 +1,42 @@
|
||||
function forward() end
|
||||
function back() end
|
||||
function up() end
|
||||
function down() end
|
||||
function turnLeft() end
|
||||
function turnRight() end
|
||||
function dig(side) end
|
||||
function digUp(side) end
|
||||
function digDown(side) end
|
||||
function place() end
|
||||
function placeUp() end
|
||||
function placeDown() end
|
||||
function drop(count) end
|
||||
function select(slot) end
|
||||
function getItemCount(slot) end
|
||||
function getItemSpace(slot) end
|
||||
function detect() end
|
||||
function detectUp() end
|
||||
function detectDown() end
|
||||
function compare() end
|
||||
function compareUp() end
|
||||
function compareDown() end
|
||||
function attack(side) end
|
||||
function attackUp(side) end
|
||||
function attackDown(side) end
|
||||
function dropUp(count) end
|
||||
function dropDown(count) end
|
||||
function suck(count) end
|
||||
function suckUp(count) end
|
||||
function suckDown(count) end
|
||||
function getFuelLevel() end
|
||||
function refuel(count) end
|
||||
function compareTo(slot) end
|
||||
function transferTo(slot, count) end
|
||||
function getSelectedSlot() end
|
||||
function getFuelLimit() end
|
||||
function equipLeft() end
|
||||
function equipRight() end
|
||||
function inspect() end
|
||||
function inspectUp() end
|
||||
function inspectDown() end
|
||||
function getItemDetail(slot) end
|
186
doc/styles.css
Normal file
186
doc/styles.css
Normal file
@ -0,0 +1,186 @@
|
||||
/* Basic reset on elements */
|
||||
h1, h2, h3, h4, p, table, div, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
/* Make the page a little more airy */
|
||||
body {
|
||||
margin: 20px auto;
|
||||
max-width: 1200px;
|
||||
padding: 0 10px;
|
||||
line-height: 1.6;
|
||||
color: #222;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* Try to use system default fonts. */
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans",
|
||||
"Droid Sans", "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
}
|
||||
|
||||
code, pre, .parameter, .type, .definition-name, .reference {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
}
|
||||
|
||||
/* Some definitions of basic tags */
|
||||
code {
|
||||
color: #c7254e;
|
||||
background-color: #f9f2f4;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0.9em 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.5em;
|
||||
font-weight: lighter;
|
||||
border-bottom: solid 1px #aaa;
|
||||
}
|
||||
|
||||
h2, h3, h4 { margin: 1.4em 0 0.3em;}
|
||||
h2 { font-size: 1.25em; }
|
||||
h3 { font-size: 1.15em; font-weight: bold; }
|
||||
h4 { font-size: 1.06em; }
|
||||
|
||||
a, a:visited, a:active { font-weight: bold; color: #004080; text-decoration: none; }
|
||||
a:hover { text-decoration: underline; }
|
||||
|
||||
blockquote { margin-left: 3em; }
|
||||
|
||||
/* Stop sublists from having initial vertical space */
|
||||
ul ul { margin-top: 0px; }
|
||||
ol ul { margin-top: 0px; }
|
||||
ol ol { margin-top: 0px; }
|
||||
ul ol { margin-top: 0px; }
|
||||
|
||||
/* Make the target distinct; helps when we're navigating to a function */
|
||||
a:target + * { background-color: #FFFF99; }
|
||||
|
||||
/* Allow linking to any subsection */
|
||||
a[name]::before { content: "#"; }
|
||||
|
||||
/* Layout */
|
||||
#main {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: space-between;
|
||||
min-height: calc(100vh - 100px);
|
||||
}
|
||||
|
||||
#main > nav {
|
||||
flex-basis: 30%;
|
||||
min-width: 150px;
|
||||
max-width: 250px;
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
nav h1, nav ul { padding: 0em 10px; }
|
||||
|
||||
nav h2 {
|
||||
background-color:#e7e7e7;
|
||||
font-size: 1.1em;
|
||||
color:#000000;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
nav ul {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#content {
|
||||
flex-shrink: 1;
|
||||
flex-basis: 80%;
|
||||
padding: 0px 10px;
|
||||
}
|
||||
|
||||
footer {
|
||||
text-align: right;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
/* The definition lists at the top of each page */
|
||||
table.definition-list {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table.definition-list td, table.definition-list th {
|
||||
border: 1px solid #cccccc;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
table.definition-list th {
|
||||
background-color: #f0f0f0;
|
||||
min-width: 200px;
|
||||
white-space: nowrap;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
table.definition-list td { width: 100%; }
|
||||
|
||||
dl.definition dt {
|
||||
border-top: 1px solid #ccc;
|
||||
padding-top: 1em;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
dl.definition dt .definition-name {
|
||||
padding: 0 0.1em;
|
||||
margin: 0 0.1em;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
|
||||
dl.definition dd {
|
||||
padding-bottom: 1em;
|
||||
margin: 10px 0 0 20px;
|
||||
}
|
||||
|
||||
dl.definition h3 {
|
||||
font-size: .95em;
|
||||
}
|
||||
|
||||
/* Links to source-code */
|
||||
.source-link { font-size: 0.8em; }
|
||||
.source-link::before { content: '[' }
|
||||
.source-link::after { content: ']' }
|
||||
a.source-link, a.source-link:visited, a.source-link:active { color: #505050; }
|
||||
|
||||
/* Method definitions */
|
||||
span.parameter:after { content:":"; padding-left: 0.3em; }
|
||||
.optional { text-decoration: underline dotted; }
|
||||
|
||||
/** Fancy colour display. */
|
||||
.colour-ref {
|
||||
display: inline-block;
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
margin: 0.1em 0.1em 0.3em 0.1em; /* Terrrible hack to force vertical alignment. */
|
||||
border: solid 1px black;
|
||||
box-sizing: border-box;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/* styles for prettification of source */
|
||||
.highlight .comment { color: #558817; }
|
||||
.highlight .constant { color: #a8660d; }
|
||||
.highlight .escape { color: #844631; }
|
||||
.highlight .keyword { color: #aa5050; font-weight: bold; }
|
||||
.highlight .library { color: #0e7c6b; }
|
||||
.highlight .marker { color: #512b1e; background: #fedc56; font-weight: bold; }
|
||||
.highlight .string { color: #8080ff; }
|
||||
.highlight .literal-kw { color: #8080ff; }
|
||||
.highlight .number { color: #f8660d; }
|
||||
.highlight .operator { color: #2239a8; font-weight: bold; }
|
||||
.highlight .preprocessor, pre .prepro { color: #a33243; }
|
||||
.highlight .global { color: #800080; }
|
||||
.highlight .user-keyword { color: #800080; }
|
||||
.highlight .prompt { color: #558817; }
|
||||
.highlight .url { color: #272fc2; text-decoration: underline; }
|
@ -1,10 +1,28 @@
|
||||
; -*- mode: Lisp;-*-
|
||||
|
||||
(sources
|
||||
/doc/stub/
|
||||
/src/main/resources/assets/computercraft/lua/bios.lua
|
||||
/src/main/resources/assets/computercraft/lua/rom/
|
||||
/src/test/resources/test-rom)
|
||||
|
||||
|
||||
(doc
|
||||
(title "CC: Tweaked")
|
||||
(index doc/index.md)
|
||||
(source-link https://github.com/SquidDev-CC/CC-Tweaked/blob/${commit}/${path}#L${line})
|
||||
|
||||
(library-path
|
||||
/doc/stub/
|
||||
|
||||
/src/main/resources/assets/computercraft/lua/rom/apis
|
||||
/src/main/resources/assets/computercraft/lua/rom/apis/command
|
||||
/src/main/resources/assets/computercraft/lua/rom/apis/turtle
|
||||
|
||||
/src/main/resources/assets/computercraft/lua/rom/modules/main
|
||||
/src/main/resources/assets/computercraft/lua/rom/modules/command
|
||||
/src/main/resources/assets/computercraft/lua/rom/modules/turtle))
|
||||
|
||||
(at /
|
||||
(linters
|
||||
;; It'd be nice to avoid this, but right now there's a lot of instances of
|
||||
@ -16,9 +34,9 @@
|
||||
-var:unused-arg
|
||||
|
||||
;; Suppress a couple of documentation comments warnings for now. We'll
|
||||
;; hopefully be able to remove them in the coming weeks.
|
||||
-doc:detached-comment -doc:undocumented -doc:undocumented-arg
|
||||
-doc:unresolved-reference))
|
||||
;; hopefully be able to remove them in the future.
|
||||
-doc:undocumented -doc:undocumented-arg -doc:unresolved-reference
|
||||
-var:unresolved-member))
|
||||
|
||||
;; We disable the unused global linter in bios.lua and the APIs. In the future
|
||||
;; hopefully we'll get illuaminate to handle this.
|
||||
@ -26,5 +44,9 @@
|
||||
(/src/main/resources/assets/computercraft/lua/bios.lua
|
||||
/src/main/resources/assets/computercraft/lua/rom/apis/)
|
||||
(linters -var:unused-global)
|
||||
(lint
|
||||
(allow-toplevel-global true)))
|
||||
(lint (allow-toplevel-global true)))
|
||||
|
||||
;; Silence some variable warnings in documentation stubs.
|
||||
(at /doc/stub
|
||||
(linters -var:unused-global)
|
||||
(lint (allow-toplevel-global true)))
|
||||
|
@ -21,7 +21,7 @@ if _VERSION == "Lua 5.1" then
|
||||
local nativeloadstring = loadstring
|
||||
local nativesetfenv = setfenv
|
||||
|
||||
--- Historically load/loadstring would handle the chunk name as if it has
|
||||
-- Historically load/loadstring would handle the chunk name as if it has
|
||||
-- been prefixed with "=". We emulate that behaviour here.
|
||||
local function prefix(chunkname)
|
||||
if type(chunkname) ~= "string" then return chunkname end
|
||||
|
@ -1,23 +1,91 @@
|
||||
--- The Colors API allows you to manipulate sets of colors.
|
||||
--
|
||||
-- This is useful in conjunction with Bundled Cables from the RedPower mod,
|
||||
-- RedNet Cables from the MineFactory Reloaded mod, and colors on Advanced
|
||||
-- Computers and Advanced Monitors.
|
||||
--
|
||||
-- For the non-American English version just replace @{colors} with @{colours}
|
||||
-- and it will use the other API, colours which is exactly the same, except in
|
||||
-- British English (e.g. @{colors.gray} is spelt @{colours.grey}).
|
||||
--
|
||||
-- @see colours
|
||||
-- @module colors
|
||||
|
||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||
|
||||
-- Colors
|
||||
white = 1
|
||||
orange = 2
|
||||
magenta = 4
|
||||
lightBlue = 8
|
||||
yellow = 16
|
||||
lime = 32
|
||||
pink = 64
|
||||
gray = 128
|
||||
lightGray = 256
|
||||
cyan = 512
|
||||
purple = 1024
|
||||
blue = 2048
|
||||
brown = 4096
|
||||
green = 8192
|
||||
red = 16384
|
||||
black = 32768
|
||||
--- White: Written as `0` in paint files and @{term.blit}, has a default
|
||||
-- terminal colour of #F0F0F0.
|
||||
white = 0x1
|
||||
|
||||
--- Orange: Written as `1` in paint files and @{term.blit}, has a
|
||||
-- default terminal colour of #F2B233.
|
||||
orange = 0x2
|
||||
|
||||
--- Magenta: Written as `2` in paint files and @{term.blit}, has a
|
||||
-- default terminal colour of #E57FD8.
|
||||
magenta = 0x4
|
||||
|
||||
--- Light blue: Written as `3` in paint files and @{term.blit}, has a
|
||||
-- default terminal colour of #99B2F2.
|
||||
lightBlue = 0x8
|
||||
|
||||
--- Yellow: Written as `4` in paint files and @{term.blit}, has a
|
||||
-- default terminal colour of #DEDE6C.
|
||||
yellow = 0x10
|
||||
|
||||
--- Lime: Written as `5` in paint files and @{term.blit}, has a default
|
||||
-- terminal colour of #7FCC19.
|
||||
lime = 0x20
|
||||
|
||||
--- Pink. Written as `6` in paint files and @{term.blit}, has a default
|
||||
-- terminal colour of #F2B2CC.
|
||||
pink = 0x40
|
||||
|
||||
--- Gray: Written as `7` in paint files and @{term.blit}, has a default
|
||||
-- terminal colour of #4C4C4C.
|
||||
gray = 0x80
|
||||
|
||||
--- Light gray: Written as `8` in paint files and @{term.blit}, has a
|
||||
-- default terminal colour of #999999.
|
||||
lightGray = 0x100
|
||||
|
||||
--- Cyan: Written as `9` in paint files and @{term.blit}, has a default
|
||||
-- terminal colour of #4C99B2.
|
||||
cyan = 0x200
|
||||
|
||||
--- Purple: Written as `a` in paint files and @{term.blit}, has a
|
||||
-- default terminal colour of #B266E5.
|
||||
purple = 0x400
|
||||
|
||||
--- Blue: Written as `b` in paint files and @{term.blit}, has a default
|
||||
-- terminal colour of #3366CC.
|
||||
blue = 0x800
|
||||
|
||||
--- Brown: Written as `c` in paint files and @{term.blit}, has a default
|
||||
-- terminal colour of #7F664C.
|
||||
brown = 0x1000
|
||||
|
||||
--- Green: Written as `d` in paint files and @{term.blit}, has a default
|
||||
-- terminal colour of #57A64E.
|
||||
green = 0x2000
|
||||
|
||||
--- Red: Written as `e` in paint files and @{term.blit}, has a default
|
||||
-- terminal colour of #CC4C4C.
|
||||
red = 0x4000
|
||||
|
||||
--- Black: Written as `f` in paint files and @{term.blit}, has a default
|
||||
-- terminal colour of #191919.
|
||||
black = 0x8000
|
||||
|
||||
--- Combines a set of colors (or sets of colors) into a larger set.
|
||||
--
|
||||
-- @tparam number ... The colors to combine.
|
||||
-- @treturn number The union of the color sets given in `...`
|
||||
-- @usage
|
||||
-- ```lua
|
||||
-- colors.combine(colors.white, colors.magenta, colours.lightBlue)
|
||||
-- -- => 13
|
||||
-- ```
|
||||
function combine( ... )
|
||||
local r = 0
|
||||
for i = 1, select('#', ...) do
|
||||
@ -28,6 +96,20 @@ function combine( ... )
|
||||
return r
|
||||
end
|
||||
|
||||
--- Removes one or more colors (or sets of colors) from an initial set.
|
||||
--
|
||||
-- Each parameter beyond the first may be a single color or may be a set of
|
||||
-- colors (in the latter case, all colors in the set are removed from the
|
||||
-- original set).
|
||||
--
|
||||
-- @tparam number colors The color from which to subtract.
|
||||
-- @tparam number ... The colors to subtract.
|
||||
-- @treturn number The resulting color.
|
||||
-- @usage
|
||||
-- ```lua
|
||||
-- colours.subtract(colours.lime, colours.orange, colours.white)
|
||||
-- -- => 32
|
||||
-- ```
|
||||
function subtract( colors, ... )
|
||||
expect(1, colors, "number")
|
||||
local r = colors
|
||||
@ -39,12 +121,33 @@ function subtract( colors, ... )
|
||||
return r
|
||||
end
|
||||
|
||||
--- Tests whether `color` is contained within `colors`.
|
||||
--
|
||||
-- @tparam number colors A color, or color set
|
||||
-- @tparam number color A color or set of colors that `colors` should contain.
|
||||
-- @treturn boolean If `colors` contains all colors within `color`.
|
||||
-- @usage
|
||||
-- ```lua
|
||||
-- colors.test(colors.combine(colors.white, colors.magenta, colours.lightBlue), colors.lightBlue)
|
||||
-- -- => true
|
||||
-- ```
|
||||
function test( colors, color )
|
||||
expect(1, colors, "number")
|
||||
expect(2, color, "number")
|
||||
return bit32.band(colors, color) == color
|
||||
end
|
||||
|
||||
--- Combine a three-colour RGB value into one hexadecimal representation.
|
||||
--
|
||||
-- @tparam number r The red channel, should be between 0 and 1.
|
||||
-- @tparam number g The red channel, should be between 0 and 1.
|
||||
-- @tparam number b The blue channel, should be between 0 and 1.
|
||||
-- @treturn number The combined hexadecimal colour.
|
||||
-- @usage
|
||||
-- ```lua
|
||||
-- colors.rgb(0.7, 0.2, 0.6)
|
||||
-- -- => 0xb23399
|
||||
-- ```
|
||||
function packRGB( r, g, b )
|
||||
expect(1, r, "number")
|
||||
expect(2, g, "number")
|
||||
@ -55,6 +158,18 @@ function packRGB( r, g, b )
|
||||
bit32.band( b * 255, 0xFF )
|
||||
end
|
||||
|
||||
--- Separate a hexadecimal RGB colour into its three constituent channels.
|
||||
--
|
||||
-- @tparam number rgb The combined hexadecimal colour.
|
||||
-- @treturn number The red channel, will be between 0 and 1.
|
||||
-- @treturn number The red channel, will be between 0 and 1.
|
||||
-- @treturn number The blue channel, will be between 0 and 1.
|
||||
-- @usage
|
||||
-- ```lua
|
||||
-- colors.rgb(0xb23399)
|
||||
-- -- => 0.7, 0.2, 0.6
|
||||
-- ```
|
||||
-- @see colors.packRGB
|
||||
function unpackRGB( rgb )
|
||||
expect(1, rgb, "number")
|
||||
return
|
||||
@ -63,6 +178,30 @@ function unpackRGB( rgb )
|
||||
bit32.band( rgb, 0xFF ) / 255
|
||||
end
|
||||
|
||||
--- Either calls @{colors.packRGB} or @{colors.unpackRGB}, depending on how many
|
||||
-- arguments it receives.
|
||||
--
|
||||
-- **Note:** This function is deprecated, and it is recommended you use the
|
||||
-- specific pack/unpack function directly.
|
||||
--
|
||||
-- @tparam[1] number r The red channel, as an argument to @{colors.packRGB}.
|
||||
-- @tparam[1] number g The green channel, as an argument to @{colors.packRGB}.
|
||||
-- @tparam[1] number b The blue channel, as an argument to @{colors.packRGB}.
|
||||
-- @tparam[2] number rgb The combined hexadecimal color, as an argument to @{colors.unpackRGB}.
|
||||
-- @treturn[1] number The combined hexadecimal colour, as returned by @{colors.packRGB}.
|
||||
-- @treturn[2] number The red channel, as returned by @{colors.unpackRGB}
|
||||
-- @treturn[2] number The green channel, as returned by @{colors.unpackRGB}
|
||||
-- @treturn[2] number The blue channel, as returned by @{colors.unpackRGB}
|
||||
-- @usage
|
||||
-- ```lua
|
||||
-- colors.rgb(0xb23399)
|
||||
-- -- => 0.7, 0.2, 0.6
|
||||
-- ```
|
||||
-- @usage
|
||||
-- ```lua
|
||||
-- colors.rgb(0.7, 0.2, 0.6)
|
||||
-- -- => 0xb23399
|
||||
-- ```
|
||||
function rgb8( r, g, b )
|
||||
if g == nil and b == nil then
|
||||
return unpackRGB( r )
|
||||
|
@ -1,11 +1,23 @@
|
||||
-- Colours (for lovers of british spelling)
|
||||
--- Colours for lovers of British spelling.
|
||||
--
|
||||
-- @see colors
|
||||
-- @module colours
|
||||
|
||||
local colours = _ENV
|
||||
for k, v in pairs(colors) do
|
||||
colours[k] = v
|
||||
end
|
||||
|
||||
--- Grey. Written as `7` in paint files and @{term.blit}, has a default
|
||||
-- terminal colour of #4C4C4C.
|
||||
--
|
||||
-- @see colors.gray
|
||||
colours.grey = colors.gray
|
||||
colours.gray = nil
|
||||
colours.gray = nil --- @local
|
||||
|
||||
--- Light grey. Written as `8` in paint files and @{term.blit}, has a
|
||||
-- default terminal colour of #999999.
|
||||
--
|
||||
-- @see colors.lightGray
|
||||
colours.lightGrey = colors.lightGray
|
||||
colours.lightGray = nil
|
||||
colours.lightGray = nil --- @local
|
||||
|
@ -1,7 +1,26 @@
|
||||
--- The commands API allows your system to directly execute [Minecraft
|
||||
-- commands][mc] and gather data from the results.
|
||||
--
|
||||
-- While one may use @{commands.exec} directly to execute a command, the
|
||||
-- commands API also provides helper methods to execute every command. For
|
||||
-- instance, `commands.say("Hi!")` is equivalent to `commands.exec("say Hi!")`.
|
||||
--
|
||||
-- @{commands.async} provides a similar interface to execute asynchronous
|
||||
-- commands. `commands.async.say("Hi!")` is equivalent to
|
||||
-- `commands.execAsync("Hi!")`.
|
||||
--
|
||||
-- [mc]: https://minecraft.gamepedia.com/Commands
|
||||
--
|
||||
-- @module commands
|
||||
|
||||
if not commands then
|
||||
error( "Cannot load command API on normal computer", 2 )
|
||||
error( "Cannot load command API on normal computer", 2 )
|
||||
end
|
||||
|
||||
--- The builtin commands API, without any generated command helper functions
|
||||
--
|
||||
-- This may be useful if a built-in function (such as @{commands.list}) has been
|
||||
-- overwritten by a command.
|
||||
native = commands.native or commands
|
||||
|
||||
local function collapseArgs( bJSONIsNBT, ... )
|
||||
|
@ -1,3 +1,15 @@
|
||||
--- The Disk API allows you to interact with disk drives.
|
||||
--
|
||||
-- These functions can operate on locally attached or remote disk drives. To use
|
||||
-- a locally attached drive, specify “side” as one of the six sides
|
||||
-- (e.g. `left`); to use a remote disk drive, specify its name as printed when
|
||||
-- enabling its modem (e.g. `drive_0`).
|
||||
--
|
||||
-- **Note:** All computers (except command computers), turtles and pocket
|
||||
-- computers can be placed within a disk drive to access it's internal storage
|
||||
-- like a disk.
|
||||
--
|
||||
-- @module disk
|
||||
|
||||
local function isDrive( name )
|
||||
if type( name ) ~= "string" then
|
||||
@ -6,6 +18,11 @@ local function isDrive( name )
|
||||
return peripheral.getType( name ) == "drive"
|
||||
end
|
||||
|
||||
--- Checks whether any item at all is in the disk drive
|
||||
--
|
||||
-- @tparam string name The name of the disk drive.
|
||||
-- @treturn boolean If something is in the disk drive.
|
||||
-- @usage disk.isPresent(false)
|
||||
function isPresent( name )
|
||||
if isDrive( name ) then
|
||||
return peripheral.call( name, "isDiskPresent" )
|
||||
@ -13,6 +30,16 @@ function isPresent( name )
|
||||
return false
|
||||
end
|
||||
|
||||
--- Get the label of the floppy disk, record, or other media within the given
|
||||
-- disk drive.
|
||||
--
|
||||
-- If there is a computer or turtle within the drive, this will set the label as
|
||||
-- read by `os.getComputerLabel`.
|
||||
--
|
||||
-- @tparam string name The name of the disk drive.
|
||||
-- @treturn string|nil The name of the current media, or `nil` if the drive is
|
||||
-- not present or empty.
|
||||
-- @see disk.setLabel
|
||||
function getLabel( name )
|
||||
if isDrive( name ) then
|
||||
return peripheral.call( name, "getDiskLabel" )
|
||||
@ -20,12 +47,23 @@ function getLabel( name )
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Set the label of the floppy disk or other media
|
||||
--
|
||||
-- @tparam string name The name of the disk drive.
|
||||
-- @tparam string|nil label The new label of the disk
|
||||
function setLabel( name, label )
|
||||
if isDrive( name ) then
|
||||
peripheral.call( name, "setDiskLabel", label )
|
||||
end
|
||||
end
|
||||
|
||||
--- Check whether the current disk provides a mount.
|
||||
--
|
||||
-- This will return true for disks and computers, but not records.
|
||||
--
|
||||
-- @tparam string name The name of the disk drive.
|
||||
-- @treturn boolean If the disk is present and provides a mount.
|
||||
-- @see disk.getMountPath
|
||||
function hasData( name )
|
||||
if isDrive( name ) then
|
||||
return peripheral.call( name, "hasData" )
|
||||
@ -33,6 +71,13 @@ function hasData( name )
|
||||
return false
|
||||
end
|
||||
|
||||
--- Find the directory name on the local computer where the contents of the
|
||||
-- current floppy disk (or other mount) can be found.
|
||||
--
|
||||
-- @tparam string name The name of the disk drive.
|
||||
-- @treturn string|nil The mount's directory, or `nil` if the drive does not
|
||||
-- contain a floppy or computer.
|
||||
-- @see disk.hasData
|
||||
function getMountPath( name )
|
||||
if isDrive( name ) then
|
||||
return peripheral.call( name, "getMountPath" )
|
||||
@ -40,6 +85,15 @@ function getMountPath( name )
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Whether the current disk is a [music disk][disk] as opposed to a floppy disk
|
||||
-- or other item.
|
||||
--
|
||||
-- If this returns true, you will can @{disk.playAudio|play} the record.
|
||||
--
|
||||
-- [disk]: https://minecraft.gamepedia.com/Music_Disc
|
||||
--
|
||||
-- @tparam string name The name of the disk drive.
|
||||
-- @treturn boolean If the disk is present and has audio saved on it.
|
||||
function hasAudio( name )
|
||||
if isDrive( name ) then
|
||||
return peripheral.call( name, "hasAudio" )
|
||||
@ -47,6 +101,13 @@ function hasAudio( name )
|
||||
return false
|
||||
end
|
||||
|
||||
--- Get the title of the audio track from the music record in the drive.
|
||||
--
|
||||
-- This generally returns the same as @{disk.getLabel} for records.
|
||||
--
|
||||
-- @tparam string name The name of the disk drive.
|
||||
-- @treturn string|false|nil The track title, `false` if there is not a music
|
||||
-- record in the drive or `nil` if no drive is present.
|
||||
function getAudioTitle( name )
|
||||
if isDrive( name ) then
|
||||
return peripheral.call( name, "getAudioTitle" )
|
||||
@ -54,12 +115,25 @@ function getAudioTitle( name )
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Starts playing the music record in the drive.
|
||||
--
|
||||
-- If any record is already playing on any disk drive, it stops before the
|
||||
-- target drive starts playing. The record stops when it reaches the end of the
|
||||
-- track, when it is removed from the drive, when @{disk.stopAudio} is called, or
|
||||
-- when another record is started.
|
||||
--
|
||||
-- @tparam string name The name of the disk drive.
|
||||
-- @usage disk.playAudio("bottom")
|
||||
function playAudio( name )
|
||||
if isDrive( name ) then
|
||||
peripheral.call( name, "playAudio" )
|
||||
end
|
||||
end
|
||||
|
||||
--- Stops the music record in the drive from playing, if it was started with
|
||||
-- @{disk.playAudio}.
|
||||
--
|
||||
-- @tparam string name The name o the disk drive.
|
||||
function stopAudio( name )
|
||||
if not name then
|
||||
for _, sName in ipairs( peripheral.getNames() ) do
|
||||
@ -72,16 +146,26 @@ function stopAudio( name )
|
||||
end
|
||||
end
|
||||
|
||||
--- Ejects any item currently in the drive, spilling it into the world as a loose item.
|
||||
--
|
||||
-- @tparam string name The name of the disk drive.
|
||||
-- @usage disk.eject("bottom")
|
||||
function eject( name )
|
||||
if isDrive( name ) then
|
||||
peripheral.call( name, "ejectDisk" )
|
||||
end
|
||||
end
|
||||
|
||||
--- Returns a number which uniquely identifies the disk in the drive.
|
||||
--
|
||||
-- Note, unlike @{disk.getLabel}, this does not return anything for other media,
|
||||
-- such as computers or turtles.
|
||||
--
|
||||
-- @tparam string name The name of the disk drive.
|
||||
-- @treturn string|nil The disk ID, or `nil` if the drive does not contain a floppy disk.
|
||||
function getID( name )
|
||||
if isDrive( name ) then
|
||||
return peripheral.call( name, "getDiskID" )
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
|
@ -1,5 +1,30 @@
|
||||
--- The GPS API provides a method for turtles and computers to retrieve their
|
||||
-- own locations.
|
||||
--
|
||||
-- It broadcasts a PING message over @{rednet} and wait for responses. In order
|
||||
-- for this system to work, there must be at least 4 computers used as gps hosts
|
||||
-- which will respond and allow trilateration. Three of these hosts should be in
|
||||
-- a plane, and the fourth should be either above or below the other three. The
|
||||
-- three in a plane should not be in a line with each other. You can set up
|
||||
-- hosts using the gps program.
|
||||
--
|
||||
-- **Note**: When entering in the coordinates for the host you need to put in
|
||||
-- the `x`, `y`, and `z` coordinates of the computer, not the modem, as all
|
||||
-- rednet distances are measured from the block the computer is in.
|
||||
--
|
||||
-- Also note that you may choose which axes x, y, or z refers to - so long as
|
||||
-- your systems have the same definition as any GPS servers that're in range, it
|
||||
-- works just the same. For example, you might build a GPS cluster according to
|
||||
-- [this tutorial][1], using z to account for height, or you might use y to
|
||||
-- account for height in the way that Minecraft's debug screen displays.
|
||||
--
|
||||
-- [1]: http://www.computercraft.info/forums2/index.php?/topic/3088-how-to-guide-gps-global-position-system/
|
||||
--
|
||||
-- @module gps
|
||||
|
||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||
|
||||
--- The channel which GPS requests and responses are broadcast on.
|
||||
CHANNEL_GPS = 65534
|
||||
|
||||
local function trilaterate( A, B, C )
|
||||
@ -56,6 +81,15 @@ local function narrow( p1, p2, fix )
|
||||
end
|
||||
end
|
||||
|
||||
--- Tries to retrieve the computer or turtles own location.
|
||||
--
|
||||
-- @tparam[opt] number timeout The maximum time taken to establish our
|
||||
-- position. Defaults to 2 seconds if not specified.
|
||||
-- @tparam[opt] boolean debug Print debugging messages
|
||||
-- @treturn[1] number This computer's `x` position.
|
||||
-- @treturn[1] number This computer's `y` position.
|
||||
-- @treturn[1] number This computer's `z` position.
|
||||
-- @treturn[2] nil If the position could not be established.
|
||||
function locate( _nTimeout, _bDebug )
|
||||
expect(1, _nTimeout, "number", "nil")
|
||||
expect(2, _bDebug, "boolean", "nil")
|
||||
|
@ -1,16 +1,38 @@
|
||||
--- Provides an API to read help files.
|
||||
--
|
||||
-- @module help
|
||||
|
||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||
|
||||
local sPath = "/rom/help"
|
||||
|
||||
--- Returns a colon-separated list of directories where help files are searched
|
||||
-- for. All directories are absolute.
|
||||
--
|
||||
-- @treturn string The current help search path, separated by colons.
|
||||
-- @see help.setPath
|
||||
function path()
|
||||
return sPath
|
||||
end
|
||||
|
||||
--- Sets the colon-seperated list of directories where help files are searched
|
||||
-- for to `newPath`
|
||||
--
|
||||
-- @tparam string newPath The new path to use.
|
||||
-- @usage help.setPath( "/disk/help/" )
|
||||
-- @usage help.setPath( help.path() .. ":/myfolder/help/" )
|
||||
-- @see help.path
|
||||
function setPath( _sPath )
|
||||
expect(1, _sPath, "string")
|
||||
sPath = _sPath
|
||||
end
|
||||
|
||||
--- Returns the location of the help file for the given topic.
|
||||
--
|
||||
-- @tparam string topic The topic to find
|
||||
-- @treturn string|nil The path to the given topic's help file, or `nil` if it
|
||||
-- cannot be found.
|
||||
-- @usage print(help.lookup("disk"))
|
||||
function lookup( _sTopic )
|
||||
expect(1, _sTopic, "string")
|
||||
-- Look on the path variable
|
||||
@ -27,6 +49,9 @@ function lookup( _sTopic )
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns a list of topics that can be looked up and/or displayed.
|
||||
--
|
||||
-- @treturn table A list of topics in alphabetical order.
|
||||
function topics()
|
||||
-- Add index
|
||||
local tItems = {
|
||||
@ -59,6 +84,11 @@ function topics()
|
||||
return tItemList
|
||||
end
|
||||
|
||||
--- Returns a list of topic endings that match the prefix. Can be used with
|
||||
-- `read` to allow input of a help topic.
|
||||
--
|
||||
-- @tparam string prefix The prefix to match
|
||||
-- @treturn table A list of matching topics.
|
||||
function completeTopic( sText )
|
||||
expect(1, sText, "string")
|
||||
local tTopics = topics()
|
||||
|
@ -1,6 +1,10 @@
|
||||
-- Definition for the IO API
|
||||
--- Emulates Lua's standard [io library][io].
|
||||
--
|
||||
-- [io]: https://www.lua.org/manual/5.1/manual.html#5.7
|
||||
--
|
||||
-- @module io
|
||||
|
||||
local expect, typeOf = dofile("rom/modules/main/cc/expect.lua").expect, _G.type
|
||||
local expect, type_of = dofile("rom/modules/main/cc/expect.lua").expect, _G.type
|
||||
|
||||
--- If we return nil then close the file, as we've reached the end.
|
||||
-- We use this weird wrapper function as we wish to preserve the varargs
|
||||
@ -9,6 +13,9 @@ local function checkResult(handle, ...)
|
||||
return ...
|
||||
end
|
||||
|
||||
--- A file handle which can be read or written to.
|
||||
--
|
||||
-- @type Handle
|
||||
local handleMetatable
|
||||
handleMetatable = {
|
||||
__name = "FILE*",
|
||||
@ -20,10 +27,17 @@ handleMetatable = {
|
||||
return "file (" .. hash .. ")"
|
||||
end
|
||||
end,
|
||||
|
||||
__index = {
|
||||
--- Close this file handle, freeing any resources it uses.
|
||||
--
|
||||
-- @treturn[1] true If this handle was successfully closed.
|
||||
-- @treturn[2] nil If this file handle could not be closed.
|
||||
-- @treturn[2] string The reason it could not be closed.
|
||||
-- @throws If this handle was already closed.
|
||||
close = function(self)
|
||||
if typeOf(self) ~= "table" or getmetatable(self) ~= handleMetatable then
|
||||
error("bad argument #1 (FILE expected, got " .. typeOf(self) .. ")", 2)
|
||||
if type_of(self) ~= "table" or getmetatable(self) ~= handleMetatable then
|
||||
error("bad argument #1 (FILE expected, got " .. type_of(self) .. ")", 2)
|
||||
end
|
||||
if self._closed then error("attempt to use a closed file", 2) end
|
||||
|
||||
@ -36,18 +50,24 @@ handleMetatable = {
|
||||
return nil, "attempt to close standard stream"
|
||||
end
|
||||
end,
|
||||
|
||||
--- Flush any buffered output, forcing it to be written to the file
|
||||
--
|
||||
-- @throws If the handle has been closed
|
||||
flush = function(self)
|
||||
if typeOf(self) ~= "table" or getmetatable(self) ~= handleMetatable then
|
||||
error("bad argument #1 (FILE expected, got " .. typeOf(self) .. ")", 2)
|
||||
if type_of(self) ~= "table" or getmetatable(self) ~= handleMetatable then
|
||||
error("bad argument #1 (FILE expected, got " .. type_of(self) .. ")", 2)
|
||||
end
|
||||
if self._closed then error("attempt to use a closed file", 2) end
|
||||
|
||||
local handle = self._handle
|
||||
if handle.flush then handle.flush() end
|
||||
return true
|
||||
end,
|
||||
|
||||
lines = function(self, ...)
|
||||
if typeOf(self) ~= "table" or getmetatable(self) ~= handleMetatable then
|
||||
error("bad argument #1 (FILE expected, got " .. typeOf(self) .. ")", 2)
|
||||
if type_of(self) ~= "table" or getmetatable(self) ~= handleMetatable then
|
||||
error("bad argument #1 (FILE expected, got " .. type_of(self) .. ")", 2)
|
||||
end
|
||||
if self._closed then error("attempt to use a closed file", 2) end
|
||||
|
||||
@ -57,9 +77,10 @@ handleMetatable = {
|
||||
local args = table.pack(...)
|
||||
return function() return checkResult(self, self:read(table.unpack(args, 1, args.n))) end
|
||||
end,
|
||||
|
||||
read = function(self, ...)
|
||||
if typeOf(self) ~= "table" or getmetatable(self) ~= handleMetatable then
|
||||
error("bad argument #1 (FILE expected, got " .. typeOf(self) .. ")", 2)
|
||||
if type_of(self) ~= "table" or getmetatable(self) ~= handleMetatable then
|
||||
error("bad argument #1 (FILE expected, got " .. type_of(self) .. ")", 2)
|
||||
end
|
||||
if self._closed then error("attempt to use a closed file", 2) end
|
||||
|
||||
@ -71,9 +92,9 @@ handleMetatable = {
|
||||
for i = 1, n do
|
||||
local arg = select(i, ...)
|
||||
local res
|
||||
if typeOf(arg) == "number" then
|
||||
if type_of(arg) == "number" then
|
||||
if handle.read then res = handle.read(arg) end
|
||||
elseif typeOf(arg) == "string" then
|
||||
elseif type_of(arg) == "string" then
|
||||
local format = arg:gsub("^%*", ""):sub(1, 1)
|
||||
|
||||
if format == "l" then
|
||||
@ -88,7 +109,7 @@ handleMetatable = {
|
||||
error("bad argument #" .. i .. " (invalid format)", 2)
|
||||
end
|
||||
else
|
||||
error("bad argument #" .. i .. " (expected string, got " .. typeOf(arg) .. ")", 2)
|
||||
error("bad argument #" .. i .. " (expected string, got " .. type_of(arg) .. ")", 2)
|
||||
end
|
||||
|
||||
output[i] = res
|
||||
@ -99,9 +120,10 @@ handleMetatable = {
|
||||
if n == 0 and handle.readLine then return handle.readLine() end
|
||||
return table.unpack(output, 1, n)
|
||||
end,
|
||||
|
||||
seek = function(self, whence, offset)
|
||||
if typeOf(self) ~= "table" or getmetatable(self) ~= handleMetatable then
|
||||
error("bad argument #1 (FILE expected, got " .. typeOf(self) .. ")", 2)
|
||||
if type_of(self) ~= "table" or getmetatable(self) ~= handleMetatable then
|
||||
error("bad argument #1 (FILE expected, got " .. type_of(self) .. ")", 2)
|
||||
end
|
||||
if self._closed then error("attempt to use a closed file", 2) end
|
||||
|
||||
@ -111,10 +133,18 @@ handleMetatable = {
|
||||
-- It's a tail call, so error positions are preserved
|
||||
return handle.seek(whence, offset)
|
||||
end,
|
||||
|
||||
setvbuf = function(self, mode, size) end,
|
||||
|
||||
--- Write one or more values to the file
|
||||
--
|
||||
-- @tparam string|number ... The values to write.
|
||||
-- @treturn[1] Handle The current file, allowing chained calls.
|
||||
-- @treturn[2] nil If the file could not be written to.
|
||||
-- @treturn[2] string The error message which occurred while writing.
|
||||
write = function(self, ...)
|
||||
if typeOf(self) ~= "table" or getmetatable(self) ~= handleMetatable then
|
||||
error("bad argument #1 (FILE expected, got " .. typeOf(self) .. ")", 2)
|
||||
if type_of(self) ~= "table" or getmetatable(self) ~= handleMetatable then
|
||||
error("bad argument #1 (FILE expected, got " .. type_of(self) .. ")", 2)
|
||||
end
|
||||
if self._closed then error("attempt to use a closed file", 2) end
|
||||
|
||||
@ -156,41 +186,88 @@ local defaultError = setmetatable({
|
||||
local currentInput = defaultInput
|
||||
local currentOutput = defaultOutput
|
||||
|
||||
--- A file handle representing the "standard input". Reading from this
|
||||
-- file will prompt the user for input.
|
||||
stdin = defaultInput
|
||||
|
||||
--- A file handle representing the "standard output". Writing to this
|
||||
-- file will display the written text to the screen.
|
||||
stdout = defaultOutput
|
||||
|
||||
--- A file handle representing the "standard error" stream.
|
||||
--
|
||||
-- One may use this to display error messages, writing to it will display
|
||||
-- them on the terminal.
|
||||
stderr = defaultError
|
||||
|
||||
function close(_file)
|
||||
if _file == nil then return currentOutput:close() end
|
||||
--- Closes the provided file handle.
|
||||
--
|
||||
-- @tparam[opt] Handle file The file handle to close, defaults to the
|
||||
-- current output file.
|
||||
--
|
||||
-- @see Handle:close
|
||||
-- @see io.output
|
||||
function close(file)
|
||||
if file == nil then return currentOutput:close() end
|
||||
|
||||
if typeOf(_file) ~= "table" or getmetatable(_file) ~= handleMetatable then
|
||||
error("bad argument #1 (FILE expected, got " .. typeOf(_file) .. ")", 2)
|
||||
if type_of(file) ~= "table" or getmetatable(file) ~= handleMetatable then
|
||||
error("bad argument #1 (FILE expected, got " .. type_of(file) .. ")", 2)
|
||||
end
|
||||
return _file:close()
|
||||
return file:close()
|
||||
end
|
||||
|
||||
--- Flushes the current output file.
|
||||
--
|
||||
-- @see Handle:flush
|
||||
-- @see io.output
|
||||
function flush()
|
||||
return currentOutput:flush()
|
||||
end
|
||||
|
||||
function input(_arg)
|
||||
if typeOf(_arg) == "string" then
|
||||
local res, err = open(_arg, "rb")
|
||||
--- Get or set the current input file.
|
||||
--
|
||||
-- @tparam[opt] Handle|string file The new input file, either as a file path or pre-existing handle.
|
||||
-- @treturn Handle The current input file.
|
||||
-- @throws If the provided filename cannot be opened for reading.
|
||||
function input(file)
|
||||
if type_of(file) == "string" then
|
||||
local res, err = open(file, "rb")
|
||||
if not res then error(err, 2) end
|
||||
currentInput = res
|
||||
elseif typeOf(_arg) == "table" and getmetatable(_arg) == handleMetatable then
|
||||
currentInput = _arg
|
||||
elseif _arg ~= nil then
|
||||
error("bad argument #1 (FILE expected, got " .. typeOf(_arg) .. ")", 2)
|
||||
elseif type_of(file) == "table" and getmetatable(file) == handleMetatable then
|
||||
currentInput = file
|
||||
elseif file ~= nil then
|
||||
error("bad fileument #1 (FILE expected, got " .. type_of(file) .. ")", 2)
|
||||
end
|
||||
|
||||
return currentInput
|
||||
end
|
||||
|
||||
function lines(_sFileName)
|
||||
expect(1, _sFileName, "string", "nil")
|
||||
if _sFileName then
|
||||
local ok, err = open(_sFileName, "rb")
|
||||
--- Opens the given file name in read mode and returns an iterator that,
|
||||
-- each time it is called, returns a new line from the file.
|
||||
--
|
||||
-- This can be used in a for loop to iterate over all lines of a file:
|
||||
--
|
||||
-- ```lua
|
||||
-- for line in io.lines(filename) do print(line) end
|
||||
-- ```
|
||||
--
|
||||
-- Once the end of the file has been reached, @{nil} will be
|
||||
-- returned. The file is automatically closed.
|
||||
--
|
||||
-- If no file name is given, the @{io.input|current input} will be used
|
||||
-- instead. In this case, the handle is not used.
|
||||
--
|
||||
-- @tparam[opt] string filename The name of the file to extract lines from
|
||||
-- @treturn function():string|nil The line iterator.
|
||||
-- @throws If the file cannot be opened for reading
|
||||
--
|
||||
-- @see Handle:lines
|
||||
-- @see io.input
|
||||
function lines(filename)
|
||||
expect(1, filename, "string", "nil")
|
||||
if filename then
|
||||
local ok, err = open(filename, "rb")
|
||||
if not ok then error(err, 2) end
|
||||
|
||||
-- We set this magic flag to mark this file as being opened by io.lines and so should be
|
||||
@ -202,38 +279,72 @@ function lines(_sFileName)
|
||||
end
|
||||
end
|
||||
|
||||
function open(_sPath, _sMode)
|
||||
expect(1, _sPath, "string")
|
||||
expect(2, _sMode, "string", "nil")
|
||||
--- Open a file with the given mode, either returning a new file handle
|
||||
-- or @{nil}, plus an error message.
|
||||
--
|
||||
-- The `mode` string can be any of the following:
|
||||
-- - **"r"**: Read mode
|
||||
-- - **"w"**: Write mode
|
||||
-- - **"w"**: Append mode
|
||||
--
|
||||
-- The mode may also have a `b` at the end, which opens the file in "binary
|
||||
-- mode". This allows you to read binary files, as well as seek within a file.
|
||||
--
|
||||
-- @tparam string filename The name of the file to open.
|
||||
-- @tparam[opt] string mode The mode to open the file with. This defaults to `rb`.
|
||||
-- @treturn[1] Handle The opened file.
|
||||
-- @treturn[2] nil In case of an error.
|
||||
-- @treturn[2] string The reason the file could not be opened.
|
||||
function open(filename, mode)
|
||||
expect(1, filename, "string")
|
||||
expect(2, mode, "string", "nil")
|
||||
|
||||
local sMode = _sMode and _sMode:gsub("%+", "") or "rb"
|
||||
local file, err = fs.open(_sPath, sMode)
|
||||
local sMode = mode and mode:gsub("%+", "") or "rb"
|
||||
local file, err = fs.open(filename, sMode)
|
||||
if not file then return nil, err end
|
||||
|
||||
return setmetatable({ _handle = file }, handleMetatable)
|
||||
end
|
||||
|
||||
function output(_arg)
|
||||
if typeOf(_arg) == "string" then
|
||||
local res, err = open(_arg, "w")
|
||||
--- Get or set the current output file.
|
||||
--
|
||||
-- @tparam[opt] Handle|string file The new output file, either as a file path or pre-existing handle.
|
||||
-- @treturn Handle The current output file.
|
||||
-- @throws If the provided filename cannot be opened for writing.
|
||||
function output(file)
|
||||
if type_of(file) == "string" then
|
||||
local res, err = open(file, "w")
|
||||
if not res then error(err, 2) end
|
||||
currentOutput = res
|
||||
elseif typeOf(_arg) == "table" and getmetatable(_arg) == handleMetatable then
|
||||
currentOutput = _arg
|
||||
elseif _arg ~= nil then
|
||||
error("bad argument #1 (FILE expected, got " .. typeOf(_arg) .. ")", 2)
|
||||
elseif type_of(file) == "table" and getmetatable(file) == handleMetatable then
|
||||
currentOutput = file
|
||||
elseif file ~= nil then
|
||||
error("bad argument #1 (FILE expected, got " .. type_of(file) .. ")", 2)
|
||||
end
|
||||
|
||||
return currentOutput
|
||||
end
|
||||
|
||||
--- Read from the currently opened input file.
|
||||
--
|
||||
-- This is equivalent to `io.input():read(...)`. See @{Handle:read|the
|
||||
-- documentation} there for full details.
|
||||
--
|
||||
-- @tparam string ... The formats to read, defaulting to a whole line.
|
||||
-- @treturn (string|nil)... The data read, or @{nil} if nothing can be read.
|
||||
function read(...)
|
||||
return currentInput:read(...)
|
||||
end
|
||||
|
||||
function type(handle)
|
||||
if typeOf(handle) == "table" and getmetatable(handle) == handleMetatable then
|
||||
if handle._closed then
|
||||
--- Checks whether `handle` is a given file handle, and determine if it is open
|
||||
-- or not.
|
||||
--
|
||||
-- @param obj The value to check
|
||||
-- @treturn string|nil `"file"` if this is an open file, `"closed file"` if it
|
||||
-- is a closed file handle, or `nil` if not a file handle.
|
||||
function type(obj)
|
||||
if type_of(obj) == "table" and getmetatable(obj) == handleMetatable then
|
||||
if obj._closed then
|
||||
return "closed file"
|
||||
else
|
||||
return "file"
|
||||
@ -242,6 +353,12 @@ function type(handle)
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Write to the currently opened output file.
|
||||
--
|
||||
-- This is equivalent to `io.output():write(...)`. See @{Handle:write|the
|
||||
-- documentation} there for full details.
|
||||
--
|
||||
-- @tparam string ... The strings to write
|
||||
function write(...)
|
||||
return currentOutput:write(...)
|
||||
end
|
||||
|
@ -1,5 +1,12 @@
|
||||
-- Minecraft key code bindings
|
||||
-- See http://www.minecraftwiki.net/wiki/Key_codes for more info
|
||||
--- The Keys API provides a table of numerical codes corresponding to keyboard
|
||||
-- keys, suitable for decoding key events.
|
||||
--
|
||||
-- The Minecraft wiki [has a list of key
|
||||
-- codes](http://www.minecraftwiki.net/wiki/Key_codes). It is recommended that
|
||||
-- you use the constants provided by this file, rather than the underlying
|
||||
-- numerical values.
|
||||
--
|
||||
-- @module keys
|
||||
|
||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||
|
||||
@ -53,12 +60,18 @@ local keys = _ENV
|
||||
for nKey, sKey in pairs( tKeys ) do
|
||||
keys[sKey] = nKey
|
||||
end
|
||||
keys["return"] = keys.enter
|
||||
--backwards compatibility to earlier, typo prone, versions
|
||||
keys.scollLock = keys.scrollLock
|
||||
keys.cimcumflex = keys.circumflex
|
||||
|
||||
function getName( _nKey )
|
||||
expect(1, _nKey, "number")
|
||||
return tKeys[ _nKey ]
|
||||
keys["return"] = keys.enter --- @local
|
||||
--backwards compatibility to earlier, typo prone, versions
|
||||
keys.scollLock = keys.scrollLock --- @local
|
||||
keys.cimcumflex = keys.circumflex --- @local
|
||||
|
||||
--- Translates a numerical key code to a human-readable name. The human-readable
|
||||
-- name is one of the constants in the keys API.
|
||||
--
|
||||
-- @tparam number code The key code to look up.
|
||||
-- @treturn string|nil The name of the key, or `nil` if not a valid key code.
|
||||
function getName( code )
|
||||
expect(1, code, "number")
|
||||
return tKeys[ code ]
|
||||
end
|
||||
|
@ -1,3 +1,8 @@
|
||||
--- An API for advanced systems which can draw pixels and lines, load and draw
|
||||
-- image files. You can use the `colors` API for easier color manipulation.
|
||||
--
|
||||
-- @module paintutils
|
||||
|
||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||
|
||||
local function drawPixelInternal( xPos, yPos )
|
||||
@ -18,51 +23,88 @@ local function parseLine( tImageArg, sLine )
|
||||
table.insert( tImageArg, tLine )
|
||||
end
|
||||
|
||||
function parseImage( sRawData )
|
||||
expect(1, sRawData, "string")
|
||||
--- Parses an image from a multi-line string
|
||||
--
|
||||
-- @tparam string image The string containing the raw-image data.
|
||||
-- @treturn table The parsed image data, suitable for use with
|
||||
-- @{paintutils.drawImage}.
|
||||
function parseImage( image )
|
||||
expect(1, image, "string")
|
||||
local tImage = {}
|
||||
for sLine in ( sRawData .. "\n" ):gmatch( "(.-)\n" ) do -- read each line like original file handling did
|
||||
for sLine in ( image .. "\n" ):gmatch( "(.-)\n" ) do
|
||||
parseLine( tImage, sLine )
|
||||
end
|
||||
return tImage
|
||||
end
|
||||
|
||||
function loadImage( sPath )
|
||||
expect(1, sPath, "string")
|
||||
--- Loads an image from a file.
|
||||
--
|
||||
-- You can create a file suitable for being loaded using the `paint` program.
|
||||
--
|
||||
-- @tparam string path The file to load.
|
||||
--
|
||||
-- @treturn table|nil The parsed image data, suitable for use with
|
||||
-- @{paintutils.drawImage}, or `nil` if the file does not exist.
|
||||
function loadImage( path )
|
||||
expect(1, path, "string")
|
||||
|
||||
if fs.exists( sPath ) then
|
||||
local file = io.open( sPath, "r" )
|
||||
if fs.exists( path ) then
|
||||
local file = io.open( path, "r" )
|
||||
local sContent = file:read("*a")
|
||||
file:close()
|
||||
return parseImage( sContent ) -- delegate image parse to parseImage
|
||||
return parseImage( sContent )
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function drawPixel( xPos, yPos, nColour )
|
||||
--- Draws a single pixel to the current term at the specified position.
|
||||
--
|
||||
-- Be warned, this may change the position of the cursor and the current
|
||||
-- background colour. You should not expect either to be preserved.
|
||||
--
|
||||
-- @tparam number xPos The x position to draw at, where 1 is the far left.
|
||||
-- @tparam number yPos The y position to draw at, where 1 is the very top.
|
||||
-- @tparam[opt] number colour The @{colors|color} of this pixel. This will be
|
||||
-- the current background colour if not specified.
|
||||
function drawPixel( xPos, yPos, colour )
|
||||
expect(1, xPos, "number")
|
||||
expect(2, yPos, "number")
|
||||
expect(3, nColour, "number", "nil")
|
||||
if nColour then
|
||||
term.setBackgroundColor( nColour )
|
||||
expect(3, colour, "number", "nil")
|
||||
|
||||
if type( xPos ) ~= "number" then error( "bad argument #1 (expected number, got " .. type( xPos ) .. ")", 2 ) end
|
||||
if type( yPos ) ~= "number" then error( "bad argument #2 (expected number, got " .. type( yPos ) .. ")", 2 ) end
|
||||
if colour ~= nil and type( colour ) ~= "number" then error( "bad argument #3 (expected number, got " .. type( colour ) .. ")", 2 ) end
|
||||
if colour then
|
||||
term.setBackgroundColor( colour )
|
||||
end
|
||||
return drawPixelInternal( xPos, yPos )
|
||||
end
|
||||
|
||||
function drawLine( startX, startY, endX, endY, nColour )
|
||||
--- Draws a straight line from the start to end position.
|
||||
--
|
||||
-- Be warned, this may change the position of the cursor and the current
|
||||
-- background colour. You should not expect either to be preserved.
|
||||
--
|
||||
-- @tparam number startX The starting x position of the line.
|
||||
-- @tparam number startY The starting y position of the line.
|
||||
-- @tparam number endX The end x position of the line.
|
||||
-- @tparam number endY The end y position of the line.
|
||||
-- @tparam[opt] number colour The @{colors|color} of this pixel. This will be
|
||||
-- the current background colour if not specified.
|
||||
function drawLine( startX, startY, endX, endY, colour )
|
||||
expect(1, startX, "number")
|
||||
expect(2, startY, "number")
|
||||
expect(3, endX, "number")
|
||||
expect(4, endY, "number")
|
||||
expect(5, nColour, "number", "nil")
|
||||
expect(5, colour, "number", "nil")
|
||||
|
||||
startX = math.floor(startX)
|
||||
startY = math.floor(startY)
|
||||
endX = math.floor(endX)
|
||||
endY = math.floor(endY)
|
||||
|
||||
if nColour then
|
||||
term.setBackgroundColor( nColour )
|
||||
if colour then
|
||||
term.setBackgroundColor( colour )
|
||||
end
|
||||
if startX == endX and startY == endY then
|
||||
drawPixelInternal( startX, startY )
|
||||
@ -110,6 +152,18 @@ function drawLine( startX, startY, endX, endY, nColour )
|
||||
end
|
||||
end
|
||||
|
||||
--- Draws the outline of a box on the current term from the specified start
|
||||
-- position to the specified end position.
|
||||
--
|
||||
-- Be warned, this may change the position of the cursor and the current
|
||||
-- background colour. You should not expect either to be preserved.
|
||||
--
|
||||
-- @tparam number startX The starting x position of the line.
|
||||
-- @tparam number startY The starting y position of the line.
|
||||
-- @tparam number endX The end x position of the line.
|
||||
-- @tparam number endY The end y position of the line.
|
||||
-- @tparam[opt] number colour The @{colors|color} of this pixel. This will be
|
||||
-- the current background colour if not specified.
|
||||
function drawBox( startX, startY, endX, endY, nColour )
|
||||
expect(1, startX, "number")
|
||||
expect(2, startY, "number")
|
||||
@ -154,7 +208,18 @@ function drawBox( startX, startY, endX, endY, nColour )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Draws a filled box on the current term from the specified start position to
|
||||
-- the specified end position.
|
||||
--
|
||||
-- Be warned, this may change the position of the cursor and the current
|
||||
-- background colour. You should not expect either to be preserved.
|
||||
--
|
||||
-- @tparam number startX The starting x position of the line.
|
||||
-- @tparam number startY The starting y position of the line.
|
||||
-- @tparam number endX The end x position of the line.
|
||||
-- @tparam number endY The end y position of the line.
|
||||
-- @tparam[opt] number colour The @{colors|color} of this pixel. This will be
|
||||
-- the current background colour if not specified.
|
||||
function drawFilledBox( startX, startY, endX, endY, nColour )
|
||||
expect(1, startX, "number")
|
||||
expect(2, startY, "number")
|
||||
@ -194,12 +259,17 @@ function drawFilledBox( startX, startY, endX, endY, nColour )
|
||||
end
|
||||
end
|
||||
|
||||
function drawImage( tImage, xPos, yPos )
|
||||
expect(1, tImage, "table")
|
||||
--- Draw an image loaded by @{paintutils.parseImage} or @{paintutils.loadImage}.
|
||||
--
|
||||
-- @tparam table image The parsed image data.
|
||||
-- @tparam number xPos The x position to start drawing at.
|
||||
-- @tparam number xPos The y position to start drawing at.
|
||||
function drawImage( image, xPos, yPos )
|
||||
expect(1, image, "table")
|
||||
expect(2, xPos, "number")
|
||||
expect(3, yPos, "number")
|
||||
for y = 1, #tImage do
|
||||
local tLine = tImage[y]
|
||||
for y = 1, #image do
|
||||
local tLine = image[y]
|
||||
for x = 1, #tLine do
|
||||
if tLine[x] > 0 then
|
||||
term.setBackgroundColor( tLine[x] )
|
||||
|
@ -1,3 +1,18 @@
|
||||
--- Provides a simple implementation of multitasking.
|
||||
--
|
||||
-- Functions are not actually executed simultaniously, but rather this API will
|
||||
-- automatically switch between them whenever they yield (eg whenever they call
|
||||
-- @{coroutine.yield}, or functions that call that - eg `os.pullEvent` - or
|
||||
-- functions that call that, etc - basically, anything that causes the function
|
||||
-- to "pause").
|
||||
--
|
||||
-- Each function executed in "parallel" gets its own copy of the event queue,
|
||||
-- and so "event consuming" functions (again, mostly anything that causes the
|
||||
-- script to pause - eg `sleep`, `rednet.receive`, most of the `turtle` API,
|
||||
-- etc) can safely be used in one without affecting the event queue accessed by
|
||||
-- the other.
|
||||
--
|
||||
-- @module parallel
|
||||
|
||||
local function create( ... )
|
||||
local tFns = table.pack(...)
|
||||
@ -55,12 +70,22 @@ local function runUntilLimit( _routines, _limit )
|
||||
end
|
||||
end
|
||||
|
||||
--- Switches between execution of the functions, until any of them
|
||||
-- finishes. If any of the functions errors, the message is propagated upwards
|
||||
-- from the @{parallel.waitForAny} call.
|
||||
--
|
||||
-- @tparam function ... The functions this task will run
|
||||
function waitForAny( ... )
|
||||
local routines = create( ... )
|
||||
return runUntilLimit( routines, #routines - 1 )
|
||||
end
|
||||
|
||||
--- Switches between execution of the functions, until all of them are
|
||||
-- finished. If any of the functions errors, the message is propagated upwards
|
||||
-- from the @{parallel.waitForAll} call.
|
||||
--
|
||||
-- @tparam function ... The functions this task will run
|
||||
function waitForAll( ... )
|
||||
local routines = create( ... )
|
||||
runUntilLimit( routines, 0 )
|
||||
return runUntilLimit( routines, 0 )
|
||||
end
|
||||
|
@ -1,110 +1,182 @@
|
||||
--- The Peripheral API is for interacting with peripherals connected to the
|
||||
-- computer, such as the Disk Drive, the Advanced Monitor and Monitor.
|
||||
--
|
||||
-- Each peripheral block has a name, either referring to the side the peripheral
|
||||
-- can be found on, or a name on an adjacent wired network.
|
||||
--
|
||||
-- If the peripheral is next to the computer, its side is either `front`,
|
||||
-- `back`, `left`, `right`, `top` or `bottom`. If the peripheral is attached by
|
||||
-- a cable, its side will follow the format `type_id`, for example `printer_0`.
|
||||
--
|
||||
-- Peripheral functions are called *methods*, a term borrowed from Java.
|
||||
--
|
||||
-- @module peripheral
|
||||
|
||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||
|
||||
local native = peripheral
|
||||
local sides = rs.getSides()
|
||||
|
||||
--- Provides a list of all peripherals available.
|
||||
--
|
||||
-- If a device is located directly next to the system, then its name will be
|
||||
-- listed as the side it is attached to. If a device is attached via a Wired
|
||||
-- Modem, then it'll be reported according to its name on the wired network.
|
||||
--
|
||||
-- @treturn table A list of the names of all attached peripherals.
|
||||
function getNames()
|
||||
local tResults = {}
|
||||
for _, sSide in ipairs( rs.getSides() ) do
|
||||
if native.isPresent( sSide ) then
|
||||
table.insert( tResults, sSide )
|
||||
if native.getType( sSide ) == "modem" and not native.call( sSide, "isWireless" ) then
|
||||
local tRemote = native.call( sSide, "getNamesRemote" )
|
||||
for _, sName in ipairs( tRemote ) do
|
||||
table.insert( tResults, sName )
|
||||
local results = {}
|
||||
for n = 1, #sides do
|
||||
local side = sides[n]
|
||||
if native.isPresent(side) then
|
||||
table.insert(results, side)
|
||||
if native.getType(side) == "modem" and not native.call(side, "isWireless") then
|
||||
local remote = native.call(side, "getNamesRemote")
|
||||
for _, name in ipairs(remote) do
|
||||
table.insert(results, name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return tResults
|
||||
return results
|
||||
end
|
||||
|
||||
function isPresent( _sSide )
|
||||
expect(1, _sSide, "string")
|
||||
if native.isPresent( _sSide ) then
|
||||
--- Determines if a peripheral is present with the given name.
|
||||
--
|
||||
-- @tparam string name The side or network name that you want to check.
|
||||
-- @treturn boolean If a peripheral is present with the given name.
|
||||
-- @usage peripheral.isPresent("top")
|
||||
-- @usage peripheral.isPresent("monitor_0")
|
||||
function isPresent(name)
|
||||
expect(1, name, "string")
|
||||
if native.isPresent(name) then
|
||||
return true
|
||||
end
|
||||
for _, sSide in ipairs( rs.getSides() ) do
|
||||
if native.getType( sSide ) == "modem" and not native.call( sSide, "isWireless" ) then
|
||||
if native.call( sSide, "isPresentRemote", _sSide ) then
|
||||
return true
|
||||
end
|
||||
|
||||
for n = 1, #sides do
|
||||
local name = sides[n]
|
||||
if native.getType(name) == "modem" and not native.call(name, "isWireless") and
|
||||
native.call(name, "isPresentRemote", name)
|
||||
then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function getType( _sSide )
|
||||
expect(1, _sSide, "string")
|
||||
if native.isPresent( _sSide ) then
|
||||
return native.getType( _sSide )
|
||||
--- Get the type of the peripheral with the given name.
|
||||
--
|
||||
-- @tparam string name The name of the peripheral to find.
|
||||
-- @treturn string|nil The peripheral's type, or `nil` if it is not present.
|
||||
function getType(name)
|
||||
expect(1, name, "string")
|
||||
if native.isPresent(name) then
|
||||
return native.getType(name)
|
||||
end
|
||||
for _, sSide in ipairs( rs.getSides() ) do
|
||||
if native.getType( sSide ) == "modem" and not native.call( sSide, "isWireless" ) then
|
||||
if native.call( sSide, "isPresentRemote", _sSide ) then
|
||||
return native.call( sSide, "getTypeRemote", _sSide )
|
||||
end
|
||||
for n = 1, #sides do
|
||||
local side = sides[n]
|
||||
if native.getType(side) == "modem" and not native.call(side, "isWireless") and
|
||||
native.call(side, "isPresentRemote", name)
|
||||
then
|
||||
return native.call(side, "getTypeRemote", name)
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function getMethods( _sSide )
|
||||
expect(1, _sSide, "string")
|
||||
if native.isPresent( _sSide ) then
|
||||
return native.getMethods( _sSide )
|
||||
--- Get all available methods for the peripheral with the given name.
|
||||
--
|
||||
-- @tparam string name The name of the peripheral to find.
|
||||
-- @treturn table|nil A list of methods provided by this peripheral, or `nil` if
|
||||
-- it is not present.
|
||||
function getMethods(name)
|
||||
expect(1, name, "string")
|
||||
if native.isPresent(name) then
|
||||
return native.getMethods(name)
|
||||
end
|
||||
for _, sSide in ipairs( rs.getSides() ) do
|
||||
if native.getType( sSide ) == "modem" and not native.call( sSide, "isWireless" ) then
|
||||
if native.call( sSide, "isPresentRemote", _sSide ) then
|
||||
return native.call( sSide, "getMethodsRemote", _sSide )
|
||||
end
|
||||
for n = 1, #sides do
|
||||
local side = sides[n]
|
||||
if native.getType(side) == "modem" and not native.call(side, "isWireless") and
|
||||
native.call(side, "isPresentRemote", name)
|
||||
then
|
||||
return native.call(side, "getMethodsRemote", name)
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function call( _sSide, _sMethod, ... )
|
||||
expect(1, _sSide, "string")
|
||||
expect(2, _sMethod, "string")
|
||||
if native.isPresent( _sSide ) then
|
||||
return native.call( _sSide, _sMethod, ... )
|
||||
--- Call a method on a peripheral with a given name
|
||||
--
|
||||
-- @tparam string name The name of the peripheral to invoke the method on.
|
||||
-- @tparam string method The name of the method
|
||||
-- @param ... Additional arguments to pass to the method
|
||||
-- @return The return values of the peripheral method.
|
||||
--
|
||||
-- @usage peripheral.call("top", "open", 1)
|
||||
function call(name, method, ...)
|
||||
expect(1, name, "string")
|
||||
expect(2, method, "string")
|
||||
if native.isPresent(name) then
|
||||
return native.call(name, method, ...)
|
||||
end
|
||||
for _, sSide in ipairs( rs.getSides() ) do
|
||||
if native.getType( sSide ) == "modem" and not native.call( sSide, "isWireless" ) then
|
||||
if native.call( sSide, "isPresentRemote", _sSide ) then
|
||||
return native.call( sSide, "callRemote", _sSide, _sMethod, ... )
|
||||
end
|
||||
|
||||
for n = 1, #sides do
|
||||
local side = sides[n]
|
||||
if native.getType(side) == "modem" and not native.call(side, "isWireless") and
|
||||
native.call(side, "isPresentRemote", name)
|
||||
then
|
||||
return native.call(side, "callRemote", name, method, ...)
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function wrap( _sSide )
|
||||
expect(1, _sSide, "string")
|
||||
if peripheral.isPresent( _sSide ) then
|
||||
local tMethods = peripheral.getMethods( _sSide )
|
||||
local tResult = {}
|
||||
for _, sMethod in ipairs( tMethods ) do
|
||||
tResult[sMethod] = function( ... )
|
||||
return peripheral.call( _sSide, sMethod, ... )
|
||||
end
|
||||
end
|
||||
return tResult
|
||||
--- Get a table containing functions pointing to the peripheral's methods, which
|
||||
-- can then be called as if using @{peripheral.call}.
|
||||
--
|
||||
-- @tparam string name The name of the peripheral to wrap.
|
||||
-- @treturn table|nil The table containing the peripheral's methods, or `nil` if
|
||||
-- there is no peripheral present with the given name.
|
||||
-- @usage peripheral.wrap("top").open(1)
|
||||
function wrap(name)
|
||||
expect(1, name, "string")
|
||||
|
||||
local methods = peripheral.getMethods(name)
|
||||
if not methods then
|
||||
return nil
|
||||
end
|
||||
return nil
|
||||
|
||||
local result = {}
|
||||
for _, method in ipairs(methods) do
|
||||
result[method] = function(...)
|
||||
return peripheral.call(name, method, ...)
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function find( sType, fnFilter )
|
||||
expect(1, sType, "string")
|
||||
expect(2, fnFilter, "function", "nil")
|
||||
local tResults = {}
|
||||
for _, sName in ipairs( peripheral.getNames() ) do
|
||||
if peripheral.getType( sName ) == sType then
|
||||
local wrapped = peripheral.wrap( sName )
|
||||
if fnFilter == nil or fnFilter( sName, wrapped ) then
|
||||
table.insert( tResults, wrapped )
|
||||
--- Find all peripherals of a specific type, and return the
|
||||
-- @{peripheral.wrap|wrapped} peripherals.
|
||||
--
|
||||
-- @tparam string ty The type of peripheral to look for.
|
||||
-- @tparam[opt] function(name:string, wrapped:table):boolean filter A
|
||||
-- filter function, which takes the peripheral's name and wrapped table
|
||||
-- and returns if it should be included in the result.
|
||||
-- @treturn table... 0 or more wrapped peripherals matching the given filters.
|
||||
-- @usage local monitors = { peripheral.find("monitor") }
|
||||
-- @usage peripheral.find("modem", rednet.open)
|
||||
function find(ty, filter)
|
||||
expect(1, ty, "string")
|
||||
expect(2, filter, "function", "nil")
|
||||
|
||||
local results = {}
|
||||
for _, name in ipairs(peripheral.getNames()) do
|
||||
if peripheral.getType(name) == ty then
|
||||
local wrapped = peripheral.wrap(name)
|
||||
if filter == nil or filter(name, wrapped) then
|
||||
table.insert(results, wrapped)
|
||||
end
|
||||
end
|
||||
end
|
||||
return table.unpack( tResults )
|
||||
return table.unpack(results)
|
||||
end
|
||||
|
@ -1,51 +1,92 @@
|
||||
--- The Rednet API allows systems to communicate between each other without
|
||||
-- using redstone. It serves as a wrapper for the modem API, offering ease of
|
||||
-- functionality (particularly in regards to repeating signals) with some
|
||||
-- expense of fine control.
|
||||
--
|
||||
-- In order to send and receive data, a modem (either wired, wireless, or ender)
|
||||
-- is required. The data reaches any possible destinations immediately after
|
||||
-- sending it, but is range limited.
|
||||
--
|
||||
-- Rednet also allows you to use a "protocol" - simple string names indicating
|
||||
-- what messages are about. Receiving systems may filter messages according to
|
||||
-- their protocols, thereby automatically ignoring incoming messages which don't
|
||||
-- specify an identical string. It's also possible to @{rednet.lookup|lookup}
|
||||
-- which systems in the area use certain protocols, hence making it easier to
|
||||
-- determine where given messages should be sent in the first place.
|
||||
--
|
||||
-- @module rednet
|
||||
|
||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||
|
||||
--- The channel used by the Rednet API to @{broadcast} messages.
|
||||
CHANNEL_BROADCAST = 65535
|
||||
|
||||
--- The channel used by the Rednet API to repeat messages.
|
||||
CHANNEL_REPEAT = 65533
|
||||
|
||||
local tReceivedMessages = {}
|
||||
local tReceivedMessageTimeouts = {}
|
||||
local tHostnames = {}
|
||||
|
||||
function open( sModem )
|
||||
expect(1, sModem, "string")
|
||||
if peripheral.getType( sModem ) ~= "modem" then
|
||||
error( "No such modem: " .. sModem, 2 )
|
||||
--- Opens a modem with the given @{peripheral} name, allowing it to send and
|
||||
--- receive messages over rednet.
|
||||
--
|
||||
-- This will open the modem on two channels: one which has the same
|
||||
-- @{os.getComputerID|ID} as the computer, and another on
|
||||
-- @{CHANNEL_BROADCAST|the broadcast channel}.
|
||||
--
|
||||
-- @tparam string modem The name of the modem to open.
|
||||
-- @throws If there is no such modem with the given name
|
||||
function open( modem )
|
||||
expect(1, modem, "string")
|
||||
if peripheral.getType( modem ) ~= "modem" then
|
||||
error( "No such modem: " .. modem, 2 )
|
||||
end
|
||||
peripheral.call( sModem, "open", os.getComputerID() )
|
||||
peripheral.call( sModem, "open", CHANNEL_BROADCAST )
|
||||
peripheral.call( modem, "open", os.getComputerID() )
|
||||
peripheral.call( modem, "open", CHANNEL_BROADCAST )
|
||||
end
|
||||
|
||||
function close( sModem )
|
||||
expect(1, sModem, "string", "nil")
|
||||
if sModem then
|
||||
--- Close a modem with the given @{peripheral} name, meaning it can no longer
|
||||
-- send and receive rednet messages.
|
||||
--
|
||||
-- @tparam[opt] string modem The side the modem exists on. If not given, all
|
||||
-- open modems will be closed.
|
||||
-- @throws If there is no such modem with the given name
|
||||
function close( modem )
|
||||
expect(1, modem, "string", "nil")
|
||||
if modem then
|
||||
-- Close a specific modem
|
||||
if peripheral.getType( sModem ) ~= "modem" then
|
||||
error( "No such modem: " .. sModem, 2 )
|
||||
if peripheral.getType( modem ) ~= "modem" then
|
||||
error( "No such modem: " .. modem, 2 )
|
||||
end
|
||||
peripheral.call( sModem, "close", os.getComputerID() )
|
||||
peripheral.call( sModem, "close", CHANNEL_BROADCAST )
|
||||
peripheral.call( modem, "close", os.getComputerID() )
|
||||
peripheral.call( modem, "close", CHANNEL_BROADCAST )
|
||||
else
|
||||
-- Close all modems
|
||||
for _, sModem in ipairs( peripheral.getNames() ) do
|
||||
if isOpen( sModem ) then
|
||||
close( sModem )
|
||||
for _, modem in ipairs( peripheral.getNames() ) do
|
||||
if isOpen( modem ) then
|
||||
close( modem )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function isOpen( sModem )
|
||||
expect(1, sModem, "string", "nil")
|
||||
if sModem then
|
||||
--- Determine if rednet is currently open.
|
||||
--
|
||||
-- @tparam[opt] string modem Which modem to check. If not given, all connected
|
||||
-- modems will be checked.
|
||||
-- @treturn boolean If the given modem is open.
|
||||
function isOpen( modem )
|
||||
expect(1, modem, "string", "nil")
|
||||
if modem then
|
||||
-- Check if a specific modem is open
|
||||
if peripheral.getType( sModem ) == "modem" then
|
||||
return peripheral.call( sModem, "isOpen", os.getComputerID() ) and peripheral.call( sModem, "isOpen", CHANNEL_BROADCAST )
|
||||
if peripheral.getType( modem ) == "modem" then
|
||||
return peripheral.call( modem, "isOpen", os.getComputerID() ) and peripheral.call( modem, "isOpen", CHANNEL_BROADCAST )
|
||||
end
|
||||
else
|
||||
-- Check if any modem is open
|
||||
for _, sModem in ipairs( peripheral.getNames() ) do
|
||||
if isOpen( sModem ) then
|
||||
for _, modem in ipairs( peripheral.getNames() ) do
|
||||
if isOpen( modem ) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
@ -53,6 +94,23 @@ function isOpen( sModem )
|
||||
return false
|
||||
end
|
||||
|
||||
--- Allows a computer or turtle with an attached modem to send a message
|
||||
-- intended for a system with a specific ID. At least one such modem must first
|
||||
-- be @{rednet.open|opened} before sending is possible.
|
||||
--
|
||||
-- Assuming the target was in range and also had a correctly opened modem, it
|
||||
-- may then use @{rednet.receive} to collect the message.
|
||||
--
|
||||
-- @tparam number nRecipient The ID of the receiving computer.
|
||||
-- @param message The message to send. This should not contain coroutines or
|
||||
-- functions, as they will be converted to @{nil}.
|
||||
-- @tparam[opt] string sProtocol The "protocol" to send this message under. When
|
||||
-- using @{rednet.receive} one can filter to only receive messages sent under a
|
||||
-- particular protocol.
|
||||
-- @treturn boolean If this message was successfully sent (i.e. if rednet is
|
||||
-- currently @{rednet.open|open}). Note, this does not guarantee the message was
|
||||
-- actually _received_.
|
||||
-- @see rednet.receive
|
||||
function send( nRecipient, message, sProtocol )
|
||||
expect(1, nRecipient, "number")
|
||||
expect(3, sProtocol, "string", "nil")
|
||||
@ -91,11 +149,34 @@ function send( nRecipient, message, sProtocol )
|
||||
return sent
|
||||
end
|
||||
|
||||
--- Broadcasts a string message over the predefined @{CHANNEL_BROADCAST}
|
||||
-- channel. The message will be received by every device listening to rednet.
|
||||
--
|
||||
-- @param message The message to send. This should not contain coroutines or
|
||||
-- functions, as they will be converted to @{nil}.
|
||||
-- @tparam[opt] string sProtocol The "protocol" to send this message under. When
|
||||
-- using @{rednet.receive} one can filter to only receive messages sent under a
|
||||
-- particular protocol.
|
||||
-- @see rednet.receive
|
||||
function broadcast( message, sProtocol )
|
||||
expect(2, sProtocol, "string", "nil")
|
||||
send( CHANNEL_BROADCAST, message, sProtocol )
|
||||
end
|
||||
|
||||
--- Wait for a rednet message to be received, or until `nTimeout` seconds have
|
||||
-- elapsed.
|
||||
--
|
||||
-- @tparam[opt] string sProtocolFilter The protocol the received message must be
|
||||
-- sent with. If specified, any messages not sent under this protocol will be
|
||||
-- discarded.
|
||||
-- @tparam[opt] number nTimeout The number of seconds to wait if no message is
|
||||
-- received.
|
||||
-- @treturn[1] number The computer which sent this message
|
||||
-- @return[1] The received message
|
||||
-- @treturn[1] string|nil The protocol this message was sent under.
|
||||
-- @treturn[2] nil If the timeout elapsed and no message was received.
|
||||
-- @see rednet.broadcast
|
||||
-- @see rednet.send
|
||||
function receive( sProtocolFilter, nTimeout )
|
||||
-- The parameters used to be ( nTimeout ), detect this case for backwards compatibility
|
||||
if type(sProtocolFilter) == "number" and nTimeout == nil then
|
||||
@ -132,6 +213,24 @@ function receive( sProtocolFilter, nTimeout )
|
||||
end
|
||||
end
|
||||
|
||||
--- Register the system as "hosting" the desired protocol under the specified
|
||||
-- name. If a rednet @{rednet.lookup|lookup} is performed for that protocol (and
|
||||
-- maybe name) on the same network, the registered system will automatically
|
||||
-- respond via a background process, hence providing the system performing the
|
||||
-- lookup with its ID number.
|
||||
--
|
||||
-- Multiple computers may not register themselves on the same network as having
|
||||
-- the same names against the same protocols, and the title `localhost` is
|
||||
-- specifically reserved. They may, however, share names as long as their hosted
|
||||
-- protocols are different, or if they only join a given network after
|
||||
-- "registering" themselves before doing so (eg while offline or part of a
|
||||
-- different network).
|
||||
--
|
||||
-- @tparam string sProtocol The protocol this computer provides.
|
||||
-- @tparam string sHostname The name this protocol exposes for the given protocol.
|
||||
-- @throws If trying to register a hostname which is reserved, or currently in use.
|
||||
-- @see rednet.unhost
|
||||
-- @see rednet.lookup
|
||||
function host( sProtocol, sHostname )
|
||||
expect(1, sProtocol, "string")
|
||||
expect(2, sHostname, "string")
|
||||
@ -146,11 +245,29 @@ function host( sProtocol, sHostname )
|
||||
end
|
||||
end
|
||||
|
||||
--- Stop @{rednet.host|hosting} a specific protocol, meaning it will no longer
|
||||
--- respond to @{rednet.lookup} requests.
|
||||
--
|
||||
-- @tparam string sProtocol The protocol to unregister your self from.
|
||||
function unhost( sProtocol )
|
||||
expect(1, sProtocol, "string")
|
||||
tHostnames[ sProtocol ] = nil
|
||||
end
|
||||
|
||||
--- Search the local rednet network for systems @{rednet.host|hosting} the
|
||||
-- desired protocol and returns any computer IDs that respond as "registered"
|
||||
-- against it.
|
||||
--
|
||||
-- If a hostname is specified, only one ID will be returned (assuming an exact
|
||||
-- match is found).
|
||||
--
|
||||
-- @tparam string sProtocol The protocol to search for.
|
||||
-- @tparam[opt] string sHostname The hostname to search for.
|
||||
--
|
||||
-- @treturn[1] { number }|nil A list of computer IDs hosting the given
|
||||
-- protocol, or @{nil} if none exist.
|
||||
-- @treturn[2] number|nil The computer ID with the provided hostname and protocol,
|
||||
-- or @{nil} if none exists.
|
||||
function lookup( sProtocol, sHostname )
|
||||
expect(1, sProtocol, "string")
|
||||
expect(2, sHostname, "string", "nil")
|
||||
@ -216,6 +333,8 @@ function lookup( sProtocol, sHostname )
|
||||
end
|
||||
|
||||
local bRunning = false
|
||||
|
||||
--- @local
|
||||
function run()
|
||||
if bRunning then
|
||||
error( "rednet is already running", 2 )
|
||||
|
@ -1,16 +1,31 @@
|
||||
--- The settings API allows to store values and save them to a file for
|
||||
-- persistent configurations for CraftOS and your programs.
|
||||
--
|
||||
-- By default, the settings API will load its configuration from the
|
||||
-- `/.settings` file. One can then use @{settings.save} to update the file.
|
||||
--
|
||||
-- @module settings
|
||||
|
||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||
|
||||
local tSettings = {}
|
||||
|
||||
function set( sName, value )
|
||||
expect(1, sName, "string")
|
||||
--- Set the value of a setting.
|
||||
--
|
||||
-- @tparam string name The name of the setting to set
|
||||
-- @param value The setting's value. This cannot be `nil`, and must be
|
||||
-- serialisable by @{textutils.serialize}.
|
||||
-- @throws If this value cannot be serialised
|
||||
-- @see settings.unset
|
||||
function set( name, value )
|
||||
expect(1, name, "string")
|
||||
expect(2, value, "number", "string", "boolean", "table")
|
||||
|
||||
if type(value) == "table" then
|
||||
-- Ensure value is serializeable
|
||||
value = textutils.unserialize( textutils.serialize(value) )
|
||||
end
|
||||
tSettings[ sName ] = value
|
||||
tSettings[ name ] = value
|
||||
end
|
||||
|
||||
local copy
|
||||
@ -26,9 +41,15 @@ function copy( value )
|
||||
end
|
||||
end
|
||||
|
||||
function get( sName, default )
|
||||
expect(1, sName, "string")
|
||||
local result = tSettings[ sName ]
|
||||
--- Get the value of a setting.
|
||||
--
|
||||
-- @tparam string name The name of the setting to get.
|
||||
-- @param[opt] default The value to use should there be pre-existing value for
|
||||
-- this setting. Defaults to `nil`.
|
||||
-- @return The setting's, or `default` if the setting has not been set.
|
||||
function get( name, default )
|
||||
expect(1, name, "string")
|
||||
local result = tSettings[ name ]
|
||||
if result ~= nil then
|
||||
return copy(result)
|
||||
else
|
||||
@ -36,15 +57,31 @@ function get( sName, default )
|
||||
end
|
||||
end
|
||||
|
||||
function unset( sName )
|
||||
expect(1, sName, "string")
|
||||
tSettings[ sName ] = nil
|
||||
--- Remove the value of a setting, clearing it back to `nil`.
|
||||
--
|
||||
-- @{settings.get} will return the default value until the setting's value is
|
||||
-- @{settings.set|set}, or the computer is rebooted.
|
||||
--
|
||||
-- @tparam string name The name of the setting to unset.
|
||||
-- @see settings.set
|
||||
-- @see settings.clear
|
||||
function unset( name )
|
||||
expect(1, name, "string")
|
||||
tSettings[ name ] = nil
|
||||
end
|
||||
|
||||
--- Removes the value of all settings. Equivalent to calling @{settings.unset}
|
||||
--- on every setting.
|
||||
--
|
||||
-- @see settings.unset
|
||||
function clear()
|
||||
tSettings = {}
|
||||
end
|
||||
|
||||
--- Get the names of all currently defined settings.
|
||||
--
|
||||
-- @treturn { string } An alphabetically sorted list of all currently-defined
|
||||
-- settings.
|
||||
function getNames()
|
||||
local result = {}
|
||||
for k in pairs( tSettings ) do
|
||||
@ -54,6 +91,17 @@ function getNames()
|
||||
return result
|
||||
end
|
||||
|
||||
--- Load settings from the given file.
|
||||
--
|
||||
-- Existing settings will be merged with any pre-existing ones. Conflicting
|
||||
-- entries will be overwritten, but any others will be preserved.
|
||||
--
|
||||
-- @tparam string sPath The file to load from.
|
||||
-- @treturn boolean Whether settings were successfully read from this
|
||||
-- file. Reasons for failure may include the file not existing or being
|
||||
-- corrupted.
|
||||
--
|
||||
-- @see settings.save
|
||||
function load( sPath )
|
||||
expect(1, sPath, "string")
|
||||
local file = fs.open( sPath, "r" )
|
||||
@ -79,6 +127,15 @@ function load( sPath )
|
||||
return true
|
||||
end
|
||||
|
||||
--- Save settings to the given file.
|
||||
--
|
||||
-- This will entirely overwrite the pre-existing file. Settings defined in the
|
||||
-- file, but not currently loaded will be removed.
|
||||
--
|
||||
-- @tparam string sPath The path to save settings to.
|
||||
-- @treturn boolean If the settings were successfully saved.
|
||||
--
|
||||
-- @see settings.load
|
||||
function save( sPath )
|
||||
expect(1, sPath, "string")
|
||||
local file = fs.open( sPath, "w" )
|
||||
|
@ -1,3 +1,8 @@
|
||||
--- The Terminal API provides functions for writing text to the terminal and
|
||||
-- monitors, and drawing ASCII graphics.
|
||||
--
|
||||
-- @module term
|
||||
|
||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||
|
||||
local native = term.native and term.native() or term
|
||||
@ -9,8 +14,26 @@ local function wrap( _sFunction )
|
||||
end
|
||||
end
|
||||
|
||||
local term = {}
|
||||
local term = _ENV
|
||||
|
||||
--- Redirects terminal output to a monitor, a @{window}, or any other custom
|
||||
-- terminal object. Once the redirect is performed, any calls to a "term"
|
||||
-- function - or to a function that makes use of a term function, as @{print} -
|
||||
-- will instead operate with the new terminal object.
|
||||
--
|
||||
-- A "terminal object" is simply a table that contains functions with the same
|
||||
-- names - and general features - as those found in the term table. For example,
|
||||
-- a wrapped monitor is suitable.
|
||||
--
|
||||
-- The redirect can be undone by pointing back to the previous terminal object
|
||||
-- (which this function returns whenever you switch).
|
||||
--
|
||||
-- @tparam Redirect target The terminal redirect the @{term} API will draw to.
|
||||
-- @treturn Redirect The previous redirect object, as returned by
|
||||
-- @{term.current}.
|
||||
-- @usage
|
||||
-- Redirect to a monitor on the right of the computer.
|
||||
-- term.redirect(peripheral.wrap("right"))
|
||||
term.redirect = function( target )
|
||||
expect(1, target, "table")
|
||||
if target == term or target == _G.term then
|
||||
@ -30,14 +53,24 @@ term.redirect = function( target )
|
||||
return oldRedirectTarget
|
||||
end
|
||||
|
||||
--- Returns the current terminal object of the computer.
|
||||
--
|
||||
-- @treturn Redirect The current terminal redirect
|
||||
-- @usage
|
||||
-- Create a new @{window} which draws to the current redirect target
|
||||
-- window.create(term.current(), 1, 1, 10, 10)
|
||||
term.current = function()
|
||||
return redirectTarget
|
||||
end
|
||||
|
||||
--- Get the native terminal object of the current computer.
|
||||
--
|
||||
-- It is recommended you do not use this function unless you absolutely have
|
||||
-- to. In a multitasked environment, @{term.native} will _not_ be the current
|
||||
-- terminal object, and so drawing may interfere with other programs.
|
||||
--
|
||||
-- @treturn Redirect The native terminal redirect.
|
||||
term.native = function()
|
||||
-- NOTE: please don't use this function unless you have to.
|
||||
-- If you're running in a redirected or multitasked enviorment, term.native() will NOT be
|
||||
-- the current terminal when your program starts up. It is far better to use term.current()
|
||||
return native
|
||||
end
|
||||
|
||||
@ -49,12 +82,7 @@ for _, method in ipairs { "nativePaletteColor", "nativePaletteColour" } do
|
||||
end
|
||||
|
||||
for k, v in pairs( native ) do
|
||||
if type( k ) == "string" and type( v ) == "function" and term[k] == nil then
|
||||
if type( k ) == "string" and type( v ) == "function" and rawget(term, k) == nil then
|
||||
term[k] = wrap( k )
|
||||
end
|
||||
end
|
||||
|
||||
local env = _ENV
|
||||
for k, v in pairs( term ) do
|
||||
env[k] = v
|
||||
end
|
||||
|
@ -1,5 +1,20 @@
|
||||
--- The `textutils` API provides helpful utilities for formatting and
|
||||
-- manipulating strings.
|
||||
--
|
||||
-- @module textutils
|
||||
|
||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||
|
||||
--- Slowly writes string text at current cursor position,
|
||||
-- character-by-character.
|
||||
--
|
||||
-- Like @{write}, this does not insert a newline at the end.
|
||||
--
|
||||
-- @tparam string sText The the text to write to the screen
|
||||
-- @tparam[opt] number nRate The number of characters to write each second,
|
||||
-- Defaults to 20.
|
||||
-- @usage textutils.slowWrite("Hello, world!")
|
||||
-- @usage textutils.slowWrite("Hello, world!", 5)
|
||||
function slowWrite( sText, nRate )
|
||||
expect(2, nRate, "number", "nil")
|
||||
nRate = nRate or 20
|
||||
@ -21,11 +36,28 @@ function slowWrite( sText, nRate )
|
||||
end
|
||||
end
|
||||
|
||||
--- Slowly prints string text at current cursor position,
|
||||
-- character-by-character.
|
||||
--
|
||||
-- Like @{print}, this inserts a newline after printing.
|
||||
--
|
||||
-- @tparam string sText The the text to write to the screen
|
||||
-- @tparam[opt] number nRate The number of characters to write each second,
|
||||
-- Defaults to 20.
|
||||
-- @usage textutils.slowPrint("Hello, world!")
|
||||
-- @usage textutils.slowPrint("Hello, world!", 5)
|
||||
function slowPrint( sText, nRate )
|
||||
slowWrite( sText, nRate )
|
||||
print()
|
||||
end
|
||||
|
||||
--- Takes input time and formats it in a more readable format such as `6:30 PM`.
|
||||
--
|
||||
-- @tparam number nTime The time to format, as provided by @{os.time}.
|
||||
-- @tparam[opt] boolean bTwentyFourHour Whether to format this as a 24-hour
|
||||
-- clock (`18:30`) rather than a 12-hour one (`6:30 AM`)
|
||||
-- @treturn string The formatted time
|
||||
-- @usage textutils.formatTime(os.time())
|
||||
function formatTime( nTime, bTwentyFourHour )
|
||||
expect(1, nTime, "number")
|
||||
expect(2, bTwentyFourHour, "boolean", "nil")
|
||||
@ -71,6 +103,23 @@ local function makePagedScroll( _term, _nFreeLines )
|
||||
end
|
||||
end
|
||||
|
||||
--- Prints a given string to the display.
|
||||
--
|
||||
-- If the action can be completed without scrolling, it acts much the same as
|
||||
-- @{print}; otherwise, it will throw up a "Press any key to continue" prompt at
|
||||
-- the bottom of the display. Each press will cause it to scroll down and write
|
||||
-- a single line more before prompting again, if need be.
|
||||
--
|
||||
-- @tparam string _sText The text to print to the screen.
|
||||
-- @tparam[opt] number _nFreeLines The number of lines which will be
|
||||
-- automatically scrolled before the first prompt appears (meaning _nFreeLines +
|
||||
-- 1 lines will be printed). This can be set to the terminal's height - 2 to
|
||||
-- always try to fill the screen. Defaults to 0, meaning only one line is
|
||||
-- displayed before prompting.
|
||||
-- @treturn number The number of lines printed.
|
||||
-- @usage
|
||||
-- local width, height = term.getSize()
|
||||
-- textutils.pagedPrint(("This is a rather verbose dose of repetition.\n"):rep(30), height - 2)
|
||||
function pagedPrint( _sText, _nFreeLines )
|
||||
expect(2, _nFreeLines, "number", "nil")
|
||||
-- Setup a redirector
|
||||
@ -159,10 +208,30 @@ local function tabulateCommon( bPaged, ... )
|
||||
end
|
||||
end
|
||||
|
||||
--- Prints tables in a structured form.
|
||||
--
|
||||
-- This accepts multiple arguments, either a table or a number. When
|
||||
-- encountering a table, this will be treated as a table row, with each column
|
||||
-- width being auto-adjusted.
|
||||
--
|
||||
-- When encountering a number, this sets the text color of the subsequent rows to it.
|
||||
--
|
||||
-- @tparam {string...}|number ... The rows and text colors to display.
|
||||
-- @usage textutils.tabulate(colors.orange, { "1", "2", "3" }, colors.lightBlue, { "A", "B", "C" })
|
||||
function tabulate( ... )
|
||||
return tabulateCommon( false, ... )
|
||||
end
|
||||
|
||||
--- Prints tables in a structured form, stopping and prompting for input should
|
||||
-- the result not fit on the terminal.
|
||||
--
|
||||
-- This functions identically to @{textutils.tabulate}, but will prompt for user
|
||||
-- input should the whole output not fit on the display.
|
||||
--
|
||||
-- @tparam {string...}|number ... The rows and text colors to display.
|
||||
-- @usage textutils.tabulate(colors.orange, { "1", "2", "3" }, colors.lightBlue, { "A", "B", "C" })
|
||||
-- @see textutils.tabulate
|
||||
-- @see textutils.pagedPrint
|
||||
function pagedTabulate( ... )
|
||||
return tabulateCommon( true, ... )
|
||||
end
|
||||
@ -238,6 +307,13 @@ local function serializeImpl( t, tTracking, sIndent )
|
||||
end
|
||||
end
|
||||
|
||||
--- A table representing an empty JSON array, in order to distinguish it from an
|
||||
-- empty JSON object.
|
||||
--
|
||||
-- The contents of this table should not be modified.
|
||||
--
|
||||
-- @usage textutils.serialiseJSON(textutils.empty_json_array)
|
||||
-- @see textutils.serialiseJSON
|
||||
empty_json_array = setmetatable({}, {
|
||||
__newindex = function()
|
||||
error("attempt to mutate textutils.empty_json_array", 2)
|
||||
@ -310,11 +386,28 @@ local function serializeJSONImpl( t, tTracking, bNBTStyle )
|
||||
end
|
||||
end
|
||||
|
||||
--- Convert a Lua object into a textual representation, suitable for
|
||||
-- saving in a file or pretty-printing.
|
||||
--
|
||||
-- @param t The object to serialise
|
||||
-- @treturn string The serialised representation
|
||||
-- @throws If the object contains a value which cannot be
|
||||
-- serialised. This includes functions and tables which appear multiple
|
||||
-- times.
|
||||
function serialize( t )
|
||||
local tTracking = {}
|
||||
return serializeImpl( t, tTracking, "" )
|
||||
end
|
||||
|
||||
serialise = serialize -- GB version
|
||||
|
||||
--- Converts a serialised string back into a reassembled Lua object.
|
||||
--
|
||||
-- This is mainly used together with @{textutils.serialize}.
|
||||
--
|
||||
-- @tparam string s The serialised string to deserialise.
|
||||
-- @return[1] The deserialised object
|
||||
-- @treturn[2] nil If the object could not be deserialised.
|
||||
function unserialize( s )
|
||||
expect(1, s, "string")
|
||||
local func = load( "return " .. s, "unserialize", "t", {} )
|
||||
@ -327,6 +420,26 @@ function unserialize( s )
|
||||
return nil
|
||||
end
|
||||
|
||||
unserialise = unserialize -- GB version
|
||||
|
||||
--- Returns a JSON representation of the given data.
|
||||
--
|
||||
-- This function attempts to guess whether a table is a JSON array or
|
||||
-- object. However, empty tables are assumed to be empty objects - use
|
||||
-- @{textutils.empty_json_array} to mark an empty array.
|
||||
--
|
||||
-- This is largely intended for interacting with various functions from the
|
||||
-- @{commands} API, though may also be used in making @{http} requests.
|
||||
--
|
||||
-- @param t The value to serialise. Like @{textutils.serialise}, this should not
|
||||
-- contain recursive tables or functions.
|
||||
-- @tparam[opt] boolean bNBTStyle Whether to produce NBT-style JSON (non-quoted keys)
|
||||
-- instead of standard JSON.
|
||||
-- @treturn string The JSON representation of the input.
|
||||
-- @throws If the object contains a value which cannot be
|
||||
-- serialised. This includes functions and tables which appear multiple
|
||||
-- times.
|
||||
-- @usage textutils.serializeJSON({ values = { 1, "2", true } })
|
||||
function serializeJSON( t, bNBTStyle )
|
||||
expect(1, t, "table", "string", "number", "boolean")
|
||||
expect(2, bNBTStyle, "boolean", "nil")
|
||||
@ -334,6 +447,13 @@ function serializeJSON( t, bNBTStyle )
|
||||
return serializeJSONImpl( t, tTracking, bNBTStyle or false )
|
||||
end
|
||||
|
||||
serialiseJSON = serializeJSON -- GB version
|
||||
|
||||
--- Replaces certain characters in a string to make it safe for use in URLs or POST data.
|
||||
--
|
||||
-- @tparam string str The string to encode
|
||||
-- @treturn string The encoded string.
|
||||
-- @usage print("https://example.com/?view=" .. textutils.urlEncode(read()))
|
||||
function urlEncode( str )
|
||||
expect(1, str, "string")
|
||||
if str then
|
||||
@ -356,6 +476,23 @@ function urlEncode( str )
|
||||
end
|
||||
|
||||
local tEmpty = {}
|
||||
|
||||
--- Provides a list of possible completions for a partial Lua expression.
|
||||
--
|
||||
-- If the completed element is a table, suggestions will have `.` appended to
|
||||
-- them. Similarly, functions have `(` appended to them.
|
||||
--
|
||||
-- @tparam string sSearchText The partial expression to complete, such as a
|
||||
-- variable name or table index.
|
||||
--
|
||||
-- @tparam[opt] table tSearchTable The table to find variables in, defaulting to
|
||||
-- the global environment (@{_G}). The function also searches the "parent"
|
||||
-- environment via the `__index` metatable field.
|
||||
--
|
||||
-- @treturn { string... } The (possibly empty) list of completions.
|
||||
-- @see shell.setCompletionFunction
|
||||
-- @see read
|
||||
-- @usage textutils.complete( "pa", getfenv() )
|
||||
function complete( sSearchText, tSearchTable )
|
||||
expect(1, sSearchText, "string")
|
||||
expect(2, tSearchTable, "table", "nil")
|
||||
@ -431,8 +568,3 @@ function complete( sSearchText, tSearchTable )
|
||||
table.sort( tResults )
|
||||
return tResults
|
||||
end
|
||||
|
||||
-- GB versions
|
||||
serialise = serialize
|
||||
unserialise = unserialize
|
||||
serialiseJSON = serializeJSON
|
||||
|
@ -1,3 +1,6 @@
|
||||
--- The turtle API allows you to control your turtle.
|
||||
--
|
||||
-- @module turtle
|
||||
|
||||
if not turtle then
|
||||
error( "Cannot load turtle API on computer", 2 )
|
||||
|
@ -1,85 +1,178 @@
|
||||
--- The vector API provides methods to create and manipulate vectors.
|
||||
--
|
||||
-- An introduction to vectors can be found on [Wikipedia][wiki].
|
||||
--
|
||||
-- [wiki]: http://en.wikipedia.org/wiki/Euclidean_vector
|
||||
--
|
||||
-- @module vector
|
||||
|
||||
--- A 3-dimensional vector, with `x`, `y`, and `z` values.
|
||||
--
|
||||
-- This is suitable for representing both position and directional vectors.
|
||||
--
|
||||
-- @type Vector
|
||||
local vector = {
|
||||
add = function( self, o )
|
||||
return vector.new(
|
||||
self.x + o.x,
|
||||
self.y + o.y,
|
||||
self.z + o.z
|
||||
)
|
||||
end,
|
||||
sub = function( self, o )
|
||||
return vector.new(
|
||||
self.x - o.x,
|
||||
self.y - o.y,
|
||||
self.z - o.z
|
||||
)
|
||||
end,
|
||||
mul = function( self, m )
|
||||
return vector.new(
|
||||
self.x * m,
|
||||
self.y * m,
|
||||
self.z * m
|
||||
)
|
||||
end,
|
||||
div = function( self, m )
|
||||
return vector.new(
|
||||
self.x / m,
|
||||
self.y / m,
|
||||
self.z / m
|
||||
)
|
||||
end,
|
||||
unm = function( self )
|
||||
return vector.new(
|
||||
-self.x,
|
||||
-self.y,
|
||||
-self.z
|
||||
)
|
||||
end,
|
||||
dot = function( self, o )
|
||||
return self.x * o.x + self.y * o.y + self.z * o.z
|
||||
end,
|
||||
cross = function( self, o )
|
||||
return vector.new(
|
||||
self.y * o.z - self.z * o.y,
|
||||
self.z * o.x - self.x * o.z,
|
||||
self.x * o.y - self.y * o.x
|
||||
)
|
||||
end,
|
||||
length = function( self )
|
||||
return math.sqrt( self.x * self.x + self.y * self.y + self.z * self.z )
|
||||
end,
|
||||
normalize = function( self )
|
||||
return self:mul( 1 / self:length() )
|
||||
end,
|
||||
round = function( self, nTolerance )
|
||||
nTolerance = nTolerance or 1.0
|
||||
return vector.new(
|
||||
math.floor( (self.x + nTolerance * 0.5) / nTolerance ) * nTolerance,
|
||||
math.floor( (self.y + nTolerance * 0.5) / nTolerance ) * nTolerance,
|
||||
math.floor( (self.z + nTolerance * 0.5) / nTolerance ) * nTolerance
|
||||
)
|
||||
end,
|
||||
tostring = function( self )
|
||||
return self.x .. "," .. self.y .. "," .. self.z
|
||||
end,
|
||||
--- Adds two vectors together.
|
||||
--
|
||||
-- @tparam Vector self The first vector to add.
|
||||
-- @tparam Vector o The second vector to add.
|
||||
-- @treturn Vector The resulting vector
|
||||
-- @usage v1:add(v2)
|
||||
-- @usage v1 + v2
|
||||
add = function(self, o)
|
||||
return vector.new(
|
||||
self.x + o.x,
|
||||
self.y + o.y,
|
||||
self.z + o.z
|
||||
)
|
||||
end,
|
||||
|
||||
--- Subtracts one vector from another.
|
||||
--
|
||||
-- @tparam Vector self The vector to subtract from.
|
||||
-- @tparam Vector o The vector to subtract.
|
||||
-- @treturn Vector The resulting vector
|
||||
-- @usage v1:sub(v2)
|
||||
-- @usage v1 - v2
|
||||
sub = function(self, o)
|
||||
return vector.new(
|
||||
self.x - o.x,
|
||||
self.y - o.y,
|
||||
self.z - o.z
|
||||
)
|
||||
end,
|
||||
|
||||
--- Multiplies a vector by a scalar value.
|
||||
--
|
||||
-- @tparam Vector self The vector to multiply.
|
||||
-- @tparam number m The scalar value to multiply with.
|
||||
-- @treturn Vector A vector with value `(x * m, y * m, z * m)`.
|
||||
-- @usage v:mul(3)
|
||||
-- @usage v * 3
|
||||
mul = function(self, m)
|
||||
return vector.new(
|
||||
self.x * m,
|
||||
self.y * m,
|
||||
self.z * m
|
||||
)
|
||||
end,
|
||||
|
||||
--- Divides a vector by a scalar value.
|
||||
--
|
||||
-- @tparam Vector self The vector to divide.
|
||||
-- @tparam number m The scalar value to divide by.
|
||||
-- @treturn Vector A vector with value `(x / m, y / m, z / m)`.
|
||||
-- @usage v:div(3)
|
||||
-- @usage v / 3
|
||||
div = function(self, m)
|
||||
return vector.new(
|
||||
self.x / m,
|
||||
self.y / m,
|
||||
self.z / m
|
||||
)
|
||||
end,
|
||||
|
||||
--- Negate a vector
|
||||
--
|
||||
-- @tparam Vector self The vector to negate.
|
||||
-- @treturn Vector The negated vector.
|
||||
-- @usage -v
|
||||
unm = function(self)
|
||||
return vector.new(
|
||||
-self.x,
|
||||
-self.y,
|
||||
-self.z
|
||||
)
|
||||
end,
|
||||
|
||||
--- Compute the dot product of two vectors
|
||||
--
|
||||
-- @tparam Vector self The first vector to compute the dot product of.
|
||||
-- @tparam Vector o The second vector to compute the dot product of.
|
||||
-- @treturn Vector The dot product of `self` and `o`.
|
||||
-- @usage v1:dot(v2)
|
||||
dot = function(self, o)
|
||||
return self.x * o.x + self.y * o.y + self.z * o.z
|
||||
end,
|
||||
|
||||
--- Compute the cross product of two vectors
|
||||
--
|
||||
-- @tparam Vector self The first vector to compute the cross product of.
|
||||
-- @tparam Vector o The second vector to compute the cross product of.
|
||||
-- @treturn Vector The cross product of `self` and `o`.
|
||||
-- @usage v1:cross(v2)
|
||||
cross = function(self, o)
|
||||
return vector.new(
|
||||
self.y * o.z - self.z * o.y,
|
||||
self.z * o.x - self.x * o.z,
|
||||
self.x * o.y - self.y * o.x
|
||||
)
|
||||
end,
|
||||
|
||||
--- Get the length (also referred to as magnitude) of this vector.
|
||||
-- @tparam Vector self This vector.
|
||||
-- @treturn number The length of this vector.
|
||||
length = function(self)
|
||||
return math.sqrt( self.x * self.x + self.y * self.y + self.z * self.z )
|
||||
end,
|
||||
|
||||
--- Divide this vector by its length, producing with the same direction, but
|
||||
-- of length 1.
|
||||
--
|
||||
-- @tparam Vector self The vector to normalise
|
||||
-- @treturn Vector The normalised vector
|
||||
-- @usage v:normalize()
|
||||
normalize = function(self)
|
||||
return self:mul( 1 / self:length() )
|
||||
end,
|
||||
|
||||
--- Construct a vector with each dimension rounded to the nearest value.
|
||||
--
|
||||
-- @tparam Vector self The vector to round
|
||||
-- @tparam[opt] number tolerance The tolerance that we should round to,
|
||||
-- defaulting to 1. For instance, a tolerance of 0.5 will round to the
|
||||
-- nearest 0.5.
|
||||
-- @treturn Vector The rounded vector.
|
||||
round = function(self, tolerance)
|
||||
tolerance = tolerance or 1.0
|
||||
return vector.new(
|
||||
math.floor((self.x + tolerance * 0.5) / tolerance) * tolerance,
|
||||
math.floor((self.y + tolerance * 0.5) / tolerance) * tolerance,
|
||||
math.floor((self.z + tolerance * 0.5) / tolerance) * tolerance
|
||||
)
|
||||
end,
|
||||
|
||||
--- Convert this vector into a string, for pretty printing.
|
||||
--
|
||||
-- @tparam Vector self This vector.
|
||||
-- @treturn string This vector's string representation.
|
||||
-- @usage v:tostring()
|
||||
-- @usage tostring(v)
|
||||
tostring = function(self)
|
||||
return self.x .. "," .. self.y .. "," .. self.z
|
||||
end,
|
||||
}
|
||||
|
||||
local vmetatable = {
|
||||
__index = vector,
|
||||
__add = vector.add,
|
||||
__sub = vector.sub,
|
||||
__mul = vector.mul,
|
||||
__div = vector.div,
|
||||
__unm = vector.unm,
|
||||
__tostring = vector.tostring,
|
||||
__index = vector,
|
||||
__add = vector.add,
|
||||
__sub = vector.sub,
|
||||
__mul = vector.mul,
|
||||
__div = vector.div,
|
||||
__unm = vector.unm,
|
||||
__tostring = vector.tostring,
|
||||
}
|
||||
|
||||
function new( x, y, z )
|
||||
local v = {
|
||||
x = tonumber(x) or 0,
|
||||
y = tonumber(y) or 0,
|
||||
z = tonumber(z) or 0,
|
||||
}
|
||||
setmetatable( v, vmetatable )
|
||||
return v
|
||||
--- Construct a new @{Vector} with the given coordinates.
|
||||
--
|
||||
-- @tparam number x The X coordinate or direction of the vector.
|
||||
-- @tparam number y The Y coordinate or direction of the vector.
|
||||
-- @tparam number z The Z coordinate or direction of the vector.
|
||||
-- @treturn Vector The constructed vector.
|
||||
function new(x, y, z)
|
||||
return setmetatable({
|
||||
x = tonumber(x) or 0,
|
||||
y = tonumber(y) or 0,
|
||||
z = tonumber(z) or 0,
|
||||
}, vmetatable)
|
||||
end
|
||||
|
@ -1,3 +1,32 @@
|
||||
--- The Window API allows easy definition of spaces within the display that can
|
||||
-- be written/drawn to, then later redrawn/repositioned/etc as need be. The API
|
||||
-- itself contains only one function, @{window.create}, which returns the
|
||||
-- windows themselves.
|
||||
--
|
||||
-- Windows are considered terminal objects - as such, they have access to nearly
|
||||
-- all the commands in the term API (plus a few extras of their own, listed
|
||||
-- within said API) and are valid targets to redirect to.
|
||||
--
|
||||
-- Each window has a "parent" terminal object, which can be the computer's own
|
||||
-- display, a monitor, another window or even other, user-defined terminal
|
||||
-- objects. Whenever a window is rendered to, the actual screen-writing is
|
||||
-- performed via that parent (or, if that has one too, then that parent, and so
|
||||
-- forth). Bear in mind that the cursor of a window's parent will hence be moved
|
||||
-- around etc when writing a given child window.
|
||||
--
|
||||
-- Windows retain a memory of everything rendered "through" them (hence acting
|
||||
-- as display buffers), and if the parent's display is wiped, the window's
|
||||
-- content can be easily redrawn later. A window may also be flagged as
|
||||
-- invisible, preventing any changes to it from being rendered until it's
|
||||
-- flagged as visible once more.
|
||||
--
|
||||
-- A parent terminal object may have multiple children assigned to it, and
|
||||
-- windows may overlap. For example, the Multishell system functions by
|
||||
-- assigning each tab a window covering the screen, each using the starting
|
||||
-- terminal display as its parent, and only one of which is visible at a time.
|
||||
--
|
||||
-- @module window
|
||||
|
||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||
|
||||
local tHex = {
|
||||
@ -23,6 +52,24 @@ local type = type
|
||||
local string_rep = string.rep
|
||||
local string_sub = string.sub
|
||||
|
||||
--- Returns a terminal object that is a space within the specified parent
|
||||
-- terminal object. This can then be used (or even redirected to) in the same
|
||||
-- manner as eg a wrapped monitor. Refer to @{term|the term API} for a list of
|
||||
-- functions available to it.
|
||||
--
|
||||
-- @{term} itself may not be passed as the parent, though @{term.native} is
|
||||
-- acceptable. Generally, @{term.current} or a wrapped monitor will be most
|
||||
-- suitable, though windows may even have other windows assigned as their
|
||||
-- parents.
|
||||
--
|
||||
-- @tparam term.Redirect parent The parent terminal redirect to draw to.
|
||||
-- @tparam number nX The x coordinate this window is drawn at in the parent terminal
|
||||
-- @tparam number nY The y coordinate this window is drawn at in the parent terminal
|
||||
-- @tparam number nWidth The width of this window
|
||||
-- @tparam number nHeight The height of this window
|
||||
-- @tparam[opt] boolean bStartVisible Whether this window is visible by
|
||||
-- default. Defaults to `true`.
|
||||
-- @treturn Window The constructed window
|
||||
function create( parent, nX, nY, nWidth, nHeight, bStartVisible )
|
||||
expect(1, parent, "table")
|
||||
expect(2, nX, "number")
|
||||
@ -182,7 +229,9 @@ function create( parent, nX, nY, nWidth, nHeight, bStartVisible )
|
||||
end
|
||||
end
|
||||
|
||||
-- Terminal implementation
|
||||
--- Terminal implementation
|
||||
--
|
||||
-- @type Window
|
||||
local window = {}
|
||||
|
||||
function window.write( sText )
|
||||
|
@ -7,7 +7,7 @@ local native_select, native_type = select, type
|
||||
|
||||
--- Expect an argument to have a specific type.
|
||||
--
|
||||
-- @tparam int index The 1-based argument index.
|
||||
-- @tparam number index The 1-based argument index.
|
||||
-- @param value The argument's value.
|
||||
-- @tparam string ... The allowed types of the argument.
|
||||
-- @throws If the value is not one of the allowed types.
|
||||
|
@ -2,7 +2,7 @@
|
||||
-- aesthetically pleasing manner.
|
||||
--
|
||||
-- In order to display something using @{cc.pretty}, you build up a series of
|
||||
-- @{documents|Doc}. These behave a little bit like strings; you can concatenate
|
||||
-- @{Doc|documents}. These behave a little bit like strings; you can concatenate
|
||||
-- them together and then print them to the screen.
|
||||
--
|
||||
-- However, documents also allow you to control how they should be printed. There
|
||||
@ -28,7 +28,7 @@ local function append(out, value)
|
||||
out[n], out.n = value, n
|
||||
end
|
||||
|
||||
--- A document, which
|
||||
--- A document containing formatted text, with multiple possible layouts.
|
||||
--
|
||||
-- Documents effectively represent a sequence of strings in alternative layouts,
|
||||
-- which we will try to print in the most compact form necessary.
|
||||
@ -61,7 +61,7 @@ end
|
||||
--
|
||||
-- @tparam string text The string to construct a new document with.
|
||||
-- @tparam[opt] number colour The colour this text should be printed with. If not given, we default to the current
|
||||
-- colour.
|
||||
-- colour.
|
||||
-- @treturn Doc The document with the provided text.
|
||||
local function text(text, colour)
|
||||
expect(1, text, "string")
|
||||
@ -94,7 +94,7 @@ local function text(text, colour)
|
||||
end
|
||||
|
||||
--- Concatenate several documents together. This behaves very similar to string concatenation.
|
||||
|
||||
--
|
||||
-- @tparam Doc|string ... The documents to concatenate.
|
||||
-- @treturn Doc The concatenated documents.
|
||||
-- @usage pretty.concat(doc1, " - ", doc2)
|
||||
@ -113,7 +113,7 @@ local function concat(...)
|
||||
return setmetatable(args, Doc)
|
||||
end
|
||||
|
||||
Doc.__concat = concat
|
||||
Doc.__concat = concat --- @local
|
||||
|
||||
--- Indent later lines of the given document with the given number of spaces.
|
||||
--
|
||||
@ -121,7 +121,7 @@ Doc.__concat = concat
|
||||
-- ```txt
|
||||
-- foo
|
||||
-- bar
|
||||
-- ``
|
||||
-- ```
|
||||
-- by two spaces will produce
|
||||
-- ```txt
|
||||
-- foo
|
||||
@ -271,8 +271,9 @@ end
|
||||
--
|
||||
-- @tparam Doc doc The document to render.
|
||||
-- @tparam[opt] number width The maximum width of this document. Note that long strings will not be wrapped to
|
||||
-- fit this width - it is only used for finding the best layout.
|
||||
-- fit this width - it is only used for finding the best layout.
|
||||
-- @tparam[opt] number ribbon_frac The maximum fraction of the width that we should write in.
|
||||
-- @treturn string The rendered document as a string.
|
||||
local function render(doc, width, ribbon_frac)
|
||||
if getmetatable(doc) ~= Doc then expect(1, doc, "document") end
|
||||
expect(2, width, "number", "nil")
|
||||
@ -316,6 +317,8 @@ local function render(doc, width, ribbon_frac)
|
||||
return table.concat(out, "", 1, out.n)
|
||||
end
|
||||
|
||||
Doc.__tostring = render --- @local
|
||||
|
||||
local keywords = {
|
||||
[ "and" ] = true, [ "break" ] = true, [ "do" ] = true, [ "else" ] = true,
|
||||
[ "elseif" ] = true, [ "end" ] = true, [ "false" ] = true, [ "for" ] = true,
|
||||
|
@ -356,32 +356,33 @@ function expect_mt:called_with_matching(...)
|
||||
return called_with_check(matches, self, ...)
|
||||
end
|
||||
|
||||
local expect = setmetatable({
|
||||
--- Construct an expectation on the error message calling this function
|
||||
-- produces
|
||||
--
|
||||
-- @tparam fun The function to call
|
||||
-- @param ... The function arguments
|
||||
-- @return The new expectation
|
||||
error = function(fun, ...)
|
||||
local ok, res = pcall(fun, ...) local _, line = pcall(error, "", 2)
|
||||
if ok then fail("expected function to error") end
|
||||
if res:sub(1, #line) == line then
|
||||
res = res:sub(#line + 1)
|
||||
elseif res:sub(1, 7) == "pcall: " then
|
||||
res = res:sub(8)
|
||||
end
|
||||
return setmetatable({ value = res }, expect_mt)
|
||||
end,
|
||||
}, {
|
||||
--- Construct a new expectation from the provided value
|
||||
--
|
||||
-- @param value The value to apply assertions to
|
||||
-- @return The new expectation
|
||||
__call = function(_, value)
|
||||
return setmetatable({ value = value }, expect_mt)
|
||||
end,
|
||||
})
|
||||
local expect = {}
|
||||
setmetatable(expect, expect)
|
||||
|
||||
--- Construct an expectation on the error message calling this function
|
||||
-- produces
|
||||
--
|
||||
-- @tparam fun The function to call
|
||||
-- @param ... The function arguments
|
||||
-- @return The new expectation
|
||||
function expect.error(fun, ...)
|
||||
local ok, res = pcall(fun, ...) local _, line = pcall(error, "", 2)
|
||||
if ok then fail("expected function to error") end
|
||||
if res:sub(1, #line) == line then
|
||||
res = res:sub(#line + 1)
|
||||
elseif res:sub(1, 7) == "pcall: " then
|
||||
res = res:sub(8)
|
||||
end
|
||||
return setmetatable({ value = res }, expect_mt)
|
||||
end
|
||||
|
||||
--- Construct a new expectation from the provided value
|
||||
--
|
||||
-- @param value The value to apply assertions to
|
||||
-- @return The new expectation
|
||||
function expect:__call(value)
|
||||
return setmetatable({ value = value }, expect_mt)
|
||||
end
|
||||
|
||||
--- The stack of "describe"s.
|
||||
local test_stack = { n = 0 }
|
||||
@ -390,7 +391,8 @@ local test_stack = { n = 0 }
|
||||
local tests_locked = false
|
||||
|
||||
--- The list of tests that we'll run
|
||||
local test_list, test_map, test_count = { }, { }, 0
|
||||
local test_list = {}
|
||||
local test_map, test_count = {}, 0
|
||||
|
||||
--- Add a new test to our queue.
|
||||
--
|
||||
|
@ -163,7 +163,7 @@ describe("cc.pretty", function()
|
||||
end)
|
||||
|
||||
describe("pretty", function()
|
||||
--- We make use of "render" here, as it's considerably easier than checking against the actual structure.
|
||||
-- We make use of "render" here, as it's considerably easier than checking against the actual structure.
|
||||
-- However, it does also mean our tests are less unit-like.
|
||||
local function pretty(x, width) return pp.render(pp.pretty(x), width) end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user