made client manager and clients scriptable

This commit is contained in:
michael-bailey 2022-07-01 00:43:13 +01:00
parent ff067f8e4b
commit 51cea3523e
8 changed files with 123 additions and 58 deletions

View File

@ -32,7 +32,7 @@ futures = "0.3.16"
async-trait = "0.1.52"
actix = "0.13"
rhai = {version = "1.7.0"}
mlua = { version = "0.8.0", features=["lua54", "async", "serde", "macros", "vendored"] }
mlua = { version = "0.8.1", features=["lua54", "async", "serde", "macros", "vendored"] }
libloading = "0.7"
toml = "0.4.2"
aquamarine = "0.1.11"

View File

@ -40,19 +40,8 @@ use crate::{
network::NetworkOutput,
prelude::messages::ObservableMessage,
};
#[derive(Message)]
#[rtype(result = "()")]
pub(crate) enum ClientManagerMessage {
AddClient(Uuid, Addr<Client>),
RemoveClient(Uuid),
}
#[derive(Message)]
#[rtype(result = "()")]
pub enum ClientManagerOutput {
UpdateRequest(Addr<ClientManager>),
}
use crate::client_management::messages::{ClientManagerDataMessage, ClientManagerDataResponse, ClientManagerMessage, ClientManagerOutput};
use crate::client_management::messages::ClientManagerDataResponse::{ClientCount, Clients};
pub struct ClientManager {
clients: HashMap<Uuid, Addr<Client>>,
@ -60,6 +49,16 @@ pub struct ClientManager {
}
impl ClientManager {
pub(crate) fn new(
delegate: WeakRecipient<ClientManagerOutput>,
) -> Addr<Self> {
ClientManager {
delegate,
clients: HashMap::new(),
}
.start()
}
pub(crate) fn send_update(
&mut self,
ctx: &mut Context<Self>,
@ -145,18 +144,6 @@ impl ClientManager {
ctx.spawn(fut);
}
}
}
impl ClientManager {
pub(crate) fn new(
delegate: WeakRecipient<ClientManagerOutput>,
) -> Addr<Self> {
ClientManager {
delegate,
clients: HashMap::new(),
}
.start()
}
fn add_client(
&mut self,
@ -231,3 +218,20 @@ impl Handler<ClientObservableMessage> for ClientManager {
}
}
}
impl Handler<ClientManagerDataMessage> for ClientManager {
type Result = ClientManagerDataResponse;
fn handle(&mut self, msg: ClientManagerDataMessage, ctx: &mut Self::Context) -> Self::Result {
match msg {
ClientManagerDataMessage::ClientCount => {
ClientCount(self.clients.values().count())
}
ClientManagerDataMessage::Clients => Clients(
self.clients.values()
.map(|a| a.downgrade())
.collect()
)
}
}
}

View File

@ -0,0 +1,29 @@
use actix::{Message, MessageResponse, Addr, WeakAddr};
use uuid::Uuid;
use crate::client_management::{Client, ClientManager};
#[derive(Message)]
#[rtype(result = "()")]
pub(crate) enum ClientManagerMessage {
AddClient(Uuid, Addr<Client>),
RemoveClient(Uuid),
}
#[derive(Message)]
#[rtype(result = "()")]
pub(crate) enum ClientManagerOutput {
UpdateRequest(Addr<ClientManager>),
}
#[derive(Message)]
#[rtype(result = "ClientManagerDataResponse")]
pub enum ClientManagerDataMessage {
ClientCount,
Clients
}
#[derive(MessageResponse)]
pub enum ClientManagerDataResponse {
ClientCount(usize),
Clients(Vec<WeakAddr<Client>>)
}

View File

@ -1,9 +1,12 @@
mod client;
mod client_manager;
mod messages;
pub(crate) use client::Client;
pub(crate) use client_manager::{
ClientManager,
pub(crate) use client_manager::ClientManager;
pub(crate) use messages::{
ClientManagerMessage,
ClientManagerOutput,
ClientManagerDataMessage,
ClientManagerDataResponse,
};

View File

@ -1,3 +1,7 @@
//! # lua_manager.rs
//!
//! Holds the LuaManger struct and implements it's methods
use actix::{Actor, Addr, ArbiterHandle, AsyncContext, Context, Running};
use actix::fut::wrap_future;
use mlua::{Lua, Thread, ThreadStatus};
@ -8,8 +12,10 @@ use crate::network::NetworkManager;
use crate::scripting::scriptable_server::ScriptableServer;
use crate::Server;
/// # LuaManager
/// Holds common server objects
/// todo: change to weak references
pub struct LuaManager {
pub(super) engine: Lua,
pub(super) server: Addr<Server>,
pub(super) network_manager: Addr<NetworkManager>,
pub(super) client_manager: Addr<ClientManager>,
@ -22,9 +28,9 @@ impl LuaManager {
client_manager: Addr<ClientManager>
) -> Builder {
Builder::new(
server.clone(),
network_manager.clone(),
client_manager.clone()
server,
network_manager,
client_manager
)
}
@ -34,7 +40,6 @@ impl LuaManager {
let api = engine.create_table().unwrap();
api.set::<&str, ScriptableServer>("server", server).unwrap();
api.set::<&str, i32>("a", 12).unwrap();
engine.globals().set("chat", api).unwrap();
engine
@ -51,7 +56,6 @@ impl Actor for LuaManager {
let coroutine: Thread = engine.load(r#"
coroutine.create(function ()
print("hello lua")
print(chat.server.Test)
print(chat.server:name())
end)
"#).eval().unwrap();
@ -65,25 +69,10 @@ impl Actor for LuaManager {
// we enforce the actor model on the consumer of the api.
impl From<Builder> for Addr<LuaManager> {
fn from(b: Builder) -> Addr<LuaManager> {
let mgr = LuaManager {
engine: b.engine,
server: b.server.clone(),
network_manager: b.network_manager.clone(),
client_manager: b.client_manager.clone()
};
let server = ScriptableServer::from(b.server);
let api = mgr.engine.create_table().unwrap();
api.set::<&str, ScriptableServer>("server", server).unwrap();
api.set::<&str, i32>("a", 12).unwrap();
let a = api.get::<&str, i32>("a").unwrap();
println!("Lua stored: {}", a);
mgr.engine.globals().set("chat", api).unwrap();
mgr.start()
LuaManager {
server: b.server,
network_manager: b.network_manager,
client_manager: b.client_manager
}.start()
}
}

View File

@ -1,3 +1,4 @@
pub(crate) mod scriptable_server;
pub(crate) mod scriptable_network_manager;
pub(crate) mod scriptable_client_manager;
pub(crate) mod scriptable_client_manager;
pub(crate) mod scriptable_client;

View File

@ -0,0 +1,19 @@
use actix::Addr;
use mlua::UserData;
use crate::client_management::Client;
pub(crate) struct ScriptableClient {
addr: Addr<Client>
}
impl UserData for ScriptableClient {
}
impl From<Addr<Client>> for ScriptableClient {
fn from(addr: Addr<Client>) -> Self {
Self {
addr
}
}
}

View File

@ -1,13 +1,33 @@
use actix::Addr;
use mlua::UserData;
use crate::client_management::ClientManager;
use actix::{ActorStreamExt, Addr};
use mlua::{Error, UserData, UserDataFields, UserDataMethods};
use crate::client_management::{ClientManager, ClientManagerDataMessage};
use crate::client_management::ClientManagerDataResponse::Clients;
use crate::scripting::scriptable_client::ScriptableClient;
#[derive(Clone)]
pub(crate) struct ScriptableClientManager {
addr: Addr<ClientManager>
}
impl UserData for ScriptableClientManager {
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
methods.add_async_method("clients", |lua, obj, ()| async move {
let res = obj.addr.send(ClientManagerDataMessage::Clients).await;
if let Ok(Clients(clients)) = res {
let clients: Vec<ScriptableClient> = clients.into_iter()
.map(|a| a.upgrade())
.filter(|o| o.is_some())
.map(|o| o.unwrap())
.map(|a| ScriptableClient::from(a))
.collect();
Ok(clients)
} else {
Err(Error::RuntimeError("clients returned null or other value".to_string()))
}
})
}
}
impl From<Addr<ClientManager>> for ScriptableClientManager {