mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
732 lines
24 KiB
Python
732 lines
24 KiB
Python
import zmq
|
|
from collections import namedtuple
|
|
from . import serial, exc, expr
|
|
|
|
Property = namedtuple("Property", [
|
|
"name",
|
|
"type",
|
|
"subtype",
|
|
#"defaults",
|
|
"ui_name",
|
|
"desc",
|
|
"is_null_allowed",
|
|
"is_expr_allowed",
|
|
"array_len",
|
|
"min_val",
|
|
"max_val",
|
|
"enum_items",
|
|
"depends"
|
|
])
|
|
|
|
class Command:
|
|
HELLO = 0
|
|
ADD_NODE = 1
|
|
REMOVE_NODE = 9
|
|
RENAME_NODE = 23
|
|
SCAN_DANGLING = 24
|
|
LOOKUP_NODE_ID = 12
|
|
ADD_PROPERTY = 11
|
|
LINK_NODE = 2
|
|
UNLINK_NODE = 8
|
|
GET_INFO = 19
|
|
GET_CHILDREN = 4
|
|
GET_PARENTS = 5
|
|
GET_PROPERTIES = 3
|
|
GET_PROPERTY_VALUE = 6
|
|
SET_PROPERTY_VALUE = 7
|
|
GET_SIGNALS = 14
|
|
REGISTER_SLOT = 15
|
|
UNREGISTER_SLOT = 16
|
|
LOOKUP_SLOT_ID = 17
|
|
GET_SLOTS = 18
|
|
GET_METHODS = 20
|
|
GET_METHOD = 21
|
|
CALL_METHOD = 22
|
|
|
|
class SceneNodeType:
|
|
NULL = 0
|
|
ROOT = 1
|
|
WINDOW = 2
|
|
WINDOW_INPUT = 3
|
|
KEYBOARD = 4
|
|
MOUSE = 5
|
|
LAYER = 6
|
|
OBJECT = 7
|
|
VECTOR_ART = 8
|
|
TEXT = 9
|
|
TEXTURE = 10
|
|
FONTS = 11
|
|
FONT = 12
|
|
CHAT_VIEW = 13
|
|
EDIT = 14
|
|
IMAGE = 15
|
|
BUTTON = 16
|
|
SHORTCUT = 17
|
|
GESTURE = 18
|
|
EMOJI_PICKER = 19
|
|
SETTING_ROOT = 20
|
|
SETTING = 21
|
|
PLUGINS = 100
|
|
PLUGIN = 101
|
|
|
|
class PropertyType:
|
|
NULL = 0
|
|
BOOL = 1
|
|
UINT32 = 2
|
|
FLOAT32 = 3
|
|
STR = 4
|
|
ENUM = 5
|
|
BUFFER = 6
|
|
SCENE_NODE_ID = 7
|
|
SEXPR = 8
|
|
|
|
@staticmethod
|
|
def to_str(prop_type):
|
|
match prop_type:
|
|
case PropertyType.NULL:
|
|
return "null"
|
|
case PropertyType.BOOL:
|
|
return "bool"
|
|
case PropertyType.UINT32:
|
|
return "uint32"
|
|
case PropertyType.FLOAT32:
|
|
return "float32"
|
|
case PropertyType.STR:
|
|
return "str"
|
|
case PropertyType.ENUM:
|
|
return "enum"
|
|
case PropertyType.BUFFER:
|
|
return "buffer"
|
|
case PropertyType.SCENE_NODE_ID:
|
|
return "scene_node_id"
|
|
case PropertyType.SEXPR:
|
|
return "sexpr"
|
|
|
|
class PropertySubType:
|
|
NULL = 0
|
|
COLOR = 1
|
|
PIXEL = 2
|
|
RESOURCE_ID = 3
|
|
|
|
@staticmethod
|
|
def to_str(prop_type):
|
|
match prop_type:
|
|
case PropertySubType.NULL:
|
|
return "null"
|
|
case PropertySubType.Color:
|
|
return "color"
|
|
case PropertySubType.PIXEL:
|
|
return "pixel"
|
|
case PropertySubType.RESOURCE_ID:
|
|
return "resource_id"
|
|
|
|
class PropertyStatus:
|
|
OK = 0
|
|
UNSET = 1
|
|
NULL = 2
|
|
EXPR = 3
|
|
|
|
class ErrorCode:
|
|
INVALID_SCENE_PATH = 1
|
|
NODE_NOT_FOUND = 2
|
|
CHILD_NODE_NOT_FOUND = 3
|
|
PARENT_NODE_NOT_FOUND = 4
|
|
PROPERTY_ALREADY_EXISTS = 5
|
|
PROPERTY_NOT_FOUND = 6
|
|
PROPERTY_WRONG_TYPE = 7
|
|
PROPERTY_WRONG_SUB_TYPE = 8
|
|
PROPERTY_WRONG_LEN = 9
|
|
PROPERTY_WRONG_INDEX = 10
|
|
PROPERTY_OUT_OF_RANGE = 11
|
|
PROPERTY_NULL_NOT_ALLOWED = 12
|
|
PROPERTY_SEXPR_NOT_ALLOWED = 13
|
|
PROPERTY_IS_BOUNDED = 14
|
|
PROPERTY_WRONG_ENUM_ITEM = 15
|
|
SIGNAL_ALREADY_EXISTS = 16
|
|
SIGNAL_NOT_FOUND = 17
|
|
SLOT_NOT_FOUND = 18
|
|
METHOD_ALREADY_EXISTS = 19
|
|
METHOD_NOT_FOUND = 20
|
|
NODES_ARE_LINKED = 21
|
|
NODES_NOT_LINKED = 22
|
|
NODE_HAS_PARENTS = 23
|
|
NODE_HAS_CHILDREN = 24
|
|
NODE_PARENT_NAME_CONFLICT = 25
|
|
NODE_CHILD_NAME_CONFLICT = 26
|
|
NODE_SIBLING_NAME_CONFLICT = 27
|
|
FILE_NOT_FOUND = 28
|
|
RESOURCE_NOT_FOUND = 29
|
|
PY_EVAL_ERR = 30
|
|
SEXPR_EMPTY = 31
|
|
SEXPR_GLOBAL_NOT_FOUND = 32
|
|
CHANNEL_CLOSED = 36
|
|
|
|
@staticmethod
|
|
def to_str(errc):
|
|
match errc:
|
|
case ErrorCode.INVALID_SCENE_PATH:
|
|
return "invalid_scene_path"
|
|
case ErrorCode.NODE_NOT_FOUND:
|
|
return "node_not_found"
|
|
case ErrorCode.CHILD_NODE_NOT_FOUND:
|
|
return "child_node_not_found"
|
|
case ErrorCode.PARENT_NODE_NOT_FOUND:
|
|
return "parent_node_not_found"
|
|
case ErrorCode.PROPERTY_ALREADY_EXISTS:
|
|
return "property_already_exists"
|
|
case ErrorCode.PROPERTY_NOT_FOUND:
|
|
return "property_not_found"
|
|
case ErrorCode.PROPERTY_WRONG_TYPE:
|
|
return "property_wrong_type"
|
|
case ErrorCode.PROPERTY_WRONG_LEN:
|
|
return "property_wrong_len"
|
|
case ErrorCode.PROPERTY_WRONG_INDEX:
|
|
return "property_wrong_index"
|
|
case ErrorCode.PROPERTY_OUT_OF_RANGE:
|
|
return "property_out_of_range"
|
|
case ErrorCode.PROPERTY_NULL_NOT_ALLOWED:
|
|
return "property_null_not_allowed"
|
|
case ErrorCode.PROPERTY_SEXPR_NOT_ALLOWED:
|
|
return "property_sexpr_not_allowed"
|
|
case ErrorCode.PROPERTY_IS_BOUNDED:
|
|
return "property_is_bounded"
|
|
case ErrorCode.PROPERTY_WRONG_ENUM_ITEM:
|
|
return "property_wrong_enum_item"
|
|
case ErrorCode.SIGNAL_ALREADY_EXISTS:
|
|
return "signal_already_exists"
|
|
case ErrorCode.SIGNAL_NOT_FOUND:
|
|
return "signal_not_found"
|
|
case ErrorCode.SLOT_NOT_FOUND:
|
|
return "slot_not_found"
|
|
case ErrorCode.METHOD_ALREADY_EXISTS:
|
|
return "method_already_exists"
|
|
case ErrorCode.METHOD_NOT_FOUND:
|
|
return "method_not_found"
|
|
case ErrorCode.NODES_ARE_LINKED:
|
|
return "nodes_are_linked"
|
|
case ErrorCode.NODES_NOT_LINKED:
|
|
return "nodes_not_linked"
|
|
case ErrorCode.NODE_HAS_PARENTS:
|
|
return "node_has_parents"
|
|
case ErrorCode.NODE_HAS_CHILDREN:
|
|
return "node_has_children"
|
|
case ErrorCode.NODE_PARENT_NAME_CONFLICT:
|
|
return "node_parent_name_conflict"
|
|
case ErrorCode.NODE_CHILD_NAME_CONFLICT:
|
|
return "node_child_name_conflict"
|
|
case ErrorCode.NODE_SIBLING_NAME_CONFLICT:
|
|
return "node_sibling_name_conflict"
|
|
case ErrorCode.FILE_NOT_FOUND:
|
|
return "file_not_found"
|
|
case ErrorCode.RESOURCE_NOT_FOUND:
|
|
return "resource_not_found"
|
|
case ErrorCode.PY_EVAL_ERR:
|
|
return "py_eval_err"
|
|
case ErrorCode.SEXPR_EMPTY:
|
|
return "sexpr_empty"
|
|
case ErrorCode.SEXPR_GLOBAL_NOT_FOUND:
|
|
return "sexpr_global_not_found"
|
|
case ErrorCode.CHANNEL_CLOSED:
|
|
return "channel_closed"
|
|
|
|
def vertex(x, y, r, g, b, a, u, v):
|
|
buf = bytearray()
|
|
serial.write_f32(buf, x)
|
|
serial.write_f32(buf, y)
|
|
serial.write_f32(buf, r)
|
|
serial.write_f32(buf, g)
|
|
serial.write_f32(buf, b)
|
|
serial.write_f32(buf, a)
|
|
serial.write_f32(buf, u)
|
|
serial.write_f32(buf, v)
|
|
return buf
|
|
|
|
def face(idx1, idx2, idx3):
|
|
buf = bytearray()
|
|
serial.write_u32(buf, idx1)
|
|
serial.write_u32(buf, idx2)
|
|
serial.write_u32(buf, idx3)
|
|
return buf
|
|
|
|
class Api:
|
|
|
|
def __init__(self, addr="127.0.0.1", port=9484):
|
|
context = zmq.Context()
|
|
self.socket = context.socket(zmq.REQ)
|
|
#self.socket.setsockopt(zmq.IPV6, True)
|
|
self.socket.connect(f"tcp://{addr}:{port}")
|
|
|
|
def _make_request(self, cmd, payload):
|
|
req_cmd = bytearray()
|
|
serial.write_u8(req_cmd, cmd)
|
|
self.socket.send_multipart([req_cmd, payload])
|
|
|
|
errc, reply = self.socket.recv_multipart()
|
|
errc = int.from_bytes(errc, "little")
|
|
cursor = serial.Cursor(reply)
|
|
match errc:
|
|
case 1:
|
|
raise exc.InvalidScenePath
|
|
case 2:
|
|
raise exc.NodeNotFound
|
|
case 3:
|
|
raise exc.ChildNodeNotFound
|
|
case 4:
|
|
raise exc.ParentNodeNotFound
|
|
case 5:
|
|
raise exc.PropertyAlreadyExists
|
|
case 6:
|
|
raise exc.PropertyNotFound
|
|
case 7:
|
|
raise exc.PropertyWrongType
|
|
case 8:
|
|
raise exc.PropertyWrongSubType
|
|
case 9:
|
|
raise exc.PropertyWrongLen
|
|
case 10:
|
|
raise exc.PropertyWrongIndex
|
|
case 11:
|
|
raise exc.PropertyOutOfRange
|
|
case 12:
|
|
raise exc.PropertyNullNotAllowed
|
|
case 12:
|
|
raise exc.PropertySExprNotAllowed
|
|
case 14:
|
|
raise exc.PropertyIsBounded
|
|
case 15:
|
|
raise exc.PropertyWrongEnumItem
|
|
case 16:
|
|
raise exc.SignalAlreadyExists
|
|
case 17:
|
|
raise exc.SignalNotFound
|
|
case 18:
|
|
raise exc.SlotNotFound
|
|
case 19:
|
|
raise exc.MethodAlreadyExists
|
|
case 20:
|
|
raise exc.MethodNotFound
|
|
case 21:
|
|
raise exc.NodesAreLinked
|
|
case 22:
|
|
raise exc.NodesNotLinked
|
|
case 23:
|
|
raise exc.NodeHasParents
|
|
case 24:
|
|
raise exc.NodeHasChildren
|
|
case 25:
|
|
raise exc.NodeParentNameConflict
|
|
case 26:
|
|
raise exc.NodeChildNameConflict
|
|
case 27:
|
|
raise exc.NodeSiblingNameConflict
|
|
case 28:
|
|
raise exc.FileNotFound
|
|
case 29:
|
|
raise exc.ResourceNotFound
|
|
case 30:
|
|
raise exc.PyEvalErr
|
|
case 31:
|
|
raise exc.SExprEmpty
|
|
case 32:
|
|
raise exc.SExprGlobalNotFound
|
|
case 36:
|
|
raise exc.ChannelClosed
|
|
return cursor
|
|
|
|
def hello(self):
|
|
response = self._make_request(Command.HELLO, bytearray())
|
|
return serial.decode_str(response)
|
|
|
|
def get_info(self, node_id):
|
|
req = bytearray()
|
|
serial.write_u32(req, node_id)
|
|
cur = self._make_request(Command.GET_INFO, req)
|
|
name = serial.decode_str(cur)
|
|
type = serial.read_u8(cur)
|
|
return (name, type)
|
|
|
|
def get_children(self, node_path):
|
|
req = bytearray()
|
|
serial.encode_str(req, node_path)
|
|
cur = self._make_request(Command.GET_CHILDREN, req)
|
|
children_len = serial.decode_varint(cur)
|
|
children = []
|
|
for _ in range(children_len):
|
|
child_name = serial.decode_str(cur)
|
|
child_id = serial.read_u32(cur)
|
|
child_type = serial.read_u8(cur)
|
|
children.append((child_name, child_id, child_type))
|
|
return children
|
|
|
|
def get_parents(self, node_id):
|
|
req = bytearray()
|
|
serial.write_u32(req, node_id)
|
|
cur = self._make_request(Command.GET_PARENTS, req)
|
|
parents_len = serial.decode_varint(cur)
|
|
parents = []
|
|
for _ in range(parents_len):
|
|
parent_name = serial.decode_str(cur)
|
|
parent_id = serial.read_u32(cur)
|
|
parent_type = serial.read_u8(cur)
|
|
parents.append((parent_name, parent_id, parent_type))
|
|
return parents
|
|
|
|
def get_properties(self, node_path):
|
|
req = bytearray()
|
|
serial.encode_str(req, node_path)
|
|
cur = self._make_request(Command.GET_PROPERTIES, req)
|
|
props_len = serial.decode_varint(cur)
|
|
props = []
|
|
|
|
enum_read_fn = lambda cur: serial.decode_arr(cur, serial.decode_str)
|
|
|
|
def depend_read_fn(cur):
|
|
i = serial.read_u32(cur)
|
|
local_name = serial.decode_str(cur)
|
|
return (i, local_name)
|
|
|
|
for _ in range(props_len):
|
|
prop_name = serial.decode_str(cur)
|
|
# We need prop_type below
|
|
prop_type = serial.read_u8(cur)
|
|
|
|
prop_read_fn = lambda cur: Api.read_prop_val(cur, prop_type)
|
|
|
|
prop = Property(
|
|
prop_name,
|
|
prop_type,
|
|
# subtype
|
|
serial.read_u8(cur),
|
|
# defaults
|
|
#serial.decode_arr(cur, prop_read_fn),
|
|
# ui_name
|
|
serial.decode_str(cur),
|
|
# desc
|
|
serial.decode_str(cur),
|
|
# is_null_allowed
|
|
bool(serial.read_u8(cur)),
|
|
# is_expr_allowed
|
|
bool(serial.read_u8(cur)),
|
|
# array_len
|
|
serial.read_u32(cur),
|
|
# min_val
|
|
serial.decode_opt(cur, prop_read_fn),
|
|
# max_val
|
|
serial.decode_opt(cur, prop_read_fn),
|
|
# enum_items
|
|
serial.decode_opt(cur, enum_read_fn),
|
|
# depends
|
|
serial.decode_arr(cur, depend_read_fn)
|
|
)
|
|
props.append(prop)
|
|
return props
|
|
|
|
@staticmethod
|
|
def read_prop_val(cur, prop_type):
|
|
match prop_type:
|
|
case PropertyType.NULL:
|
|
return None
|
|
case PropertyType.BOOL:
|
|
return bool(serial.read_u8(cur))
|
|
case PropertyType.UINT32:
|
|
return serial.read_u32(cur)
|
|
case PropertyType.FLOAT32:
|
|
return serial.read_f32(cur)
|
|
case PropertyType.STR:
|
|
return serial.decode_str(cur)
|
|
case PropertyType.ENUM:
|
|
return serial.decode_str(cur)
|
|
case PropertyType.BUFFER:
|
|
pass
|
|
case PropertyType.SCENE_NODE_ID:
|
|
return serial.read_u32(cur)
|
|
case _:
|
|
raise Exception("unknown property type returned")
|
|
|
|
def get_property_value(self, node_path, prop_name):
|
|
req = bytearray()
|
|
serial.encode_str(req, node_path)
|
|
serial.encode_str(req, prop_name)
|
|
cur = self._make_request(Command.GET_PROPERTY_VALUE, req)
|
|
prop_type = serial.read_u8(cur)
|
|
|
|
def prop_read_fn(cur):
|
|
prop_status = serial.read_u8(cur)
|
|
match prop_status:
|
|
case PropertyStatus.NULL:
|
|
return None
|
|
case PropertyStatus.EXPR:
|
|
return None
|
|
case PropertyStatus.UNSET | PropertyStatus.OK:
|
|
return Api.read_prop_val(cur, prop_type)
|
|
|
|
vals = serial.decode_arr(cur, prop_read_fn)
|
|
return vals
|
|
|
|
def add_node(self, node_name, node_type):
|
|
req = bytearray()
|
|
serial.encode_str(req, node_name)
|
|
serial.write_u8(req, int(node_type))
|
|
cur = self._make_request(Command.ADD_NODE, req)
|
|
node_id = serial.read_u32(cur)
|
|
return node_id
|
|
|
|
def remove_node(self, node_id):
|
|
req = bytearray()
|
|
serial.write_u32(req, node_id)
|
|
self._make_request(Command.REMOVE_NODE, req)
|
|
|
|
def rename_node(self, node_id, node_name):
|
|
req = bytearray()
|
|
serial.write_u32(req, node_id)
|
|
serial.encode_str(req, node_name)
|
|
self._make_request(Command.RENAME_NODE, req)
|
|
|
|
def scan_dangling(self):
|
|
cur = self._make_request(Command.SCAN_DANGLING, bytearray())
|
|
dangling_len = serial.decode_varint(cur)
|
|
dangling = []
|
|
for _ in range(dangling_len):
|
|
node_id = serial.read_u32(cur)
|
|
dangling.append(node_id)
|
|
return dangling
|
|
|
|
def lookup_node_id(self, node_path):
|
|
req = bytearray()
|
|
serial.encode_str(req, node_path)
|
|
try:
|
|
cur = self._make_request(Command.LOOKUP_NODE_ID, req)
|
|
except exc.NodeNotFound:
|
|
return None
|
|
return serial.read_u32(cur)
|
|
|
|
def add_property(self, node_id, prop):
|
|
req = bytearray()
|
|
serial.write_u32(req, node_id)
|
|
serial.encode_str(req, prop.name)
|
|
serial.write_u8(req, int(prop.type))
|
|
serial.write_u8(req, int(prop.subtype))
|
|
serial.write_u32(req, int(prop.array_len))
|
|
|
|
def write_defaults(by):
|
|
assert prop.defaults is not None
|
|
defaults_len = len(prop.defaults)
|
|
serial.encode_varint(req, defaults_len)
|
|
for default in prop.defaults:
|
|
match prop.type:
|
|
case PropertyType.UINT32:
|
|
serial.write_u32(req, default)
|
|
case PropertyType.FLOAT32:
|
|
serial.write_f32(req, default)
|
|
case PropertyType.STR:
|
|
serial.encode_str(req, default)
|
|
case _:
|
|
raise exc.PropertyWrongType
|
|
|
|
serial.encode_opt(req, prop.defaults, write_defaults)
|
|
|
|
serial.encode_str(req, prop.ui_name)
|
|
serial.encode_str(req, prop.desc)
|
|
serial.write_u8(req, int(prop.is_null_allowed))
|
|
serial.write_u8(req, int(prop.is_expr_allowed))
|
|
|
|
def write_mxx(v, by):
|
|
assert v is not None
|
|
match prop.type:
|
|
case PropertyType.UINT32:
|
|
serial.write_u32(req, v)
|
|
case PropertyType.FLOAT32:
|
|
serial.write_f32(req, v)
|
|
case _:
|
|
raise exc.PropertyWrongType
|
|
|
|
write_min = lambda by: write_mxx(prop.min_val, by)
|
|
write_max = lambda by: write_mxx(prop.max_val, by)
|
|
|
|
serial.encode_opt(req, prop.min_val, write_min)
|
|
serial.encode_opt(req, prop.max_val, write_max)
|
|
|
|
serial.encode_varint(req, len(prop.enum_items))
|
|
for enum_item in prop.enum_items:
|
|
if prop.type != PropertyType.ENUM:
|
|
raise exc.PropertyWrongType
|
|
serial.encode_str(req, enum_item)
|
|
self._make_request(Command.ADD_PROPERTY, req)
|
|
|
|
def link_node(self, child_id, parent_id):
|
|
req = bytearray()
|
|
serial.write_u32(req, child_id)
|
|
serial.write_u32(req, parent_id)
|
|
self._make_request(Command.LINK_NODE, req)
|
|
|
|
def unlink_node(self, child_id, parent_id):
|
|
req = bytearray()
|
|
serial.write_u32(req, child_id)
|
|
serial.write_u32(req, parent_id)
|
|
self._make_request(Command.UNLINK_NODE, req)
|
|
|
|
def set_property_null(self, node_path, prop_name, i):
|
|
req = bytearray()
|
|
serial.encode_str(req, node_path)
|
|
serial.encode_str(req, prop_name)
|
|
serial.write_u32(req, i)
|
|
serial.write_u8(req, PropertyType.NULL)
|
|
self._make_request(Command.SET_PROPERTY_VALUE, req)
|
|
|
|
def set_property_bool(self, node_path, prop_name, i, val):
|
|
req = bytearray()
|
|
serial.encode_str(req, node_path)
|
|
serial.encode_str(req, prop_name)
|
|
serial.write_u32(req, i)
|
|
serial.write_u8(req, PropertyType.BOOL)
|
|
serial.write_u8(req, int(val))
|
|
self._make_request(Command.SET_PROPERTY_VALUE, req)
|
|
|
|
def set_property_u32(self, node_path, prop_name, i, val):
|
|
req = bytearray()
|
|
serial.encode_str(req, node_path)
|
|
serial.encode_str(req, prop_name)
|
|
serial.write_u32(req, i)
|
|
serial.write_u8(req, PropertyType.UINT32)
|
|
serial.write_u32(req, val)
|
|
self._make_request(Command.SET_PROPERTY_VALUE, req)
|
|
|
|
def set_property_f32(self, node_path, prop_name, i, val):
|
|
req = bytearray()
|
|
serial.encode_str(req, node_path)
|
|
serial.encode_str(req, prop_name)
|
|
serial.write_u32(req, i)
|
|
serial.write_u8(req, PropertyType.FLOAT32)
|
|
serial.write_f32(req, val)
|
|
self._make_request(Command.SET_PROPERTY_VALUE, req)
|
|
|
|
def set_property_str(self, node_path, prop_name, i, val):
|
|
req = bytearray()
|
|
serial.encode_str(req, node_path)
|
|
serial.encode_str(req, prop_name)
|
|
serial.write_u32(req, i)
|
|
serial.write_u8(req, PropertyType.STR)
|
|
serial.encode_str(req, val)
|
|
self._make_request(Command.SET_PROPERTY_VALUE, req)
|
|
|
|
def set_property_enum(self, node_path, prop_name, i, val):
|
|
req = bytearray()
|
|
serial.encode_str(req, node_path)
|
|
serial.encode_str(req, prop_name)
|
|
serial.write_u32(req, i)
|
|
serial.write_u8(req, PropertyType.ENUM)
|
|
serial.encode_str(req, val)
|
|
self._make_request(Command.SET_PROPERTY_VALUE, req)
|
|
|
|
def set_property_buf(self, node_path, prop_name, i, buf):
|
|
req = bytearray()
|
|
serial.encode_str(req, node_path)
|
|
serial.encode_str(req, prop_name)
|
|
serial.write_u32(req, i)
|
|
serial.write_u8(req, PropertyType.BUFFER)
|
|
serial.encode_buf(req, buf)
|
|
self._make_request(Command.SET_PROPERTY_VALUE, req)
|
|
|
|
def set_property_expr(self, node_path, prop_name, i, code):
|
|
req = bytearray()
|
|
serial.encode_str(req, node_path)
|
|
serial.encode_str(req, prop_name)
|
|
serial.write_u32(req, i)
|
|
serial.write_u8(req, PropertyType.SEXPR)
|
|
serial.encode_varint(req, len(code))
|
|
for sexpr in code:
|
|
expr.encode_expr(req, sexpr)
|
|
self._make_request(Command.SET_PROPERTY_VALUE, req)
|
|
|
|
def get_signals(self, node_id):
|
|
req = bytearray()
|
|
serial.write_u32(req, node_id)
|
|
cur = self._make_request(Command.GET_SIGNALS, req)
|
|
sigs_len = serial.decode_varint(cur)
|
|
sigs = []
|
|
for _ in range(sigs_len):
|
|
sigs.append(serial.decode_str(cur))
|
|
return sigs
|
|
|
|
def register_slot(self, node_id, sig_name, slot_name, user_data):
|
|
req = bytearray()
|
|
serial.write_u32(req, node_id)
|
|
serial.encode_str(req, sig_name)
|
|
serial.encode_str(req, slot_name)
|
|
serial.encode_varint(req, len(user_data))
|
|
req += user_data
|
|
cur = self._make_request(Command.REGISTER_SLOT, req)
|
|
slot_id = serial.read_u32(cur)
|
|
return slot_id
|
|
|
|
def unregister_slot(self, node_id, sig_name, slot_id):
|
|
req = bytearray()
|
|
serial.write_u32(req, node_id)
|
|
serial.encode_str(req, sig_name)
|
|
serial.write_u32(req, slot_id)
|
|
self._make_request(Command.UNREGISTER_SLOT, req)
|
|
|
|
def lookup_slot_id(self, node_id, sig_name, slot_name):
|
|
req = bytearray()
|
|
serial.write_u32(req, node_id)
|
|
serial.encode_str(req, sig_name)
|
|
serial.encode_str(req, slot_name)
|
|
try:
|
|
cur = self._make_request(Command.LOOKUP_SLOT_ID, req)
|
|
except exc.RequestSlotNotFound:
|
|
return None
|
|
return serial.read_u32(cur)
|
|
|
|
def get_slots(self, node_id, sig_name):
|
|
req = bytearray()
|
|
serial.write_u32(req, node_id)
|
|
serial.encode_str(req, sig_name)
|
|
cur = self._make_request(Command.GET_SLOTS, req)
|
|
|
|
def read_slot(cur):
|
|
slot_name = serial.decode_str(cur)
|
|
slot_id = serial.read_u32(cur)
|
|
return (slot_name, slot_id)
|
|
|
|
slots = serial.decode_arr(cur, read_slot)
|
|
return slots
|
|
|
|
def get_methods(self, node_id):
|
|
req = bytearray()
|
|
serial.write_u32(req, node_id)
|
|
cur = self._make_request(Command.GET_METHODS, req)
|
|
|
|
def read_method(cur):
|
|
method_name = serial.decode_str(cur)
|
|
return method_name
|
|
|
|
methods = serial.decode_arr(cur, read_method)
|
|
return methods
|
|
|
|
def get_method(self, node_id, method_name):
|
|
req = bytearray()
|
|
serial.write_u32(req, node_id)
|
|
serial.encode_str(req, method_name)
|
|
cur = self._make_request(Command.GET_METHOD, req)
|
|
|
|
def read_arg(cur):
|
|
arg_name = serial.decode_str(cur)
|
|
arg_desc = serial.decode_str(cur)
|
|
arg_type = serial.read_u8(cur)
|
|
return (arg_name, arg_desc, arg_type)
|
|
|
|
args = serial.decode_arr(cur, read_arg)
|
|
results = serial.decode_arr(cur, read_arg)
|
|
|
|
return (args, results)
|
|
|
|
def call_method(self, node_path, method_name, arg_data):
|
|
req = bytearray()
|
|
serial.encode_str(req, node_path)
|
|
serial.encode_str(req, method_name)
|
|
serial.encode_buf(req, arg_data)
|
|
cur = self._make_request(Command.CALL_METHOD, req)
|
|
result = serial.decode_opt(cur, serial.decode_buf)
|
|
return result
|
|
|