feat, multi_flutter_ui_sessions

Signed-off-by: dignow <linlong1265@gmail.com>
This commit is contained in:
dignow
2023-10-08 21:44:54 +08:00
parent 5e616dd502
commit 013d307bcd
83 changed files with 2954 additions and 1319 deletions

View File

@@ -1,16 +1,19 @@
use super::*;
use std::{
collections::HashSet,
ops::{Deref, DerefMut},
thread::{self, JoinHandle},
time,
};
pub trait Service: Send + Sync {
fn name(&self) -> &'static str;
fn name(&self) -> String;
fn on_subscribe(&self, sub: ConnInner);
fn on_unsubscribe(&self, id: i32);
fn is_subed(&self, id: i32) -> bool;
fn join(&self);
fn get_option(&self, opt: &str) -> Option<String>;
fn set_option(&self, opt: &str, val: &str) -> Option<String>;
}
pub trait Subscriber: Default + Send + Sync + 'static {
@@ -20,12 +23,13 @@ pub trait Subscriber: Default + Send + Sync + 'static {
#[derive(Default)]
pub struct ServiceInner<T: Subscriber + From<ConnInner>> {
name: &'static str,
name: String,
handle: Option<JoinHandle<()>>,
subscribes: HashMap<i32, T>,
new_subscribes: HashMap<i32, T>,
active: bool,
need_snapshot: bool,
options: HashMap<String, String>,
}
pub trait Reset {
@@ -37,6 +41,35 @@ pub struct ServiceSwap<T: Subscriber + From<ConnInner>>(ServiceTmpl<T>);
pub type GenericService = ServiceTmpl<ConnInner>;
pub const HIBERNATE_TIMEOUT: u64 = 30;
pub const MAX_ERROR_TIMEOUT: u64 = 1_000;
pub const SERVICE_OPTION_VALUE_TRUE: &str = "1";
pub const SERVICE_OPTION_VALUE_FALSE: &str = "0";
#[derive(Clone)]
pub struct EmptyExtraFieldService {
pub sp: GenericService,
}
impl Deref for EmptyExtraFieldService {
type Target = ServiceTmpl<ConnInner>;
fn deref(&self) -> &Self::Target {
&self.sp
}
}
impl DerefMut for EmptyExtraFieldService {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.sp
}
}
impl EmptyExtraFieldService {
pub fn new(name: String, need_snapshot: bool) -> Self {
Self {
sp: GenericService::new(name, need_snapshot),
}
}
}
impl<T: Subscriber + From<ConnInner>> ServiceInner<T> {
fn send_new_subscribes(&mut self, msg: Arc<Message>) {
@@ -60,8 +93,8 @@ impl<T: Subscriber + From<ConnInner>> ServiceInner<T> {
impl<T: Subscriber + From<ConnInner>> Service for ServiceTmpl<T> {
#[inline]
fn name(&self) -> &'static str {
self.0.read().unwrap().name
fn name(&self) -> String {
self.0.read().unwrap().name.clone()
}
fn is_subed(&self, id: i32) -> bool {
@@ -96,6 +129,18 @@ impl<T: Subscriber + From<ConnInner>> Service for ServiceTmpl<T> {
}
}
}
fn get_option(&self, opt: &str) -> Option<String> {
self.0.read().unwrap().options.get(opt).cloned()
}
fn set_option(&self, opt: &str, val: &str) -> Option<String> {
self.0
.write()
.unwrap()
.options
.insert(opt.to_string(), val.to_string())
}
}
impl<T: Subscriber + From<ConnInner>> Clone for ServiceTmpl<T> {
@@ -105,7 +150,7 @@ impl<T: Subscriber + From<ConnInner>> Clone for ServiceTmpl<T> {
}
impl<T: Subscriber + From<ConnInner>> ServiceTmpl<T> {
pub fn new(name: &'static str, need_snapshot: bool) -> Self {
pub fn new(name: String, need_snapshot: bool) -> Self {
Self(Arc::new(RwLock::new(ServiceInner::<T> {
name,
active: true,
@@ -114,6 +159,21 @@ impl<T: Subscriber + From<ConnInner>> ServiceTmpl<T> {
})))
}
#[inline]
pub fn is_option_true(&self, opt: &str) -> bool {
self.get_option(opt)
.map_or(false, |v| v == SERVICE_OPTION_VALUE_TRUE)
}
#[inline]
pub fn set_option_bool(&self, opt: &str, val: bool) {
if val {
self.set_option(opt, SERVICE_OPTION_VALUE_TRUE);
} else {
self.set_option(opt, SERVICE_OPTION_VALUE_FALSE);
}
}
#[inline]
pub fn has_subscribes(&self) -> bool {
self.0.read().unwrap().has_subscribes()
@@ -189,14 +249,15 @@ impl<T: Subscriber + From<ConnInner>> ServiceTmpl<T> {
}
}
pub fn repeat<S, F>(&self, interval_ms: u64, callback: F)
pub fn repeat<S, F, Svc>(svc: &Svc, interval_ms: u64, callback: F)
where
F: 'static + FnMut(Self, &mut S) -> ResultType<()> + Send,
F: 'static + FnMut(Svc, &mut S) -> ResultType<()> + Send,
S: 'static + Default + Reset,
Svc: 'static + Clone + Send + DerefMut<Target = ServiceTmpl<T>>,
{
let interval = time::Duration::from_millis(interval_ms);
let mut callback = callback;
let sp = self.clone();
let sp = svc.clone();
let thread = thread::spawn(move || {
let mut state = S::default();
let mut may_reset = false;
@@ -223,14 +284,15 @@ impl<T: Subscriber + From<ConnInner>> ServiceTmpl<T> {
}
log::info!("Service {} exit", sp.name());
});
self.0.write().unwrap().handle = Some(thread);
svc.0.write().unwrap().handle = Some(thread);
}
pub fn run<F>(&self, callback: F)
pub fn run<F, Svc>(svc: &Svc, callback: F)
where
F: 'static + FnMut(Self) -> ResultType<()> + Send,
F: 'static + FnMut(Svc) -> ResultType<()> + Send,
Svc: 'static + Clone + Send + DerefMut<Target = ServiceTmpl<T>>,
{
let sp = self.clone();
let sp = svc.clone();
let mut callback = callback;
let thread = thread::spawn(move || {
let mut error_timeout = HIBERNATE_TIMEOUT;
@@ -259,7 +321,7 @@ impl<T: Subscriber + From<ConnInner>> ServiceTmpl<T> {
}
log::info!("Service {} exit", sp.name());
});
self.0.write().unwrap().handle = Some(thread);
svc.0.write().unwrap().handle = Some(thread);
}
#[inline]