Skip to content

Commit

Permalink
Add Object::start method
Browse files Browse the repository at this point in the history
  • Loading branch information
matthunz committed Dec 11, 2023
1 parent 89b4702 commit 93716be
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 17 deletions.
2 changes: 1 addition & 1 deletion examples/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ fn main() {
let ui = UserInterface::new();
let _guard = ui.enter();

let window = Window {}.spawn_window();
let window = Window {}.spawn();
let app = App.spawn();

window.cursor_moved().bind(&app, App::cursor_moved);
Expand Down
7 changes: 7 additions & 0 deletions macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub fn object(_attrs: TokenStream, input: TokenStream) -> TokenStream {

let mut items = Vec::new();
let mut handle_items = Vec::new();
let mut start_item = None;
for item in item.items {
match item {
syn::ImplItem::Fn(fn_item) => {
Expand Down Expand Up @@ -42,6 +43,8 @@ pub fn object(_attrs: TokenStream, input: TokenStream) -> TokenStream {
});

handle_items.push(fn_item.clone());
} else if fn_item.sig.ident.to_string() == "start" {
start_item = Some(fn_item.block);
} else {
items.push(fn_item.clone());
}
Expand Down Expand Up @@ -101,6 +104,10 @@ pub fn object(_attrs: TokenStream, input: TokenStream) -> TokenStream {
let output = quote! {
impl viewbuilder::Object for #ident {
type Handle = #handle_ident;

fn start(&mut self, handle: viewbuilder::Handle<Self>) {
#start_item
}
}

impl #ident {
Expand Down
13 changes: 12 additions & 1 deletion src/any_object.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
use crate::Object;
use slotmap::DefaultKey;

use crate::{HandleState, Object};
use std::any::Any;

pub trait AnyObject {
fn as_any(&self) -> &dyn Any;

fn as_any_mut(&mut self) -> &mut dyn Any;

fn start_any(&mut self, key: DefaultKey);
}

impl<O> AnyObject for O
Expand All @@ -18,4 +22,11 @@ where
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}

fn start_any(&mut self, key: DefaultKey) {
self.start(crate::Handle {
state: HandleState::new(key),
handle: HandleState::new(key).into(),
})
}
}
45 changes: 44 additions & 1 deletion src/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::{
cell::{self, RefCell},
marker::PhantomData,
mem,
ops::Deref,
ops::{Deref, DerefMut},
rc::Rc,
};

Expand Down Expand Up @@ -39,6 +39,11 @@ impl<O: Object> Handle<O> {
pub fn borrow(&self) -> Ref<O> {
self.state.borrow()
}

/// Mutably borrow the object.
pub fn borrow_mut(&self) -> RefMut<O> {
self.state.borrow_mut()
}
}

impl<O: Object> Deref for Handle<O> {
Expand Down Expand Up @@ -119,6 +124,25 @@ impl<O: Object> HandleState<O> {
object,
}
}

/// Mutably borrow the object.
pub fn borrow_mut(&self) -> RefMut<O> {
let guard = Runtime::current().inner.borrow().nodes[self.key()]
.object
.clone();

let object = cell::RefMut::map(guard.borrow_mut(), |object| {
object.as_any_mut().downcast_mut::<O>().unwrap()
});

// Safety: `guard` is held as long as `Ref`.
let object = unsafe { mem::transmute(object) };

RefMut {
_guard: guard,
object,
}
}
}

pub struct Ref<O: 'static> {
Expand All @@ -133,3 +157,22 @@ impl<O: 'static> Deref for Ref<O> {
&*self.object
}
}

pub struct RefMut<O: 'static> {
object: cell::RefMut<'static, O>,
_guard: Rc<RefCell<dyn AnyObject>>,
}

impl<O: 'static> Deref for RefMut<O> {
type Target = O;

fn deref(&self) -> &Self::Target {
&*self.object
}
}

impl<O: 'static> DerefMut for RefMut<O> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut *self.object
}
}
9 changes: 7 additions & 2 deletions src/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ pub trait Object: Sized {
/// Handle for this object.
type Handle: From<HandleState<Self>> + Clone;

#[allow(unused_variables)]
fn start(&mut self, handle: Handle<Self>) {}

/// Spawn this object and return a handle to it.
fn spawn(self) -> Handle<Self>
where
Expand All @@ -16,9 +19,11 @@ pub trait Object: Sized {
listeners: Vec::new(),
});

Handle {
let handle: Handle<Self> = Handle {
state: HandleState::new(key),
handle: HandleState::new(key).into(),
}
};
handle.borrow_mut().start(handle.clone());
handle
}
}
2 changes: 1 addition & 1 deletion src/ui/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{rt::RuntimeGuard, Handle, Runtime};
use kurbo::Point;
use std::{cell::RefCell, collections::HashMap, mem, rc::Rc};
use std::{cell::RefCell, collections::HashMap, rc::Rc};
use winit::event::WindowEvent;
use winit::event_loop::EventLoop;
use winit::window::WindowId;
Expand Down
20 changes: 9 additions & 11 deletions src/ui/window.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{object, Handle, Object, UserInterface};
use crate::object;
use kurbo::Point;
use winit::{
dpi::PhysicalSize,
Expand All @@ -12,6 +12,14 @@ pub struct Window {}

#[object]
impl Window {
fn start(&mut self, handle: Handle<Self>) {
Context::current()
.inner
.borrow_mut()
.pending_windows
.push(handle.clone());
}

/// Signal for the cursor movement event.
fn cursor_moved(&self, point: Point);

Expand All @@ -32,14 +40,4 @@ impl Window {

/// Signal for the cursor leave event.
fn cursor_left(&self);

pub fn spawn_window(self) -> Handle<Self> {
let handle = self.spawn();
Context::current()
.inner
.borrow_mut()
.pending_windows
.push(handle.clone());
handle
}
}

0 comments on commit 93716be

Please sign in to comment.