Memory improvements
This commit is contained in:
@@ -949,20 +949,7 @@ namespace Discord
|
||||
await _gatewayLogger.WarningAsync("PRESENCE_UPDATE referenced an unknown guild.").ConfigureAwait(false);
|
||||
break;
|
||||
}
|
||||
if (data.Status == UserStatus.Offline)
|
||||
guild.RemovePresence(data.User.Id);
|
||||
else
|
||||
{
|
||||
guild.AddOrUpdatePresence(data);
|
||||
if (data.Roles.IsSpecified || data.Nick.IsSpecified) //Happens when a user we haven't seen before logs in
|
||||
{
|
||||
CachedGuildUser user = guild.GetUser(data.User.Id);
|
||||
if (user == null)
|
||||
guild.AddUser(data, DataStore);
|
||||
else
|
||||
user.Update(data, UpdateSource.WebSocket);
|
||||
}
|
||||
}
|
||||
guild.UpdatePresence(data, DataStore);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace Discord
|
||||
//if (model.Roles.IsSpecified)
|
||||
UpdateRoles(model.Roles);
|
||||
}
|
||||
public void Update(PresenceModel model, UpdateSource source)
|
||||
public virtual void Update(PresenceModel model, UpdateSource source)
|
||||
{
|
||||
if (source == UpdateSource.Rest && IsAttached) return;
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ namespace Discord
|
||||
private TaskCompletionSource<bool> _downloaderPromise;
|
||||
private ConcurrentHashSet<ulong> _channels;
|
||||
private ConcurrentDictionary<ulong, CachedGuildUser> _members;
|
||||
private ConcurrentDictionary<ulong, Presence> _presences;
|
||||
private ConcurrentDictionary<ulong, VoiceState> _voiceStates;
|
||||
|
||||
public bool Available { get; private set; }
|
||||
@@ -53,12 +52,8 @@ namespace Discord
|
||||
_channels = new ConcurrentHashSet<ulong>();
|
||||
if (_members == null)
|
||||
_members = new ConcurrentDictionary<ulong, CachedGuildUser>();
|
||||
if (_presences == null)
|
||||
_presences = new ConcurrentDictionary<ulong, Presence>();
|
||||
if (_roles == null)
|
||||
_roles = new ConcurrentDictionary<ulong, Role>();
|
||||
if (_voiceStates == null)
|
||||
_voiceStates = new ConcurrentDictionary<ulong, VoiceState>();
|
||||
if (Emojis == null)
|
||||
Emojis = ImmutableArray.Create<Emoji>();
|
||||
if (Features == null)
|
||||
@@ -69,17 +64,15 @@ namespace Discord
|
||||
base.Update(model as Model, source);
|
||||
|
||||
MemberCount = model.MemberCount;
|
||||
|
||||
var channels = new ConcurrentHashSet<ulong>();
|
||||
if (model.Channels != null)
|
||||
|
||||
var channels = new ConcurrentHashSet<ulong>(1, (int)(model.Channels.Length * 1.05));
|
||||
{
|
||||
for (int i = 0; i < model.Channels.Length; i++)
|
||||
AddChannel(model.Channels[i], dataStore, channels);
|
||||
}
|
||||
_channels = channels;
|
||||
|
||||
var members = new ConcurrentDictionary<ulong, CachedGuildUser>();
|
||||
if (model.Members != null)
|
||||
var members = new ConcurrentDictionary<ulong, CachedGuildUser>(1, (int)(model.Presences.Length * 1.05));
|
||||
{
|
||||
DownloadedMemberCount = 0;
|
||||
for (int i = 0; i < model.Members.Length; i++)
|
||||
@@ -87,23 +80,17 @@ namespace Discord
|
||||
_downloaderPromise = new TaskCompletionSource<bool>();
|
||||
if (!model.Large)
|
||||
_downloaderPromise.SetResult(true);
|
||||
}
|
||||
_members = members;
|
||||
|
||||
var presences = new ConcurrentDictionary<ulong, Presence>();
|
||||
if (model.Presences != null)
|
||||
{
|
||||
for (int i = 0; i < model.Presences.Length; i++)
|
||||
{
|
||||
var presence = model.Presences[i];
|
||||
AddOrUpdatePresence(presence, presences);
|
||||
UpdatePresence(presence, dataStore, members);
|
||||
//AddUser(presence, dataStore, members);
|
||||
}
|
||||
}
|
||||
_presences = presences;
|
||||
|
||||
var voiceStates = new ConcurrentDictionary<ulong, VoiceState>();
|
||||
if (model.VoiceStates != null)
|
||||
_members = members;
|
||||
|
||||
var voiceStates = new ConcurrentDictionary<ulong, VoiceState>(1, (int)(model.VoiceStates.Length * 1.05));
|
||||
{
|
||||
for (int i = 0; i < model.VoiceStates.Length; i++)
|
||||
AddOrUpdateVoiceState(model.VoiceStates[i], dataStore, voiceStates);
|
||||
@@ -128,29 +115,7 @@ namespace Discord
|
||||
_channels.TryRemove(id);
|
||||
return Discord.DataStore.RemoveChannel(id) as ICachedGuildChannel;
|
||||
}
|
||||
|
||||
public Presence AddOrUpdatePresence(PresenceModel model, ConcurrentDictionary<ulong, Presence> presences = null)
|
||||
{
|
||||
var game = model.Game != null ? new Game(model.Game) : (Game?)null;
|
||||
var presence = new Presence(model.Status, game);
|
||||
(presences ?? _presences)[model.User.Id] = presence;
|
||||
return presence;
|
||||
}
|
||||
public Presence? GetPresence(ulong id)
|
||||
{
|
||||
Presence presence;
|
||||
if (_presences.TryGetValue(id, out presence))
|
||||
return presence;
|
||||
return null;
|
||||
}
|
||||
public Presence? RemovePresence(ulong id)
|
||||
{
|
||||
Presence presence;
|
||||
if (_presences.TryRemove(id, out presence))
|
||||
return presence;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public Role AddRole(RoleModel model, ConcurrentDictionary<ulong, Role> roles = null)
|
||||
{
|
||||
var role = new Role(this, model);
|
||||
@@ -165,28 +130,6 @@ namespace Discord
|
||||
return null;
|
||||
}
|
||||
|
||||
public VoiceState AddOrUpdateVoiceState(VoiceStateModel model, DataStore dataStore, ConcurrentDictionary<ulong, VoiceState> voiceStates = null)
|
||||
{
|
||||
var voiceChannel = dataStore.GetChannel(model.ChannelId.Value) as CachedVoiceChannel;
|
||||
var voiceState = new VoiceState(voiceChannel, model.SessionId, model.SelfMute, model.SelfDeaf, model.Suppress);
|
||||
(voiceStates ?? _voiceStates)[model.UserId] = voiceState;
|
||||
return voiceState;
|
||||
}
|
||||
public VoiceState? GetVoiceState(ulong id)
|
||||
{
|
||||
VoiceState voiceState;
|
||||
if (_voiceStates.TryGetValue(id, out voiceState))
|
||||
return voiceState;
|
||||
return null;
|
||||
}
|
||||
public VoiceState? RemoveVoiceState(ulong id)
|
||||
{
|
||||
VoiceState voiceState;
|
||||
if (_voiceStates.TryRemove(id, out voiceState))
|
||||
return voiceState;
|
||||
return null;
|
||||
}
|
||||
|
||||
public override Task<IGuildUser> GetUserAsync(ulong id) => Task.FromResult<IGuildUser>(GetUser(id));
|
||||
public override Task<IGuildUser> GetCurrentUserAsync()
|
||||
=> Task.FromResult<IGuildUser>(CurrentUser);
|
||||
@@ -197,7 +140,6 @@ namespace Discord
|
||||
=> Task.FromResult<IReadOnlyCollection<IGuildUser>>(Members.OrderBy(x => x.Id).Skip(offset).Take(limit).ToImmutableArray());
|
||||
public CachedGuildUser AddUser(MemberModel model, DataStore dataStore, ConcurrentDictionary<ulong, CachedGuildUser> members = null)
|
||||
{
|
||||
var user = Discord.GetOrAddUser(model.User, dataStore);
|
||||
members = members ?? _members;
|
||||
|
||||
CachedGuildUser member;
|
||||
@@ -205,6 +147,7 @@ namespace Discord
|
||||
member.Update(model, UpdateSource.WebSocket);
|
||||
else
|
||||
{
|
||||
var user = Discord.GetOrAddUser(model.User, dataStore);
|
||||
member = new CachedGuildUser(this, user, model);
|
||||
members[user.Id] = member;
|
||||
user.AddRef();
|
||||
@@ -243,6 +186,22 @@ namespace Discord
|
||||
return member;
|
||||
return null;
|
||||
}
|
||||
public void UpdatePresence(PresenceModel model, DataStore dataStore, ConcurrentDictionary<ulong, CachedGuildUser> members = null)
|
||||
{
|
||||
members = members ?? _members;
|
||||
|
||||
CachedGuildUser member;
|
||||
if (members.TryGetValue(model.User.Id, out member))
|
||||
member.Update(model, UpdateSource.WebSocket);
|
||||
else
|
||||
{
|
||||
var user = Discord.GetOrAddUser(model.User, dataStore);
|
||||
member = new CachedGuildUser(this, user, model);
|
||||
members[user.Id] = member;
|
||||
user.AddRef();
|
||||
DownloadedMemberCount++;
|
||||
}
|
||||
}
|
||||
public async Task DownloadMembersAsync()
|
||||
{
|
||||
if (!HasAllMembers)
|
||||
@@ -254,6 +213,28 @@ namespace Discord
|
||||
_downloaderPromise.TrySetResult(true);
|
||||
}
|
||||
|
||||
public VoiceState AddOrUpdateVoiceState(VoiceStateModel model, DataStore dataStore, ConcurrentDictionary<ulong, VoiceState> voiceStates = null)
|
||||
{
|
||||
var voiceChannel = dataStore.GetChannel(model.ChannelId.Value) as CachedVoiceChannel;
|
||||
var voiceState = new VoiceState(voiceChannel, model.SessionId, model.SelfMute, model.SelfDeaf, model.Suppress);
|
||||
(voiceStates ?? _voiceStates)[model.UserId] = voiceState;
|
||||
return voiceState;
|
||||
}
|
||||
public VoiceState? GetVoiceState(ulong id)
|
||||
{
|
||||
VoiceState voiceState;
|
||||
if (_voiceStates.TryGetValue(id, out voiceState))
|
||||
return voiceState;
|
||||
return null;
|
||||
}
|
||||
public VoiceState? RemoveVoiceState(ulong id)
|
||||
{
|
||||
VoiceState voiceState;
|
||||
if (_voiceStates.TryRemove(id, out voiceState))
|
||||
return voiceState;
|
||||
return null;
|
||||
}
|
||||
|
||||
public CachedGuild Clone() => MemberwiseClone() as CachedGuild;
|
||||
|
||||
new internal ICachedGuildChannel ToChannel(ChannelModel model)
|
||||
|
||||
@@ -5,13 +5,15 @@ namespace Discord
|
||||
{
|
||||
internal class CachedGuildUser : GuildUser, ICachedUser
|
||||
{
|
||||
private Game? _game;
|
||||
private UserStatus _status;
|
||||
|
||||
public new DiscordSocketClient Discord => base.Discord as DiscordSocketClient;
|
||||
public new CachedGuild Guild => base.Guild as CachedGuild;
|
||||
public new CachedPublicUser User => base.User as CachedPublicUser;
|
||||
|
||||
public Presence? Presence => Guild.GetPresence(Id);
|
||||
public override Game? Game => Presence?.Game;
|
||||
public override UserStatus Status => Presence?.Status ?? UserStatus.Offline;
|
||||
public override Game? Game => _game;
|
||||
public override UserStatus Status => _status;
|
||||
|
||||
public VoiceState? VoiceState => Guild.GetVoiceState(Id);
|
||||
public bool IsSelfDeafened => VoiceState?.IsSelfDeafened ?? false;
|
||||
@@ -28,6 +30,14 @@ namespace Discord
|
||||
{
|
||||
}
|
||||
|
||||
public override void Update(PresenceModel model, UpdateSource source)
|
||||
{
|
||||
base.Update(model, source);
|
||||
|
||||
_status = model.Status;
|
||||
_game = model.Game != null ? new Game(model.Game) : (Game?)null;
|
||||
}
|
||||
|
||||
public CachedGuildUser Clone() => MemberwiseClone() as CachedGuildUser;
|
||||
ICachedUser ICachedUser.Clone() => Clone();
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
namespace Discord
|
||||
{
|
||||
internal struct Presence : IPresence
|
||||
{
|
||||
public UserStatus Status { get; }
|
||||
public Game? Game { get; }
|
||||
|
||||
public Presence(UserStatus status, Game? game)
|
||||
{
|
||||
Status = status;
|
||||
Game = game;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user