api.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. from collections import namedtuple
  2. from pydrk import Api, PropertyType, PropertySubType, Property, serial
  3. import zmq
  4. api = Api()
  5. print("Node status:", api.hello())
  6. def make_sub_socket():
  7. context = zmq.Context()
  8. socket = context.socket(zmq.SUB)
  9. socket.setsockopt(zmq.SUBSCRIBE, b'')
  10. socket.connect("tcp://localhost:9485")
  11. return socket
  12. def rename_node(node, name):
  13. node_id = lookup_node(node)
  14. api.rename_node(node_id, name)
  15. def remove_all_slots(node_path, sig):
  16. node_id = api.lookup_node_id(node_path)
  17. for slot_id, slot in api.get_slots(node_id, sig):
  18. print(f"{node_path}:{sig}(): Unregistering slot '{slot}':{slot_id}")
  19. api.unregister_slot(node_id, sig, slot_id)
  20. def register_slot(node_path, sig, tag):
  21. #remove_all_slots(node_path, sig)
  22. node_id = api.lookup_node_id(node_path)
  23. api.register_slot(node_id, sig, "", tag)
  24. def get_property(node_id, prop):
  25. node_id = lookup_node(node_id)
  26. return api.get_property_value(node_id, prop)
  27. def set_property(node_id, prop, val):
  28. node_id = lookup_node(node_id)
  29. match val:
  30. case float():
  31. api.set_property_f32(node_id, prop, val)
  32. case int():
  33. api.set_property_u32(node_id, prop, val)
  34. def set_property_bool(node_id, prop, val):
  35. node_id = lookup_node(node_id)
  36. api.set_property_bool(node_id, prop, val)
  37. def set_property_f32(node_id, prop, val):
  38. node_id = lookup_node(node_id)
  39. api.set_property_f32(node_id, prop, float(val))
  40. def set_property_u32(node_id, prop, val):
  41. node_id = lookup_node(node_id)
  42. api.set_property_u32(node_id, prop, int(val))
  43. def add_property_bool(node_id, prop, val=None):
  44. api.add_property(node_id, prop, PropertyType.BOOL)
  45. if val is not None:
  46. api.set_property_bool(node_id, prop, val)
  47. def add_property_f32(node_id, prop, val=None):
  48. api.add_property(node_id, prop, PropertyType.FLOAT32)
  49. if val is not None:
  50. api.set_property_f32(node_id, prop, val)
  51. def add_property_u32(node_id, prop, val=None):
  52. api.add_property(node_id, prop, PropertyType.UINT32)
  53. if val is not None:
  54. api.set_property_u32(node_id, prop, val)
  55. def lookup_node(node_id):
  56. if isinstance(node_id, str):
  57. node_id = api.lookup_node_id(node_id)
  58. return node_id
  59. def link_node(child_id, parent_id):
  60. child_id = lookup_node(child_id)
  61. parent_id = lookup_node(parent_id)
  62. api.link_node(child_id, parent_id)
  63. def unlink_node(child_id, parent_id):
  64. child_id = lookup_node(child_id)
  65. parent_id = lookup_node(parent_id)
  66. api.unlink_node(child_id, parent_id)
  67. def unlink_from_parents(node_id):
  68. node_id = lookup_node(node_id)
  69. for (_, parent_id, _) in api.get_parents(node_id):
  70. api.unlink_node(node_id, parent_id)
  71. def remove_node_recursive(node_id):
  72. node_id = lookup_node(node_id)
  73. for (_, child_id, _) in api.get_children(node_id):
  74. # Unlink the child
  75. api.unlink_node(child_id, node_id)
  76. # Remove the node
  77. remove_node_recursive(child_id)
  78. # Garbage collection
  79. if not api.get_parents(node_id):
  80. api.remove_node(node_id)
  81. def garbage_collect():
  82. dangling = api.scan_dangling()
  83. for node_id in dangling:
  84. remove_node_recursive(node_id)
  85. print(f"Garbage collect: removed {len(dangling)} nodes")
  86. KeyMods = namedtuple("KeyMods", ["shift", "ctrl", "alt", "logo"])
  87. class EventLoop:
  88. def __init__(self):
  89. self.subsock = make_sub_socket()
  90. #register_slot("/window", "resize", b"rs")
  91. #register_slot("/window/input/mouse", "button_down", b"ck")
  92. #register_slot("/window/input/mouse", "wheel", b"wh")
  93. #register_slot("/window/input/mouse", "move", b"mm")
  94. register_slot("/window/input/keyboard", "key_down", b"kd")
  95. def run(self):
  96. while True:
  97. signal_data, user_data = self.subsock.recv_multipart()
  98. cur = serial.Cursor(signal_data)
  99. match user_data:
  100. #case b"rs":
  101. # w = get_property("/window", "width")
  102. # h = get_property("/window", "height")
  103. # self.resize_event(w, h)
  104. #case b"ck":
  105. # x = get_property("/window/input/mouse", "click_x")
  106. # y = get_property("/window/input/mouse", "click_y")
  107. # self.mouse_click(x, y)
  108. #case b"wh":
  109. # y = get_property("/window/input/mouse", "wheel_y")
  110. # self.mouse_wheel(y)
  111. #case b"mm":
  112. # pass
  113. case b"kd":
  114. shift = bool(serial.read_u8(cur))
  115. ctrl = bool(serial.read_u8(cur))
  116. alt = bool(serial.read_u8(cur))
  117. logo = bool(serial.read_u8(cur))
  118. repeat = bool(serial.read_u8(cur))
  119. keycode = serial.decode_str(cur)
  120. keymods = KeyMods(shift, ctrl, alt, logo)
  121. # Sometimes these get stuck when exiting the window.
  122. # We don't need these anyway
  123. if keycode in ("LeftShift", "LeftSuper"):
  124. continue
  125. self.key_down(keycode, keymods, repeat)
  126. def resize_event(self, w, h):
  127. pass
  128. def mouse_click(self, x, y):
  129. pass
  130. def mouse_wheel(self, y):
  131. pass
  132. def key_down(self, keycode, keymods, repeat):
  133. pass