Initial implementation of lua module.
This commit is contained in:
parent
41fa36cccf
commit
d9ab75a607
@ -6,6 +6,9 @@ extern crate pvn;
|
||||
extern crate echobox;
|
||||
extern crate transformable_channels;
|
||||
|
||||
#[macro_use]
|
||||
extern crate hlua;
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use toml::Table;
|
||||
|
||||
@ -20,6 +23,7 @@ use std::sync::Arc;
|
||||
use std::sync::mpsc;
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::cell::{Cell, RefCell};
|
||||
|
||||
use transformable_channels::mpsc::TransformableSender;
|
||||
|
@ -6,6 +6,7 @@ use modules::Module;
|
||||
use toml::Table;
|
||||
|
||||
use event;
|
||||
use event::Envelope;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::sync::mpsc::Receiver;
|
||||
@ -72,7 +73,7 @@ impl Module for DiscordModule {
|
||||
for channel in server.channels {
|
||||
info!(" - Joined channel: {}", channel.name);
|
||||
|
||||
match sender.send(event::Envelope::new(event::Event::SelfJoin {
|
||||
match sender.send(Envelope::new(event::Event::SelfJoin {
|
||||
channel: Channel {
|
||||
name: channel.name,
|
||||
description: String::from(""),
|
||||
@ -116,7 +117,7 @@ impl Module for DiscordModule {
|
||||
channel: Some(channel)
|
||||
};
|
||||
|
||||
match sender.send(event::Envelope::new(event::Event::Message { message: message })) {
|
||||
match sender.send(Envelope::new(event::Event::Message { message: message })) {
|
||||
Err(err) => error!("Error sending message event: {:?}", err),
|
||||
Ok(_) => {}
|
||||
}
|
||||
|
@ -1,14 +1,106 @@
|
||||
use modules::Module;
|
||||
use toml::Table;
|
||||
|
||||
use toml::{Table, Value};
|
||||
|
||||
use hlua;
|
||||
use hlua::{Lua, LuaFunction, Push};
|
||||
|
||||
use event::{Event, Envelope};
|
||||
use Message;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::sync::mpsc::Receiver;
|
||||
use transformable_channels::mpsc::ExtSender;
|
||||
|
||||
use std::path::Path;
|
||||
use std::fs::File;
|
||||
|
||||
pub struct LuaModule {
|
||||
|
||||
code: Option<String>,
|
||||
file: Option<String>,
|
||||
variables: Table
|
||||
}
|
||||
|
||||
impl LuaModule {
|
||||
pub fn new (_: &Table) -> Box<Module> {
|
||||
Box::new(LuaModule {})
|
||||
pub fn new (config: &Table) -> Box<Module> {
|
||||
Box::new(LuaModule {
|
||||
code: config.get("code").and_then(|value| value.as_str()).map(String::from),
|
||||
file: config.get("file").and_then(|value| value.as_str()).map(String::from),
|
||||
variables: config.clone()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Module for LuaModule {}
|
||||
fn set (lua: &mut Lua, key: &str, value: &Value) {
|
||||
match value.clone() {
|
||||
Value::String(string) => lua.set(key, string),
|
||||
Value::Integer(integer) => lua.set(key, integer as i32),
|
||||
Value::Float(float) => lua.set(key, float),
|
||||
Value::Boolean(boolean) => lua.set(key, boolean),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
implement_lua_read!(Message);
|
||||
implement_lua_push!(Message, |mut metatable| {
|
||||
let mut index = metatable.empty_array("__index");
|
||||
index.set("content", hlua::function1(|message: &mut Message| message.content.clone()));
|
||||
index.set("reply", hlua::function2(|message: &mut Message, reply: String| message.reply(&reply)));
|
||||
});
|
||||
|
||||
impl Module for LuaModule {
|
||||
fn run (&self, _: Box<ExtSender<Envelope>>, receiver: Receiver<Arc<Envelope>>) {
|
||||
let mut lua = Lua::new();
|
||||
lua.openlibs();
|
||||
|
||||
for (key, value) in &self.variables {
|
||||
set(&mut lua, key, value);
|
||||
}
|
||||
|
||||
match self.code {
|
||||
Some(ref code) => { lua.execute(&code).unwrap() },
|
||||
None => {
|
||||
match self.file {
|
||||
Some(ref file) => { lua.execute_from_reader::<(), _>(File::open(&Path::new(file)).unwrap()).unwrap(); }
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loop {
|
||||
match receiver.recv() {
|
||||
Ok(envelope) => {
|
||||
match envelope.event {
|
||||
Event::Message { ref message } => {
|
||||
let on_message: Option<LuaFunction<_>> = lua.get("on_message");
|
||||
match on_message {
|
||||
Some(mut on_message) => {
|
||||
/*
|
||||
* What this does is clone the envelope reference (an Arc - atomic refcounted)
|
||||
* and pass it into the reply_callback, where it becomes owned by the closure
|
||||
* (since it's a move closure). We then pass this callback into the lua code,
|
||||
* where it can be used to send a reply.
|
||||
*
|
||||
* TODO: Replace this with a table (struct/class) which has a
|
||||
* reply() method.
|
||||
*/
|
||||
let envelope_clone = envelope.clone();
|
||||
let reply_callback = hlua::function1(move |reply: String| {
|
||||
match envelope_clone.event {
|
||||
Event::Message { ref message } => message.reply(&reply),
|
||||
_ => {}
|
||||
}
|
||||
});
|
||||
on_message.call_with_args::<(), _, _>((message.content.clone(), reply_callback)).unwrap();
|
||||
},
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
Err(error) => { error!("Error {:?}", error) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user