added config support to network manager, changed lifecycle a bit as well

This commit is contained in:
michael-bailey 2022-09-10 23:09:16 +01:00
parent a090f8a65a
commit 4e5620cf82
5 changed files with 104 additions and 47 deletions

View File

@ -16,7 +16,7 @@ use crate::{
ConfigManagerDataMessage, ConfigManagerDataResponse,
ConfigManagerOutput,
},
types::ConfigValue,
types::{ConfigError, ConfigValue},
},
prelude::messages::ObservableMessage,
};
@ -53,7 +53,8 @@ impl ConfigManager {
// instance methods
impl ConfigManager {
pub fn get_value(&self, key: String) -> Result<ConfigValue, &'static str> {
pub fn get_value(&self, key: String) -> Result<ConfigValue, ConfigError> {
use ConfigError::{NoKey, NoValue};
use ConfigValue::Dict;
if let Dict(dict) = &self.root {
@ -61,26 +62,44 @@ impl ConfigManager {
return if let Some(value) = opt_value {
Ok(value.clone())
} else {
Err("[ConfigManager] get_value: Value does not exist")
Err(NoValue)
};
}
Err("[ConfigManager] get_value: Key does not exist")
Err(NoKey)
}
// this doesn't work for now
pub fn set_value(
&mut self,
key: String,
value: ConfigValue,
) -> Result<ConfigManagerDataResponse, &'static str> {
use ConfigManagerDataResponse::SetValue;
) -> Result<ConfigValue, ConfigError> {
use ConfigError::IncompatableValue;
use ConfigValue::Dict;
if let Dict(dict) = &mut self.root {
dict.insert(key, value);
Ok(SetValue)
if let (Dict(stored), Dict(root)) = (&mut self.stored, &mut self.root) {
stored.insert(key.clone(), value.clone());
root.insert(key.clone(), value.clone());
Ok(value)
} else {
Err("[ConfigManager] set_value: What the hell did ou do wrong")
Err(IncompatableValue)
}
}
// this doesn't work for now
pub fn soft_set_value(
&mut self,
key: String,
value: ConfigValue,
) -> Result<ConfigValue, ConfigError> {
use ConfigError::IncompatableValue;
use ConfigValue::Dict;
if let Dict(root) = &mut self.root {
root.insert(key, value.clone());
Ok(value)
} else {
Err(IncompatableValue)
}
}
}
@ -88,7 +107,10 @@ impl ConfigManager {
impl Actor for ConfigManager {
type Context = Context<Self>;
fn started(&mut self, _ctx: &mut Self::Context) {}
fn started(&mut self, _ctx: &mut Self::Context) {
println!("[ConfigManager] starting");
println!("[ConfigManager] started");
}
}
impl Handler<ObservableMessage<ConfigManagerOutput>> for ConfigManager {
@ -104,23 +126,25 @@ impl Handler<ObservableMessage<ConfigManagerOutput>> for ConfigManager {
}
impl Handler<ConfigManagerDataMessage> for ConfigManager {
type Result = Result<ConfigManagerDataResponse, &'static str>;
type Result = Result<ConfigManagerDataResponse, ConfigError>;
fn handle(
&mut self,
msg: ConfigManagerDataMessage,
_ctx: &mut Self::Context,
) -> Self::Result {
use ConfigManagerDataResponse::{GotValue, SetValue};
use ConfigManagerDataResponse::{GotValue, SetValue, SoftSetValue};
match msg {
ConfigManagerDataMessage::GetValue(val) => {
Ok(GotValue(self.get_value(val)?))
}
ConfigManagerDataMessage::SetValue(key, value) => {
self.set_value(key, value)
Ok(SetValue(key.clone(), self.set_value(key, value)?))
}
ConfigManagerDataMessage::SoftSetValue(key, value) => {
Ok(SoftSetValue(key.clone(), self.soft_set_value(key, value)?))
}
ConfigManagerDataMessage::SoftSetValue(_, _) => Ok(SetValue),
}
}
}

View File

@ -1,22 +1,24 @@
use super::types::ConfigError;
use crate::config_manager::types::ConfigValue;
use actix::{Message, MessageResponse};
#[derive(Message)]
#[derive(Message, Debug)]
#[rtype(result = "()")]
pub enum ConfigManagerOutput {
ConfigUpdated(String, ConfigValue),
}
#[derive(Message)]
#[rtype(result = "Result<ConfigManagerDataResponse, &'static str>")]
#[derive(Message, Debug)]
#[rtype(result = "Result<ConfigManagerDataResponse, ConfigError>")]
pub enum ConfigManagerDataMessage {
GetValue(String),
SetValue(String, ConfigValue),
SoftSetValue(String, ConfigValue),
}
#[derive(MessageResponse)]
#[derive(MessageResponse, Debug)]
pub enum ConfigManagerDataResponse {
GotValue(ConfigValue),
SetValue,
SetValue(String, ConfigValue),
SoftSetValue(String, ConfigValue),
}

View File

@ -1,10 +1,11 @@
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap};
use std::ops::Index;
use serde::{Serialize, Deserialize};
use toml::value::Value;
pub enum Error {
UnknownField,
#[derive(Debug)]
pub enum ConfigError {
NoKey,
IncompatableValue,
NoValue,
}
@ -12,7 +13,7 @@ pub enum Error {
/// # ConfigValue
/// Each value type that can be used within a config file.
/// gets used when reading and writing to a config file.
#[derive(Clone)]
#[derive(Clone, Debug)]
pub enum ConfigValue {
Dict(BTreeMap<String, Self>),
Array(Vec<Self>),
@ -26,11 +27,11 @@ impl From<ConfigValue> for Value {
fn from(v: ConfigValue) -> Self {
match v {
ConfigValue::Dict(dict) => Value::Table(
dict.into_iter().map(|(k,v)| (k, v.into())).collect()
),
ConfigValue::Array(arr) => Value::Array(
arr.into_iter().map(|v| v.into()).collect()
dict.into_iter().map(|(k, v)| (k, v.into())).collect(),
),
ConfigValue::Array(arr) => {
Value::Array(arr.into_iter().map(|v| v.into()).collect())
}
ConfigValue::String(s) => Value::String(s),
ConfigValue::Number(n) => Value::Integer(n),
ConfigValue::Float(f) => Value::Float(f),
@ -43,11 +44,11 @@ impl From<Value> for ConfigValue {
fn from(v: Value) -> Self {
match v {
Value::Table(dict) => ConfigValue::Dict(
dict.into_iter().map(|(k,v)| (k, v.into())).collect()
),
Value::Array(arr) => ConfigValue::Array(
arr.into_iter().map(|v| v.into()).collect()
dict.into_iter().map(|(k, v)| (k, v.into())).collect(),
),
Value::Array(arr) => {
ConfigValue::Array(arr.into_iter().map(|v| v.into()).collect())
}
Value::String(s) => ConfigValue::String(s),
Value::Integer(n) => ConfigValue::Number(n),
Value::Float(f) => ConfigValue::Float(f),
@ -56,5 +57,3 @@ impl From<Value> for ConfigValue {
}
}
}

View File

@ -1,4 +1,7 @@
use crate::config_manager::ConfigManager;
use crate::config_manager::{
ConfigManager, ConfigManagerDataMessage, ConfigManagerDataResponse,
ConfigValue,
};
use crate::network::listener::NetworkListener;
use crate::network::listener::{ListenerMessage, ListenerOutput};
use crate::network::network_manager::config::Config;
@ -10,8 +13,10 @@ use crate::network::{
Connection, ConnectionInitiator, InitiatorOutput, NetworkDataMessage,
NetworkDataOutput,
};
use actix::fut::wrap_future;
use actix::{
Actor, Addr, AsyncContext, Context, Handler, WeakAddr, WeakRecipient,
Actor, ActorFutureExt, Addr, AsyncContext, Context, Handler, WeakAddr,
WeakRecipient,
};
use foundation::ClientDetails;
@ -44,6 +49,9 @@ impl NetworkManager {
fn start_listener(&mut self, _ctx: &mut <Self as actix::Actor>::Context) {
use ListenerMessage::StartListening;
println!("[NetworkManager] got Listen message");
if let Some(addr) = self.listener_addr.as_ref() {
addr.do_send(StartListening);
}
@ -124,12 +132,40 @@ impl Actor for NetworkManager {
type Context = Context<Self>;
fn started(&mut self, ctx: &mut Self::Context) {
println!("[NetworkManager] started with config {:?}", self.config);
let recipient = ctx.address().recipient();
self.listener_addr.replace(NetworkListener::new(
format!("0.0.0.0:{}", self.config.port),
recipient,
));
println!("[NetworkManager] Starting");
let config_mgr = self.config_manager.clone().upgrade();
if let Some(config_mgr) = config_mgr {
let fut = wrap_future(config_mgr.send(
ConfigManagerDataMessage::GetValue("Network.Port".to_owned()),
))
.map(
|out,
a: &mut NetworkManager,
ctx: &mut Context<NetworkManager>| {
use crate::config_manager::ConfigManagerDataResponse::GotValue;
use crate::config_manager::ConfigValue::Number;
let recipient = ctx.address().recipient();
let port = out
.map(|inner| inner.ok())
.ok()
.unwrap_or(None)
.unwrap_or(GotValue(Number(5600)));
println!("[NetworkManager] got port: {:?}", port);
if let GotValue(Number(port)) = port {
let nl = NetworkListener::new(
format!("0.0.0.0:{}", port),
recipient,
);
nl.do_send(ListenerMessage::StartListening);
a.listener_addr.replace(nl);
}
},
);
ctx.spawn(fut);
println!("[NetworkManager] Finished Starting");
}
}
}

View File

@ -97,10 +97,6 @@ impl Actor for Server {
let lm = LuaManager::create(ctx.address(), nm, cm).build();
self.lua_manager.replace(lm);
if let Some(net_mgr) = self.network_manager.as_ref() {
net_mgr.do_send(NetworkMessage::StartListening);
}
}
}