tuio_server.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #!/usr/bin/env python
  2. from OSC import OSCServer
  3. OSCServer.print_tracebacks = True
  4. from logger import Logger
  5. class TuioServer2D(Logger):
  6. __tuio_address__ = 'localhost', 3333
  7. def __init__(self, handler_obj):
  8. # OSC server that listens to incoming TUIO events
  9. self.server = OSCServer(self.__tuio_address__)
  10. self.server.addDefaultHandlers()
  11. self.server.addMsgHandler('/tuio/2Dobj', self._receive)
  12. self.server.addMsgHandler('/tuio/2Dcur', self._receive)
  13. self.server.addMsgHandler('/tuio/2Dblb', self._receive)
  14. # List of alive seddion id's
  15. self.alive = set()
  16. # List of session id's of points that have generated a 'point_down'
  17. # event
  18. self.down = set()
  19. self.handler_obj = handler_obj
  20. def _receive(self, addr, tags, data, source):
  21. surface = addr[8:]
  22. #self.debug('Received message <surface=%s tags="%s" '
  23. # 'data=%s source=%s>' % (surface, tags, data, source))
  24. msg_type = data[0]
  25. # FIXME: Ignore obj/blb events?
  26. if surface != 'cur':
  27. return
  28. if msg_type == 'alive':
  29. alive = set(data[1:])
  30. released = self.alive - alive
  31. self.alive = alive
  32. if released:
  33. self.debug('Released %s.' % ', '.join(map(str, released)))
  34. self.down -= released
  35. for sid in released:
  36. self.handler_obj.on_point_up(sid)
  37. elif msg_type == 'set':
  38. sid, x, y = data[1:4]
  39. if sid not in self.alive:
  40. raise ValueError('Point with sid "%d" is not alive.' % sid)
  41. # Check if 'point_down' has already been triggered. If so, trigger
  42. # a 'point_move' event instead
  43. if sid in self.down:
  44. self.debug('Moved %d to (%s, %s).' % (sid, x, y))
  45. self.handler_obj.on_point_move(sid, x, y)
  46. else:
  47. self.debug('Down %d at (%s, %s).' % (sid, x, y))
  48. self.down.add(sid)
  49. self.handler_obj.on_point_down(sid, x, y)
  50. def start(self):
  51. try:
  52. self.info('Starting OSC server')
  53. self.server.serve_forever()
  54. except SystemExit:
  55. self.stop()
  56. def stop(self):
  57. self.info('Stopping OSC server')
  58. self.server.close()
  59. class TuioServerHandler(object):
  60. """
  61. Interface for touch servers. Defines point_up, point_move and point_down
  62. handlers.
  63. """
  64. def on_point_down(self, sid, x, y):
  65. return NotImplemented
  66. def on_point_move(self, sid, x, y):
  67. return NotImplemented
  68. def on_point_up(self, sid):
  69. return NotImplemented
  70. if __name__ == '__main__':
  71. import argparse
  72. import logging
  73. parser = argparse.ArgumentParser(description='TUIO server test.')
  74. parser.add_argument('--log', metavar='LOG_LEVEL', default='INFO',
  75. choices=['DEBUG', 'INFO', 'WARNING'], help='Global log level.')
  76. parser.add_argument('--logfile', metavar='FILENAME', help='Filename for '
  77. 'the log file (the log is printed to stdout by default).')
  78. args = parser.parse_args()
  79. # Configure logger
  80. log_config = dict(level=getattr(logging, args.log))
  81. if args.logfile:
  82. log_config['filename'] = args.logfile
  83. Logger.configure(**log_config)
  84. # Define handlers
  85. class Handler(TuioServerHandler, Logger):
  86. def on_point_down(self, sid, x, y):
  87. self.info('Point down: sid=%d (%s, %s)' % (sid, x, y))
  88. def on_point_up(self, sid):
  89. self.info('Point up: sid=%d' % sid)
  90. def on_point_move(self, sid, x, y):
  91. self.info('Point move: sid=%d (%s, %s)' % (sid, x, y))
  92. server = TuioServer2D(Handler())
  93. try:
  94. server.start()
  95. except KeyboardInterrupt:
  96. server.stop()