From ad439faed06aa4213f00736fd387fa9c1cee1206 Mon Sep 17 00:00:00 2001 From: Elnath Date: Fri, 11 Jun 2021 00:50:31 +0200 Subject: [PATCH] Game: decorator to save config after end of method --- GameFiles/Game.py | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/GameFiles/Game.py b/GameFiles/Game.py index 567230c..d2e39bd 100644 --- a/GameFiles/Game.py +++ b/GameFiles/Game.py @@ -43,6 +43,20 @@ def vote_running(func): 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: """ Game state for one guild @@ -149,6 +163,7 @@ class Game: def get_player_channel(self, player: Union[int, discord.Member]) -> discord.TextChannel: 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): if self.is_started(): raise ValueError("Game already started") @@ -202,9 +217,9 @@ class Game: logger.debug(f"[{self.guild.name}] Created player channels") self.config["game_started"] = True - self.save_function() @game_started + @save_on_success async def delete(self): category = self.get_game_category() for channel in category.channels: @@ -212,8 +227,8 @@ class Game: await category.delete() self.config.clear() self.config.update(self.new_dict()) - self.save_function() + @save_on_success async def start_vote(self, president: discord.Member, chancellor: discord.Member): if self.is_vote_running(): raise RuntimeError("A vote is already running") @@ -226,7 +241,6 @@ class Game: "revealed": False, } self.config["vote"].update({str(player_id): None for player_id in self.get_players_id()}) - self.save_function() await self.update_vote_message() @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()) @vote_running + @save_on_success 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}") self.config["vote"][str(user.id)] = vote await self.update_vote_message() - self.save_function() @vote_running + @save_on_success async def stop_vote(self): logging.debug(f"[{self.guild.name}] Stopping the vote") passed = self.is_vote_passing() @@ -285,14 +300,15 @@ class Game: 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)) self.config["vote"] = None - self.save_function() @game_started + @save_on_success async def draw_policies(self) -> List[Policy]: self.config["drawn"] = [self.config["deck"].pop() for _ in range(3)] - self.save_function() return [Policy(p) for p in self.config["drawn"]] + @game_started + @save_on_success async def enact_drawn_policy(self, index: int): if self.config["drawn"] is None: 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["discard"] = [] random.shuffle(self.config["deck"]) - self.save_function() 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!")