GPUI Book

repository·main·Indexed 42 days ago

https://github.com/matinaniss/gpui-book

An educational resource for building applications with the GPUI framework. Covers core architecture including the App and Application abstractions, Context management, Window handling, and asynchronous task execution via Foreground and Background Executors. Includes guides on UI elements like Div, Deferred, and Img, as well as creating animations using Animation::new and with_animation.

Tokens
14K
Snippets
70
Records
106
Agent score
54%

What's inside GPUI

  1. Use primitive elements in GPUI

    main
    GPUI provides a set of primitive elements that serve as the building blocks for user interfaces. This chapter covers the various built-in primitive elements available for use in your application. For instructions on how to define and create custom UI components from scratch, refer to the 'Implementing Element' guide.
  2. What is the Foreground Executor?

    main

    The Foreground Executor is a mechanism used to spawn asynchronous tasks that run specifically on the main thread.

    Critical Warning: Because these tasks run on the main thread, you must never perform operations that block for a non-trivial duration. Blocking the foreground executor will block the main thread and cause the entire application to hang.

  3. Use SharedString to avoid heap allocations during re-renders

    main

    In GPUI, using a String inside a render function causes a heap allocation on every re-render. To optimize performance, use SharedString.

    SharedString is an immutable string that can be cheaply cloned. The recommended pattern is to store the SharedString in your Entity state, where it can be accessed by the render function without re-allocating memory.

    // Example pattern: Store SharedString in Entity state to avoid re-allocation in render
    struct MyEntity {
        text: SharedString,
    }
    
    impl Element for MyEntity {
        fn render(&self, cx: &mut ViewContext<Self>) -> impl IntoElement {
            // Accessing self.text here is cheap because it is a SharedString
            text(&self.text)
        }
    }
  4. Render an image using the Img element

    main
    The img element is used to render images within a GPUI application. It accepts any type that implements Into<ImageSource>. Common sources include file system paths or other ImageSource implementations. For information on how to apply styles to an image, refer to the styling documentation.
  5. Implement the Render trait to create views

    main

    In GPUI, the Render trait is used to define how a type draws elements to the screen. Implementing Render for a type T effectively turns an Entity<T> into a view.

    GPUI uses retained mode rendering for views, meaning a view will not re-render automatically unless it is explicitly notified of a change.

    Views can contain components that implement RenderOnce, which provides immediate mode rendering capabilities within the retained mode view structure.

    // Note: The specific implementation details are provided in the snippets/render.rs file.
    // Implementing Render allows your type to be displayed as a view in GPUI.
  6. Understand the two ways to render elements in GPUI

    main

    GPUI provides two primary trait implementations for rendering elements within an application:

    1. Render: The standard way to render elements that may need to update or re-render based on state changes.
    2. RenderOnce: A specialized way to render elements that are intended to be rendered only once.
  7. Use the RenderOnce trait for immediate mode components

    main

    The RenderOnce trait is used to create components rather than views. Unlike the Render trait, which is used for retained mode views, RenderOnce follows an immediate mode rendering pattern: components are constructed, rendered, and then immediately dropped.

    Key characteristics:

    • Lifecycle: Rendered exactly once per construction.
    • Ownership: The render function takes ownership of self (unlike Render, which provides a mutable reference &mut self).
    • Use Case: Ideal for components that do not need to store mutable application state and are intended to be rendered inside retained mode views.
    // Note: The actual implementation snippet is provided via a template include in the source.
    // A typical implementation would look like this:
    impl RenderOnce for MyComponent {
        fn render(self) -> impl Renderable {
            // Implementation logic
        }
    }