some potentially nice trait stuff

This commit is contained in:
2026-03-15 21:07:06 -04:00
parent 1102dc7338
commit c118bb446b
7 changed files with 90 additions and 30 deletions
-2
View File
@@ -2,10 +2,8 @@
#![feature(const_ops)]
#![feature(const_trait_impl)]
#![feature(const_convert)]
#![feature(map_try_insert)]
#![feature(unboxed_closures)]
#![feature(fn_traits)]
#![feature(const_cmp)]
#![feature(const_destruct)]
#![feature(portable_simd)]
#![feature(associated_type_defaults)]
+8 -1
View File
@@ -34,7 +34,7 @@ pub trait HasRoot {
pub trait WidgetArrLike<Rsc, const LEN: usize, Tag> {
#[track_caller]
fn add(self, state: &mut Rsc) -> WidgetArr<LEN>;
fn add(self, rsc: &mut Rsc) -> WidgetArr<LEN>;
}
impl<Rsc, const LEN: usize> WidgetArrLike<Rsc, LEN, ArrTag> for WidgetArr<LEN> {
@@ -58,6 +58,13 @@ macro_rules! impl_widget_arr {
)
}
}
impl<Rsc: UiRsc, $($W: WidgetLike<Rsc, $Tag>,$Tag,)*> IntoWidgetVec<Rsc, ($($Tag,)*), ArrTag> for ($($W,)*) {
fn into_vec(self, rsc: &mut Rsc) -> Vec<StrongWidget> {
#[allow(non_snake_case)]
let ($($W,)*) = self;
vec![$($W.add(rsc).upgrade(rsc),)*]
}
}
};
}
+14 -1
View File
@@ -1,4 +1,4 @@
use crate::{Axis, AxisT, Len, Painter, SizeCtx};
use crate::{Axis, AxisT, Len, Painter, SizeCtx, UiRsc};
use std::any::Any;
mod data;
@@ -85,3 +85,16 @@ impl<State, F: FnOnce(&mut State) -> Option<StrongWidget>> WidgetOption<State> f
self(state)
}
}
pub trait IntoWidgetVec<Rsc, WTag, GTag> {
fn into_vec(self, rsc: &mut Rsc) -> Vec<StrongWidget>;
}
impl<Rsc: UiRsc, I: IntoIterator, Tag> IntoWidgetVec<Rsc, Tag, IterTag> for I
where
I::Item: WidgetLike<Rsc, Tag>,
{
fn into_vec(self, rsc: &mut Rsc) -> Vec<StrongWidget> {
self.into_iter().map(|w| w.add_strong(rsc).any()).collect()
}
}
+1
View File
@@ -62,3 +62,4 @@ impl<Rsc: UiRsc, V: WidgetView> WidgetLike<Rsc, ViewTag> for V {
}
pub struct ArrTag;
pub struct IterTag;
+9 -9
View File
@@ -152,32 +152,32 @@ impl Span {
}
}
pub struct SpanBuilder<State, const LEN: usize, Wa: WidgetArrLike<State, LEN, Tag>, Tag> {
pub children: Wa,
pub struct SpanBuilder<Children, Rsc, Tag, GTag> {
pub children: Children,
pub dir: Dir,
pub gap: f32,
_pd: PhantomData<(State, Tag)>,
_pd: PhantomData<(Rsc, Tag, GTag)>,
}
impl<Rsc, const LEN: usize, Wa: WidgetArrLike<Rsc, LEN, Tag>, Tag> WidgetFnTrait<Rsc>
for SpanBuilder<Rsc, LEN, Wa, Tag>
impl<Children: IntoWidgetVec<Rsc, Tag, GTag>, Rsc, Tag, GTag> WidgetFnTrait<Rsc>
for SpanBuilder<Children, Rsc, Tag, GTag>
{
type Widget = Span;
#[track_caller]
fn run(self, rsc: &mut Rsc) -> Self::Widget {
Span {
children: self.children.add(rsc).arr.into_iter().collect(),
children: self.children.into_vec(rsc),
dir: self.dir,
gap: self.gap,
}
}
}
impl<State, const LEN: usize, Wa: WidgetArrLike<State, LEN, Tag>, Tag>
SpanBuilder<State, LEN, Wa, Tag>
impl<Children: IntoWidgetVec<Rsc, Tag, GTag>, Rsc, Tag, GTag>
SpanBuilder<Children, Rsc, Tag, GTag>
{
pub fn new(children: Wa, dir: Dir) -> Self {
pub fn new(children: Children, dir: Dir) -> Self {
Self {
children,
dir,
+8 -10
View File
@@ -42,30 +42,28 @@ pub enum StackSize {
Child(usize),
}
pub struct StackBuilder<State, const LEN: usize, Wa: WidgetArrLike<State, LEN, Tag>, Tag> {
pub children: Wa,
pub struct StackBuilder<Children, Rsc, Tag, GTag> {
pub children: Children,
pub size: StackSize,
_pd: PhantomData<(State, Tag)>,
_pd: PhantomData<(Rsc, Tag, GTag)>,
}
impl<Rsc, const LEN: usize, Wa: WidgetArrLike<Rsc, LEN, Tag>, Tag> WidgetFnTrait<Rsc>
for StackBuilder<Rsc, LEN, Wa, Tag>
impl<Children: IntoWidgetVec<Rsc, Tag, GTag>, Rsc, Tag, GTag> WidgetFnTrait<Rsc>
for StackBuilder<Children, Rsc, Tag, GTag>
{
type Widget = Stack;
#[track_caller]
fn run(self, rsc: &mut Rsc) -> Self::Widget {
Stack {
children: self.children.add(rsc).arr.into_iter().collect(),
children: self.children.into_vec(rsc),
size: self.size,
}
}
}
impl<State, const LEN: usize, Wa: WidgetArrLike<State, LEN, Tag>, Tag>
StackBuilder<State, LEN, Wa, Tag>
{
pub fn new(children: Wa) -> Self {
impl<Children: IntoWidgetVec<Rsc, Tag, GTag>, Rsc, Tag, GTag> StackBuilder<Children, Rsc, Tag, GTag> {
pub fn new(children: Children) -> Self {
Self {
children,
size: StackSize::default(),
+50 -7
View File
@@ -131,18 +131,61 @@ widget_trait! {
}
}
pub trait CoreWidgetArr<Rsc, const LEN: usize, Wa: WidgetArrLike<Rsc, LEN, Tag>, Tag> {
fn span(self, dir: Dir) -> SpanBuilder<Rsc, LEN, Wa, Tag>;
fn stack(self) -> StackBuilder<Rsc, LEN, Wa, Tag>;
pub trait CoreWidgetArr<Children, Rsc, Tag, GTag> {
fn span(self, dir: Dir) -> SpanBuilder<Children, Rsc, Tag, GTag>;
fn stack(self) -> StackBuilder<Children, Rsc, Tag, GTag>;
}
impl<State, const LEN: usize, Wa: WidgetArrLike<State, LEN, Tag>, Tag>
CoreWidgetArr<State, LEN, Wa, Tag> for Wa
impl<Children: IntoWidgetVec<Rsc, Tag, GTag>, Rsc, Tag, GTag>
CoreWidgetArr<Children, Rsc, Tag, GTag> for Children
{
fn span(self, dir: Dir) -> SpanBuilder<State, LEN, Wa, Tag> {
fn span(self, dir: Dir) -> SpanBuilder<Children, Rsc, Tag, GTag> {
SpanBuilder::new(self, dir)
}
fn stack(self) -> StackBuilder<State, LEN, Wa, Tag> {
fn stack(self) -> StackBuilder<Children, Rsc, Tag, GTag> {
StackBuilder::new(self)
}
}
pub trait RscFnMap<Rsc> {
type Input;
fn rsc_map<O>(
self,
f: impl Fn(Self::Input, &mut Rsc) -> O + Clone,
) -> impl Iterator<Item = impl FnOnce(&mut Rsc) -> O>;
}
impl<I: IntoIterator, Rsc> RscFnMap<Rsc> for I {
type Input = I::Item;
fn rsc_map<O>(
self,
f: impl Fn(Self::Input, &mut Rsc) -> O + Clone,
) -> impl Iterator<Item = impl FnOnce(&mut Rsc) -> O> {
self.into_iter().map(move |i| {
let f = f.clone();
move |rsc: &mut Rsc| f(i, rsc)
})
}
}
pub trait WidgetFnMap<Rsc: UiRsc> {
fn widget_map<O: WidgetLike<Rsc, Tag>, Tag>(
self,
f: impl Fn(WeakWidget) -> O + Clone,
) -> impl Iterator<Item = impl FnOnce(&mut Rsc) -> WeakWidget>;
}
impl<I: IntoIterator, Rsc: UiRsc> WidgetFnMap<Rsc> for I
where
I::Item: WidgetIdFn<Rsc>,
{
fn widget_map<O: WidgetLike<Rsc, Tag>, Tag>(
self,
f: impl Fn(WeakWidget) -> O + Clone,
) -> impl Iterator<Item = impl FnOnce(&mut Rsc) -> WeakWidget> {
self.into_iter().map(move |f2| {
let f = f.clone();
move |rsc: &mut Rsc| f(f2(rsc)).add(rsc) as WeakWidget
})
}
}