plugins room_games, radiocol, libervia: small changes like refactorization to ease the maintenance

This commit is contained in:
souliane 2014-01-17 15:02:46 +01:00
commit 30dfdf1025
3 changed files with 73 additions and 52 deletions

View file

@ -235,27 +235,19 @@ class Radiocol(object):
else:
error(_('Unmanaged game element: %s') % elt.name)
def getSyncData(self, room_jid_s, force_nicks=[]):
data = {}
def getSyncDataForPlayer(self, room_jid_s, nick):
game_data = self.games[room_jid_s]
status = game_data['status']
nicks = [nick for nick in status if status[nick] == 'desync']
for nick in force_nicks:
if nick not in nicks:
nicks.append(nick)
for nick in nicks:
elements = []
if game_data['playing']:
preload = copy.deepcopy(game_data['playing'])
preload['filename'] += '#t=%.2f' % (time.time() - game_data['playing_time'])
elements.append(preload)
play = domish.Element(('', 'play'))
play['filename'] = preload['filename']
elements.append(play)
if len(game_data['queue']) > 0:
elements.extend(copy.deepcopy(game_data['queue']))
if len(game_data['queue']) == QUEUE_LIMIT:
elements.append(domish.Element(('', 'no_upload')))
if data:
data[nick] = elements
return data
elements = []
if game_data['playing']:
preload = copy.deepcopy(game_data['playing'])
current_time = game_data['playing_time'] + 1 if self.testing else time.time()
preload['filename'] += '#t=%.2f' % (current_time - game_data['playing_time'])
elements.append(preload)
play = domish.Element(('', 'play'))
play['filename'] = preload['filename']
elements.append(play)
if len(game_data['queue']) > 0:
elements.extend(copy.deepcopy(game_data['queue']))
if len(game_data['queue']) == QUEUE_LIMIT:
elements.append(domish.Element(('', 'no_upload')))
return elements

View file

