aboutsummaryrefslogtreecommitdiff
path: root/src/ext
diff options
context:
space:
mode:
authorIllia K <[email protected]>2016-11-28 19:21:33 +0000
committerAustin Hellyer <[email protected]>2016-11-28 12:13:46 -0800
commit83515e1a5ccc850a8c352060a19394a53aed8454 (patch)
treee5531327c82e37ae8b6874ebcba4b81746b4dd1e /src/ext
parentImprove docs and add new message builder methods (diff)
downloadserenity-83515e1a5ccc850a8c352060a19394a53aed8454.tar.xz
serenity-83515e1a5ccc850a8c352060a19394a53aed8454.zip
Add before/after framework command hooks
These hooks will each be run prior to or after the command, and will finish execution before executing the command. These can be configured in a Framework via: ```rs client.with_framework(|f| f .before(|_context, message, _command_name| { println!("Got command '{}'", command_name); }) .after(|_context, _message, command_name| { println!("Finished command '{}'", command_name); })); ``` This does introduce a backwards compatibility break, by requiring commands' Context/Message to be borrowed Upgrade path: If not using the `command!` macro, modify command signatures from: ```rs fn some_command(context: Context, message: Message, args: Vec<String>) ``` to ```rs fn some_command(context: &Context, message: &Message, args: Vec<String>) ```
Diffstat (limited to 'src/ext')
-rw-r--r--src/ext/framework/command.rs2
-rw-r--r--src/ext/framework/mod.rs36
2 files changed, 33 insertions, 5 deletions
diff --git a/src/ext/framework/command.rs b/src/ext/framework/command.rs
index 0c595b3..e0a4616 100644
--- a/src/ext/framework/command.rs
+++ b/src/ext/framework/command.rs
@@ -4,7 +4,7 @@ use ::client::Context;
use ::model::Message;
#[doc(hidden)]
-pub type Command = Fn(Context, Message, Vec<String>) + Send + Sync;
+pub type Command = Fn(&Context, &Message, Vec<String>) + Send + Sync;
#[doc(hidden)]
pub type InternalCommand = Arc<Command>;
diff --git a/src/ext/framework/mod.rs b/src/ext/framework/mod.rs
index 2a92840..731efd0 100644
--- a/src/ext/framework/mod.rs
+++ b/src/ext/framework/mod.rs
@@ -100,12 +100,12 @@ use ::model::Message;
#[macro_export]
macro_rules! command {
($fname:ident($c:ident, $m:ident, $a:ident) $b:block) => {
- fn $fname($c: Context, $m: Message, $a: Vec<String>) {
+ fn $fname($c: &Context, $m: &Message, $a: Vec<String>) {
$b
}
};
($fname:ident($c:ident, $m:ident, $a:ident, $($name:ident: $t:ty),*) $b:block) => {
- fn $fname($c: Context, $m: Message, $a: Vec<String>) {
+ fn $fname($c: &Context, $m: &Message, $a: Vec<String>) {
let mut i = $a.iter();
$(
@@ -163,6 +163,8 @@ pub enum CommandType {
pub struct Framework {
configuration: Configuration,
commands: HashMap<String, InternalCommand>,
+ before: Option<Arc<Fn(&Context, &Message, &String) + Send + Sync + 'static>>,
+ after: Option<Arc<Fn(&Context, &Message, &String) + Send + Sync + 'static>>,
checks: HashMap<String, Arc<Fn(&Context, &Message) -> bool + Send + Sync + 'static>>,
/// Whether the framework has been "initialized".
///
@@ -261,15 +263,25 @@ impl Framework {
}
}
+ let before = self.before.clone();
let command = command.clone();
+ let after = self.after.clone();
thread::spawn(move || {
+ if let Some(before) = before {
+ (before)(&context, &message, &built);
+ }
+
let args = message.content[position + built.len()..]
.split_whitespace()
.map(|arg| arg.to_owned())
.collect::<Vec<String>>();
- (command)(context, message, args)
+ (command)(&context, &message, args);
+
+ if let Some(after) = after {
+ (after)(&context, &message, &built);
+ }
});
return;
@@ -289,7 +301,7 @@ impl Framework {
///
/// [module-level documentation]: index.html
pub fn on<F, S>(mut self, command_name: S, f: F) -> Self
- where F: Fn(Context, Message, Vec<String>) + Send + Sync + 'static,
+ where F: Fn(&Context, &Message, Vec<String>) + Send + Sync + 'static,
S: Into<String> {
self.commands.insert(command_name.into(), Arc::new(f));
self.initialized = true;
@@ -297,6 +309,22 @@ impl Framework {
self
}
+ /// This will call given closure before every command's execution
+ pub fn before<F>(mut self, f: F) -> Self
+ where F: Fn(&Context, &Message, &String) + Send + Sync + 'static {
+ self.before = Some(Arc::new(f));
+
+ self
+ }
+
+ /// This will call given closure after every command's execution
+ pub fn after<F>(mut self, f: F) -> Self
+ where F: Fn(&Context, &Message, &String) + Send + Sync + 'static {
+ self.after = Some(Arc::new(f));
+
+ self
+ }
+
/// Adds a "check" to a command, which checks whether or not the command's
/// associated function should be called.
///