Rewrite lua_eval result processing
This commit is contained in:
parent
cb66ca9741
commit
1b5c81679e
|
@ -6,6 +6,7 @@ local url = 'http://127.0.0.1:4343/'
|
|||
local tasks = {}
|
||||
local filters = {}
|
||||
local ycounts = {}
|
||||
local coparams = {}
|
||||
|
||||
ws = http.websocket(url..'ws/')
|
||||
if ws == false then
|
||||
|
@ -117,12 +118,13 @@ while true do
|
|||
ws_send{
|
||||
action='task_result',
|
||||
task_id=msg.task_id,
|
||||
result={fn()},
|
||||
result={fn(table.unpack(msg.params or {}))},
|
||||
yields=0,
|
||||
}
|
||||
else
|
||||
tasks[msg.task_id] = coroutine.create(fn)
|
||||
ycounts[msg.task_id] = 0
|
||||
coparams[msg.task_id] = msg.params or {}
|
||||
end
|
||||
end
|
||||
elseif msg.action == 'drop' then
|
||||
|
@ -130,6 +132,7 @@ while true do
|
|||
tasks[task_id] = nil
|
||||
filters[task_id] = nil
|
||||
ycounts[task_id] = nil
|
||||
coparams[task_id] = nil
|
||||
end
|
||||
elseif msg.action == 'sub' then
|
||||
event_sub[msg.event] = true
|
||||
|
@ -152,7 +155,13 @@ while true do
|
|||
local del_tasks = {}
|
||||
for task_id in pairs(tasks) do
|
||||
if filters[task_id] == nil or filters[task_id] == event then
|
||||
local r = {coroutine.resume(tasks[task_id], event, p1, p2, p3, p4, p5)}
|
||||
local r
|
||||
if coparams[task_id] ~= nil then
|
||||
r = {coroutine.resume(tasks[task_id], table.unpack(coparams[task_id]))}
|
||||
coparams[task_id] = nil
|
||||
else
|
||||
r = {coroutine.resume(tasks[task_id], event, p1, p2, p3, p4, p5)}
|
||||
end
|
||||
if coroutine.status(tasks[task_id]) == 'dead' then
|
||||
ws_send{
|
||||
action='task_result',
|
||||
|
@ -175,6 +184,7 @@ while true do
|
|||
tasks[task_id] = nil
|
||||
filters[task_id] = nil
|
||||
ycounts[task_id] = nil
|
||||
coparams[task_id] = nil
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -58,6 +58,8 @@ def lua_value(v):
|
|||
return 'true'
|
||||
if isinstance(v, str):
|
||||
return lua_string(v)
|
||||
if isinstance(v, bytes):
|
||||
return lua_string(v.decode('latin1'))
|
||||
if isinstance(v, (int, float)):
|
||||
return str(v)
|
||||
if isinstance(v, list):
|
||||
|
|
|
@ -1,6 +1,155 @@
|
|||
from .errors import LuaException
|
||||
|
||||
|
||||
def lua_table_to_list(x, length: int = None):
|
||||
if not x:
|
||||
return [] if length is None else [None] * length
|
||||
assert all(map(lambda k: isinstance(k, int), x.keys()))
|
||||
assert min(x.keys()) >= 1
|
||||
if length is not None:
|
||||
assert max(x.keys()) <= length
|
||||
else:
|
||||
length = max(x.keys())
|
||||
return [x.get(i + 1) for i in range(length)]
|
||||
|
||||
|
||||
class ResultProc:
|
||||
def __init__(self, result):
|
||||
self._v = result
|
||||
self._i = 1
|
||||
|
||||
def forward(self):
|
||||
self._i += 1
|
||||
|
||||
def back(self):
|
||||
self._i -= 1
|
||||
|
||||
def peek(self):
|
||||
return self._v.get(self._i)
|
||||
|
||||
def take(self):
|
||||
r = self.peek()
|
||||
self.forward()
|
||||
return r
|
||||
|
||||
def take_none(self):
|
||||
x = self.take()
|
||||
assert x is None
|
||||
return x
|
||||
|
||||
def take_bool(self):
|
||||
x = self.take()
|
||||
assert x is True or x is False
|
||||
return x
|
||||
|
||||
def take_int(self):
|
||||
x = self.take()
|
||||
assert isinstance(x, int)
|
||||
assert not isinstance(x, bool)
|
||||
return x
|
||||
|
||||
def take_number(self):
|
||||
x = self.take()
|
||||
assert isinstance(x, (int, float))
|
||||
assert not isinstance(x, bool)
|
||||
return x
|
||||
|
||||
def take_bytes(self):
|
||||
x = self.take()
|
||||
assert isinstance(x, bytes)
|
||||
return x
|
||||
|
||||
def take_string(self):
|
||||
return self.take_bytes().decode('latin1')
|
||||
|
||||
def take_unicode(self):
|
||||
return self.take_bytes().decode('utf-8')
|
||||
|
||||
def take_dict(self, keys=None):
|
||||
x = self.take()
|
||||
assert isinstance(x, dict)
|
||||
if keys is None:
|
||||
return x
|
||||
return TableProc(x, keys)
|
||||
|
||||
def take_list(self, length: int = None):
|
||||
return lua_table_to_list(self.take_dict(), length)
|
||||
|
||||
def check_bool_error(self):
|
||||
success = self.take_bool()
|
||||
if not success:
|
||||
raise LuaException(self.take_string())
|
||||
|
||||
def check_nil_error(self):
|
||||
if self.peek() is None:
|
||||
self.forward()
|
||||
raise LuaException(self.take_string())
|
||||
|
||||
def bool_error_exclude(self, exc_msg):
|
||||
success = self.take_bool()
|
||||
if success:
|
||||
return True
|
||||
msg = self.take_string()
|
||||
if msg == exc_msg:
|
||||
return False
|
||||
raise LuaException(msg)
|
||||
|
||||
def take_option_int(self):
|
||||
if self.peek() is None:
|
||||
return self.take_none()
|
||||
return self.take_int()
|
||||
|
||||
def take_option_bytes(self):
|
||||
if self.peek() is None:
|
||||
return self.take_none()
|
||||
return self.take_bytes()
|
||||
|
||||
def take_option_string(self):
|
||||
if self.peek() is None:
|
||||
return self.take_none()
|
||||
return self.take_string()
|
||||
|
||||
def take_option_unicode(self):
|
||||
if self.peek() is None:
|
||||
return self.take_none()
|
||||
return self.take_unicode()
|
||||
|
||||
def take_option_string_bool(self):
|
||||
p = self.peek()
|
||||
if p is None or p is True or p is False:
|
||||
self.forward()
|
||||
return p
|
||||
return self.take_string()
|
||||
|
||||
def take_list_of_strings(self, length: int = None):
|
||||
x = self.take_list(length)
|
||||
assert all(map(lambda v: isinstance(v, bytes), x))
|
||||
return [v.decode('latin1') for v in x]
|
||||
|
||||
def take_list_of_ints(self):
|
||||
x = self.take_list()
|
||||
assert all(map(lambda v: isinstance(v, int), x))
|
||||
return x
|
||||
|
||||
def take_2d_int(self):
|
||||
x = self.take_list()
|
||||
x = [lua_table_to_list(item) for item in x]
|
||||
for row in x:
|
||||
for item in row:
|
||||
assert isinstance(item, int)
|
||||
return x
|
||||
|
||||
|
||||
class TableProc(ResultProc):
|
||||
def __init__(self, result, keys):
|
||||
self._v = result
|
||||
self._keys = keys
|
||||
self._i = 0
|
||||
|
||||
def peek(self):
|
||||
return self._v.get(self._keys[self._i])
|
||||
|
||||
|
||||
def coro(result):
|
||||
assert isinstance(result, list)
|
||||
assert len(result) >= 1
|
||||
|
|
|
@ -21,6 +21,8 @@ def serialize(v: Any) -> bytes:
|
|||
return b'T'
|
||||
elif isinstance(v, (int, float)):
|
||||
return '[{}]'.format(v).encode(_ENC)
|
||||
elif isinstance(v, bytes):
|
||||
return '<{}>'.format(len(v)) + v
|
||||
elif isinstance(v, str):
|
||||
v = v.encode(_ENC)
|
||||
return '<{}>'.format(len(v)).encode(_ENC) + v
|
||||
|
@ -56,7 +58,7 @@ def _deserialize(b: bytes, _idx: int) -> Tuple[Any, int]:
|
|||
elif tok == 60: # <
|
||||
newidx = b.index(b'>', _idx)
|
||||
ln = int(b[_idx:newidx].decode(_ENC))
|
||||
return b[newidx + 1:newidx + 1 + ln].decode(_ENC), newidx + 1 + ln
|
||||
return b[newidx + 1:newidx + 1 + ln], newidx + 1 + ln
|
||||
elif tok == 123: # {
|
||||
r = {}
|
||||
while True:
|
||||
|
@ -67,12 +69,6 @@ def _deserialize(b: bytes, _idx: int) -> Tuple[Any, int]:
|
|||
key, _idx = _deserialize(b, _idx)
|
||||
value, _idx = _deserialize(b, _idx)
|
||||
r[key] = value
|
||||
if r:
|
||||
for i in range(1, len(r) + 1):
|
||||
if i not in r:
|
||||
break
|
||||
else:
|
||||
r = [r[i + 1] for i in range(len(r))]
|
||||
return r, _idx
|
||||
else:
|
||||
raise ValueError
|
||||
|
|
|
@ -25,7 +25,7 @@ class CCApplication(web.Application):
|
|||
async def _launch_program(self, ws):
|
||||
async for msg in self._bin_messages(ws):
|
||||
msg = ser.deserialize(msg)
|
||||
if msg['action'] != 'run':
|
||||
if msg[b'action'] != b'run':
|
||||
await ws.send_bytes(ser.serialize({
|
||||
'action': 'close',
|
||||
'error': 'protocol error',
|
||||
|
@ -36,9 +36,9 @@ class CCApplication(web.Application):
|
|||
sys.__stdout__.write('ws send ' + repr(data) + '\n')
|
||||
asyncio.create_task(ws.send_bytes(data))
|
||||
|
||||
sess = CCSession(msg['computer'], sender)
|
||||
if msg['args']:
|
||||
sess.run_program(msg['args'][0])
|
||||
sess = CCSession(msg[b'computer'], sender)
|
||||
if msg[b'args']:
|
||||
sess.run_program(msg[b'args'][1].decode('latin1'))
|
||||
else:
|
||||
sess.run_repl()
|
||||
return sess
|
||||
|
@ -51,10 +51,10 @@ class CCApplication(web.Application):
|
|||
if sess is not None:
|
||||
async for msg in self._bin_messages(ws):
|
||||
msg = ser.deserialize(msg)
|
||||
if msg['action'] == 'event':
|
||||
sess.on_event(msg['event'], msg['params'])
|
||||
elif msg['action'] == 'task_result':
|
||||
sess.on_task_result(msg['task_id'], msg['result'])
|
||||
if msg[b'action'] == b'event':
|
||||
sess.on_event(msg[b'event'].decode('latin1'), msg[b'params'])
|
||||
elif msg[b'action'] == b'task_result':
|
||||
sess.on_task_result(msg[b'task_id'].decode('latin1'), msg[b'result'])
|
||||
else:
|
||||
await ws.send_bytes(ser.serialize({
|
||||
'action': 'close',
|
||||
|
|
|
@ -73,22 +73,22 @@ class StdFileProxy:
|
|||
raise RuntimeError(
|
||||
"Computercraft environment doesn't support "
|
||||
"stdin readline method with parameter")
|
||||
return rproc.string(eval_lua(
|
||||
return eval_lua(
|
||||
return_lua_call('io.read')
|
||||
)) + '\n'
|
||||
).take_string() + '\n'
|
||||
|
||||
def write(self, s):
|
||||
if _is_global_greenlet():
|
||||
return self._native.write(s)
|
||||
else:
|
||||
if self._err:
|
||||
return rproc.nil(eval_lua(
|
||||
return eval_lua(
|
||||
lua_call('io.stderr:write', s)
|
||||
))
|
||||
).take_none()
|
||||
else:
|
||||
return rproc.nil(eval_lua(
|
||||
return eval_lua(
|
||||
lua_call('io.write', s)
|
||||
))
|
||||
).take_none()
|
||||
|
||||
def fileno(self):
|
||||
if _is_global_greenlet():
|
||||
|
@ -147,9 +147,10 @@ def eval_lua(lua_code, immediate=False):
|
|||
})
|
||||
result = get_current_session()._server_greenlet.switch(request)
|
||||
# debug('{} → {}'.format(lua_code, repr(result)))
|
||||
rp = rproc.ResultProc(result)
|
||||
if not immediate:
|
||||
result = rproc.coro(result)
|
||||
return result
|
||||
rp.check_bool_error()
|
||||
return rp
|
||||
|
||||
|
||||
@contextmanager
|
||||
|
@ -342,7 +343,7 @@ class CCSession:
|
|||
|
||||
def run_program(self, program):
|
||||
def _run_program():
|
||||
p, code = eval_lua('''
|
||||
rp = eval_lua('''
|
||||
local p = fs.combine(shell.dir(), {})
|
||||
if not fs.exists(p) then return nil end
|
||||
if fs.isDir(p) then return nil end
|
||||
|
@ -351,6 +352,8 @@ local code = f.readAll()
|
|||
f.close()
|
||||
return p, code
|
||||
'''.lstrip().format(lua_string(program)))
|
||||
p = rp.take_string()
|
||||
code = rp.take_string()
|
||||
cc = compile(code, p, 'exec')
|
||||
exec(cc, {'__file__': p})
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ from types import ModuleType
|
|||
|
||||
from ..errors import LuaException
|
||||
from ..lua import lua_string
|
||||
from ..rproc import boolean, option_string
|
||||
from ..sess import eval_lua
|
||||
|
||||
|
||||
|
@ -26,7 +25,7 @@ def import_file(path: str, relative_to: str = None):
|
|||
lua_string(relative_to),
|
||||
path_expr,
|
||||
)
|
||||
source = option_string(eval_lua('''
|
||||
source = eval_lua('''
|
||||
local p = {}
|
||||
if not fs.exists(p) then return nil end
|
||||
if fs.isDir(p) then return nil end
|
||||
|
@ -36,7 +35,7 @@ f.close()
|
|||
return src
|
||||
'''.lstrip().format(
|
||||
path_expr,
|
||||
)))
|
||||
)).take_option_string()
|
||||
if source is None:
|
||||
raise ImportError('File not found: {}'.format(path))
|
||||
cc = compile(source, mod.__name__, 'exec')
|
||||
|
@ -45,16 +44,16 @@ return src
|
|||
|
||||
|
||||
def is_commands() -> bool:
|
||||
return boolean(eval_lua('return commands ~= nil'))
|
||||
return eval_lua('return commands ~= nil').take_bool()
|
||||
|
||||
|
||||
def is_multishell() -> bool:
|
||||
return boolean(eval_lua('return multishell ~= nil'))
|
||||
return eval_lua('return multishell ~= nil').take_bool()
|
||||
|
||||
|
||||
def is_turtle() -> bool:
|
||||
return boolean(eval_lua('return turtle ~= nil'))
|
||||
return eval_lua('return turtle ~= nil').take_bool()
|
||||
|
||||
|
||||
def is_pocket() -> bool:
|
||||
return boolean(eval_lua('return pocket ~= nil'))
|
||||
return eval_lua('return pocket ~= nil').take_bool()
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
from typing import Tuple
|
||||
|
||||
from ..rproc import boolean, integer, tuple3_number
|
||||
from ..sess import eval_lua_method_factory
|
||||
|
||||
|
||||
|
@ -55,23 +54,24 @@ black = 0x8000
|
|||
# combine, subtract and test are mostly for redstone.setBundledOutput
|
||||
|
||||
def combine(*colors: int) -> int:
|
||||
return integer(method('combine', *colors))
|
||||
return method('combine', *colors).take_int()
|
||||
|
||||
|
||||
def subtract(color_set: int, *colors: int) -> int:
|
||||
return integer(method('subtract', color_set, *colors))
|
||||
return method('subtract', color_set, *colors).take_int()
|
||||
|
||||
|
||||
def test(colors: int, color: int) -> bool:
|
||||
return boolean(method('test', colors, color))
|
||||
return method('test', colors, color).take_bool()
|
||||
|
||||
|
||||
def packRGB(r: float, g: float, b: float) -> int:
|
||||
return integer(method('packRGB', r, g, b))
|
||||
return method('packRGB', r, g, b).take_int()
|
||||
|
||||
|
||||
def unpackRGB(rgb: int) -> Tuple[float, float, float]:
|
||||
return tuple3_number(method('unpackRGB', rgb))
|
||||
rp = method('unpackRGB', rgb)
|
||||
return tuple(rp.take_number() for _ in range(3))
|
||||
|
||||
|
||||
# use these chars for term.blit
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
from typing import Tuple, List, Optional
|
||||
|
||||
from ..rproc import tuple3_integer, any_dict, any_list, array_string, fact_tuple, boolean, option_integer
|
||||
from ..sess import eval_lua_method_factory
|
||||
|
||||
|
||||
command_result = fact_tuple(boolean, array_string, option_integer, tail_nils=1)
|
||||
method = eval_lua_method_factory('commands.')
|
||||
|
||||
|
||||
|
@ -18,20 +16,25 @@ __all__ = (
|
|||
|
||||
|
||||
def exec(command: str) -> Tuple[bool, List[str], Optional[int]]:
|
||||
return command_result(method('exec', command))
|
||||
rp = method('exec', command)
|
||||
success = rp.take_bool()
|
||||
log = rp.take_list_of_strings()
|
||||
n = rp.take_option_int()
|
||||
return success, log, n
|
||||
|
||||
|
||||
def list() -> List[str]:
|
||||
return array_string(method('list'))
|
||||
return method('list').take_list_of_strings()
|
||||
|
||||
|
||||
def getBlockPosition() -> Tuple[int, int, int]:
|
||||
return tuple3_integer(method('getBlockPosition'))
|
||||
rp = method('getBlockPosition')
|
||||
return tuple(rp.take_int() for _ in range(3))
|
||||
|
||||
|
||||
def getBlockInfo(x: int, y: int, z: int) -> dict:
|
||||
return any_dict(method('getBlockInfo', x, y, z))
|
||||
return method('getBlockInfo', x, y, z).take_dict()
|
||||
|
||||
|
||||
def getBlockInfos(x1: int, y1: int, z1: int, x2: int, y2: int, z2: int) -> List[dict]:
|
||||
return any_list(method('getBlockInfos', x1, y1, z1, x2, y2, z2))
|
||||
return method('getBlockInfos', x1, y1, z1, x2, y2, z2).take_list()
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
from typing import Optional, Union
|
||||
|
||||
from ..rproc import boolean, nil, option_integer, option_string, option_string_bool
|
||||
from ..sess import eval_lua_method_factory
|
||||
|
||||
|
||||
|
@ -23,44 +22,44 @@ __all__ = (
|
|||
|
||||
|
||||
def isPresent(side: str) -> bool:
|
||||
return boolean(method('isPresent', side))
|
||||
return method('isPresent', side).take_bool()
|
||||
|
||||
|
||||
def hasData(side: str) -> bool:
|
||||
return boolean(method('hasData', side))
|
||||
return method('hasData', side).take_bool()
|
||||
|
||||
|
||||
def getMountPath(side: str) -> Optional[str]:
|
||||
return option_string(method('getMountPath', side))
|
||||
return method('getMountPath', side).take_option_string()
|
||||
|
||||
|
||||
def setLabel(side: str, label: str):
|
||||
return nil(method('setLabel', side, label))
|
||||
return method('setLabel', side, label).take_none()
|
||||
|
||||
|
||||
def getLabel(side: str) -> Optional[str]:
|
||||
return option_string(method('getLabel', side))
|
||||
return method('getLabel', side).take_option_string()
|
||||
|
||||
|
||||
def getID(side: str) -> Optional[int]:
|
||||
return option_integer(method('getID', side))
|
||||
return method('getID', side).take_option_int()
|
||||
|
||||
|
||||
def hasAudio(side: str) -> bool:
|
||||
return boolean(method('hasAudio', side))
|
||||
return method('hasAudio', side).take_bool()
|
||||
|
||||
|
||||
def getAudioTitle(side: str) -> Optional[Union[bool, str]]:
|
||||
return option_string_bool(method('getAudioTitle', side))
|
||||
return method('getAudioTitle', side).take_option_string_bool()
|
||||
|
||||
|
||||
def playAudio(side: str):
|
||||
return nil(method('playAudio', side))
|
||||
return method('playAudio', side).take_none()
|
||||
|
||||
|
||||
def stopAudio(side: str):
|
||||
return nil(method('stopAudio', side))
|
||||
return method('stopAudio', side).take_none()
|
||||
|
||||
|
||||
def eject(side: str):
|
||||
return nil(method('eject', side))
|
||||
return method('eject', side).take_none()
|
||||
|
|
|
@ -1,55 +1,31 @@
|
|||
import builtins
|
||||
from contextlib import contextmanager
|
||||
from typing import Optional, List
|
||||
|
||||
from .base import BaseSubAPI
|
||||
from ..errors import LuaException
|
||||
from ..lua import lua_call, lua_args, lua_string
|
||||
from ..rproc import boolean, string, integer, nil, array_string, option_string, fact_scheme_dict
|
||||
from ..sess import eval_lua, eval_lua_method_factory, lua_context_object
|
||||
|
||||
|
||||
attribute = fact_scheme_dict({
|
||||
'created': integer,
|
||||
'modification': integer,
|
||||
'isDir': boolean,
|
||||
'size': integer,
|
||||
}, {})
|
||||
from ..lua import lua_call
|
||||
from ..sess import eval_lua_method_factory, lua_context_object
|
||||
|
||||
|
||||
class SeekMixin:
|
||||
def seek(self, whence: str = None, offset: int = None) -> int:
|
||||
# whence: set, cur, end
|
||||
r = self._method('seek', whence, offset)
|
||||
if isinstance(r, builtins.list):
|
||||
assert r[0] is False
|
||||
raise LuaException(r[1])
|
||||
return integer(r)
|
||||
rp = self._method('seek', whence, offset)
|
||||
rp.check_nil_error()
|
||||
return rp.take_int()
|
||||
|
||||
|
||||
class ReadHandle(BaseSubAPI):
|
||||
def _decode(self, b):
|
||||
return b.decode('utf-8')
|
||||
|
||||
def _read(self, name, params, val):
|
||||
code = '''
|
||||
local s = {}.{}({})
|
||||
if s == nil then return nil end
|
||||
s = s:gsub('.', function(c) return string.format('%02X', string.byte(c)) end)
|
||||
return s
|
||||
'''.lstrip().format(
|
||||
self.get_expr_code(), name, lua_args(*params),
|
||||
)
|
||||
return self._decode(bytes.fromhex(val(eval_lua(code))))
|
||||
class ReadMixin:
|
||||
def _take(self, rp):
|
||||
raise NotImplementedError
|
||||
|
||||
def read(self, count: int = 1) -> Optional[str]:
|
||||
return self._read('read', (count, ), option_string)
|
||||
return self._take(self._method('read', count))
|
||||
|
||||
def readLine(self) -> Optional[str]:
|
||||
return self._read('readLine', (), option_string)
|
||||
def readLine(self, withTrailing: bool = False) -> Optional[str]:
|
||||
return self._take(self._method('readLine', withTrailing))
|
||||
|
||||
def readAll(self) -> str:
|
||||
return self._read('readAll', (), string)
|
||||
def readAll(self) -> Optional[str]:
|
||||
return self._take(self._method('readAll'))
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
@ -61,39 +37,38 @@ return s
|
|||
return line
|
||||
|
||||
|
||||
class BinaryReadHandle(ReadHandle, SeekMixin):
|
||||
def _decode(self, b):
|
||||
return b
|
||||
|
||||
|
||||
class WriteHandle(BaseSubAPI):
|
||||
def _encode(self, s):
|
||||
return s.encode('utf-8')
|
||||
|
||||
def _write(self, name, text, val):
|
||||
code = '''
|
||||
local s = {}
|
||||
s = s:gsub('..', function(cc) return string.char(tonumber(cc, 16)) end)
|
||||
return {}.{}(s)
|
||||
'''.lstrip().format(
|
||||
lua_string(self._encode(text).hex()),
|
||||
self.get_expr_code(), name,
|
||||
)
|
||||
return val(eval_lua(code))
|
||||
class WriteMixin:
|
||||
def _put(self, t):
|
||||
raise NotImplementedError
|
||||
|
||||
def write(self, text: str):
|
||||
return nil(self._method('write', text))
|
||||
|
||||
def writeLine(self, text: str):
|
||||
return nil(self._method('writeLine', text))
|
||||
return self._method('write', self._put(text)).take_none()
|
||||
|
||||
def flush(self):
|
||||
return nil(self._method('flush'))
|
||||
return self._method('flush').take_none()
|
||||
|
||||
|
||||
class BinaryWriteHandle(WriteHandle, SeekMixin):
|
||||
def _encode(self, s):
|
||||
return s
|
||||
class ReadHandle(ReadMixin, BaseSubAPI):
|
||||
def _take(self, rp):
|
||||
return rp.take_option_unicode()
|
||||
|
||||
|
||||
class BinaryReadHandle(ReadMixin, SeekMixin, BaseSubAPI):
|
||||
def _take(self, rp):
|
||||
return rp.take_option_bytes()
|
||||
|
||||
|
||||
class WriteHandle(WriteMixin, BaseSubAPI):
|
||||
def _put(self, t: str) -> bytes:
|
||||
return t.encode('utf-8')
|
||||
|
||||
def writeLine(self, text: str):
|
||||
return self.write(text + '\n')
|
||||
|
||||
|
||||
class BinaryWriteHandle(WriteMixin, SeekMixin, BaseSubAPI):
|
||||
def _put(self, b: bytes) -> bytes:
|
||||
return b
|
||||
|
||||
|
||||
method = eval_lua_method_factory('fs.')
|
||||
|
@ -124,55 +99,55 @@ __all__ = (
|
|||
|
||||
|
||||
def list(path: str) -> List[str]:
|
||||
return array_string(method('list', path))
|
||||
return method('list', path).take_list_of_strings()
|
||||
|
||||
|
||||
def exists(path: str) -> bool:
|
||||
return boolean(method('exists', path))
|
||||
return method('exists', path).take_bool()
|
||||
|
||||
|
||||
def isDir(path: str) -> bool:
|
||||
return boolean(method('isDir', path))
|
||||
return method('isDir', path).take_bool()
|
||||
|
||||
|
||||
def isReadOnly(path: str) -> bool:
|
||||
return boolean(method('isReadOnly', path))
|
||||
return method('isReadOnly', path).take_bool()
|
||||
|
||||
|
||||
def getDrive(path: str) -> Optional[str]:
|
||||
return option_string(method('getDrive', path))
|
||||
return method('getDrive', path).take_option_string()
|
||||
|
||||
|
||||
def getSize(path: str) -> int:
|
||||
return integer(method('getSize', path))
|
||||
return method('getSize', path).take_int()
|
||||
|
||||
|
||||
def getFreeSpace(path: str) -> int:
|
||||
return integer(method('getFreeSpace', path))
|
||||
return method('getFreeSpace', path).take_int()
|
||||
|
||||
|
||||
def getCapacity(path: str) -> int:
|
||||
return integer(method('getCapacity', path))
|
||||
return method('getCapacity', path).take_int()
|
||||
|
||||
|
||||
def makeDir(path: str):
|
||||
return nil(method('makeDir', path))
|
||||
return method('makeDir', path).take_none()
|
||||
|
||||
|
||||
def move(fromPath: str, toPath: str):
|
||||
return nil(method('move', fromPath, toPath))
|
||||
return method('move', fromPath, toPath).take_none()
|
||||
|
||||
|
||||
def copy(fromPath: str, toPath: str):
|
||||
return nil(method('copy', fromPath, toPath))
|
||||
return method('copy', fromPath, toPath).take_none()
|
||||
|
||||
|
||||
def delete(path: str):
|
||||
return nil(method('delete', path))
|
||||
return method('delete', path).take_none()
|
||||
|
||||
|
||||
def combine(basePath: str, localPath: str) -> str:
|
||||
return string(method('combine', basePath, localPath))
|
||||
return method('combine', basePath, localPath).take_string()
|
||||
|
||||
|
||||
@contextmanager
|
||||
|
@ -199,27 +174,39 @@ def open(path: str, mode: str):
|
|||
|
||||
|
||||
def find(wildcard: str) -> List[str]:
|
||||
return array_string(method('find', wildcard))
|
||||
return method('find', wildcard).take_list_of_strings()
|
||||
|
||||
|
||||
def getDir(path: str) -> str:
|
||||
return string(method('getDir', path))
|
||||
return method('getDir', path).take_string()
|
||||
|
||||
|
||||
def getName(path: str) -> str:
|
||||
return string(method('getName', path))
|
||||
return method('getName', path).take_string()
|
||||
|
||||
|
||||
def isDriveRoot(path: str) -> bool:
|
||||
return boolean(method('isDriveRoot', path))
|
||||
return method('isDriveRoot', path).take_bool()
|
||||
|
||||
|
||||
def complete(
|
||||
partialName: str, path: str, includeFiles: bool = None, includeDirs: bool = None,
|
||||
) -> List[str]:
|
||||
return array_string(method(
|
||||
'complete', partialName, path, includeFiles, includeDirs))
|
||||
return method(
|
||||
'complete', partialName, path, includeFiles, includeDirs,
|
||||
).take_list_of_strings()
|
||||
|
||||
|
||||
def attributes(path: str) -> dict:
|
||||
return attribute(method('attributes', path))
|
||||
tp = method('attributes', path).take_dict((
|
||||
b'created',
|
||||
b'modification',
|
||||
b'isDir',
|
||||
b'size',
|
||||
))
|
||||
r = {}
|
||||
r['created'] = tp.take_int()
|
||||
r['modification'] = tp.take_int()
|
||||
r['isDir'] = tp.take_bool()
|
||||
r['size'] = tp.take_int()
|
||||
return r
|
||||
|
|
|
@ -19,4 +19,7 @@ CHANNEL_GPS = 65534
|
|||
|
||||
|
||||
def locate(timeout: LuaNum = None, debug: bool = None) -> Optional[Tuple[LuaNum, LuaNum, LuaNum]]:
|
||||
return option_tuple3_number(method('locate', timeout, debug))
|
||||
rp = method('locate', timeout, debug)
|
||||
if rp.peek() is None:
|
||||
return None
|
||||
return tuple(rp.take_number() for _ in range(3))
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
from typing import Optional, List
|
||||
|
||||
from ..rproc import string, nil, array_string, option_string
|
||||
from ..sess import eval_lua_method_factory
|
||||
|
||||
|
||||
|
@ -17,20 +16,20 @@ __all__ = (
|
|||
|
||||
|
||||
def path() -> str:
|
||||
return string(method('path'))
|
||||
return method('path').take_string()
|
||||
|
||||
|
||||
def setPath(path: str):
|
||||
return nil(method('setPath', path))
|
||||
return method('setPath', path).take_none()
|
||||
|
||||
|
||||
def lookup(topic: str) -> Optional[str]:
|
||||
return option_string(method('lookup', topic))
|
||||
return method('lookup', topic).take_option_string()
|
||||
|
||||
|
||||
def topics() -> List[str]:
|
||||
return array_string(method('topics'))
|
||||
return method('topics').take_list_of_strings()
|
||||
|
||||
|
||||
def completeTopic(topicPrefix: str) -> List[str]:
|
||||
return array_string(method('completeTopic', topicPrefix))
|
||||
return method('completeTopic', topicPrefix).take_list_of_strings()
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
from typing import Optional
|
||||
|
||||
from ..lua import lua_string
|
||||
from ..rproc import option_integer, option_string
|
||||
from ..sess import eval_lua, eval_lua_method_factory
|
||||
|
||||
|
||||
|
@ -17,12 +16,12 @@ __all__ = (
|
|||
def getCode(name: str) -> Optional[int]:
|
||||
# replaces properties
|
||||
# keys.space → keys.getCode('space')
|
||||
return option_integer(eval_lua('''
|
||||
return eval_lua('''
|
||||
if type(keys[{key}]) == 'number' then
|
||||
return keys[{key}]
|
||||
end
|
||||
return nil'''.format(key=lua_string(name))))
|
||||
return nil'''.format(key=lua_string(name))).take_option_int()
|
||||
|
||||
|
||||
def getName(code: int) -> Optional[str]:
|
||||
return option_string(method('getName', code))
|
||||
return method('getName', code).take_option_string()
|
||||
|
|
|
@ -1,60 +1,62 @@
|
|||
from typing import Tuple
|
||||
|
||||
from ..lua import LuaExpr
|
||||
from ..rproc import boolean, nil, integer, tuple3_number, tuple2_integer
|
||||
|
||||
|
||||
class TermMixin:
|
||||
def write(self, text: str):
|
||||
return nil(self._method('write', text))
|
||||
return self._method('write', text).take_none()
|
||||
|
||||
def blit(self, text: str, textColors: str, backgroundColors: str):
|
||||
return nil(self._method('blit', text, textColors, backgroundColors))
|
||||
return self._method('blit', text, textColors, backgroundColors).take_none()
|
||||
|
||||
def clear(self):
|
||||
return nil(self._method('clear'))
|
||||
return self._method('clear').take_none()
|
||||
|
||||
def clearLine(self):
|
||||
return nil(self._method('clearLine'))
|
||||
return self._method('clearLine').take_none()
|
||||
|
||||
def getCursorPos(self) -> Tuple[int, int]:
|
||||
return tuple2_integer(self._method('getCursorPos'))
|
||||
rp = self._method('getCursorPos')
|
||||
return tuple(rp.take_int() for _ in range(2))
|
||||
|
||||
def setCursorPos(self, x: int, y: int):
|
||||
return nil(self._method('setCursorPos', x, y))
|
||||
return self._method('setCursorPos', x, y).take_none()
|
||||
|
||||
def getCursorBlink(self) -> bool:
|
||||
return boolean(self._method('getCursorBlink'))
|
||||
return self._method('getCursorBlink').take_bool()
|
||||
|
||||
def setCursorBlink(self, value: bool):
|
||||
return nil(self._method('setCursorBlink', value))
|
||||
return self._method('setCursorBlink', value).take_none()
|
||||
|
||||
def isColor(self) -> bool:
|
||||
return boolean(self._method('isColor'))
|
||||
return self._method('isColor').take_bool()
|
||||
|
||||
def getSize(self) -> Tuple[int, int]:
|
||||
return tuple2_integer(self._method('getSize'))
|
||||
rp = self._method('getSize')
|
||||
return tuple(rp.take_int() for _ in range(2))
|
||||
|
||||
def scroll(self, lines: int):
|
||||
return nil(self._method('scroll', lines))
|
||||
return self._method('scroll', lines).take_none()
|
||||
|
||||
def setTextColor(self, colorID: int):
|
||||
return nil(self._method('setTextColor', colorID))
|
||||
return self._method('setTextColor', colorID).take_none()
|
||||
|
||||
def getTextColor(self) -> int:
|
||||
return integer(self._method('getTextColor'))
|
||||
return self._method('getTextColor').take_int()
|
||||
|
||||
def setBackgroundColor(self, colorID: int):
|
||||
return nil(self._method('setBackgroundColor', colorID))
|
||||
return self._method('setBackgroundColor', colorID).take_none()
|
||||
|
||||
def getBackgroundColor(self) -> int:
|
||||
return integer(self._method('getBackgroundColor'))
|
||||
return self._method('getBackgroundColor').take_int()
|
||||
|
||||
def getPaletteColor(self, colorID: int) -> Tuple[float, float, float]:
|
||||
return tuple3_number(self._method('getPaletteColor', colorID))
|
||||
rp = self._method('getPaletteColor', colorID)
|
||||
return tuple(rp.take_number() for _ in range(3))
|
||||
|
||||
def setPaletteColor(self, colorID: int, r: float, g: float, b: float):
|
||||
return nil(self._method('setPaletteColor', colorID, r, g, b))
|
||||
return self._method('setPaletteColor', colorID, r, g, b).take_none()
|
||||
|
||||
|
||||
class TermTarget(LuaExpr):
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
from typing import Optional
|
||||
|
||||
from ..rproc import integer, nil, boolean, option_string
|
||||
from ..sess import eval_lua_method_factory
|
||||
|
||||
|
||||
|
@ -19,28 +18,28 @@ __all__ = (
|
|||
|
||||
|
||||
def getCurrent() -> int:
|
||||
return integer(method('getCurrent'))
|
||||
return method('getCurrent').take_int()
|
||||
|
||||
|
||||
def getCount() -> int:
|
||||
return integer(method('getCount'))
|
||||
return method('getCount').take_int()
|
||||
|
||||
|
||||
def launch(environment: dict, programPath: str, *args: str) -> int:
|
||||
return integer(method('launch', environment, programPath, *args))
|
||||
return method('launch', environment, programPath, *args).take_int()
|
||||
|
||||
|
||||
def setTitle(tabID: int, title: str):
|
||||
return nil(method('setTitle', tabID, title))
|
||||
return method('setTitle', tabID, title).take_none()
|
||||
|
||||
|
||||
def getTitle(tabID: int) -> Optional[str]:
|
||||
return option_string(method('getTitle', tabID))
|
||||
return method('getTitle', tabID).take_option_string()
|
||||
|
||||
|
||||
def setFocus(tabID: int) -> bool:
|
||||
return boolean(method('setFocus', tabID))
|
||||
return method('setFocus', tabID).take_bool()
|
||||
|
||||
|
||||
def getFocus() -> int:
|
||||
return integer(method('getFocus'))
|
||||
return method('getFocus').take_int()
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
from typing import Optional, List
|
||||
|
||||
from ..lua import LuaNum
|
||||
from ..rproc import nil, string, option_string, number, integer, boolean
|
||||
from ..sess import eval_lua_method_factory, get_current_greenlet
|
||||
|
||||
|
||||
|
@ -31,23 +30,23 @@ __all__ = (
|
|||
|
||||
|
||||
def version() -> str:
|
||||
return string(method('version'))
|
||||
return method('version').take_string()
|
||||
|
||||
|
||||
def getComputerID() -> int:
|
||||
return integer(method('getComputerID'))
|
||||
return method('getComputerID').take_int()
|
||||
|
||||
|
||||
def getComputerLabel() -> Optional[str]:
|
||||
return option_string(method('getComputerLabel'))
|
||||
return method('getComputerLabel').take_option_string()
|
||||
|
||||
|
||||
def setComputerLabel(label: Optional[str]):
|
||||
return nil(method('setComputerLabel', label))
|
||||
return method('setComputerLabel', label).take_none()
|
||||
|
||||
|
||||
def run(environment: dict, programPath: str, *args: List[str]):
|
||||
return boolean(method('run', environment, programPath, *args))
|
||||
return method('run', environment, programPath, *args).take_bool()
|
||||
|
||||
|
||||
def captureEvent(event: str):
|
||||
|
@ -68,12 +67,12 @@ def captureEvent(event: str):
|
|||
|
||||
|
||||
def queueEvent(event: str, *params):
|
||||
return nil(method('queueEvent', event, *params))
|
||||
return method('queueEvent', event, *params).take_none()
|
||||
|
||||
|
||||
def clock() -> LuaNum:
|
||||
# number of game ticks * 0.05, roughly seconds
|
||||
return number(method('clock'))
|
||||
return method('clock').take_number()
|
||||
|
||||
|
||||
# regarding ingame parameter below:
|
||||
|
@ -82,42 +81,42 @@ def clock() -> LuaNum:
|
|||
|
||||
def time() -> LuaNum:
|
||||
# in hours 0..24
|
||||
return number(method('time', 'ingame'))
|
||||
return method('time', 'ingame').take_number()
|
||||
|
||||
|
||||
def day() -> int:
|
||||
return integer(method('day', 'ingame'))
|
||||
return method('day', 'ingame').take_int()
|
||||
|
||||
|
||||
def epoch() -> int:
|
||||
return integer(method('epoch', 'ingame'))
|
||||
return method('epoch', 'ingame').take_int()
|
||||
|
||||
|
||||
def sleep(seconds: LuaNum):
|
||||
return nil(method('sleep', seconds))
|
||||
return method('sleep', seconds).take_none()
|
||||
|
||||
|
||||
def startTimer(timeout: LuaNum) -> int:
|
||||
return integer(method('startTimer', timeout))
|
||||
return method('startTimer', timeout).take_int()
|
||||
|
||||
|
||||
def cancelTimer(timerID: int):
|
||||
return nil(method('cancelTimer', timerID))
|
||||
return method('cancelTimer', timerID).take_none()
|
||||
|
||||
|
||||
def setAlarm(time: LuaNum) -> int:
|
||||
# takes time of the day in hours 0..24
|
||||
# returns integer alarmID
|
||||
return integer(method('setAlarm', time))
|
||||
return method('setAlarm', time).take_int()
|
||||
|
||||
|
||||
def cancelAlarm(alarmID: int):
|
||||
return nil(method('cancelAlarm', alarmID))
|
||||
return method('cancelAlarm', alarmID).take_none()
|
||||
|
||||
|
||||
def shutdown():
|
||||
return nil(method('shutdown'))
|
||||
return method('shutdown').take_none()
|
||||
|
||||
|
||||
def reboot():
|
||||
return nil(method('reboot'))
|
||||
return method('reboot').take_none()
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
from typing import List
|
||||
|
||||
from ..rproc import nil, integer, fact_array
|
||||
from ..sess import eval_lua_method_factory
|
||||
|
||||
|
||||
array_2d_integer = fact_array(fact_array(integer))
|
||||
method = eval_lua_method_factory('paintutils.')
|
||||
|
||||
|
||||
|
@ -20,28 +18,28 @@ __all__ = (
|
|||
|
||||
|
||||
def parseImage(data: str) -> List[List[int]]:
|
||||
return array_2d_integer(method('parseImage', data))
|
||||
return method('parseImage', data).take_2d_int()
|
||||
|
||||
|
||||
def loadImage(path: str) -> List[List[int]]:
|
||||
return array_2d_integer(method('loadImage', path))
|
||||
return method('loadImage', path).take_2d_int()
|
||||
|
||||
|
||||
def drawPixel(x: int, y: int, color: int = None):
|
||||
return nil(method('drawPixel', x, y, color))
|
||||
return method('drawPixel', x, y, color).take_none()
|
||||
|
||||
|
||||
def drawLine(startX: int, startY: int, endX: int, endY: int, color: int = None):
|
||||
return nil(method('drawLine', startX, startY, endX, endY, color))
|
||||
return method('drawLine', startX, startY, endX, endY, color).take_none()
|
||||
|
||||
|
||||
def drawBox(startX: int, startY: int, endX: int, endY: int, color: int = None):
|
||||
return nil(method('drawBox', startX, startY, endX, endY, color))
|
||||
return method('drawBox', startX, startY, endX, endY, color).take_none()
|
||||
|
||||
|
||||
def drawFilledBox(startX: int, startY: int, endX: int, endY: int, color: int = None):
|
||||
return nil(method('drawFilledBox', startX, startY, endX, endY, color))
|
||||
return method('drawFilledBox', startX, startY, endX, endY, color).take_none()
|
||||
|
||||
|
||||
def drawImage(image: List[List[int]], xPos: int, yPos: int):
|
||||
return nil(method('drawImage', image, xPos, yPos))
|
||||
return method('drawImage', image, xPos, yPos).take_none()
|
||||
|
|
|
@ -2,12 +2,7 @@ from dataclasses import dataclass
|
|||
from typing import Optional, List, Tuple, Any, Union
|
||||
|
||||
from .mixins import TermMixin, TermTarget
|
||||
from .turtle import craft_result
|
||||
from ..lua import LuaNum, lua_args, return_lua_call
|
||||
from ..rproc import (
|
||||
boolean, nil, integer, string, option_integer, option_string,
|
||||
tuple2_integer, array_string, option_string_bool, flat_try_result,
|
||||
)
|
||||
from ..sess import eval_lua, eval_lua_method_factory
|
||||
|
||||
|
||||
|
@ -28,65 +23,65 @@ class BasePeripheral:
|
|||
|
||||
class CCDrive(BasePeripheral):
|
||||
def isDiskPresent(self) -> bool:
|
||||
return boolean(self._method('isDiskPresent'))
|
||||
return self._method('isDiskPresent').take_bool()
|
||||
|
||||
def getDiskLabel(self) -> Optional[str]:
|
||||
return option_string(self._method('getDiskLabel'))
|
||||
return self._method('getDiskLabel').take_option_string()
|
||||
|
||||
def setDiskLabel(self, label: str):
|
||||
return nil(self._method('setDiskLabel', label))
|
||||
return self._method('setDiskLabel', label).take_none()
|
||||
|
||||
def hasData(self) -> bool:
|
||||
return boolean(self._method('hasData'))
|
||||
return self._method('hasData').take_bool()
|
||||
|
||||
def getMountPath(self) -> Optional[str]:
|
||||
return option_string(self._method('getMountPath'))
|
||||
return self._method('getMountPath').take_option_string()
|
||||
|
||||
def hasAudio(self) -> bool:
|
||||
return boolean(self._method('hasAudio'))
|
||||
return self._method('hasAudio').take_bool()
|
||||
|
||||
def getAudioTitle(self) -> Optional[Union[bool, str]]:
|
||||
return option_string_bool(self._method('getAudioTitle'))
|
||||
return self._method('getAudioTitle').take_option_string_bool()
|
||||
|
||||
def playAudio(self):
|
||||
return nil(self._method('playAudio'))
|
||||
return self._method('playAudio').take_none()
|
||||
|
||||
def stopAudio(self):
|
||||
return nil(self._method('stopAudio'))
|
||||
return self._method('stopAudio').take_none()
|
||||
|
||||
def ejectDisk(self):
|
||||
return nil(self._method('ejectDisk'))
|
||||
return self._method('ejectDisk').take_none()
|
||||
|
||||
def getDiskID(self) -> Optional[int]:
|
||||
return option_integer(self._method('getDiskID'))
|
||||
return self._method('getDiskID').take_option_int()
|
||||
|
||||
|
||||
class CCMonitor(BasePeripheral, TermMixin):
|
||||
def getTextScale(self) -> int:
|
||||
return integer(self._method('getTextScale'))
|
||||
return self._method('getTextScale').take_int()
|
||||
|
||||
def setTextScale(self, scale: int):
|
||||
return nil(self._method('setTextScale', scale))
|
||||
return self._method('setTextScale', scale).take_none()
|
||||
|
||||
|
||||
class ComputerMixin:
|
||||
def turnOn(self):
|
||||
return nil(self._method('turnOn'))
|
||||
return self._method('turnOn').take_none()
|
||||
|
||||
def shutdown(self):
|
||||
return nil(self._method('shutdown'))
|
||||
return self._method('shutdown').take_none()
|
||||
|
||||
def reboot(self):
|
||||
return nil(self._method('reboot'))
|
||||
return self._method('reboot').take_none()
|
||||
|
||||
def getID(self) -> int:
|
||||
return integer(self._method('getID'))
|
||||
return self._method('getID').take_int()
|
||||
|
||||
def getLabel(self) -> Optional[str]:
|
||||
return option_string(self._method('getLabel'))
|
||||
return self._method('getLabel').take_option_string()
|
||||
|
||||
def isOn(self) -> bool:
|
||||
return boolean(self._method('isOn'))
|
||||
return self._method('isOn').take_bool()
|
||||
|
||||
|
||||
class CCComputer(BasePeripheral, ComputerMixin):
|
||||
|
@ -106,22 +101,22 @@ class ModemMessage:
|
|||
|
||||
class ModemMixin:
|
||||
def isOpen(self, channel: int) -> bool:
|
||||
return boolean(self._method('isOpen', channel))
|
||||
return self._method('isOpen', channel).take_bool()
|
||||
|
||||
def open(self, channel: int):
|
||||
return nil(self._method('open', channel))
|
||||
return self._method('open', channel).take_none()
|
||||
|
||||
def close(self, channel: int):
|
||||
return nil(self._method('close', channel))
|
||||
return self._method('close', channel).take_none()
|
||||
|
||||
def closeAll(self):
|
||||
return nil(self._method('closeAll'))
|
||||
return self._method('closeAll').take_none()
|
||||
|
||||
def transmit(self, channel: int, replyChannel: int, message: Any):
|
||||
return nil(self._method('transmit', channel, replyChannel, message))
|
||||
return self._method('transmit', channel, replyChannel, message).take_none()
|
||||
|
||||
def isWireless(self) -> bool:
|
||||
return boolean(self._method('isWireless'))
|
||||
return self._method('isWireless').take_bool()
|
||||
|
||||
@property
|
||||
def _side(self):
|
||||
|
@ -151,16 +146,16 @@ class CCWirelessModem(BasePeripheral, ModemMixin):
|
|||
|
||||
class CCWiredModem(BasePeripheral, ModemMixin):
|
||||
def getNameLocal(self) -> Optional[str]:
|
||||
return option_string(self._method('getNameLocal'))
|
||||
return self._method('getNameLocal').take_option_string()
|
||||
|
||||
def getNamesRemote(self) -> List[str]:
|
||||
return array_string(self._method('getNamesRemote'))
|
||||
return self._method('getNamesRemote').take_list_of_strings()
|
||||
|
||||
def getTypeRemote(self, peripheralName: str) -> Optional[str]:
|
||||
return option_string(self._method('getTypeRemote', peripheralName))
|
||||
return self._method('getTypeRemote', peripheralName).take_option_string()
|
||||
|
||||
def isPresentRemote(self, peripheralName: str) -> bool:
|
||||
return boolean(self._method('isPresentRemote', peripheralName))
|
||||
return self._method('isPresentRemote', peripheralName).take_bool()
|
||||
|
||||
def wrapRemote(self, peripheralName: str) -> Optional[BasePeripheral]:
|
||||
# use instead getMethodsRemote and callRemote
|
||||
|
@ -180,31 +175,33 @@ class CCWiredModem(BasePeripheral, ModemMixin):
|
|||
|
||||
class CCPrinter(BasePeripheral):
|
||||
def newPage(self) -> bool:
|
||||
return boolean(self._method('newPage'))
|
||||
return self._method('newPage').take_bool()
|
||||
|
||||
def endPage(self) -> bool:
|
||||
return boolean(self._method('endPage'))
|
||||
return self._method('endPage').take_bool()
|
||||
|
||||
def write(self, text: str):
|
||||
return nil(self._method('write', text))
|
||||
return self._method('write', text).take_none()
|
||||
|
||||
def setCursorPos(self, x: int, y: int):
|
||||
return nil(self._method('setCursorPos', x, y))
|
||||
return self._method('setCursorPos', x, y).take_none()
|
||||
|
||||
def getCursorPos(self) -> Tuple[int, int]:
|
||||
return tuple2_integer(self._method('getCursorPos'))
|
||||
rp = self._method('getCursorPos')
|
||||
return tuple(rp.take_int() for _ in range(2))
|
||||
|
||||
def getPageSize(self) -> Tuple[int, int]:
|
||||
return tuple2_integer(self._method('getPageSize'))
|
||||
rp = self._method('getPageSize')
|
||||
return tuple(rp.take_int() for _ in range(2))
|
||||
|
||||
def setPageTitle(self, title: str):
|
||||
return nil(self._method('setPageTitle', title))
|
||||
return self._method('setPageTitle', title).take_none()
|
||||
|
||||
def getPaperLevel(self) -> int:
|
||||
return integer(self._method('getPaperLevel'))
|
||||
return self._method('getPaperLevel').take_int()
|
||||
|
||||
def getInkLevel(self) -> int:
|
||||
return integer(self._method('getInkLevel'))
|
||||
return self._method('getInkLevel').take_int()
|
||||
|
||||
|
||||
class CCSpeaker(BasePeripheral):
|
||||
|
@ -229,28 +226,28 @@ class CCSpeaker(BasePeripheral):
|
|||
|
||||
# volume 0..3
|
||||
# pitch 0..24
|
||||
return boolean(self._method('playNote', instrument, volume, pitch))
|
||||
return self._method('playNote', instrument, volume, pitch).take_bool()
|
||||
|
||||
def playSound(self, sound: str, volume: int = 1, pitch: int = 1):
|
||||
def playSound(self, sound: str, volume: int = 1, pitch: int = 1) -> bool:
|
||||
# volume 0..3
|
||||
# pitch 0..2
|
||||
return boolean(self._method('playSound', sound, volume, pitch))
|
||||
return self._method('playSound', sound, volume, pitch).take_bool()
|
||||
|
||||
|
||||
class CCCommandBlock(BasePeripheral):
|
||||
def getCommand(self) -> str:
|
||||
return string(self._method('getCommand'))
|
||||
return self._method('getCommand').take_string()
|
||||
|
||||
def setCommand(self, command: str):
|
||||
return nil(self._method('setCommand', command))
|
||||
return self._method('setCommand', command).take_none()
|
||||
|
||||
def runCommand(self):
|
||||
return flat_try_result(self._method('runCommand'))
|
||||
return self._method('runCommand').check_bool_error()
|
||||
|
||||
|
||||
class CCWorkbench(BasePeripheral):
|
||||
def craft(self, quantity: int = 64) -> bool:
|
||||
return craft_result(self._method('craft', quantity))
|
||||
return self._method('craft', quantity).bool_error_exclude('No matching recipes')
|
||||
|
||||
|
||||
TYPE_MAP = {
|
||||
|
@ -278,15 +275,15 @@ __all__ = (
|
|||
|
||||
|
||||
def isPresent(side: str) -> bool:
|
||||
return boolean(method('isPresent', side))
|
||||
return method('isPresent', side).take_bool()
|
||||
|
||||
|
||||
def getType(side: str) -> Optional[str]:
|
||||
return option_string(method('getType', side))
|
||||
return method('getType', side).take_option_string()
|
||||
|
||||
|
||||
def getNames() -> List[str]:
|
||||
return array_string(method('getNames'))
|
||||
return method('getNames').take_list_of_strings()
|
||||
|
||||
|
||||
# use instead getMethods and call
|
||||
|
@ -298,7 +295,7 @@ def wrap(side: str) -> Optional[BasePeripheral]:
|
|||
m = 'peripheral.call'
|
||||
|
||||
if ptype == 'modem':
|
||||
if boolean(method('call', side, 'isWireless')):
|
||||
if method('call', side, 'isWireless').take_bool():
|
||||
return CCWirelessModem(m, side)
|
||||
else:
|
||||
return CCWiredModem(m, side)
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
from ..rproc import flat_try_result
|
||||
from ..sess import eval_lua_method_factory
|
||||
|
||||
|
||||
|
@ -12,8 +11,8 @@ __all__ = (
|
|||
|
||||
|
||||
def equipBack():
|
||||
return flat_try_result(method('equipBack'))
|
||||
return method('equipBack').check_bool_error()
|
||||
|
||||
|
||||
def unequipBack():
|
||||
return flat_try_result(method('unequipBack'))
|
||||
return method('unequipBack').check_bool_error()
|
||||
|
|
|
@ -1,16 +1,9 @@
|
|||
from typing import Any, List, Optional, Tuple, Union
|
||||
|
||||
from ..lua import LuaNum
|
||||
from ..rproc import nil, integer, option_string, boolean, array_integer, option_integer, fact_option, fact_tuple
|
||||
from ..sess import eval_lua_method_factory
|
||||
|
||||
|
||||
recv_result = fact_option(fact_tuple(
|
||||
integer,
|
||||
lambda v: v,
|
||||
option_string,
|
||||
tail_nils=1,
|
||||
))
|
||||
method = eval_lua_method_factory('rednet.')
|
||||
|
||||
|
||||
|
@ -34,46 +27,47 @@ CHANNEL_BROADCAST = 65535
|
|||
|
||||
|
||||
def open(side: str):
|
||||
return nil(method('open', side))
|
||||
return method('open', side).take_none()
|
||||
|
||||
|
||||
def close(side: str = None):
|
||||
return nil(method('close', side))
|
||||
return method('close', side).take_none()
|
||||
|
||||
|
||||
def send(receiverID: int, message: Any, protocol: str = None) -> bool:
|
||||
return boolean(method('send', receiverID, message, protocol))
|
||||
return method('send', receiverID, message, protocol).take_bool()
|
||||
|
||||
|
||||
def broadcast(message: Any, protocol: str = None):
|
||||
return nil(method('broadcast', message, protocol))
|
||||
return method('broadcast', message, protocol).take_none()
|
||||
|
||||
|
||||
def receive(
|
||||
protocolFilter: str = None, timeout: LuaNum = None,
|
||||
) -> Optional[Tuple[int, Any, Optional[str]]]:
|
||||
return recv_result(method('receive', protocolFilter, timeout))
|
||||
rp = method('receive', protocolFilter, timeout)
|
||||
if rp.peek() is None:
|
||||
return None
|
||||
return (rp.take_int(), rp.take(), rp.take_option_string())
|
||||
|
||||
|
||||
def isOpen(side: str = None) -> bool:
|
||||
return boolean(method('isOpen', side))
|
||||
return method('isOpen', side).take_bool()
|
||||
|
||||
|
||||
def host(protocol: str, hostname: str):
|
||||
return nil(method('host', protocol, hostname))
|
||||
return method('host', protocol, hostname).take_none()
|
||||
|
||||
|
||||
def unhost(protocol: str):
|
||||
return nil(method('unhost', protocol))
|
||||
return method('unhost', protocol).take_none()
|
||||
|
||||
|
||||
def lookup(protocol: str, hostname: str = None) -> Union[Optional[int], List[int]]:
|
||||
result = method('lookup', protocol, hostname)
|
||||
rp = method('lookup', protocol, hostname)
|
||||
if hostname is None:
|
||||
if result is None:
|
||||
if rp.peek() is None:
|
||||
return []
|
||||
if isinstance(result, list):
|
||||
return array_integer(result)
|
||||
return [integer(result)]
|
||||
return rp.take_list_of_ints()
|
||||
else:
|
||||
return option_integer(result)
|
||||
return rp.take_option_int()
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
from typing import List
|
||||
|
||||
from ..rproc import boolean, nil, integer, array_string
|
||||
from ..sess import eval_lua_method_factory
|
||||
|
||||
|
||||
|
@ -23,46 +22,46 @@ __all__ = (
|
|||
|
||||
|
||||
def getSides() -> List[str]:
|
||||
return array_string(method('getSides'))
|
||||
return method('getSides').take_list_of_strings()
|
||||
|
||||
|
||||
def getInput(side: str) -> bool:
|
||||
return boolean(method('getInput', side))
|
||||
return method('getInput', side).take_bool()
|
||||
|
||||
|
||||
def setOutput(side: str, value: bool):
|
||||
return nil(method('setOutput', side, value))
|
||||
return method('setOutput', side, value).take_none()
|
||||
|
||||
|
||||
def getOutput(side: str) -> bool:
|
||||
return boolean(method('getOutput', side))
|
||||
return method('getOutput', side).take_bool()
|
||||
|
||||
|
||||
def getAnalogInput(side: str) -> int:
|
||||
return integer(method('getAnalogInput', side))
|
||||
return method('getAnalogInput', side).take_int()
|
||||
|
||||
|
||||
def setAnalogOutput(side: str, strength: int):
|
||||
return nil(method('setAnalogOutput', side, strength))
|
||||
return method('setAnalogOutput', side, strength).take_none()
|
||||
|
||||
|
||||
def getAnalogOutput(side: str) -> int:
|
||||
return integer(method('getAnalogOutput', side))
|
||||
return method('getAnalogOutput', side).take_int()
|
||||
|
||||
|
||||
# bundled cables are not available in vanilla
|
||||
|
||||
def getBundledInput(side: str) -> int:
|
||||
return integer(method('getBundledInput', side))
|
||||
return method('getBundledInput', side).take_int()
|
||||
|
||||
|
||||
def setBundledOutput(side: str, colors: int):
|
||||
return nil(method('setBundledOutput', side, colors))
|
||||
return method('setBundledOutput', side, colors).take_none()
|
||||
|
||||
|
||||
def getBundledOutput(side: str) -> int:
|
||||
return integer(method('getBundledOutput', side))
|
||||
return method('getBundledOutput', side).take_int()
|
||||
|
||||
|
||||
def testBundledInput(side: str, color: int) -> bool:
|
||||
return boolean(method('testBundledInput', side, color))
|
||||
return method('testBundledInput', side, color).take_bool()
|
||||
|
|
|
@ -1,17 +1,8 @@
|
|||
from typing import Any, List
|
||||
|
||||
from ..rproc import nil, boolean, string, array_string, fact_scheme_dict
|
||||
from ..sess import eval_lua_method_factory
|
||||
|
||||
|
||||
setting = fact_scheme_dict({
|
||||
'changed': boolean,
|
||||
}, {
|
||||
'description': string,
|
||||
'default': lambda v: v,
|
||||
'type': string,
|
||||
'value': lambda v: v,
|
||||
})
|
||||
method = eval_lua_method_factory('settings.')
|
||||
|
||||
|
||||
|
@ -37,40 +28,57 @@ def define(name: str, description: str = None, default: Any = None, type: str =
|
|||
options['default'] = default
|
||||
if type is not None:
|
||||
options['type'] = type
|
||||
return nil(method('define', name, options))
|
||||
return method('define', name, options).take_none()
|
||||
|
||||
|
||||
def undefine(name: str):
|
||||
return nil(method('undefine', name))
|
||||
return method('undefine', name).take_none()
|
||||
|
||||
|
||||
def getDetails(name: str) -> dict:
|
||||
return setting(method('getDetails', name))
|
||||
tp = method('getDetails', name).take_dict((
|
||||
b'changed',
|
||||
b'description',
|
||||
b'default',
|
||||
b'type',
|
||||
b'value',
|
||||
))
|
||||
r = {}
|
||||
r['changed'] = tp.take_bool()
|
||||
for k, v in [
|
||||
('description', tp.take_option_string()),
|
||||
('default', tp.take()),
|
||||
('type', tp.take_option_string()),
|
||||
('value', tp.take()),
|
||||
]:
|
||||
if v is not None:
|
||||
r[k] = v
|
||||
return r
|
||||
|
||||
|
||||
def set(name: str, value: Any):
|
||||
return nil(method('set', name, value))
|
||||
return method('set', name, value).take_none()
|
||||
|
||||
|
||||
def get(name: str, default: Any = None) -> Any:
|
||||
return method('get', name, default)
|
||||
return method('get', name, default).take()
|
||||
|
||||
|
||||
def unset(name: str):
|
||||
return nil(method('unset', name))
|
||||
return method('unset', name).take_none()
|
||||
|
||||
|
||||
def clear():
|
||||
return nil(method('clear'))
|
||||
return method('clear').take_none()
|
||||
|
||||
|
||||
def getNames() -> List[str]:
|
||||
return array_string(method('getNames'))
|
||||
return method('getNames').take_list_of_strings()
|
||||
|
||||
|
||||
def load(path: str = None) -> bool:
|
||||
return boolean(method('load', path))
|
||||
return method('load', path).take_bool()
|
||||
|
||||
|
||||
def save(path: str = None) -> bool:
|
||||
return boolean(method('save', path))
|
||||
return method('save', path).take_bool()
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
from typing import List, Dict, Optional
|
||||
|
||||
from ..rproc import nil, string, boolean, integer, array_string, fact_mono_dict, option_string
|
||||
from ..sess import eval_lua_method_factory
|
||||
|
||||
|
||||
map_string_string = fact_mono_dict(string, string)
|
||||
method = eval_lua_method_factory('shell.')
|
||||
|
||||
|
||||
|
@ -31,75 +29,76 @@ __all__ = (
|
|||
|
||||
|
||||
def exit():
|
||||
return nil(method('exit'))
|
||||
return method('exit').take_none()
|
||||
|
||||
|
||||
def dir() -> str:
|
||||
return string(method('dir'))
|
||||
return method('dir').take_string()
|
||||
|
||||
|
||||
def setDir(path: str):
|
||||
return nil(method('setDir', path))
|
||||
return method('setDir', path).take_none()
|
||||
|
||||
|
||||
def path() -> str:
|
||||
return string(method('path'))
|
||||
return method('path').take_string()
|
||||
|
||||
|
||||
def setPath(path: str):
|
||||
return nil(method('setPath', path))
|
||||
return method('setPath', path).take_none()
|
||||
|
||||
|
||||
def resolve(localPath: str) -> str:
|
||||
return string(method('resolve', localPath))
|
||||
return method('resolve', localPath).take_string()
|
||||
|
||||
|
||||
def resolveProgram(name: str) -> Optional[str]:
|
||||
return option_string(method('resolveProgram', name))
|
||||
return method('resolveProgram', name).take_option_string()
|
||||
|
||||
|
||||
def aliases() -> Dict[str, str]:
|
||||
return map_string_string(method('aliases'))
|
||||
d = method('aliases').take_dict()
|
||||
return {k.decode('latin1'): v.decode('latin1') for k, v in d.items()}
|
||||
|
||||
|
||||
def setAlias(alias: str, program: str):
|
||||
return nil(method('setAlias', alias, program))
|
||||
return method('setAlias', alias, program).take_none()
|
||||
|
||||
|
||||
def clearAlias(alias: str):
|
||||
return nil(method('clearAlias', alias))
|
||||
return method('clearAlias', alias).take_none()
|
||||
|
||||
|
||||
def programs(showHidden: bool = None) -> List[str]:
|
||||
return array_string(method('programs', showHidden))
|
||||
return method('programs', showHidden).take_list_of_strings()
|
||||
|
||||
|
||||
def getRunningProgram() -> str:
|
||||
return string(method('getRunningProgram'))
|
||||
return method('getRunningProgram').take_string()
|
||||
|
||||
|
||||
def run(command: str, *args: str) -> bool:
|
||||
return boolean(method('run', command, *args))
|
||||
return method('run', command, *args).take_bool()
|
||||
|
||||
|
||||
def execute(command: str, *args: str) -> bool:
|
||||
return boolean(method('execute', command, *args))
|
||||
return method('execute', command, *args).take_bool()
|
||||
|
||||
|
||||
def openTab(command: str, *args: str) -> int:
|
||||
return integer(method('openTab', command, *args))
|
||||
return method('openTab', command, *args).take_int()
|
||||
|
||||
|
||||
def switchTab(tabID: int):
|
||||
return nil(method('switchTab', tabID))
|
||||
return method('switchTab', tabID).take_none()
|
||||
|
||||
|
||||
def complete(prefix: str) -> List[str]:
|
||||
return array_string(method('complete', prefix))
|
||||
return method('complete', prefix).take_list_of_strings()
|
||||
|
||||
|
||||
def completeProgram(prefix: str) -> List[str]:
|
||||
return array_string(method('completeProgram', prefix))
|
||||
return method('completeProgram', prefix).take_list_of_strings()
|
||||
|
||||
# TODO: ?
|
||||
# these functions won't be implemented
|
||||
|
|
|
@ -4,7 +4,6 @@ from typing import Tuple
|
|||
from .base import BaseSubAPI
|
||||
from .mixins import TermMixin, TermTarget
|
||||
from ..lua import lua_call
|
||||
from ..rproc import tuple3_number
|
||||
from ..sess import eval_lua_method_factory, lua_context_object
|
||||
|
||||
|
||||
|
@ -61,7 +60,8 @@ setPaletteColor = tapi.setPaletteColor
|
|||
|
||||
|
||||
def nativePaletteColor(colorID: int) -> Tuple[float, float, float]:
|
||||
return tuple3_number(method('nativePaletteColor', colorID))
|
||||
rp = method('nativePaletteColor', colorID)
|
||||
return tuple(rp.take_number() for _ in range(3))
|
||||
|
||||
|
||||
@contextmanager
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
from typing import List, Union
|
||||
|
||||
from ..lua import LuaNum
|
||||
from ..rproc import nil, string, integer
|
||||
from ..sess import eval_lua_method_factory
|
||||
|
||||
|
||||
|
@ -20,27 +19,27 @@ __all__ = (
|
|||
|
||||
|
||||
def slowWrite(text: str, rate: LuaNum = None):
|
||||
return nil(method('slowWrite', text, rate))
|
||||
return method('slowWrite', text, rate).take_none()
|
||||
|
||||
|
||||
def slowPrint(text: str, rate: LuaNum = None):
|
||||
return nil(method('slowPrint', text, rate))
|
||||
return method('slowPrint', text, rate).take_none()
|
||||
|
||||
|
||||
def formatTime(time: LuaNum, twentyFourHour: bool = None) -> str:
|
||||
return string(method('formatTime', time, twentyFourHour))
|
||||
return method('formatTime', time, twentyFourHour).take_string()
|
||||
|
||||
|
||||
def tabulate(*rows_and_colors: Union[list, int]):
|
||||
return nil(method('tabulate', *rows_and_colors))
|
||||
return method('tabulate', *rows_and_colors).take_none()
|
||||
|
||||
|
||||
def pagedTabulate(*rows_and_colors: Union[list, int]):
|
||||
return nil(method('pagedTabulate', *rows_and_colors))
|
||||
return method('pagedTabulate', *rows_and_colors).take_none()
|
||||
|
||||
|
||||
def pagedPrint(text: str, freeLines: int = None) -> int:
|
||||
return integer(method('pagedPrint', text, freeLines))
|
||||
return method('pagedPrint', text, freeLines).take_int()
|
||||
|
||||
|
||||
def complete(partial: str, possible: List[str]) -> List[str]:
|
||||
|
|
|
@ -1,41 +1,26 @@
|
|||
from typing import Optional
|
||||
|
||||
from ..errors import LuaException
|
||||
from ..rproc import integer, boolean, fact_option, any_dict, flat_try_result
|
||||
from ..sess import eval_lua_method_factory
|
||||
|
||||
|
||||
method = eval_lua_method_factory('turtle.')
|
||||
option_any_dict = fact_option(any_dict)
|
||||
|
||||
|
||||
def inspect_result(r):
|
||||
assert isinstance(r, list)
|
||||
assert len(r) == 2
|
||||
success, data = r
|
||||
assert isinstance(success, bool)
|
||||
def inspect_result(rp):
|
||||
success = rp.take_bool()
|
||||
if not success:
|
||||
if data == 'No block to inspect':
|
||||
msg = rp.take_string()
|
||||
if msg == 'No block to inspect':
|
||||
return None
|
||||
raise LuaException(data)
|
||||
raise LuaException(msg)
|
||||
else:
|
||||
return any_dict(data)
|
||||
return rp.take_dict()
|
||||
|
||||
|
||||
def boolean_with_error_exclusion(exclude_msg):
|
||||
def proc(r):
|
||||
if r is True:
|
||||
return True
|
||||
assert isinstance(r, list)
|
||||
assert len(r) == 2
|
||||
success, msg = r
|
||||
assert isinstance(success, bool)
|
||||
if not success:
|
||||
if msg == exclude_msg:
|
||||
return False
|
||||
raise LuaException(msg)
|
||||
else:
|
||||
return True
|
||||
def proc(rp):
|
||||
return rp.bool_error_exclude(exclude_msg)
|
||||
return proc
|
||||
|
||||
|
||||
|
@ -49,8 +34,8 @@ attack_result = boolean_with_error_exclusion('Nothing to attack here')
|
|||
craft_result = boolean_with_error_exclusion('No matching recipes')
|
||||
|
||||
|
||||
def always_true(r):
|
||||
assert boolean(r) is True
|
||||
def always_true(rp):
|
||||
assert rp.take_bool() is True
|
||||
# return value is useless
|
||||
return None
|
||||
|
||||
|
@ -135,19 +120,22 @@ def select(slotNum: int):
|
|||
|
||||
|
||||
def getSelectedSlot() -> int:
|
||||
return integer(method('getSelectedSlot'))
|
||||
return method('getSelectedSlot').take_int()
|
||||
|
||||
|
||||
def getItemCount(slotNum: int = None) -> int:
|
||||
return integer(method('getItemCount', slotNum))
|
||||
return method('getItemCount', slotNum).take_int()
|
||||
|
||||
|
||||
def getItemSpace(slotNum: int = None) -> int:
|
||||
return integer(method('getItemSpace', slotNum))
|
||||
return method('getItemSpace', slotNum).take_int()
|
||||
|
||||
|
||||
def getItemDetail(slotNum: int = None) -> dict:
|
||||
return option_any_dict(method('getItemDetail', slotNum))
|
||||
def getItemDetail(slotNum: int = None) -> Optional[dict]:
|
||||
rp = method('getItemDetail', slotNum)
|
||||
if rp.peek() is None:
|
||||
return None
|
||||
return rp.take_dict()
|
||||
|
||||
|
||||
def equipLeft():
|
||||
|
@ -195,15 +183,15 @@ def placeDown() -> bool:
|
|||
|
||||
|
||||
def detect() -> bool:
|
||||
return boolean(method('detect'))
|
||||
return method('detect').take_bool()
|
||||
|
||||
|
||||
def detectUp() -> bool:
|
||||
return boolean(method('detectUp'))
|
||||
return method('detectUp').take_bool()
|
||||
|
||||
|
||||
def detectDown() -> bool:
|
||||
return boolean(method('detectDown'))
|
||||
return method('detectDown').take_bool()
|
||||
|
||||
|
||||
def inspect() -> Optional[dict]:
|
||||
|
@ -219,19 +207,19 @@ def inspectDown() -> Optional[dict]:
|
|||
|
||||
|
||||
def compare() -> bool:
|
||||
return boolean(method('compare'))
|
||||
return method('compare').take_bool()
|
||||
|
||||
|
||||
def compareUp() -> bool:
|
||||
return boolean(method('compareUp'))
|
||||
return method('compareUp').take_bool()
|
||||
|
||||
|
||||
def compareDown() -> bool:
|
||||
return boolean(method('compareDown'))
|
||||
return method('compareDown').take_bool()
|
||||
|
||||
|
||||
def compareTo(slot: int) -> bool:
|
||||
return boolean(method('compareTo', slot))
|
||||
return method('compareTo', slot).take_bool()
|
||||
|
||||
|
||||
def drop(count: int = None) -> bool:
|
||||
|
@ -259,15 +247,15 @@ def suckDown(amount: int = None) -> bool:
|
|||
|
||||
|
||||
def refuel(quantity: int = None):
|
||||
return flat_try_result(method('refuel', quantity))
|
||||
return method('refuel', quantity).check_bool_error()
|
||||
|
||||
|
||||
def getFuelLevel() -> int:
|
||||
return integer(method('getFuelLevel'))
|
||||
return method('getFuelLevel').take_int()
|
||||
|
||||
|
||||
def getFuelLimit() -> int:
|
||||
return integer(method('getFuelLimit'))
|
||||
return method('getFuelLimit').take_int()
|
||||
|
||||
|
||||
def transferTo(slot: int, quantity: int = None) -> bool:
|
||||
|
|
|
@ -2,7 +2,6 @@ from contextlib import contextmanager
|
|||
from typing import Tuple
|
||||
|
||||
from ..lua import lua_call
|
||||
from ..rproc import nil, tuple2_integer, tuple3_string
|
||||
from ..sess import eval_lua_method_factory, lua_context_object
|
||||
from .base import BaseSubAPI
|
||||
from .mixins import TermMixin, TermTarget
|
||||
|
@ -10,22 +9,24 @@ from .mixins import TermMixin, TermTarget
|
|||
|
||||
class CCWindow(BaseSubAPI, TermMixin):
|
||||
def setVisible(self, visibility: bool):
|
||||
return nil(self._method('setVisible', visibility))
|
||||
return self._method('setVisible', visibility).take_none()
|
||||
|
||||
def redraw(self):
|
||||
return nil(self._method('redraw'))
|
||||
return self._method('redraw').take_none()
|
||||
|
||||
def restoreCursor(self):
|
||||
return nil(self._method('restoreCursor'))
|
||||
return self._method('restoreCursor').take_none()
|
||||
|
||||
def getPosition(self) -> Tuple[int, int]:
|
||||
return tuple2_integer(self._method('getPosition'))
|
||||
rp = self._method('getPosition')
|
||||
return tuple(rp.take_int() for _ in range(2))
|
||||
|
||||
def reposition(self, x: int, y: int, width: int = None, height: int = None, parent: TermTarget = None):
|
||||
return nil(self._method('reposition', x, y, width, height, parent))
|
||||
return self._method('reposition', x, y, width, height, parent).take_none()
|
||||
|
||||
def getLine(self, y: int) -> Tuple[str, str, str]:
|
||||
return tuple3_string(self._method('getLine', y))
|
||||
rp = self._method('getLine', y)
|
||||
return tuple(rp.take_string() for _ in range(3))
|
||||
|
||||
def get_term_target(self) -> TermTarget:
|
||||
return TermTarget(self.get_expr_code())
|
||||
|
|
|
@ -39,7 +39,7 @@ def step(text):
|
|||
|
||||
|
||||
def get_object_table(objname):
|
||||
r = eval_lua(f"""
|
||||
rp = eval_lua(f"""
|
||||
local r = {{}}
|
||||
for k in pairs({objname}) do
|
||||
local t = type({objname}[k])
|
||||
|
@ -51,8 +51,12 @@ for k in pairs({objname}) do
|
|||
end
|
||||
end
|
||||
return r""", immediate=True)
|
||||
assert len(r) == 1
|
||||
return r[0]
|
||||
d = rp.take_dict()
|
||||
return {
|
||||
k1.decode('latin1'): {
|
||||
k2.decode('latin1'): v for k2, v in t.items()
|
||||
} for k1, t in d.items()
|
||||
}
|
||||
|
||||
|
||||
def get_class_table(cls):
|
||||
|
|
|
@ -151,50 +151,32 @@ assert fs.complete('ap', 'tdir', includeFiles=False) == []
|
|||
|
||||
assert fs.getSize('tdir/banana') == 9
|
||||
with fs.open('tdir/banana', 'r') as f:
|
||||
assert _lib.get_object_table(f.get_expr_code()) == {'function': {
|
||||
'close': True,
|
||||
'read': True,
|
||||
'readLine': True,
|
||||
'readAll': True,
|
||||
}}
|
||||
assert f.read(4) == 'text'
|
||||
assert f.readLine() == 'line'
|
||||
assert f.read(1) is None
|
||||
assert f.readLine() is None
|
||||
assert f.readAll() == ''
|
||||
assert f.readAll() == ''
|
||||
assert f.readAll() is None
|
||||
assert f.readAll() is None
|
||||
assert fs.getSize('tdir/banana') == 9
|
||||
with fs.open('tdir/banana', 'a') as f:
|
||||
assert _lib.get_object_table(f.get_expr_code()) == {'function': {
|
||||
'close': True,
|
||||
'write': True,
|
||||
'writeLine': True,
|
||||
'flush': True,
|
||||
}}
|
||||
assert f.write('x') is None
|
||||
assert fs.getSize('tdir/banana') == 10
|
||||
with fs.open('tdir/banana', 'w') as f:
|
||||
pass
|
||||
assert fs.getSize('tdir/banana') == 0 # truncate
|
||||
with fs.open('tdir/banana', 'w') as f:
|
||||
assert _lib.get_object_table(f.get_expr_code()) == {'function': {
|
||||
'close': True,
|
||||
'write': True,
|
||||
'writeLine': True,
|
||||
'flush': True,
|
||||
}}
|
||||
assert f.write('Bro') is None
|
||||
assert f.writeLine('wn fox jumps') is None
|
||||
assert fs.getSize('tdir/banana') == 0 # changes are not on a disk
|
||||
# assert fs.getSize('tdir/banana') == 0 # changes are not on a disk
|
||||
assert f.flush() is None
|
||||
assert fs.getSize('tdir/banana') == len('Brown fox jumps\n')
|
||||
assert f.write('ov') is None
|
||||
assert f.write('er ') is None
|
||||
assert f.write('a lazy') is None
|
||||
assert f.writeLine(' dog.') is None
|
||||
assert f.writeLine(' дог.') is None
|
||||
assert fs.getSize('tdir/banana') > 9
|
||||
with fs.open('tdir/banana', 'r') as f:
|
||||
assert f.readAll() == 'Brown fox jumps\nover a lazy dog.' # no newline?
|
||||
assert f.readAll() == 'Brown fox jumps\nover a lazy дог.\n'
|
||||
with assert_raises(LuaException):
|
||||
with fs.open('tdir/banana', 'rw') as f:
|
||||
pass
|
||||
|
@ -202,22 +184,19 @@ with assert_raises(LuaException):
|
|||
assert fs.exists('tdir/banana') is True
|
||||
|
||||
with fs.open('tdir/binfile', 'wb') as f:
|
||||
assert f.write('a' * 9) is None
|
||||
assert f.write(b'a' * 9) is None
|
||||
assert f.seek() == 9
|
||||
assert f.seek('set', 0) == 0
|
||||
assert f.write('b' * 3) is None
|
||||
assert f.write(b'b' * 3) is None
|
||||
assert f.seek('cur', -1) == 2
|
||||
assert f.write('c' * 3) is None
|
||||
assert f.write(b'c' * 3) is None
|
||||
assert f.seek('end') == 9
|
||||
assert f.write('d' * 3) is None
|
||||
assert f.write(b'd' * 3) is None
|
||||
with assert_raises(LuaException):
|
||||
f.seek('set', -10)
|
||||
|
||||
with fs.open('tdir/binfile', 'rb') as f:
|
||||
assert f.readAll() == 'bbcccaaaaddd'
|
||||
|
||||
with fs.open('tdir/binfile', 'rb') as f:
|
||||
assert isinstance(f.read(), int)
|
||||
assert f.readAll() == b'bbcccaaaaddd'
|
||||
|
||||
with fs.open('tdir/binfile', 'r') as f:
|
||||
assert [line for line in f] == ['bbcccaaaaddd']
|
||||
|
|
|
@ -146,3 +146,5 @@ for _, v in ipairs(roundtrip_tables) do
|
|||
end
|
||||
|
||||
print('ALL OK')
|
||||
|
||||
print(serialize({true, false, 'Position is negative'}))
|
||||
|
|
Loading…
Reference in a new issue