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 logging
|
||||||
import random
|
import random
|
||||||
from typing import Dict, Callable, List, Union
|
|
||||||
from functools import wraps
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
from functools import wraps
|
||||||
|
from typing import Dict, Callable, List, Union
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
|
|
||||||
|
|
@ -174,6 +175,8 @@ class Game:
|
||||||
if self.is_started():
|
if self.is_started():
|
||||||
raise ValueError("Game already started")
|
raise ValueError("Game already started")
|
||||||
logger.info(f"[{self.guild.name}] Starting game")
|
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["gm_role"] = gm_role.id
|
||||||
self.config["player_role"] = player_role.id
|
self.config["player_role"] = player_role.id
|
||||||
self.config["players"] = [member.id for member in player_role.members]
|
self.config["players"] = [member.id for member in player_role.members]
|
||||||
|
|
@ -185,51 +188,62 @@ class Game:
|
||||||
self.config["drawn"] = None
|
self.config["drawn"] = None
|
||||||
self.config["enacted"] = []
|
self.config["enacted"] = []
|
||||||
|
|
||||||
permissions = {
|
category_permissions = {
|
||||||
self.guild.default_role: discord.PermissionOverwrite(send_messages = False),
|
self.guild.default_role: discord.PermissionOverwrite(send_messages = False),
|
||||||
gm_role: discord.PermissionOverwrite(send_messages = True),
|
gm_role: discord.PermissionOverwrite(send_messages = True),
|
||||||
player_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
|
self.config["category"] = game_category.id
|
||||||
logger.debug(f"[{self.guild.name}] Created game category")
|
logger.debug(f"[{self.guild.name}] Created game category")
|
||||||
|
|
||||||
permissions = {
|
async def create_admin_chan():
|
||||||
self.guild.default_role: discord.PermissionOverwrite(read_messages = False),
|
perms = {
|
||||||
gm_role: discord.PermissionOverwrite(read_messages = True),
|
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")
|
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 = {
|
async def create_announcements_and_vote_chans():
|
||||||
self.guild.default_role: discord.PermissionOverwrite(send_messages = False),
|
perms = {
|
||||||
gm_role: discord.PermissionOverwrite(send_messages = True),
|
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
|
channels = await asyncio.gather(
|
||||||
logger.debug(f"[{self.guild.name}] Created announcements and votes channels")
|
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
|
async def create_discussion_chan():
|
||||||
logger.debug(f"[{self.guild.name}] Created discussion channel")
|
# 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:
|
async def create_player_channel(player: discord.Member, position: int):
|
||||||
channel_permissions = {
|
perms = {
|
||||||
self.guild.default_role: discord.PermissionOverwrite(read_messages = False),
|
self.guild.default_role: discord.PermissionOverwrite(read_messages = False),
|
||||||
player: discord.PermissionOverwrite(read_messages = True),
|
player: discord.PermissionOverwrite(read_messages = True),
|
||||||
gm_role: 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"] = (await game_category.create_text_channel(player.name, overwrites = perms, position = position)).id
|
||||||
self.config["player_info"][str(player.id)]["channel"] = player_channel.id
|
logger.debug(f"[{self.guild.name}] Created channel for player {player.name}")
|
||||||
logger.debug(f"[{self.guild.name}] Created player channels")
|
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
|
@game_started
|
||||||
@save_on_success
|
@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:
|
await asyncio.wait([channel.delete() for channel in category.channels])
|
||||||
await channel.delete()
|
|
||||||
await category.delete()
|
await category.delete()
|
||||||
self.config.clear()
|
self.config.clear()
|
||||||
self.config.update(self.new_dict())
|
self.config.update(self.new_dict())
|
||||||
|
|
@ -292,10 +306,11 @@ class Game:
|
||||||
@save_on_success
|
@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")
|
||||||
|
tasks = []
|
||||||
passed = self.is_vote_passing()
|
passed = self.is_vote_passing()
|
||||||
self.config["vote"]["revealed"] = True
|
self.config["vote"]["revealed"] = True
|
||||||
await self.update_vote_message()
|
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 = [
|
announcement_content = [
|
||||||
f"{self.get_player_role().mention} the vote has ended!",
|
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**"
|
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"]
|
president = self.config["vote"]["president"]
|
||||||
chancellor = self.config["vote"]["chancellor"]
|
chancellor = self.config["vote"]["chancellor"]
|
||||||
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))
|
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
|
self.config["vote"] = None
|
||||||
|
|
||||||
@game_started
|
@game_started
|
||||||
|
|
@ -345,7 +361,7 @@ class Game:
|
||||||
message_content = [
|
message_content = [
|
||||||
f"{self.get_player_role().mention} A **{last_enacted.name}** policy {last_enacted.square_emoji()} has been enacted!",
|
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",
|
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])),
|
" ".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))
|
await self.get_announcements_channel().send("\n".join(message_content), allowed_mentions = discord.AllowedMentions(roles = True))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue