1 module dscord.state; 2 3 import std.functional, 4 std.stdio, 5 std.experimental.logger; 6 7 import dscord.client, 8 dscord.api.client, 9 dscord.gateway.client, 10 dscord.gateway.events, 11 dscord.gateway.packets, 12 dscord.types.all, 13 dscord.util.emitter; 14 15 /** 16 The State class is used to track and maintain client state. 17 */ 18 class State : Emitter { 19 // Client 20 Client client; 21 APIClient api; 22 GatewayClient gw; 23 24 // Storage 25 User me; 26 GuildMap guilds; 27 ChannelMap channels; 28 UserMap users; 29 30 private { 31 Logger log; 32 ulong onReadyGuildCount; 33 } 34 35 this(Client client) { 36 this.log = client.log; 37 38 this.client = client; 39 this.api = client.api; 40 this.gw = client.gw; 41 42 this.guilds = new GuildMap; 43 this.channels = new ChannelMap; 44 this.users = new UserMap; 45 46 this.bindEvents(); 47 } 48 49 void bindEvents() { 50 this.client.events.listen!Ready(&this.onReady); 51 52 // Guilds 53 this.client.events.listen!GuildCreate(&this.onGuildCreate); 54 this.client.events.listen!GuildUpdate(&this.onGuildUpdate); 55 this.client.events.listen!GuildDelete(&this.onGuildDelete); 56 57 // Channels 58 this.client.events.listen!ChannelCreate(&this.onChannelCreate); 59 this.client.events.listen!ChannelUpdate(&this.onChannelUpdate); 60 this.client.events.listen!ChannelDelete(&this.onChannelDelete); 61 62 // Voice State 63 this.client.events.listen!VoiceStateUpdate(&this.onVoiceStateUpdate); 64 } 65 66 void onReady(Ready r) { 67 this.me = r.me; 68 this.onReadyGuildCount = r.guilds.length; 69 } 70 71 void onGuildCreate(GuildCreate c) { 72 this.guilds[c.guild.id] = c.guild; 73 74 // Add channels 75 c.guild.channels.each((c) { 76 this.channels[c.id] = c; 77 }); 78 } 79 80 void onGuildUpdate(GuildUpdate c) { 81 this.log.warning("Hit onGuildUpdate leaving state stale"); 82 // TODO: handle state changes in here 83 // this.guilds[c.guild.id].load(c.payload); 84 } 85 86 void onGuildDelete(GuildDelete c) { 87 if (!this.guilds.has(c.guildID)) return; 88 89 destroy(this.guilds[c.guildID]); 90 this.guilds.remove(c.guildID); 91 } 92 93 void onChannelCreate(ChannelCreate c) { 94 this.channels[c.channel.id] = c.channel; 95 } 96 97 void onChannelUpdate(ChannelUpdate c) { 98 this.channels[c.channel.id] = c.channel; 99 } 100 101 void onChannelDelete(ChannelDelete c) { 102 if (this.channels.has(c.channel.id)) { 103 destroy(this.channels[c.channel.id]); 104 this.channels.remove(c.channel.id); 105 } 106 } 107 108 void onVoiceStateUpdate(VoiceStateUpdate u) { 109 auto guild = this.guilds.get(u.state.guildID); 110 111 if (!u.state.channelID) { 112 guild.voiceStates.remove(u.state.sessionID); 113 } else { 114 guild.voiceStates[u.state.sessionID] = u.state; 115 } 116 } 117 }