Browse Source

Got Discord half to be alive

master
Thomas Johnson 3 years ago
parent
commit
d8e9671e04
  1. 3
      Cargo.toml
  2. 91
      src/discord_endpoint.rs
  3. 11
      src/main.rs
  4. 25
      src/refset.rs

3
Cargo.toml

@ -7,5 +7,6 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = "1.0.104"
serde = { version = "1.0", features = [ "derive" ] }
serde_json = "1.0"
serenity = "0.7.0"

91
src/discord_endpoint.rs

@ -1,10 +1,13 @@
use std::collections::hash_map::HashMap;
use std::sync::Arc;
use std::mem;
use std::thread;
use serenity::client::Client;
use serenity::prelude::*;
use serenity::client::bridge::gateway::ShardManager;
use serenity::model;
use serenity::client::bridge::gateway::{ShardManager, event::ShardStageUpdateEvent};
use serenity::gateway::ConnectionStage;
use serenity::cache::Cache;
use crate::endpoint::{Endpoint, Bridge, BridgeResult, Message, ReceiveCallback};
@ -12,30 +15,38 @@ use crate::refset::RefSet;
pub struct DiscordManager
{
instances: Vec<DiscordInstance>,
pub instances: Vec<DiscordInstance>,
}
impl DiscordManager
{
pub fn new() -> DiscordManager
{
DiscordManager { instances: Vec::new() }
}
}
#[derive(Clone)]
struct DiscordInstance(Arc<Mutex<DiscordInstanceInner>>);
pub struct DiscordInstance(Arc<Mutex<DiscordInstanceInner>>);
pub enum DiscordState
{
GoingUp(),
Up(),
GoingDown(),
Down(),
Failed(serenity::Error),
}
impl TypeMapKey for DiscordInstance { type Value = DiscordInstance; }
struct DiscordInstanceInner
{
client: Option<Arc<Mutex<Client>>>,
shard_manager: Option<Arc<Mutex<ShardManager>>>,
state: DiscordState,
runner: Option<thread::JoinHandle<()>>,
on_ready_callbacks: Arc<RwLock<RefSet<dyn Fn() + Sync + Send>>>,
}
impl DiscordInstance
@ -48,10 +59,12 @@ impl DiscordInstance
shard_manager: None,
state: DiscordState::Down(),
runner: None,
on_ready_callbacks: Arc::new(RwLock::new(RefSet::new())),
})));
let client = Client::new(token, instance.clone())?;
let mut client = Client::new(token, instance.clone())?;
let mut guard = instance.0.lock();
guard.shard_manager = Some(client.shard_manager.clone());
client.data.write().insert::<DiscordInstance>(instance.clone());
guard.client = Some(Arc::new(Mutex::new(client)));
mem::drop(guard);
Ok(instance)
@ -60,28 +73,27 @@ impl DiscordInstance
pub fn start(&self)
{
let inner = self.0.clone();
let jh = thread::spawn(move ||
{
let client;
{
let mut topguard = inner.lock();
client = match &topguard.client
{
Some(c) => c.clone(),
None => return,
};
topguard.state = DiscordState::Up();
}
match client.try_lock()
{
Some(mut lock) => match lock.start()
{
Ok(()) => inner.lock().state = DiscordState::Down(),
Err(e) => inner.lock().state = DiscordState::Failed(e),
},
None => (),
};
});
let jh = thread::spawn(move || {
let client;
{
let mut topguard = inner.lock();
client = match &topguard.client
{
Some(c) => c.clone(),
None => return,
};
topguard.state = DiscordState::GoingUp();
}
match client.try_lock()
{
Some(mut lock) => match lock.start()
{
Ok(()) => inner.lock().state = DiscordState::Down(),
Err(e) => inner.lock().state = DiscordState::Failed(e),
},
None => (),
};
});
self.0.lock().runner = Some(jh);
}
@ -129,6 +141,33 @@ impl DiscordInstance
impl EventHandler for DiscordInstance
{
fn ready(&self, _ctx: Context, _data: model::gateway::Ready)
{
let arc;
{
let mut guard = self.0.lock();
guard.state = DiscordState::Up();
arc = guard.on_ready_callbacks.clone();
}
println!("handler ready");
for cb in arc.read().iter()
{
cb();
}
}
fn shard_stage_update(&self, _ctx: Context, ev: ShardStageUpdateEvent)
{
match ev.new
{
ConnectionStage::Connected => println!("shard connected"),
_ => match ev.old
{
ConnectionStage::Connected => println!("shard disconnected"),
_ => (),
},
};
}
}

11
src/main.rs

@ -7,6 +7,17 @@ mod endpoint;
mod discord_endpoint;
mod refset;
use std::thread;
fn main()
{
let token = std::env::var("TOKEN").expect("no token");
let inst = discord_endpoint::DiscordInstance::new(token).expect("error during instantiation");
println!("instantiated");
inst.start();
println!("started");
thread::sleep(std::time::Duration::from_millis(10000));
print!("stopping ... ");
inst.stop_sync();
println!("done");
}

25
src/refset.rs

@ -4,25 +4,28 @@
use std::sync::Arc;
use std::collections::hash_map::HashMap;
pub struct RefSet<T, U = Arc<T>>
where U: AsRef<T>
pub struct RefSet<T, U = Arc<T>> where
T: ?Sized,
U: AsRef<T>,
{
map: HashMap<*const T, U>,
map: HashMap<usize, U>,
_pd: std::marker::PhantomData<T>,
}
type Iter<'a, T, U> = std::collections::hash_map::Values<'a, *const T, U>;
type Iter<'a, U> = std::collections::hash_map::Values<'a, usize, U>;
impl<T, U> RefSet<T, U>
where U: AsRef<T>
impl<T, U> RefSet<T, U> where
U: AsRef<T>,
T: ?Sized
{
pub fn new() -> RefSet<T, U>
{
RefSet { map: HashMap::new() }
RefSet { map: HashMap::new(), _pd: std::marker::PhantomData }
}
pub fn with_capacity(capacity: usize) -> RefSet<T, U>
{
RefSet { map: HashMap::with_capacity(capacity) }
RefSet { map: HashMap::with_capacity(capacity), _pd: std::marker::PhantomData }
}
pub fn capacity(&self) -> usize
@ -30,7 +33,7 @@ where U: AsRef<T>
self.map.capacity()
}
pub fn iter(&self) -> Iter<T, U>
pub fn iter(&self) -> Iter<U>
{
self.map.values()
}
@ -52,7 +55,7 @@ where U: AsRef<T>
pub fn insert(&mut self, value: U) -> bool
{
match self.map.insert(value.as_ref() as *const T, value)
match self.map.insert(value.as_ref() as *const T as *const () as usize, value)
{
Some(_) => false,
None => true,
@ -61,7 +64,7 @@ where U: AsRef<T>
pub fn remove(&mut self, value: U) -> bool
{
match self.map.remove(&(value.as_ref() as *const T))
match self.map.remove(&(value.as_ref() as *const T as *const () as usize))
{
Some(_) => true,
None => false,

Loading…
Cancel
Save