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 run(self):
  51. self.server.handle_request()
  52. def start(self):
  53. self.info('Starting OSC server')
  54. self.server.serve_forever()
  55. def stop(self):
  56. self.info('Stopping OSC server')
  57. self.server.close()
  58. class TuioServerHandler(object):
  59. """
  60. Interface for touch servers. Defines point_up, point_move and point_down
  61. handlers.
  62. """
  63. def on_point_down(self, sid, x, y):
  64. return NotImplemented
  65. def on_point_move(self, sid, x, y):
  66. return NotImplemented
  67. def on_point_up(self, sid):
  68. return NotImplemented
  69. if __name__ == '__main__':
  70. import argparse
  71. import logging
  72. parser = argparse.ArgumentParser(description='TUIO server test.')
  73. parser.add_argument('--log', metavar='LOG_LEVEL', default='INFO',
  74. choices=['DEBUG', 'INFO', 'WARNING'], help='Global log level.')
  75. parser.add_argument('--logfile', metavar='FILENAME', help='Filename for '
  76. 'the log file (the log is printed to stdout by default).')
  77. args = parser.parse_args()
  78. # Configure logger
  79. log_config = dict(level=getattr(logging, args.log))
  80. if args.logfile:
  81. log_config['filename'] = args.logfile
  82. Logger.configure(**log_config)
  83. # Define handlers
  84. class Handler(TuioServerHandler, Logger):
  85. def on_point_down(self, sid, x, y):
  86. self.info('Point down: sid=%d (%s, %s)' % (sid, x, y))
  87. def on_point_up(self, sid):
  88. self.info('Point up: sid=%d' % sid)
  89. def on_point_move(self, sid, x, y):
  90. self.info('Point move: sid=%d (%s, %s)' % (sid, x, y))
  91. server = TuioServer2D(Handler())
  92. try:
  93. server.start()
  94. except KeyboardInterrupt:
  95. server.stop()