diff options
| author | Zeyla Hellyer <[email protected]> | 2018-05-28 16:34:38 -0700 |
|---|---|---|
| committer | Zeyla Hellyer <[email protected]> | 2018-05-28 16:34:38 -0700 |
| commit | 6b5f3b98084b86b00e3f7e78b5eb9512e75e78a0 (patch) | |
| tree | 4011d56b63d88999eb8169e332c54f3eafe972ae /examples | |
| parent | Make Message Builder use &mut self instead of self (diff) | |
| parent | Futures shard manager #298 (WIP) (#300) (diff) | |
| download | serenity-6b5f3b98084b86b00e3f7e78b5eb9512e75e78a0.tar.xz serenity-6b5f3b98084b86b00e3f7e78b5eb9512e75e78a0.zip | |
Merge branch 'futures' into v0.6.x
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/01_basic_ping_bot/Cargo.toml | 2 | ||||
| -rw-r--r-- | examples/01_basic_ping_bot/src/main.rs | 90 | ||||
| -rw-r--r-- | examples/dev_shard_manager/Cargo.toml | 11 | ||||
| -rw-r--r-- | examples/dev_shard_manager/src/main.rs | 78 |
4 files changed, 138 insertions, 43 deletions
diff --git a/examples/01_basic_ping_bot/Cargo.toml b/examples/01_basic_ping_bot/Cargo.toml index 30ce62c..7c30ce7 100644 --- a/examples/01_basic_ping_bot/Cargo.toml +++ b/examples/01_basic_ping_bot/Cargo.toml @@ -4,4 +4,6 @@ version = "0.1.0" authors = ["my name <[email protected]>"] [dependencies] +futures-await = "~0.1" serenity = { path = "../../", default-features = true } +tokio-core = "~0.1" diff --git a/examples/01_basic_ping_bot/src/main.rs b/examples/01_basic_ping_bot/src/main.rs index 3bccb74..7d858f1 100644 --- a/examples/01_basic_ping_bot/src/main.rs +++ b/examples/01_basic_ping_bot/src/main.rs @@ -1,56 +1,60 @@ +#![feature(proc_macro, conservative_impl_trait, generators)] + +extern crate futures_await as futures; extern crate serenity; +extern crate tokio_core; -use serenity::prelude::*; -use serenity::model::channel::Message; -use serenity::model::gateway::Ready; +use futures::prelude::*; +use serenity::gateway::Shard; +use serenity::model::event::{Event, GatewayEvent}; +use serenity::model::gateway::Game; +use serenity::model::user::OnlineStatus; +use std::error::Error; use std::env; +use tokio_core::reactor::{Core, Handle}; -struct Handler; - -impl EventHandler for Handler { - // Set a handler for the `message` event - so that whenever a new message - // is received - the closure (or function) passed will be called. - // - // Event handlers are dispatched through a threadpool, and so multiple - // events can be dispatched simultaneously. - fn message(&self, _: Context, msg: Message) { - if msg.content == "!ping" { - // Sending a message can fail, due to a network error, an - // authentication error, or lack of permissions to post in the - // channel, so log to stdout when some error happens, with a - // description of it. - if let Err(why) = msg.channel_id.say("Pong!") { - println!("Error sending message: {:?}", why); - } - } - } +fn main() { + let mut core = Core::new().expect("Error creating event loop"); + let future = try_main(core.handle()); - // Set a handler to be called on the `ready` event. This is called when a - // shard is booted, and a READY payload is sent by Discord. This payload - // contains data like the current user's guild Ids, current user data, - // private channels, and more. - // - // In this case, just print what the current user's username is. - fn ready(&self, _: Context, ready: Ready) { - println!("{} is connected!", ready.user.name); - } + core.run(future).expect("Error running event loop"); } -fn main() { +#[async] +fn try_main(handle: Handle) -> Result<(), Box<Error + 'static>> { // Configure the client with your Discord bot token in the environment. let token = env::var("DISCORD_TOKEN") .expect("Expected a token in the environment"); - // Create a new instance of the Client, logging in as a bot. This will - // automatically prepend your bot token with "Bot ", which is a requirement - // by Discord for bot users. - let mut client = Client::new(&token, Handler).expect("Err creating client"); - - // Finally, start a single shard, and start listening to events. - // - // Shards will automatically attempt to reconnect, and will perform - // exponential backoff until it reconnects. - if let Err(why) = client.start() { - println!("Client error: {:?}", why); + // Create a new shard, specifying the token, the ID of the shard (0 of 1), + // and a handle to the event loop + let mut shard = await!(Shard::new(token, [0, 1], handle))?; + + // Loop over websocket messages. + #[async] + for message in shard.messages() { + // Parse the websocket message into a serenity GatewayEvent. + let event = shard.parse(message)?; + + // Have the shard process the WebSocket event, in case it needs to + // mutate its state, send a packet, etc. + shard.process(&event); + + // Now you can do whatever you want with the event. + match event { + GatewayEvent::Dispatch(_, Event::MessageCreate(ev)) => { + if ev.message.content == "!ping" { + println!("Pong!"); + } + }, + GatewayEvent::Dispatch(_, Event::Ready(_)) => { + println!("Connected to Discord!"); + }, + _ => { + // Ignore all other messages. + }, + } } + + Ok(()) } diff --git a/examples/dev_shard_manager/Cargo.toml b/examples/dev_shard_manager/Cargo.toml new file mode 100644 index 0000000..79bfd53 --- /dev/null +++ b/examples/dev_shard_manager/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "dev_shard_manager" +version = "0.1.0" +authors = ["my name <[email protected]>"] + +[dependencies] +serenity = { path = "../../", default-features = true } +tokio-core = "~0.1" +futures = "~0.1" +env_logger = "~0.4" + diff --git a/examples/dev_shard_manager/src/main.rs b/examples/dev_shard_manager/src/main.rs new file mode 100644 index 0000000..77855f3 --- /dev/null +++ b/examples/dev_shard_manager/src/main.rs @@ -0,0 +1,78 @@ +extern crate futures; +extern crate serenity; +extern crate tokio_core; +extern crate env_logger; + +use serenity::{ + gateway::{ + ShardingStrategy, + ShardManager, + ShardManagerOptions, + SimpleReconnectQueue, + }, + model::event::{ + Event, + GatewayEvent, + }, +}; +use std::{ + env, + rc::Rc, +}; +use tokio_core::reactor::{Core, Handle}; +use futures::{future, Future, Stream}; + +fn main() { + env_logger::init().expect("Error initializing env_logger"); + + let mut core = Core::new().expect("Error creating event loop"); + let future = try_main(core.handle()); + + core.run(future).expect("Error running event loop"); +} + +fn try_main(handle: Handle) -> Box<Future<Item = (), Error = ()>> { + let token = env::var("DISCORD_TOKEN") + .expect("Expected a token in the environment"); + + let opts = ShardManagerOptions { + strategy: ShardingStrategy::multi(4), + token: Rc::new(token), + ws_uri: Rc::new(String::from("nothing")), + queue: SimpleReconnectQueue::new(4), + }; + + let mut shard_manager = ShardManager::new(opts, handle.clone()); + let future = shard_manager.start() + .map_err(|e| println!("Error starting shard manager: {:?}", e)); + + handle.spawn(future); + + let future = shard_manager.messages().for_each(move |(shard, message)| { + let mut shard = shard.borrow_mut(); + + let event = shard.parse(message) + .expect("Could not parse shard stream message"); + + shard.process(&event); + shard_manager.process(&event); + + match event { + GatewayEvent::Dispatch(_, Event::MessageCreate(ev)) => { + if ev.message.content == "!ping" { + println!("Pong!"); + } + }, + GatewayEvent::Dispatch(_, Event::Ready(_)) => { + println!("Connected to Discord!"); + }, + _ => { + // Ignore all other messages. + }, + } + + future::ok(()) + }); + + Box::new(future) +} |