mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-04-22 16:51:59 +00:00
Improve performance of parsing MESSAGE_UPDATE and MESSAGE_CREATE events
Embed edits are no longer special cased in the dispatch code, which could lead to on_message_edit being called more often than it used to be called. I am not sure on the general impact on that being removed. Fixes #2195
This commit is contained in:
parent
3c9bcc2851
commit
f84219c2b2
@ -160,7 +160,19 @@ class Attachment:
|
||||
data = await self._http.get_from_cdn(url)
|
||||
return data
|
||||
|
||||
def flatten_handlers(cls):
|
||||
prefix = len('_handle_')
|
||||
cls._HANDLERS = {
|
||||
key[prefix:]: value
|
||||
for key, value in cls.__dict__.items()
|
||||
if key.startswith('_handle_')
|
||||
}
|
||||
cls._CACHED_SLOTS = [
|
||||
attr for attr in cls.__slots__ if attr.startswith('_cs_')
|
||||
]
|
||||
return cls
|
||||
|
||||
@flatten_handlers
|
||||
class Message:
|
||||
r"""Represents a message from Discord.
|
||||
|
||||
@ -259,9 +271,24 @@ class Message:
|
||||
self.id = int(data['id'])
|
||||
self.webhook_id = utils._get_as_snowflake(data, 'webhook_id')
|
||||
self.reactions = [Reaction(message=self, data=d) for d in data.get('reactions', [])]
|
||||
self.attachments = [Attachment(data=a, state=self._state) for a in data['attachments']]
|
||||
self.embeds = [Embed.from_dict(a) for a in data['embeds']]
|
||||
self.application = data.get('application')
|
||||
self.activity = data.get('activity')
|
||||
self._update(channel, data)
|
||||
self.channel = channel
|
||||
self._edited_timestamp = utils.parse_time(data['edited_timestamp'])
|
||||
self.type = try_enum(MessageType, data['type'])
|
||||
self.pinned = data['pinned']
|
||||
self.mention_everyone = data['mention_everyone']
|
||||
self.tts = data['tts']
|
||||
self.content = data['content']
|
||||
self.nonce = data.get('nonce')
|
||||
|
||||
for handler in ('author', 'member', 'mentions', 'mention_roles', 'call'):
|
||||
try:
|
||||
getattr(self, '_handle_%s' % handler)(data[handler])
|
||||
except KeyError:
|
||||
continue
|
||||
|
||||
def __repr__(self):
|
||||
return '<Message id={0.id} channel={0.channel!r} type={0.type!r} author={0.author!r}>'.format(self)
|
||||
@ -310,34 +337,53 @@ class Message:
|
||||
|
||||
return reaction
|
||||
|
||||
def _update(self, channel, data):
|
||||
self.channel = channel
|
||||
self._edited_timestamp = utils.parse_time(data.get('edited_timestamp'))
|
||||
self._try_patch(data, 'pinned')
|
||||
self._try_patch(data, 'application')
|
||||
self._try_patch(data, 'activity')
|
||||
self._try_patch(data, 'mention_everyone')
|
||||
self._try_patch(data, 'tts')
|
||||
self._try_patch(data, 'type', lambda x: try_enum(MessageType, x))
|
||||
self._try_patch(data, 'content')
|
||||
self._try_patch(data, 'attachments', lambda x: [Attachment(data=a, state=self._state) for a in x])
|
||||
self._try_patch(data, 'embeds', lambda x: list(map(Embed.from_dict, x)))
|
||||
self._try_patch(data, 'nonce')
|
||||
|
||||
for handler in ('author', 'member', 'mentions', 'mention_roles', 'call'):
|
||||
def _update(self, data):
|
||||
handlers = self._HANDLERS
|
||||
for key, value in data.items():
|
||||
try:
|
||||
getattr(self, '_handle_%s' % handler)(data[handler])
|
||||
handler = handlers[key]
|
||||
except KeyError:
|
||||
continue
|
||||
else:
|
||||
handler(self, value)
|
||||
|
||||
# clear the cached properties
|
||||
cached = filter(lambda attr: attr.startswith('_cs_'), self.__slots__)
|
||||
for attr in cached:
|
||||
for attr in self._CACHED_SLOTS:
|
||||
try:
|
||||
delattr(self, attr)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def _handle_pinned(self, value):
|
||||
self.pinned = value
|
||||
|
||||
def _handle_application(self, value):
|
||||
self.application = value
|
||||
|
||||
def _handle_activity(self, value):
|
||||
self.activity = value
|
||||
|
||||
def _handle_mention_everyone(self, value):
|
||||
self.mention_everyone = value
|
||||
|
||||
def _handle_tts(self, value):
|
||||
self.tts = value
|
||||
|
||||
def _handle_type(self, value):
|
||||
self.type = try_enum(MessageType, value)
|
||||
|
||||
def _handle_content(self, value):
|
||||
self.content = value
|
||||
|
||||
def _handle_attachments(self, value):
|
||||
self.attachments = [Attachment(data=a, state=self._state) for a in value]
|
||||
|
||||
def _handle_embeds(self, value):
|
||||
self.embeds = [Embed.from_dict(data) for data in value]
|
||||
|
||||
def _handle_nonce(self, value):
|
||||
self.nonce = value
|
||||
|
||||
def _handle_author(self, author):
|
||||
self.author = self._state.store_user(author)
|
||||
if self.guild is not None:
|
||||
@ -693,7 +739,7 @@ class Message:
|
||||
fields['embed'] = embed.to_dict()
|
||||
|
||||
data = await self._state.http.edit_message(self.channel.id, self.id, **fields)
|
||||
self._update(channel=self.channel, data=data)
|
||||
self._update(data)
|
||||
|
||||
try:
|
||||
delete_after = fields['delete_after']
|
||||
|
@ -397,15 +397,7 @@ class ConnectionState:
|
||||
older_message = copy.copy(message)
|
||||
raw.cached_message = older_message
|
||||
self.dispatch('raw_message_edit', raw)
|
||||
if 'call' in data:
|
||||
# call state message edit
|
||||
message._handle_call(data['call'])
|
||||
elif 'content' not in data:
|
||||
# embed only edit
|
||||
message.embeds = [Embed.from_dict(d) for d in data['embeds']]
|
||||
else:
|
||||
message._update(channel=message.channel, data=data)
|
||||
|
||||
message._update(data)
|
||||
self.dispatch('message_edit', older_message, message)
|
||||
else:
|
||||
self.dispatch('raw_message_edit', raw)
|
||||
|
Loading…
x
Reference in New Issue
Block a user