This repository has been archived on 2026-05-18. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
multipong/display.py

121 lines
3.9 KiB
Python
Raw Normal View History

from common import *
import event
import game
import registry
class Display(event.EventHandler, registry.Registerable):
# --- Static methods
@staticmethod
def CurrentDisplay():
return getattr(Display, '__currentDisplay__')
@staticmethod
def NewDisplay(displayType):
display = globals()["{}Display".format(displayType.title())]()
setattr(Display, '__currentDisplay__', display)
return display
@staticmethod
def StaticRefresh():
display = Display.CurrentDisplay()
display.refresh()
# --- Member methods
def __init__(self, *args, **kwargs):
registry.Registerable.__init__(self, *args, **kwargs)
event.EventHandler.__init__(self, *args, **kwargs)
self.width = 0
self.height = 0
self.__lock_actors__ = threading.RLock()
self.__lock_timer__ = threading.RLock()
self.__lock_drawing__ = threading.RLock()
self.__actors__ = {}
self.__setDrawTimer__()
def __setDrawTimer__(self):
self.__drawTimer__ = threading.Timer(FRAMERATE, Display.StaticRefresh)
self.__drawTimer__.start()
def cleanup(self):
self.__drawTimer__.cancel()
# ---
def checkInput(self):
raise Exception("lol implement me")
def refresh(self):
try:
with self.__lock_drawing__:
self.__screen__.clear()
for actor in self.__actors__.values():
self.drawActor(actor)
self.__setDrawTimer__()
except Exception, e:
game.Game.CurrentGame().addEvent(('endGame', traceback.format_exc()))
def addActor(self, actor):
logger = logging.getLogger()
with self.__lock_actors__:
if not actor.uuid in self.__actors__.keys():
logger.debug("Added actor {}".format(actor.uuid))
self.__actors__[actor.uuid] = actor
def delActor(self, actor):
with self.__lock_actors__:
try:
del(self.__actors__, actor.uuid)
except KeyError, e:
return
class CursesDisplay(Display):
def __init__(self, *args, **kwargs):
self.logger = logging.getLogger()
self.logger.info("CursesDisplay starting")
Display.__init__(self, *args, **kwargs)
self.__screen__ = curses.initscr()
maxyx = self.__screen__.getmaxyx()
self.width = maxyx[1]
self.height = maxyx[0]
self.__screen__.keypad(1)
try:
curses.curs_set(0)
except:
logger.warn("I couldn't make the cursor invisible - I'm sorry")
curses.noecho()
curses.cbreak()
def cleanup(self):
self.logger.info("CursesDisplay cleaning up")
curses.nocbreak()
self.__screen__.keypad(0)
curses.echo()
curses.endwin()
Display.cleanup(self)
def refresh(self):
Display.refresh(self)
self.__screen__.refresh()
def checkInput(self):
key = self.__screen__.getch()
if key == ord('q'):
raise event.EventBubble(('endGame',
'User terminated the game',
'/Game/uuid/*'))
elif key == ord('w'):
raise event.EventBubble(('moveUp', '', '/Player/cn/player1'))
elif key == ord('s'):
raise event.EventBubble(('moveDown', '', '/Player/cn/player1'))
elif key == curses.KEY_UP:
raise event.EventBubble(('moveUp', '', '/Player/cn/player2'))
elif key == curses.KEY_DOWN:
raise event.EventBubble(('moveDown', '', '/Player/cn/player2'))
def drawActor(self, actor):
# Curses displays have it easy; actors return us a function to call
# with a reference to ourselves, and they draw on us.
actor.frame(self)(self)