Browse Source

Minor documentation improvements.

Kestrel 3 days ago
parent
commit
2a34e1edc4
3 changed files with 24 additions and 1 deletions
  1. 20 0
      src/layout.rs
  2. 3 0
      src/ui.rs
  3. 1 1
      src/window.rs

+ 20 - 0
src/layout.rs

@@ -536,6 +536,10 @@ impl<'l> Iterator for LayoutChildIter<'l> {
 }
 
 /// Accessor trait for a struct that stores edge information for the layout tree.
+///
+/// This trait accepts a tag type parameter to allow a single struct to store multiple layout nodes
+/// with internal edges. Use a `Tag` type of `()` or similar to denote a struct that only
+/// stores a single layout node.
 pub trait LayoutTreeNode<Tag: 'static> {
     fn current_node(&self) -> &LayoutNode;
     fn child_count(&self) -> usize;
@@ -562,6 +566,22 @@ fn child_dispatch<'l, Tag: 'static>(dynptr: DynPtr, ndx: usize) -> Option<Layout
 ///
 /// Use this struct if you wish to accept arbitrary [`LayoutNode`]s and require information about
 /// the layout tree as well.
+///
+/// <details><summary>Implementation details</summary>
+///
+/// `LayoutNodeAccess` is currently implemented with some unsafe code under the hood due to
+/// limitations of the Rust type system. Specifically, this type has three goals:
+/// 1. Avoid being a generic type for ease of use
+/// 2. Represent [`LayoutTreeNode`] instances with arbitrary tags
+/// 3. For performance reasons, avoid dynamic allocation: all storage should be interior to the type
+///
+/// The most obvious way to implement this type is by storing several functions as e.g. `Box<Fn() ->
+/// usize>` to proxy the methods in the tagged `LayoutTreeNode` instance, but this trivially fails
+/// goal #3. The current implementation stores a copy of the instance and the vtable pointer to
+/// perform dynamic dispatch directly, which maintains type-safety invariants because the only
+/// varying parameter is the tag type.
+/// </details>
+
 #[derive(Clone, Copy)]
 pub struct LayoutNodeAccess<'l> {
     current_node_func: fn(DynPtr) -> &'l LayoutNode,

+ 3 - 0
src/ui.rs

@@ -257,6 +257,9 @@ impl<'l, WC: WindowComponent<ParentMsg = UIControlMsg>> UIComponent
 
 /// Build an [`OpinionatedUIComponent`] for a given [`WindowComponent`] that passes
 /// [`UIControlMsg`]s back to its parent component and uses system fonts.
+///
+/// As noted in the documentation for [`OpinionatedUIComponent`], you'll want this unless you need
+/// multiple windows or need to use a custom font database.
 pub fn make_opinionated_ui<'l, WC: WindowComponent<ParentMsg = UIControlMsg>>(
     wc: impl 'l + FnOnce(&mut UIHandle) -> WC,
 ) -> UI<OpinionatedUIComponent<'l, WC>> {

+ 1 - 1
src/window.rs

@@ -44,7 +44,7 @@ pub(crate) struct WindowState<WC: WindowComponent> {
 impl<WC: WindowComponent> WindowState<WC> {
     fn redraw(&mut self, uih: &UIHandle) {
         let size = self.window.inner_size();
-        // if size.width != self.surface.buffer_mut().unwrap().
+
         self.surface
             .resize(
                 size.width.try_into().unwrap(),