@ -108,14 +108,19 @@ class RoomGame(object):
self.join_mode = self.INVITED
self.ready_mode = self.FORCE # TODO: asking for confirmation is not implemented
# this has been added for testing purpose. It is sometimes needed to remove a dependence
# while building the synchronization data, for example to replace a call to time.time()
# by an arbitrary value. If needed, this attribute would be set to True from the testcase.
self.testing = False
host.trigger.add("MUC user joined", self.userJoinedTrigger)
host.trigger.add("MUC user left", self.userLeftTrigger)
def _createOrInvite(self, room, other_players, profile):
"""
This is called only when someone explicitly wants to play.
The game must not be created if one already exists in the room,
and its creation could be postponed until all the expected players
The game will not be created if one already exists in the room,
also its creation could be postponed until all the expected players
join the room (in that case it will be created from userJoinedTrigger).
@param room: instance of wokkel.muc.Room
@param other_players: list for other players JID userhosts
@ -128,7 +133,7 @@ class RoomGame(object):
if not self._checkJoinAuth(room_jid_s, user_jid.userhost(), nick):
return
nicks.extend(self._invitePlayers(room, other_players, nick, profile))
self._updatePlayers(room_jid_s, nicks, profile)
self._updatePlayers(room_jid_s, nicks, True, profile)
else:
self._initGame(room_jid_s, nick)
(auth, waiting, missing) = self._checkWaitAuth(room, other_players)
@ -137,7 +142,7 @@ class RoomGame(object):
if auth:
self.createGame(room_jid_s, nicks, profile)
else:
self._updatePlayers(room_jid_s, nicks, profile)
self._updatePlayers(room_jid_s, nicks, False, profile)
def _initGame(self, room_jid_s, referee_nick):
"""Important: do not add the referee to 'players' yet. For a
@ -191,11 +196,14 @@ class RoomGame(object):
debug(_("%s not allowed to join the game %s in %s") % (user_jid_s or nick, self.name, room_jid_s))
return auth
def _updatePlayers(self, room_jid_s, nicks, profile):
def _updatePlayers(self, room_jid_s, nicks, sync, profile):
"""Update the list of players and signal to the room that some players joined the game.
If sync is True, the news players are synchronized with the game data they have missed.
Remark: self.games[room_jid_s]['players'] should not be modified outside this method.
@param room_jid_s: room userhost
@param nicks: list of players nicks in the room (referee included, in first position)
@param sync: set to True to send synchronization data to the new players
@param profile
"""
if nicks == []:
return
@ -203,12 +211,12 @@ class RoomGame(object):
new_nicks = [nick for nick in nicks if nick not in self.games[room_jid_s]['players']]
if len(new_nicks) == 0:
return
sync = self._gameExists(room_jid_s, True) and len(self.games[room_jid_s]['players']) > 0
def setStatus(status):
for nick in new_nicks:
self.games[room_jid_s]['status'][nick] = status
sync = sync and self._gameExists(room_jid_s, True) and len(self.games[room_jid_s]['players']) > 0
setStatus('desync' if sync else 'init')
self.games[room_jid_s]['players'].extend(new_nicks)
self._synchronizeRoom(room_jid_s, [JID(room_jid_s)], profile)
@ -231,7 +239,7 @@ class RoomGame(object):
elements = [(element, None, None)]
sync_args = []
sync_data = self.getSyncData(room_jid_s)
sync_data = self._getSyncData(room_jid_s)
for nick in sync_data:
user_jid = JID(room_jid_s + '/' + nick)
if user_jid in recipients:
@ -248,16 +256,35 @@ class RoomGame(object):
for args, kwargs in sync_args:
self._sendElements(*args, **kwargs)
def getSyncData(self, room_jid_s, force_nicks=[]):
"""This method may (and should probably) be overwritten by a child class.
The synchronization data are returned for each player who has the state
'desync' or if he's been contained by force_nicks.
def _getSyncData(self, room_jid_s, force_nicks=[]):
"""The synchronization data are returned for each player who
has the state 'desync' or if he's been contained by force_nicks.
@param room_jid_s: room userhost
@param force_nicks: force the synchronization for this list of the nicks
@return: a mapping between player nicks and a list of child elements
to be sent by self._synchronizeRoom for the game to be synchronized.
@return: a mapping between player nicks and a list of elements to
be sent by self._synchronizeRoom for the game to be synchronized.
"""
return {}
if not self._gameExists(room_jid_s):
return {}
data = {}
status = self.games[room_jid_s]['status']
nicks = [nick for nick in status if status[nick] == 'desync']
for nick in force_nicks:
if nick not in nicks:
nicks.append(nick)
for nick in nicks:
elements = self.getSyncDataForPlayer(room_jid_s, nick)
if elements:
data[nick] = elements
return data
def getSyncDataForPlayer(self, room_jid_s, nick):
"""This method may (and should probably) be overwritten by a child class.
@param room_jid_s: room userhost
@param nick: the nick of the player to be synchronized
@return: a list of elements to synchronize this player with the game.
"""
return []
def _invitePlayers(self, room, other_players, nick, profile):
"""Invite players to a room, associated game may exist or not.
@ -424,7 +451,7 @@ class RoomGame(object):
self.createGame(room_jid_s, nicks, profile_key=profile)
return True
# let the room know that a new player joined
self._updatePlayers(room_jid_s, [user.nick], profile)
self._updatePlayers(room_jid_s, [user.nick], True, profile)
return True
def userLeftTrigger(self, room, user, profile):
@ -442,6 +469,9 @@ class RoomGame(object):
self.games[room_jid_s]['players'].remove(user.nick)
except ValueError:
pass
if len(self.games[room_jid_s]['players']) == 0:
del self.games[room_jid_s] # finish the game
return True
if self.wait_mode == self.FOR_ALL:
# allow this user to join the game again
user_jid_s = user.entity.userhost()
@ -493,11 +523,10 @@ class RoomGame(object):
(create, sync) = self._checkCreateGameAndInit(room_jid_s, profile)
if not create:
if sync:
debug(_('Synchronize game %s in %s for %s') % (self.name, room_jid_s, ', '.join(nicks)))
self._updatePlayers(room_jid_s, nicks, profile)
self._updatePlayers(room_jid_s, nicks, True, profile)
return
self.games[room_jid_s]['started'] = True
self._updatePlayers(room_jid_s, nicks, profile)
self._updatePlayers(room_jid_s, nicks, False, profile)
if self.player_init:
# specific data to each player (score, private data)
self.games[room_jid_s].setdefault('players_data', {})

View file

@ -631,5 +631,5 @@ class Tarot(object):
else:
error(_('Unmanaged card game element: %s') % elt.name)
def getSyncData(self, room_jid_s):
return {}
def getSyncDataForPlayer(self, room_jid_s, nick):
return []