mirror of https://github.com/sgoudham/neovide.git
Add event aggregator and remove manual usage of channels. Also add redraw editor command on resume
parent
d220477b73
commit
26169f84c0
@ -0,0 +1,75 @@
|
||||
use std::any::{type_name, Any, TypeId};
|
||||
use std::collections::{hash_map::Entry, HashMap};
|
||||
use std::fmt::Debug;
|
||||
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver};
|
||||
|
||||
use crate::channel_utils::*;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref EVENT_AGGREGATOR: EventAggregator = EventAggregator::default();
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
static THREAD_SENDERS: RwLock<HashMap<TypeId, Box<dyn Any + Send>>> = RwLock::new(HashMap::new());
|
||||
}
|
||||
|
||||
pub struct EventAggregator {
|
||||
parent_senders: RwLock<HashMap<TypeId, Mutex<Box<dyn Any + Send>>>>,
|
||||
unclaimed_receivers: RwLock<HashMap<TypeId, Box<dyn Any + Send + Sync>>>,
|
||||
}
|
||||
|
||||
impl Default for EventAggregator {
|
||||
fn default() -> Self {
|
||||
EventAggregator {
|
||||
parent_senders: RwLock::new(HashMap::new()),
|
||||
unclaimed_receivers: RwLock::new(HashMap::new()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EventAggregator {
|
||||
fn get_sender<T: Any + Clone + Debug + Send>(&self) -> LoggingTx<T> {
|
||||
match self.parent_senders.write().entry(TypeId::of::<T>()) {
|
||||
Entry::Occupied(entry) => {
|
||||
let sender = entry.get().lock();
|
||||
sender.downcast_ref::<LoggingTx<T>>().unwrap().clone()
|
||||
}
|
||||
Entry::Vacant(entry) => {
|
||||
let (sender, receiver) = unbounded_channel();
|
||||
let logging_tx = LoggingTx::attach(sender, type_name::<T>().to_owned());
|
||||
entry.insert(Mutex::new(Box::new(logging_tx.clone())));
|
||||
self.unclaimed_receivers
|
||||
.write()
|
||||
.insert(TypeId::of::<T>(), Box::new(receiver));
|
||||
logging_tx
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn send<T: Any + Clone + Debug + Send>(&self, event: T) {
|
||||
let sender = self.get_sender::<T>();
|
||||
sender.send(event).unwrap();
|
||||
}
|
||||
|
||||
pub fn register_event<T: Any + Clone + Debug + Send>(&self) -> UnboundedReceiver<T> {
|
||||
let type_id = TypeId::of::<T>();
|
||||
|
||||
if let Some(receiver) = self.unclaimed_receivers.write().remove(&type_id) {
|
||||
*receiver.downcast::<UnboundedReceiver<T>>().unwrap()
|
||||
} else {
|
||||
let (sender, receiver) = unbounded_channel();
|
||||
let logging_sender = LoggingTx::attach(sender, type_name::<T>().to_owned());
|
||||
|
||||
match self.parent_senders.write().entry(type_id) {
|
||||
Entry::Occupied(_) => panic!("EventAggregator: type already registered"),
|
||||
Entry::Vacant(entry) => {
|
||||
entry.insert(Mutex::new(Box::new(logging_sender)));
|
||||
}
|
||||
}
|
||||
|
||||
receiver
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue