121 lines
3.9 KiB
Python
Executable File
121 lines
3.9 KiB
Python
Executable File
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)
|
|
|