client.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. #!/usr/bin/python
  2. # Ping a peer
  3. from pydrk import Api, exc, ErrorCode, HostApi, SceneNodeType, PropertyType, vertex, face, serial
  4. import sys, zmq
  5. def join(parent_path, child_name):
  6. if parent_path == "/":
  7. return f"/{child_name}"
  8. return f"{parent_path}/{child_name}"
  9. def print_tree():
  10. root_id = api.lookup_node_id("/")
  11. print_node_info(root_id)
  12. def print_node_info(parent_id, indent=0):
  13. ws = " "*4*indent
  14. for (child_name, child_id, child_type) in api.get_children(parent_id):
  15. match child_type:
  16. case SceneNodeType.ROOT:
  17. child_type = "root"
  18. case SceneNodeType.WINDOW:
  19. child_type = "window"
  20. case SceneNodeType.WINDOW_INPUT:
  21. child_type = "window_input"
  22. case SceneNodeType.KEYBOARD:
  23. child_type = "keyboard"
  24. case SceneNodeType.MOUSE:
  25. child_type = "mouse"
  26. case SceneNodeType.RENDER_LAYER:
  27. child_type = "render_layer"
  28. case SceneNodeType.RENDER_OBJECT:
  29. child_type = "render_object"
  30. case SceneNodeType.RENDER_MESH:
  31. child_type = "render_mesh"
  32. case SceneNodeType.RENDER_TEXT:
  33. child_type = "render_text"
  34. case SceneNodeType.RENDER_TEXTURE:
  35. child_type = "render_texture"
  36. case SceneNodeType.FONTS:
  37. child_type = "fonts"
  38. case SceneNodeType.FONT:
  39. child_type = "font"
  40. case SceneNodeType.LINE_POSITION:
  41. child_type = "line_position"
  42. desc = f"{ws}{child_name}:{child_id}/"
  43. desc += " "*(50 - len(desc))
  44. desc += f"[{child_type}]"
  45. print(desc)
  46. print_node_info(child_id, indent+1)
  47. for prop_name, prop_type in api.get_properties(parent_id):
  48. if prop_type == PropertyType.STR:
  49. prop_val = api.get_property(parent_id, prop_name)
  50. prop_val = f" = \"{prop_val}\""
  51. elif prop_type != PropertyType.BUFFER:
  52. prop_val = api.get_property(parent_id, prop_name)
  53. prop_val = f" = {prop_val}"
  54. else:
  55. prop_val = ""
  56. prop_type = PropertyType.to_str(prop_type)
  57. print(f"{ws}{prop_name}: {prop_type}{prop_val}")
  58. for sig in api.get_signals(parent_id):
  59. print(f"{ws}~{sig}")
  60. for slot_id, slot in api.get_slots(parent_id, sig):
  61. print(f"{ws}- '{slot}' ({slot_id})")
  62. for method_name in api.get_methods(parent_id):
  63. args, results = api.get_method(parent_id, method_name)
  64. args = [f"{name}: " + PropertyType.to_str(typ) for (name, typ) in args]
  65. results = [f"{name}: " + PropertyType.to_str(typ) for (name, typ) in results]
  66. method_str = f"{method_name}(" + ", ".join(args) + ") -> (" + ", ".join(results) + ")"
  67. print(f"{ws}{method_str}")
  68. def make_sub_socket():
  69. context = zmq.Context()
  70. socket = context.socket(zmq.SUB)
  71. socket.setsockopt(zmq.SUBSCRIBE, b'')
  72. socket.connect("tcp://localhost:9485")
  73. return socket
  74. def remove_node_recursive(node_id):
  75. for (_, child_id, _) in api.get_children(node_id):
  76. # Unlink the child
  77. api.unlink_node(child_id, node_id)
  78. # Remove the node
  79. remove_node_recursive(child_id)
  80. # Garbage collection
  81. if not api.get_parents(node_id):
  82. api.remove_node(node_id)
  83. def clear_layer(layer_path):
  84. layer_id = api.lookup_node_id("/window/layer2")
  85. for (_, child_id, child_type) in api.get_children(layer_id):
  86. api.unlink_node(child_id, layer_id)
  87. if child_type == SceneNodeType.RENDER_OBJECT:
  88. remove_node_recursive(child_id)
  89. def remove_all_slots(node_path, sig):
  90. node_id = api.lookup_node_id(node_path)
  91. for slot_id, slot in api.get_slots(node_id, sig):
  92. print(f"{node_path}:{sig}(): Unregistering slot '{slot}':{slot_id}")
  93. api.unregister_slot(node_id, sig, slot_id)
  94. def register_slot(node_path, sig, tag):
  95. remove_all_slots(node_path, sig)
  96. node_id = api.lookup_node_id(node_path)
  97. api.register_slot(node_id, sig, "", tag)
  98. def get_property(node_path, prop):
  99. node_id = api.lookup_node_id(node_path)
  100. return api.get_property(node_id, prop)
  101. def set_property(node_path, prop, val):
  102. node_id = api.lookup_node_id(node_path)
  103. match val:
  104. case float():
  105. api.set_property_f32(node_id, prop, val)
  106. case int():
  107. api.set_property_u32(node_id, prop, val)
  108. def recalc_areas():
  109. w = get_property("/window", "width")
  110. h = get_property("/window", "height")
  111. set_property("/window/layer1", "rect_w", int(w))
  112. set_property("/window/layer1", "rect_h", int(h))
  113. set_property("/window/layer2", "rect_w", int(w))
  114. set_property("/window/layer2", "rect_h", int(h))
  115. api = Api()
  116. host = HostApi(api)
  117. print(api.hello())
  118. clear_layer("/window/layer2")
  119. print("Generating scene...")
  120. subsock = make_sub_socket()
  121. register_slot("/window", "resize", b"resize")
  122. register_slot("/window/input/mouse", "button_down", b"click")
  123. register_slot("/window/input/mouse", "wheel", b"wheel")
  124. #register_slot("/window/input/mouse", "move", b"mouse")
  125. if True:
  126. layer_id = api.lookup_node_id("/window/layer2")
  127. obj_id = api.add_node("obj1", SceneNodeType.RENDER_OBJECT)
  128. api.add_property(obj_id, "x", PropertyType.FLOAT32)
  129. api.add_property(obj_id, "y", PropertyType.FLOAT32)
  130. api.add_property(obj_id, "scale", PropertyType.FLOAT32)
  131. api.set_property_f32(obj_id, "scale", 1.0)
  132. mesh_id = api.add_node("mesh", SceneNodeType.RENDER_MESH)
  133. api.add_property(mesh_id, "verts", PropertyType.BUFFER)
  134. api.add_property(mesh_id, "faces", PropertyType.BUFFER)
  135. texture_id = host.load_texture("da_king", "king.png")
  136. api.link_node(texture_id, obj_id)
  137. # To preserve the ratio, we should do this when resize happens too
  138. texture_w = api.get_property(texture_id, "width")
  139. texture_h = api.get_property(texture_id, "width")
  140. texture_ratio = texture_w / texture_h
  141. screen_w = get_property("/window", "width")
  142. screen_h = get_property("/window", "height")
  143. screen_ratio = screen_w / screen_h
  144. aspect_ratio = texture_ratio / screen_ratio
  145. #api.set_property_bool("/window/layer2", "is_visible", False)
  146. # Lets add a poly - must be counterclockwise
  147. x, y = 0.25, 0.25
  148. w, h = 0.5 * aspect_ratio, 0.5
  149. vert1 = vertex(x, y, 1, 1, 1, 1, 0, 0)
  150. vert2 = vertex(x + w, y, 1, 1, 1, 1, 1, 0)
  151. vert3 = vertex(x, y + h, 1, 1, 1, 1, 0, 1)
  152. vert4 = vertex(x + w, y + h, 1, 1, 1, 1, 1, 1)
  153. api.set_property_buffer(mesh_id, "verts", vert1 + vert2 + vert3 + vert4)
  154. api.set_property_buffer(mesh_id, "faces", face(0, 2, 1) + face(1, 2, 3))
  155. api.link_node(mesh_id, obj_id)
  156. api.link_node(obj_id, layer_id)
  157. if True:
  158. set_property("/window/layer1", "is_visible", False)
  159. layer_id = api.lookup_node_id("/window/layer2")
  160. obj_id = api.add_node("obj", SceneNodeType.RENDER_OBJECT)
  161. api.add_property(obj_id, "x", PropertyType.FLOAT32)
  162. api.add_property(obj_id, "y", PropertyType.FLOAT32)
  163. api.add_property(obj_id, "scale", PropertyType.FLOAT32)
  164. api.set_property_f32(obj_id, "scale", 1.0)
  165. # Call method
  166. text_id = host.create_text(
  167. "/font/inter-regular", "mytxt2", "hello world", 34
  168. )
  169. if text_id is None:
  170. sys.exit(-1)
  171. print("create text node id:", text_id)
  172. api.set_property_f32(obj_id, "x", 0.5)
  173. api.set_property_f32(text_id, "r", 1.0)
  174. api.set_property_f32(text_id, "g", 1.0)
  175. api.set_property_f32(text_id, "b", 1.0)
  176. api.set_property_f32(text_id, "a", 1.0)
  177. api.link_node(text_id, obj_id)
  178. api.link_node(obj_id, layer_id)
  179. # Screen init
  180. recalc_areas()
  181. print_tree()
  182. print()
  183. print("Scene created.")
  184. while True:
  185. data = subsock.recv()
  186. match data:
  187. case b"resize":
  188. recalc_areas()
  189. case b"click":
  190. x = get_property("/window/input/mouse", "x")
  191. y = get_property("/window/input/mouse", "y")
  192. print(f"mouse clicked ({x}, {y})")
  193. case b"wheel":
  194. print("mouse wheely")