aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorZeyla Hellyer <[email protected]>2018-05-28 16:34:38 -0700
committerZeyla Hellyer <[email protected]>2018-05-28 16:34:38 -0700
commit6b5f3b98084b86b00e3f7e78b5eb9512e75e78a0 (patch)
tree4011d56b63d88999eb8169e332c54f3eafe972ae /examples
parentMake Message Builder use &mut self instead of self (diff)
parentFutures shard manager #298 (WIP) (#300) (diff)
downloadserenity-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.toml2
-rw-r--r--examples/01_basic_ping_bot/src/main.rs90
-rw-r--r--examples/dev_shard_manager/Cargo.toml11
-rw-r--r--examples/dev_shard_manager/src/main.rs78
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)
+}