Pure lasagna:
trait AppLogic {
fn run(&mut self, actions: Vec<(Id, Box<dyn Any>)>) -> Mutation;
}A callback based approach to the actions:
| // Fifth attempt at safe wrapper, this time using atomics to avoid race | |
| // when dropped without holding GIL. | |
| // User code is same as pyo3_mut_rc | |
| mod safe_wrapper { | |
| use pyo3::Python; | |
| use std::sync::atomic::{AtomicPtr, Ordering}; | |
| pub struct SafeWrapper<T>(*mut AtomicPtr<T>); |
| extern crate proc_macro; | |
| use proc_macro::TokenStream; | |
| #[proc_macro_attribute] | |
| pub fn widget(attr: TokenStream, item: TokenStream) -> TokenStream { | |
| r#" | |
| #[track_caller] | |
| fn answer() -> u32 { | |
| println!("{:?}", std::panic::Location::caller()); | |
| 42 |
| use xi_unicode::LineBreakIterator; | |
| use skribo::{AdvanceWidth, FontCollection, LayoutSession}; | |
| pub struct LayoutBuilder { | |
| text: String, | |
| default_font: FontCollection, | |
| default_size: f64, | |
| max_width: f64, | |
| } |
| pub trait IntoRefs<'a, T: 'a> { | |
| type Iterator: Iterator<Item = &'a T>; | |
| fn into_refs(self) -> Self::Iterator; | |
| } | |
| impl<'a, T> IntoRefs<'a, T> for &'a [T] { | |
| type Iterator = std::slice::Iter<'a, T>; | |
| fn into_refs(self) -> Self::Iterator { | |
| self.into_iter() |
Pure lasagna:
trait AppLogic {
fn run(&mut self, actions: Vec<(Id, Box<dyn Any>)>) -> Mutation;
}A callback based approach to the actions:
| :1:0257:0257[20554002x_00000001x] mov.s32s32 r0.z, 1 | |
| :0:0258:0258[00000500x_00000000x] (rpt5)nop | |
| :6:0259:0264[c0260202x_02618001x] ldib.untyped.1d.u32.1.imm r0.z, r0.z, 1 | |
| :2:0260:0265[52b400f8x_20000002x] (sy)cmps.s.eq p0.x, r0.z, 0 | |
| :1:0261:0266[20044906x_000000cfx] (rpt1)mov.f32f32 r1.z, (r)r51.w | |
| :0:0262:0268[00000300x_00000000x] (rpt3)nop | |
| :0:0263:0272[00900000x_0000057cx] br !p0.x, #1404 | |
| :1:0264:0273[20554002x_00000002x] mov.s32s32 r0.z, 2 | |
| :1:0265:0274[20554003x_00000000x] mov.s32s32 r0.w, 0 | |
| :0:0266:0275[00000200x_00000000x] (rpt2)nop |
The new (November 2021) element processing pipeline has a particularly clever approach to path segment encoding, and this document explains that.
By way of motivation, in the old scene encoding, all elements take a fixed amount of space, currently 36 bytes, but that's at risk of expanding if a new element type requires even more space. The new design is based on stream compaction. The input is separated into multiple streams, so in particular path segment data gets its own stream. Further, that stream can be packed.
As explained in [#119], the path stream is separated into one stream for tag bytes, and another stream for the path segment data.
| NEWWG | |
| NEWSG | |
| NEWTHREAD | |
| st.atom.scopedev.sc0 x = 1 | |
| NEWWG | |
| NEWSG | |
| NEWTHREAD | |
| ld.atom.scopedev.sc0 x = 1 | |
| ld.scopedev.sc0 x | |
| NOSOLUTION consistent[X] && #X.dr=0 |
| NEWWG | |
| NEWSG | |
| NEWTHREAD | |
| st.atom.scopedev.sc0 x = 2 | |
| NEWWG | |
| NEWSG | |
| NEWTHREAD | |
| st.atom.scopedev.sc0 x = 1 | |
| NEWWG | |
| NEWSG |
| // Copyright 2022 Google LLC. | |
| // SPDX-License-Identifier: Apache-2.0 | |
| // Scrolling test case by Raph Levien | |
| import SwiftUI | |
| import CryptoKit | |
| struct ContentView: View { | |
| var body: some View { |