Skip to content

Instantly share code, notes, and snippets.

@rust-play
Created March 16, 2022 17:24
Show Gist options
  • Save rust-play/d830916a42f650eae3a590e24b0d1504 to your computer and use it in GitHub Desktop.
Save rust-play/d830916a42f650eae3a590e24b0d1504 to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
struct ContextManager<'a> {
f: Option<Box<dyn FnOnce(&mut Ui, &mut Ui)>>,
parent: &'a mut Ui,
child: Ui,
}
use core::fmt::Debug;
impl Debug for ContextManager<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "ContextManager{{parent={:?}, child={:?}}}", self.parent, self.child)
}
}
impl<'a> ContextManager<'a> {
fn new(f: impl FnOnce(&mut Ui, &mut Ui) + 'static, parent: &'a mut Ui, child: Ui) -> ContextManager {
ContextManager{f: Some(Box::new(f)), parent, child}
}
fn horizontal(&mut self, render: bool) -> Option<ContextManager> {
self.child.horizontal(render)
}
fn horizontal_cb<R>(&mut self, f: impl FnOnce(&mut Ui) -> R, render: bool) -> Option<R> {
self.child.horizontal_cb(f, render)
}
fn exit(&mut self) {
if let Some(f) = self.f.take() {
f(&mut self.parent, &mut self.child);
}
}
}
impl Drop for ContextManager<'_> {
fn drop(&mut self) {
self.exit();
}
}
#[derive(Debug)]
struct Ui {
id: u64,
parent: u64,
data: u64,
}
impl Ui {
#[must_use]
fn horizontal(&mut self, render: bool) -> Option<ContextManager> {
if !render { return None; }
let child = Ui{id: self.id + 1, parent: self.id, data: 0};
let local = 1;
self.cm(child, move |parent, child| {
println!("cm exit parent={:?} child={:?} local={}", parent, child, local);
child.data += 1;
parent.data += 1;
})
}
fn horizontal_cb<R>(&mut self, f: impl FnOnce(&mut Self) -> R, render: bool) -> Option<R> {
match self.horizontal(render) {
Some(mut cm) => Some(f(&mut cm.child)),
None => None,
}
}
fn cm(&mut self, child: Ui, f: impl FnOnce(&mut Ui, &mut Ui) + 'static) -> Option<ContextManager> {
Some(ContextManager::new(f, self, child))
}
}
fn main() {
let mut ui = Ui{id: 0, parent: 0, data: 0};
if let Some(mut ui) = ui.horizontal(true) {
println!("inside first horizontal: {:?}", ui);
if let Some(mut ui) = ui.horizontal(true) {
println!("inside second horizontal: {:?}", ui);
if let Some(ui) = ui.horizontal(true) {
println!("inside third horizontal: {:?}", ui);
}
}
if let Some(ui) = ui.horizontal(false) {
println!("this horizontal render will be skipped: {:?}", ui);
}
}
ui.horizontal_cb(|ui| {
println!("inside first cb horizontal: {:?}", ui);
ui.horizontal_cb(|ui| {
println!("inside second cb horizontal: {:?}", ui);
ui.horizontal_cb(|ui| {
println!("inside third cb horizontal: {:?}", ui);
}, true);
}, true);
ui.horizontal_cb(|ui| {
println!("this horizontal render will be skipped: {:?}", ui);
}, false);
}, true);
println!("final root ui {:?}", ui);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment