using Maki.Structures.Channels;
using Maki.Structures.Gateway;
using Maki.Structures.Guilds;
using Maki.Structures.Messages;
using Maki.Structures.Presences;
using Maki.Structures.Users;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Maki.Gateway
{
///
/// Gateway connection shard manager
///
class GatewayShardClient : IDisposable
{
///
/// Managed (active) shards
///
private readonly List Shards = new List();
private readonly object Lock = new object();
///
/// Parent DiscordClient instance
///
private Discord Client;
///
/// Number of active managed shards
///
public int ShardCount
=> Shards.Count;
///
/// Constructor
///
/// Parent DiscordClient instance
public GatewayShardClient(Discord client)
=> Client = client;
///
/// Creates a new Gateway Shard
///
/// Id of the shard
/// New Gateway Shard
public GatewayShard Create(int id)
{
GatewayShard shard = new GatewayShard(id, Client);
ApplyEvents(shard);
lock (Lock)
Shards.Add(shard);
return shard;
}
///
/// Destroys a Gateway Shard
///
/// Shard to destroy
public void Destroy(GatewayShard shard)
{
lock (Lock)
Shards.Remove(shard);
// Disconnect and Dispose are called separately so OnSocketClose is called properly
shard.Disconnect();
RemoveEvents(shard);
shard.Dispose();
}
///
/// Destroys all shards
///
public void Disconnect()
{
lock (Lock)
Shards.ToList().ForEach(x => Destroy(x));
}
///
/// Links all gateway events handlers to the shard
///
/// Shard to link events to
private void ApplyEvents(GatewayShard shard)
{
shard.OnCallCreate += OnCallCreate;
shard.OnCallDelete += OnCallDelete;
shard.OnCallUpdate += OnCallUpdate;
shard.OnVoiceServerUpdate += OnVoiceServerUpdate;
shard.OnVoiceStateUpdate += OnVoiceStateUpdate;
shard.OnChannelCreate += OnChannelCreate;
shard.OnChannelDelete += OnChannelDelete;
shard.OnChannelPinsAck += OnChannelPinsAck;
shard.OnChannelPinsUpdate += OnChannelPinsUpdate;
shard.OnChannelRecipientAdd += OnChannelRecipientAdd;
shard.OnChannelRecipientRemove += OnChannelRecipientRemove;
shard.OnChannelUpdate += OnChannelUpdate;
shard.OnGuildBanAdd += OnGuildBanAdd;
shard.OnGuildBanRemove += OnGuildBanRemove;
shard.OnGuildCreate += OnGuildCreate;
shard.OnGuildDelete += OnGuildDelete;
shard.OnGuildEmojisUpdate += OnGuildEmojisUpdate;
shard.OnGuildIntegrationsUpdate += OnGuildIntegrationsUpdate;
shard.OnGuildMemberAdd += OnGuildMemberAdd;
shard.OnGuildMemberUpdate += OnGuildMemberUpdate;
shard.OnGuildMemberRemove += OnGuildMemberRemove;
shard.OnGuildMembersChunk += OnGuildMembersChunk;
shard.OnGuildRoleCreate += OnGuildRoleCreate;
shard.OnGuildRoleUpdate += OnGuildRoleUpdate;
shard.OnGuildRoleDelete += OnGuildRoleDelete;
shard.OnGuildUpdate += OnGuildUpdate;
shard.OnMessageAck += OnMessageAck;
shard.OnMessageCreate += OnMessageCreate;
shard.OnMessageDelete += OnMessageDelete;
shard.OnMessageDeleteBulk += OnMessageDeleteBulk;
shard.OnMessageReactionAdd += OnMessageReactionAdd;
shard.OnMessageReactionRemove += OnMessageReactionRemove;
shard.OnMessageReactionsRemoveAll += OnMessageReactionsRemoveAll;
shard.OnMessageUpdate += OnMessageUpdate;
shard.OnTypingStart += OnTypingStart;
shard.OnPresenceUpdate += OnPresenceUpdate;
shard.OnPresencesReplace += OnPresencesReplace;
shard.OnFriendSuggestionDelete += OnFriendSuggestionDelete;
shard.OnRelationshipAdd += OnRelationshipAdd;
shard.OnRelationshipRemove += OnRelationshipRemove;
shard.OnReady += OnReady;
shard.OnResumed += OnResumed;
shard.OnUserUpdate += OnUserUpdate;
shard.OnUserNoteUpdate += OnUserNoteUpdate;
shard.OnUserSettingsUpdate += OnUserSettingsUpdate;
shard.OnSocketOpen += OnSocketOpen;
shard.OnSocketClose += OnSocketClose;
shard.OnSocketError += OnSocketError;
shard.OnSocketMessage += OnSocketMessage;
}
///
/// Unlinks all gateway events handlers from the shard
///
/// Shard to unlink events from
public void RemoveEvents(GatewayShard shard)
{
shard.OnCallCreate -= OnCallCreate;
shard.OnCallDelete -= OnCallDelete;
shard.OnCallUpdate -= OnCallUpdate;
shard.OnVoiceServerUpdate -= OnVoiceServerUpdate;
shard.OnVoiceStateUpdate -= OnVoiceStateUpdate;
shard.OnChannelCreate -= OnChannelCreate;
shard.OnChannelDelete -= OnChannelDelete;
shard.OnChannelPinsAck -= OnChannelPinsAck;
shard.OnChannelPinsUpdate -= OnChannelPinsUpdate;
shard.OnChannelRecipientAdd -= OnChannelRecipientAdd;
shard.OnChannelRecipientRemove -= OnChannelRecipientRemove;
shard.OnChannelUpdate -= OnChannelUpdate;
shard.OnGuildBanAdd -= OnGuildBanAdd;
shard.OnGuildBanRemove -= OnGuildBanRemove;
shard.OnGuildCreate -= OnGuildCreate;
shard.OnGuildDelete -= OnGuildDelete;
shard.OnGuildEmojisUpdate -= OnGuildEmojisUpdate;
shard.OnGuildIntegrationsUpdate -= OnGuildIntegrationsUpdate;
shard.OnGuildMemberAdd -= OnGuildMemberAdd;
shard.OnGuildMemberUpdate -= OnGuildMemberUpdate;
shard.OnGuildMemberRemove -= OnGuildMemberRemove;
shard.OnGuildMembersChunk -= OnGuildMembersChunk;
shard.OnGuildRoleCreate -= OnGuildRoleCreate;
shard.OnGuildRoleUpdate -= OnGuildRoleUpdate;
shard.OnGuildRoleDelete -= OnGuildRoleDelete;
shard.OnGuildUpdate -= OnGuildUpdate;
shard.OnMessageAck -= OnMessageAck;
shard.OnMessageCreate -= OnMessageCreate;
shard.OnMessageDelete -= OnMessageDelete;
shard.OnMessageDeleteBulk -= OnMessageDeleteBulk;
shard.OnMessageReactionAdd -= OnMessageReactionAdd;
shard.OnMessageReactionRemove -= OnMessageReactionRemove;
shard.OnMessageReactionsRemoveAll -= OnMessageReactionsRemoveAll;
shard.OnMessageUpdate -= OnMessageUpdate;
shard.OnTypingStart -= OnTypingStart;
shard.OnPresenceUpdate -= OnPresenceUpdate;
shard.OnPresencesReplace -= OnPresencesReplace;
shard.OnFriendSuggestionDelete -= OnFriendSuggestionDelete;
shard.OnRelationshipAdd -= OnRelationshipAdd;
shard.OnRelationshipRemove -= OnRelationshipRemove;
shard.OnReady -= OnReady;
shard.OnResumed -= OnResumed;
shard.OnUserUpdate -= OnUserUpdate;
shard.OnUserNoteUpdate -= OnUserNoteUpdate;
shard.OnUserSettingsUpdate -= OnUserSettingsUpdate;
shard.OnSocketOpen -= OnSocketOpen;
shard.OnSocketClose -= OnSocketClose;
shard.OnSocketError -= OnSocketError;
shard.OnSocketMessage -= OnSocketMessage;
}
#region Events
public event Action OnCallCreate;
public event Action OnCallDelete;
public event Action OnCallUpdate;
public event Action OnVoiceServerUpdate;
public event Action OnVoiceStateUpdate;
public event Action OnChannelCreate;
public event Action OnChannelDelete;
public event Action OnChannelPinsAck;
public event Action OnChannelPinsUpdate;
public event Action OnChannelRecipientAdd;
public event Action OnChannelRecipientRemove;
public event Action OnChannelUpdate;
public event Action OnGuildBanAdd;
public event Action OnGuildBanRemove;
public event Action OnGuildCreate;
public event Action OnGuildDelete;
public event Action OnGuildEmojisUpdate;
public event Action OnGuildIntegrationsUpdate;
public event Action OnGuildMemberAdd;
public event Action OnGuildMemberUpdate;
public event Action OnGuildMemberRemove;
public event Action OnGuildMembersChunk;
public event Action OnGuildRoleCreate;
public event Action OnGuildRoleUpdate;
public event Action OnGuildRoleDelete;
public event Action OnGuildUpdate;
public event Action OnMessageAck;
public event Action OnMessageCreate;
public event Action OnMessageDelete;
public event Action OnMessageDeleteBulk;
public event Action OnMessageReactionAdd;
public event Action OnMessageReactionRemove;
public event Action OnMessageReactionsRemoveAll;
public event Action OnMessageUpdate;
public event Action OnTypingStart;
public event Action OnPresenceUpdate;
public event Action OnPresencesReplace;
public event Action OnFriendSuggestionDelete;
public event Action OnRelationshipAdd;
public event Action OnRelationshipRemove;
public event Action OnReady;
public event Action OnResumed;
public event Action OnUserUpdate;
public event Action OnUserNoteUpdate;
public event Action OnUserSettingsUpdate;
public event Action OnSocketOpen;
public event Action OnSocketClose;
public event Action OnSocketError;
public event Action OnSocketMessage;
#endregion
#region IDisposable
private bool IsDisposed = false;
///
/// Releases all unmanaged resources used by this object
///
private void Dispose(bool disposing)
{
if (IsDisposed)
return;
IsDisposed = true;
Disconnect();
if (disposing)
GC.SuppressFinalize(this);
}
~GatewayShardClient()
=> Dispose(false);
public void Dispose()
=> Dispose(true);
#endregion
}
}