Last active
March 10, 2017 19:56
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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