Game: using asyncio tasks to run in parallel operation that do not need to be sequential
This commit is contained in:
parent
867f7c48eb
commit
15945d839c
|
|
@ -1,9 +1,10 @@
|
|||
import asyncio
|
||||
import logging
|
||||
import random
|
||||
from typing import Dict, Callable, List, Union
|
||||
from functools import wraps
|
||||
from collections import defaultdict
|
||||
from enum import Enum
|
||||
from functools import wraps
|
||||
from typing import Dict, Callable, List, Union
|
||||
|
||||
import discord
|
||||
|
||||
|
|
@ -174,6 +175,8 @@ class Game:
|
|||
if self.is_started():
|
||||
raise ValueError("Game already started")
|
||||
logger.info(f"[{self.guild.name}] Starting game")
|
||||
tasks = [] # Asyncio tasks scheduled to run in parallel (e.g. channel creation), so that we can wait them all at the end of the function
|
||||
self.config["game_started"] = True
|
||||
self.config["gm_role"] = gm_role.id
|
||||
self.config["player_role"] = player_role.id
|
||||
self.config["players"] = [member.id for member in player_role.members]
|
||||
|
|
@ -185,51 +188,62 @@ class Game:
|
|||
self.config["drawn"] = None
|
||||
self.config["enacted"] = []
|
||||
|
||||
permissions = {
|
||||
category_permissions = {
|
||||
self.guild.default_role: discord.PermissionOverwrite(send_messages = False),
|
||||
gm_role: discord.PermissionOverwrite(send_messages = True),
|
||||
player_role: discord.PermissionOverwrite(send_messages = True),
|
||||
}
|
||||
game_category = await self.guild.create_category("In-game", overwrites = permissions)
|
||||
game_category = await self.guild.create_category("In-game", overwrites = category_permissions)
|
||||
self.config["category"] = game_category.id
|
||||
logger.debug(f"[{self.guild.name}] Created game category")
|
||||
|
||||
permissions = {
|
||||
self.guild.default_role: discord.PermissionOverwrite(read_messages = False),
|
||||
gm_role: discord.PermissionOverwrite(read_messages = True),
|
||||
}
|
||||
self.config["admin_chan"] = (await game_category.create_text_channel("admin", overwrites = permissions)).id
|
||||
logger.debug(f"[{self.guild.name}] Created admin channel")
|
||||
async def create_admin_chan():
|
||||
perms = {
|
||||
self.guild.default_role: discord.PermissionOverwrite(read_messages = False),
|
||||
gm_role: discord.PermissionOverwrite(read_messages = True),
|
||||
}
|
||||
self.config["admin_chan"] = (await game_category.create_text_channel("admin", overwrites = perms, position = 0)).id
|
||||
logger.debug(f"[{self.guild.name}] Created admin channel")
|
||||
tasks.append(asyncio.create_task(create_admin_chan()))
|
||||
|
||||
permissions = {
|
||||
self.guild.default_role: discord.PermissionOverwrite(send_messages = False),
|
||||
gm_role: discord.PermissionOverwrite(send_messages = True),
|
||||
}
|
||||
self.config["announce_chan"] = (await game_category.create_text_channel("announce", overwrites = permissions)).id
|
||||
self.config["votes_chan"] = (await game_category.create_text_channel("votes", overwrites = permissions)).id
|
||||
logger.debug(f"[{self.guild.name}] Created announcements and votes channels")
|
||||
async def create_announcements_and_vote_chans():
|
||||
perms = {
|
||||
self.guild.default_role: discord.PermissionOverwrite(send_messages = False),
|
||||
gm_role: discord.PermissionOverwrite(send_messages = True),
|
||||
}
|
||||
channels = await asyncio.gather(
|
||||
game_category.create_text_channel("announcements", overwrites = perms, position = 1),
|
||||
game_category.create_text_channel("votes", overwrites = perms, position = 2)
|
||||
)
|
||||
self.config["announce_chan"] = channels[0].id
|
||||
self.config["votes_chan"] = channels[1].id
|
||||
logger.debug(f"[{self.guild.name}] Created announcements and votes channels")
|
||||
tasks.append(asyncio.create_task(create_announcements_and_vote_chans()))
|
||||
|
||||
self.config["discussion_chan"] = (await game_category.create_text_channel("discussion")).id # Permissions are inherited from the category
|
||||
logger.debug(f"[{self.guild.name}] Created discussion channel")
|
||||
async def create_discussion_chan():
|
||||
# Permissions are inherited from the category
|
||||
self.config["discussion_chan"] = (await game_category.create_text_channel("discussion", position = 3)).id # Permissions are inherited from the category
|
||||
logger.debug(f"[{self.guild.name}] Created discussion channel")
|
||||
tasks.append(asyncio.create_task(create_discussion_chan()))
|
||||
|
||||
for player in player_role.members:
|
||||
channel_permissions = {
|
||||
async def create_player_channel(player: discord.Member, position: int):
|
||||
perms = {
|
||||
self.guild.default_role: discord.PermissionOverwrite(read_messages = False),
|
||||
player: discord.PermissionOverwrite(read_messages = True),
|
||||
gm_role: discord.PermissionOverwrite(read_messages = True),
|
||||
}
|
||||
player_channel = await game_category.create_text_channel(player.name, overwrites = channel_permissions)
|
||||
self.config["player_info"][str(player.id)]["channel"] = player_channel.id
|
||||
logger.debug(f"[{self.guild.name}] Created player channels")
|
||||
self.config["player_info"][str(player.id)]["channel"] = (await game_category.create_text_channel(player.name, overwrites = perms, position = position)).id
|
||||
logger.debug(f"[{self.guild.name}] Created channel for player {player.name}")
|
||||
for i, player in enumerate(player_role.members):
|
||||
tasks.append(asyncio.create_task(create_player_channel(player, 4+i)))
|
||||
|
||||
self.config["game_started"] = True
|
||||
await asyncio.wait(tasks)
|
||||
|
||||
@game_started
|
||||
@save_on_success
|
||||
async def delete(self):
|
||||
category = self.get_game_category()
|
||||
for channel in category.channels:
|
||||
await channel.delete()
|
||||
await asyncio.wait([channel.delete() for channel in category.channels])
|
||||
await category.delete()
|
||||
self.config.clear()
|
||||
self.config.update(self.new_dict())
|
||||
|
|
@ -292,10 +306,11 @@ class Game:
|
|||
@save_on_success
|
||||
async def stop_vote(self):
|
||||
logging.debug(f"[{self.guild.name}] Stopping the vote")
|
||||
tasks = []
|
||||
passed = self.is_vote_passing()
|
||||
self.config["vote"]["revealed"] = True
|
||||
await self.update_vote_message()
|
||||
await self.get_votes_channel().send("**The vote has ended**")
|
||||
tasks.append(asyncio.create_task(self.get_votes_channel().send("**The vote has ended**")))
|
||||
announcement_content = [
|
||||
f"{self.get_player_role().mention} the vote has ended!",
|
||||
f"{':green_square:' if passed else ':red_square:'} The vote has **{'' if passed else 'not '}passed**"
|
||||
|
|
@ -304,7 +319,8 @@ class Game:
|
|||
president = self.config["vote"]["president"]
|
||||
chancellor = self.config["vote"]["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))
|
||||
tasks.append(asyncio.create_task(self.get_announcements_channel().send("\n".join(announcement_content), allowed_mentions = discord.AllowedMentions(roles = True))))
|
||||
await asyncio.wait(tasks)
|
||||
self.config["vote"] = None
|
||||
|
||||
@game_started
|
||||
|
|
@ -345,7 +361,7 @@ class Game:
|
|||
message_content = [
|
||||
f"{self.get_player_role().mention} A **{last_enacted.name}** policy {last_enacted.square_emoji()} has been enacted!",
|
||||
f"In total, **{enacted_count[Policy.LIBERAL]} {Policy.LIBERAL.name}** policies and **{enacted_count[Policy.FASCIST]} {Policy.FASCIST.name}** policies have been enacted",
|
||||
" ".join([Policy.LIBERAL.square_emoji()]*enacted_count[Policy.LIBERAL] + [":black_small_square:"]*(5-enacted_count[Policy.LIBERAL])),
|
||||
" ".join([Policy.LIBERAL.square_emoji()] * enacted_count[Policy.LIBERAL] + [":black_small_square:"] * (5 - enacted_count[Policy.LIBERAL])),
|
||||
" ".join([Policy.FASCIST.square_emoji()] * enacted_count[Policy.FASCIST] + [":black_small_square:"] * (6 - enacted_count[Policy.FASCIST])),
|
||||
]
|
||||
await self.get_announcements_channel().send("\n".join(message_content), allowed_mentions = discord.AllowedMentions(roles = True))
|
||||
|
|
|
|||
Loading…
Reference in New Issue