Game: decorator to save config after end of method

This commit is contained in:
Elnath 2021-06-11 00:50:31 +02:00
parent 4e825e10ce
commit ad439faed0
1 changed files with 22 additions and 7 deletions

View File

@ -43,6 +43,20 @@ def vote_running(func):
return decorated return decorated
def save_on_success(func):
"""
Decorator for *async methods* of game that calls the save function after the method has executed without exceptions
"""
@wraps(func)
async def decorated(obj: 'Game', *args, **kwargs):
return_value = await func(obj, *args, **kwargs)
obj.save_function()
return return_value
return decorated
class Game: class Game:
""" """
Game state for one guild Game state for one guild
@ -149,6 +163,7 @@ class Game:
def get_player_channel(self, player: Union[int, discord.Member]) -> discord.TextChannel: def get_player_channel(self, player: Union[int, discord.Member]) -> discord.TextChannel:
return self.guild.get_channel(self.get_player_channel_id(player)) return self.guild.get_channel(self.get_player_channel_id(player))
@save_on_success
async def start(self, gm_role: discord.Role, player_role: discord.Role): async def start(self, gm_role: discord.Role, player_role: discord.Role):
if self.is_started(): if self.is_started():
raise ValueError("Game already started") raise ValueError("Game already started")
@ -202,9 +217,9 @@ class Game:
logger.debug(f"[{self.guild.name}] Created player channels") logger.debug(f"[{self.guild.name}] Created player channels")
self.config["game_started"] = True self.config["game_started"] = True
self.save_function()
@game_started @game_started
@save_on_success
async def delete(self): async def delete(self):
category = self.get_game_category() category = self.get_game_category()
for channel in category.channels: for channel in category.channels:
@ -212,8 +227,8 @@ class Game:
await category.delete() await category.delete()
self.config.clear() self.config.clear()
self.config.update(self.new_dict()) self.config.update(self.new_dict())
self.save_function()
@save_on_success
async def start_vote(self, president: discord.Member, chancellor: discord.Member): async def start_vote(self, president: discord.Member, chancellor: discord.Member):
if self.is_vote_running(): if self.is_vote_running():
raise RuntimeError("A vote is already running") raise RuntimeError("A vote is already running")
@ -226,7 +241,6 @@ class Game:
"revealed": False, "revealed": False,
} }
self.config["vote"].update({str(player_id): None for player_id in self.get_players_id()}) self.config["vote"].update({str(player_id): None for player_id in self.get_players_id()})
self.save_function()
await self.update_vote_message() await self.update_vote_message()
@vote_running @vote_running
@ -262,13 +276,14 @@ class Game:
await (await self.get_votes_channel().fetch_message(self.config["vote"]["message"])).edit(content = message_content_str, allowed_mentions = discord.AllowedMentions.none()) await (await self.get_votes_channel().fetch_message(self.config["vote"]["message"])).edit(content = message_content_str, allowed_mentions = discord.AllowedMentions.none())
@vote_running @vote_running
@save_on_success
async def cast_vote(self, user: discord.Member, vote: Union[bool, None]): async def cast_vote(self, user: discord.Member, vote: Union[bool, None]):
logging.debug(f"[{self.guild.name}] Casting vote with value {vote} for user {user.display_name}") logging.debug(f"[{self.guild.name}] Casting vote with value {vote} for user {user.display_name}")
self.config["vote"][str(user.id)] = vote self.config["vote"][str(user.id)] = vote
await self.update_vote_message() await self.update_vote_message()
self.save_function()
@vote_running @vote_running
@save_on_success
async def stop_vote(self): async def stop_vote(self):
logging.debug(f"[{self.guild.name}] Stopping the vote") logging.debug(f"[{self.guild.name}] Stopping the vote")
passed = self.is_vote_passing() passed = self.is_vote_passing()
@ -285,14 +300,15 @@ class Game:
announcement_content.append(f"Congratulations to president <@{president}> and chancellor <@{chancellor}>!") announcement_content.append(f"Congratulations to president <@{president}> and chancellor <@{chancellor}>!")
await self.get_announcements_channel().send("\n".join(announcement_content), allowed_mentions = discord.AllowedMentions(roles = True)) await self.get_announcements_channel().send("\n".join(announcement_content), allowed_mentions = discord.AllowedMentions(roles = True))
self.config["vote"] = None self.config["vote"] = None
self.save_function()
@game_started @game_started
@save_on_success
async def draw_policies(self) -> List[Policy]: async def draw_policies(self) -> List[Policy]:
self.config["drawn"] = [self.config["deck"].pop() for _ in range(3)] self.config["drawn"] = [self.config["deck"].pop() for _ in range(3)]
self.save_function()
return [Policy(p) for p in self.config["drawn"]] return [Policy(p) for p in self.config["drawn"]]
@game_started
@save_on_success
async def enact_drawn_policy(self, index: int): async def enact_drawn_policy(self, index: int):
if self.config["drawn"] is None: if self.config["drawn"] is None:
raise RuntimeError("Can only enact a policy when they have been drawn") raise RuntimeError("Can only enact a policy when they have been drawn")
@ -308,6 +324,5 @@ class Game:
self.config["deck"].extend(self.config["discard"]) self.config["deck"].extend(self.config["discard"])
self.config["discard"] = [] self.config["discard"] = []
random.shuffle(self.config["deck"]) random.shuffle(self.config["deck"])
self.save_function()
enacted = Policy(self.config["enacted"][-1]) enacted = Policy(self.config["enacted"][-1])
await self.get_announcements_channel().send(f"{self.get_player_role().mention} A **{enacted.name}** policy has been enacted!") await self.get_announcements_channel().send(f"{self.get_player_role().mention} A **{enacted.name}** policy has been enacted!")