Skip to content

Instantly share code, notes, and snippets.

@azriel91
Last active March 10, 2017 19:56
Show Gist options
  • Save azriel91/e0dfd46e2f8f729b87d4e07d5ed1f631 to your computer and use it in GitHub Desktop.
Save azriel91/e0dfd46e2f8f729b87d4e07d5ed1f631 to your computer and use it in GitHub Desktop.
Test the ability to store a hashmap where the value can be a reference to arbitrary types.
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::rc::Rc;
use std::sync::mpsc::{self, Sender, Receiver};
mod app_menu {
pub const ID: &'static str = module_path!();
pub trait Input {
fn listen(&self, message: String);
fn silence(&self);
}
}
mod preload {
pub const ID: &'static str = module_path!();
pub trait Input {
fn listen(&self, message: i32);
fn silence(&self);
}
}
#[derive(Debug)]
#[allow(non_camel_case_types)]
enum ChannelSender {
app_menu(Sender<String>),
preload(Sender<i32>),
}
#[derive(Debug)]
#[allow(non_camel_case_types)]
enum ChannelReceiver {
app_menu(Arc<Mutex<Receiver<String>>>),
preload(Arc<Mutex<Receiver<i32>>>),
}
// Thanks to Dabo from the rustc beginners channel
// HashMap<_, SenderEnum>, where SenderEnum is like `enum SenderEnum { Trait1(Sender<Struct1>), ..`
pub struct View {
listener_txs: HashMap<&'static str, ChannelSender>,
listener_rxs: HashMap<&'static str, ChannelReceiver>,
}
impl View {
pub fn new() -> Self {
let (listener_txs, listener_rxs) = View::init_channels();
View {
listener_txs: listener_txs,
listener_rxs: listener_rxs,
}
}
fn init_channels
()
-> (HashMap<&'static str, ChannelSender>, HashMap<&'static str, ChannelReceiver>)
{
let mut listener_txs = HashMap::new();
let mut listener_rxs = HashMap::new();
let (tx, rx) = mpsc::channel();
listener_txs.insert(app_menu::ID, ChannelSender::app_menu(tx));
listener_rxs.insert(app_menu::ID,
ChannelReceiver::app_menu(Arc::new(Mutex::new(rx))));
let (tx, rx) = mpsc::channel();
listener_txs.insert(preload::ID, ChannelSender::preload(tx));
listener_rxs.insert(preload::ID,
ChannelReceiver::preload(Arc::new(Mutex::new(rx))));
(listener_txs, listener_rxs)
}
}
impl app_menu::Input for View {
fn listen(&self, _message: String) {
if let Some(listener_rx) = self.listener_rxs.get(app_menu::ID) {
println!("Found listener_rx for app_menu: Sender: {:?}", listener_rx);
} else {
println!("Could not find listener_rx for app_menu");
}
}
fn silence(&self) {
if let Some(listener_tx) = self.listener_txs.get(app_menu::ID) {
println!("Found listener_tx for app_menu: Sender: {:?}", listener_tx);
} else {
println!("Could not find listener_tx for app_menu");
}
}
}
impl preload::Input for View {
fn listen(&self, _message: i32) {
if let Some(listener_rx) = self.listener_rxs.get(preload::ID) {
println!("Found listener_rx for preload: Sender: {:?}", listener_rx);
} else {
println!("Could not find listener_rx for preload");
}
}
fn silence(&self) {
if let Some(listener_tx) = self.listener_txs.get(preload::ID) {
println!("Found listener_tx for preload: Sender: {:?}", listener_tx);
} else {
println!("Could not find listener_tx for preload");
}
}
}
fn main() {
let view = Rc::new(View::new());
let app_menu_views: Vec<Rc<app_menu::Input>> = vec![view.clone()];
let preload_views: Vec<Rc<preload::Input>> = vec![view.clone()];
for input in &app_menu_views {
input.listen("asdf".to_string());
input.silence();
}
for input in &preload_views {
input.listen(123);
input.silence();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment