Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 89 additions & 6 deletions pelita/ui/tk_canvas.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ def __init__(self, window, controller_address=None,
self.init_bot_sprites([None] * 4)

self._game_state = {}
self.history = {}

self.ui_game_canvas = tkinter.Canvas(self.window)
self.ui_game_canvas.configure(background="white", bd=0, highlightthickness=0, relief='flat')
Expand Down Expand Up @@ -351,19 +352,22 @@ def __init__(self, window, controller_address=None,
**LABEL_STYLE)
self.ui_status_selected.pack(side=tkinter.RIGHT)

# previous
tkinter.Button(self.ui_status_00,
text="PLAY/PAUSE",
command=self.toggle_running,
text="previous",
command=self.button_show_previous,
**BUTTON_STYLE).pack(side=tkinter.LEFT, expand=True, **BUTTON_PADDING)

# play/pause
tkinter.Button(self.ui_status_00,
text="STEP",
command=self.request_step,
text="play/pause",
command=self.toggle_running,
**BUTTON_STYLE).pack(side=tkinter.LEFT, expand=True, **BUTTON_PADDING)

# next
tkinter.Button(self.ui_status_00,
text="ROUND",
command=self.request_round,
text="next",
command=self.button_show_next,
**BUTTON_STYLE).pack(side=tkinter.LEFT, expand=True, **BUTTON_PADDING)

tkinter.Button(self.ui_status_01,
Expand Down Expand Up @@ -1153,6 +1157,85 @@ def request_step(self):
_logger.debug('---> play_step')
self.controller_socket.send_json({"__action__": "play_step"})

def get_current_pointer(self):
GS = self._game_state

# the game state might be empty;
# happens before any message has been received
if not GS:
return None

round = GS["round"]
turn = GS["turn"]

# the round is None on INIT game phase;
# return this game state to be saved under key `None`
if round is None:
return None

# convert 1-indexed round to 0-indexed, convert to total turns
# played and add the turns in the current round
return (round - 1) * 4 + turn

def show_previous(self):
"""
Show the previous game step.
"""
current = self.get_current_pointer()

if current in (None, 0):
# we are either in the first or second game state recorded;
# so the previous step is always the first game state
new = None
else:
new = current - 1

# set the currently displayed game state
self._game_state = self.history[new]

# update ui
self.update()

def get_next_pointer(self):
"""
Get the pointer to the next game step.
"""
current = self.get_current_pointer()

if current is None:
new = 0
else:
new = current + 1

return new

def show_next(self):
"""
Show the next step either from history or message queue.
"""
pointer = self.get_next_pointer()

if pointer not in self.history:
# this gamestate is not existing yet;
# we need to get it from the message queue
self.request_step()
else:
# set the currently displayed game state
self._game_state = self.history[pointer]

# update ui
self.update()

def button_show_previous(self):
# put game in pause automatically when pushing the button
self.running = False
self.show_previous()

def button_show_next(self):
# put game in pause automatically when pushing the button
self.running = False
self.show_next()

def request_round(self):
if not self.controller_socket:
return
Expand Down
33 changes: 20 additions & 13 deletions pelita/ui/tk_viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,19 +140,26 @@ def read_queue(self):
if self._delay > 100:
self._delay = 100
try:
# read all events.
# if queue is empty, try again in a few ms
# we don’t want to block here and lock
# Tk animations
message = self.socket.recv_unicode(flags=zmq.NOBLOCK)
message = json.loads(message)

_logger.debug(message["__action__"])
# we currently don’t care about the action
game_state = message["__data__"]
if game_state:
self.app.observe(game_state, self.standalone_mode)

next_history_pointer = self.app.get_next_pointer()
if self.app.running and next_history_pointer in self.app.history:
# we are running in history, so just show the next game state
# in history until we run out of states
self.app.show_next()
else:
# read all events.
# if queue is empty, try again in a few ms
# we don’t want to block here and lock
# Tk animations
message = self.socket.recv_unicode(flags=zmq.NOBLOCK)
message = json.loads(message)

_logger.debug(message["__action__"])
# we currently don’t care about the action
game_state = message["__data__"]

if game_state:
self.app.observe(game_state, self.standalone_mode)
self.app.history[self.app.get_current_pointer()] = game_state
self._delay = 2
self._after(2, self.read_queue)
except zmq.Again:
Expand Down
Loading