Last active
April 2, 2021 04:16
-
-
Save KHN190/d7918bedd3bc047ee25c4befcf7e30d6 to your computer and use it in GitHub Desktop.
Create singleton instance in Rust
This file contains 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::sync::atomic::{AtomicBool, Ordering}; | |
pub trait Loader { | |
fn load(&self, name: &str); | |
} | |
struct ResourceLoader; | |
impl Loader for ResourceLoader { | |
fn load(&self, name: &str) { | |
println!("load {}", name); | |
} | |
} | |
static mut LOADER: Option<&dyn Loader> = None; | |
static INITIALIZED: AtomicBool = AtomicBool::new(false); | |
fn set_loader(loader: &'static dyn Loader) { | |
set_loader_inner(|| loader) | |
} | |
fn set_loader_inner<F>(make_loader: F) | |
where | |
F: FnOnce() -> &'static dyn Loader, | |
{ | |
unsafe { | |
if std::ptr::read(&INITIALIZED).into_inner() | |
{ | |
println!("loader already initialized"); | |
} | |
else { | |
LOADER = Some(make_loader()); | |
INITIALIZED.store(true, Ordering::Relaxed); | |
} | |
} | |
} | |
fn init_loader() { | |
let loader = Box::new(ResourceLoader {}); | |
set_loader(Box::leak(loader)); | |
} | |
pub fn get_loader() -> &'static dyn Loader { | |
unsafe { | |
if !std::ptr::read(&INITIALIZED).into_inner() | |
{ | |
init_loader(); | |
} | |
LOADER.unwrap() | |
} | |
} |
This file contains 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
mod loader; | |
fn main() { | |
let ld = loader::get_loader(); | |
ld.load("what?"); | |
let rs = loader::get_loader(); | |
rs.load("hei!"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Use singleton so you don't have to pass in a logger / resource loader 10 levels deep from a top level function...
Instead, call anywhere in your code: