layers initial impl (no sensors)

This commit is contained in:
2025-09-20 00:50:58 -04:00
parent 7651699743
commit 8ecd8bb171
7 changed files with 312 additions and 198 deletions

View File

@@ -6,7 +6,13 @@ pub struct Stack {
impl Widget for Stack { impl Widget for Stack {
fn draw(&mut self, painter: &mut Painter) { fn draw(&mut self, painter: &mut Painter) {
let base = painter.layer;
for child in &self.children { for child in &self.children {
if painter.layer == base {
painter.layer = painter.child_layer();
} else {
painter.layer = painter.next_layer();
}
painter.widget(child); painter.widget(child);
} }
} }

164
src/layout/layer.rs Normal file
View File

@@ -0,0 +1,164 @@
use std::ops::{Index, IndexMut};
use crate::{
layout::UiRegion,
render::{Primitive, PrimitiveHandle, Primitives},
util::Id,
};
struct LayerNode<T> {
prev: Option<usize>,
next: Next,
child: Option<usize>,
data: T,
}
#[derive(Clone, Copy)]
enum Next {
/// continue on same level
Same(usize),
/// go back to parent
Parent(usize),
/// end
None,
}
pub struct Layers<T> {
vec: Vec<LayerNode<T>>,
}
impl<T: Default> Layers<T> {
pub fn new() -> Layers<T>
where
T: Default,
{
Self {
vec: vec![LayerNode::head()],
}
}
pub fn clear(&mut self)
where
T: Default,
{
self.vec.clear();
self.vec.push(LayerNode::head());
}
fn push(&mut self, node: LayerNode<T>) -> usize {
let i = self.vec.len();
self.vec.push(node);
i
}
pub fn next(&mut self, i: usize) -> usize {
if let Next::Same(i) = self.vec[i].next {
return i;
}
let i_next = self.push(LayerNode::new(T::default(), self.vec[i].next));
self.vec[i].next = Next::Same(i_next);
self.vec[i_next].prev = Some(i);
i_next
}
pub fn child(&mut self, i: usize) -> usize {
if let Some(i) = self.vec[i].child {
return i;
}
let i_next = self.push(LayerNode::new(T::default(), Next::Parent(i)));
self.vec[i].child = Some(i_next);
self.vec[i_next].prev = Some(i);
i_next
}
pub fn iter_mut(&mut self) -> LayerIteratorMut<'_, T> {
LayerIteratorMut {
next: Some(0),
vec: &mut self.vec,
}
}
}
impl<T: Default> Default for Layers<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> Index<usize> for Layers<T> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
&self.vec[index].data
}
}
impl<T> IndexMut<usize> for Layers<T> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
&mut self.vec[index].data
}
}
impl<T> LayerNode<T> {
pub fn new(data: T, next: Next) -> Self {
Self {
prev: None,
next,
child: None,
data,
}
}
pub fn head() -> Self
where
T: Default,
{
Self::new(T::default(), Next::None)
}
}
pub struct LayerIteratorMut<'a, T> {
next: Option<usize>,
vec: &'a mut Vec<LayerNode<T>>,
}
impl<'a, T> Iterator for LayerIteratorMut<'a, T> {
type Item = (usize, &'a mut T);
fn next(&mut self) -> Option<Self::Item> {
// chat are we cooked? (if it's not set up correctly this could be catastrophic)
let ret_i = self.next?;
let node: &mut LayerNode<T> = unsafe { std::mem::transmute(&mut self.vec[ret_i]) };
self.next = if let Some(i) = node.child {
Some(i)
} else if let Next::Same(i) = node.next {
Some(i)
} else if let Next::Parent(i) = node.next {
let node = &self.vec[i];
if let Next::Same(i) = node.next {
Some(i)
} else {
None
}
} else {
None
};
Some((ret_i, &mut node.data))
}
}
impl Layers<Primitives> {
pub fn write<P: Primitive>(
&mut self,
layer: usize,
id: Id,
primitive: P,
region: UiRegion,
) -> PrimitiveHandle {
self[layer].write(layer, id, primitive, region)
}
pub fn free(&mut self, h: &PrimitiveHandle) {
self[h.layer].free(h)
}
}

View File

@@ -1,5 +1,6 @@
mod color; mod color;
mod id; mod id;
mod layer;
mod num; mod num;
mod orientation; mod orientation;
mod painter; mod painter;
@@ -13,6 +14,7 @@ mod widget;
pub use color::*; pub use color::*;
pub use id::*; pub use id::*;
pub use layer::*;
pub use num::*; pub use num::*;
pub use orientation::*; pub use orientation::*;
pub use painter::*; pub use painter::*;

View File

@@ -1,9 +1,7 @@
use std::ops::Range;
use crate::{ use crate::{
layout::{ layout::{
Active, TextAttrs, TextBuffer, TextData, TextOffset, TextureHandle, Textures, UiRegion, Active, Layers, TextAttrs, TextBuffer, TextData, TextOffset, TextureHandle, Textures,
UiVec2, Vec2, WidgetId, Widgets, UiRegion, UiVec2, Vec2, WidgetId, Widgets,
}, },
render::{Primitive, PrimitiveHandle, Primitives}, render::{Primitive, PrimitiveHandle, Primitives},
util::{HashMap, HashSet, Id, IdUtil}, util::{HashMap, HashSet, Id, IdUtil},
@@ -16,13 +14,14 @@ pub struct Painter<'a, 'c> {
primitives: Vec<PrimitiveHandle>, primitives: Vec<PrimitiveHandle>,
children: Vec<Id>, children: Vec<Id>,
sized_children: HashMap<Id, UiVec2>, sized_children: HashMap<Id, UiVec2>,
pub layer: usize,
id: Id, id: Id,
} }
pub struct PainterCtx<'a> { pub struct PainterCtx<'a> {
pub widgets: &'a Widgets, pub widgets: &'a Widgets,
pub active: &'a mut Active, pub active: &'a mut Active,
pub primitives: &'a mut Primitives, pub layers: &'a mut Layers<Primitives>,
pub textures: &'a mut Textures, pub textures: &'a mut Textures,
pub text: &'a mut TextData, pub text: &'a mut TextData,
pub screen_size: Vec2, pub screen_size: Vec2,
@@ -37,13 +36,13 @@ pub struct WidgetInstance {
pub primitives: Vec<PrimitiveHandle>, pub primitives: Vec<PrimitiveHandle>,
pub children: Vec<Id>, pub children: Vec<Id>,
pub resize: Option<(Id, UiVec2)>, pub resize: Option<(Id, UiVec2)>,
pub span: Range<usize>, pub layer: usize,
} }
impl<'a> PainterCtx<'a> { impl<'a> PainterCtx<'a> {
pub fn new( pub fn new(
widgets: &'a Widgets, widgets: &'a Widgets,
primitives: &'a mut Primitives, layers: &'a mut Layers<Primitives>,
active: &'a mut Active, active: &'a mut Active,
textures: &'a mut Textures, textures: &'a mut Textures,
text: &'a mut TextData, text: &'a mut TextData,
@@ -52,7 +51,7 @@ impl<'a> PainterCtx<'a> {
Self { Self {
widgets, widgets,
active, active,
primitives, layers,
textures, textures,
text, text,
screen_size, screen_size,
@@ -77,32 +76,25 @@ impl<'a> PainterCtx<'a> {
return; return;
}; };
self.primitives.set_pos(active.span.start);
self.draw_inner( self.draw_inner(
active.layer,
id, id,
active.region, active.region,
active.parent.duplicate(), active.parent.duplicate(),
Some(active.children), Some(active.children),
); );
self.active.widgets.get_mut(id).unwrap().resize = active.resize; self.active.widgets.get_mut(id).unwrap().resize = active.resize;
let delta = self.primitives.apply(active.span.clone());
if delta != 0
&& let Some(parent) = active.parent
{
self.shift_parent(id, parent, active.span.start, delta);
}
} }
pub fn draw(&mut self, id: &Id) { pub fn draw(&mut self, id: &Id) {
self.drawing.clear(); self.drawing.clear();
self.primitives.clear(); self.layers.clear();
self.draw_inner(id, UiRegion::full(), None, None); self.draw_inner(0, id, UiRegion::full(), None, None);
self.primitives.replace();
} }
fn draw_inner( fn draw_inner(
&mut self, &mut self,
layer: usize,
id: &Id, id: &Id,
region: UiRegion, region: UiRegion,
parent: Option<Id>, parent: Option<Id>,
@@ -124,7 +116,6 @@ impl<'a> PainterCtx<'a> {
panic!("Cannot draw the same widget twice (2)"); panic!("Cannot draw the same widget twice (2)");
} }
if active.region == region { if active.region == region {
self.primitives.skip(&mut active.span);
return; return;
} }
// TODO: // TODO:
@@ -138,6 +129,7 @@ impl<'a> PainterCtx<'a> {
let mut painter = Painter { let mut painter = Painter {
region, region,
layer,
id: id.duplicate(), id: id.duplicate(),
textures: Vec::new(), textures: Vec::new(),
primitives: Vec::new(), primitives: Vec::new(),
@@ -147,9 +139,7 @@ impl<'a> PainterCtx<'a> {
}; };
// draw widgets // draw widgets
let start_i = painter.ctx.primitives.cur_pos();
painter.ctx.widgets.get_dyn_dynamic(id).draw(&mut painter); painter.ctx.widgets.get_dyn_dynamic(id).draw(&mut painter);
let end_i = painter.ctx.primitives.cur_pos();
let sized_children = painter.sized_children; let sized_children = painter.sized_children;
@@ -159,10 +149,10 @@ impl<'a> PainterCtx<'a> {
region, region,
parent, parent,
textures: painter.textures, textures: painter.textures,
span: start_i..end_i,
primitives: painter.primitives, primitives: painter.primitives,
children: painter.children, children: painter.children,
resize, resize,
layer,
}; };
for (cid, size) in sized_children { for (cid, size) in sized_children {
if let Some(w) = self.active.widgets.get_mut(&cid) { if let Some(w) = self.active.widgets.get_mut(&cid) {
@@ -183,7 +173,7 @@ impl<'a> PainterCtx<'a> {
let mut inst = self.active.remove(id); let mut inst = self.active.remove(id);
if let Some(inst) = &mut inst { if let Some(inst) = &mut inst {
for h in &inst.primitives { for h in &inst.primitives {
self.primitives.free(h); self.layers.free(h);
} }
inst.textures.clear(); inst.textures.clear();
self.textures.free(); self.textures.free();
@@ -200,56 +190,14 @@ impl<'a> PainterCtx<'a> {
} }
inst inst
} }
/// shifts the primitive spans for all widgets above this one in the tree
/// also goes into children of them and modifies those that come after this one
/// should be done after applying primitives to ensure active spans are correct
fn shift_parent(&mut self, original: &Id, parent: Id, start: usize, delta: isize) {
let instance = self.active.widgets.get_mut(&parent).unwrap();
let end = &mut instance.span.end;
*end = end.strict_add_signed(delta);
let parent_parent = instance.parent.duplicate();
for child in instance
.children
.iter()
// skip original
.skip_while(|id| *id != original)
.skip(1)
.map(|id| id.duplicate())
.collect::<Vec<_>>()
{
self.shift_child(&child, start, delta);
}
if let Some(parent_parent) = parent_parent {
self.shift_parent(&parent, parent_parent, start, delta);
}
}
fn shift_child(&mut self, child: &Id, start: usize, delta: isize) {
let instance = self.active.widgets.get_mut(child).unwrap();
// = also prevents the original id from getting shifted
if instance.span.start < start {
return;
}
instance.span.start = instance.span.start.strict_add_signed(delta);
instance.span.end = instance.span.end.strict_add_signed(delta);
for child in instance
.children
.iter()
.map(|id| id.duplicate())
.collect::<Vec<_>>()
{
self.shift_child(&child, start, delta);
}
}
} }
impl<'a, 'c> Painter<'a, 'c> { impl<'a, 'c> Painter<'a, 'c> {
fn primitive_at<P: Primitive>(&mut self, primitive: P, region: UiRegion) { fn primitive_at<P: Primitive>(&mut self, primitive: P, region: UiRegion) {
let h = self let h = self
.ctx .ctx
.primitives .layers
.write(self.id.duplicate(), primitive, region); .write(self.layer, self.id.duplicate(), primitive, region);
self.primitives.push(h); self.primitives.push(h);
} }
@@ -276,7 +224,7 @@ impl<'a, 'c> Painter<'a, 'c> {
fn widget_at<W>(&mut self, id: &WidgetId<W>, region: UiRegion) { fn widget_at<W>(&mut self, id: &WidgetId<W>, region: UiRegion) {
self.children.push(id.id.duplicate()); self.children.push(id.id.duplicate());
self.ctx self.ctx
.draw_inner(&id.id, region, Some(self.id.duplicate()), None); .draw_inner(self.layer, &id.id, region, Some(self.id.duplicate()), None);
} }
pub fn texture_within(&mut self, handle: &TextureHandle, region: UiRegion) { pub fn texture_within(&mut self, handle: &TextureHandle, region: UiRegion) {
@@ -323,6 +271,14 @@ impl<'a, 'c> Painter<'a, 'c> {
pub fn text_data(&mut self) -> &mut TextData { pub fn text_data(&mut self) -> &mut TextData {
self.ctx.text self.ctx.text
} }
pub fn child_layer(&mut self) -> usize {
self.ctx.layers.child(self.layer)
}
pub fn next_layer(&mut self) -> usize {
self.ctx.layers.next(self.layer)
}
} }
pub struct SizeCtx<'a> { pub struct SizeCtx<'a> {

View File

@@ -3,8 +3,8 @@ use image::DynamicImage;
use crate::{ use crate::{
core::{TextEdit, TextEditCtx}, core::{TextEdit, TextEditCtx},
layout::{ layout::{
ActiveSensors, PainterCtx, Sensor, SensorMap, StaticWidgetId, TextData, TextureHandle, ActiveSensors, Layers, PainterCtx, Sensor, SensorMap, StaticWidgetId, TextData,
Textures, Vec2, Widget, WidgetId, WidgetInstance, WidgetLike, TextureHandle, Textures, Vec2, Widget, WidgetId, WidgetInstance, WidgetLike,
}, },
render::Primitives, render::Primitives,
util::{DynBorrower, HashMap, HashSet, Id, IdTracker}, util::{DynBorrower, HashMap, HashSet, Id, IdTracker},
@@ -23,12 +23,12 @@ pub struct Ui<Ctx> {
pub(super) send: Sender<Id>, pub(super) send: Sender<Id>,
size: Vec2, size: Vec2,
// TODO: make these non pub(crate) // TODO: make these non pub(crate)
pub(crate) primitives: Primitives, pub(crate) layers: Layers<Primitives>,
pub(crate) textures: Textures, pub(crate) textures: Textures,
pub(crate) text: TextData, pub(crate) text: TextData,
full_redraw: bool, full_redraw: bool,
pub(super) active: Active, pub(crate) active: Active,
pub(super) sensor_map: SensorMap<Ctx>, pub(super) sensor_map: SensorMap<Ctx>,
} }
@@ -129,7 +129,7 @@ impl<Ctx> Ui<Ctx> {
self.free(); self.free();
let mut ctx = PainterCtx::new( let mut ctx = PainterCtx::new(
&self.widgets, &self.widgets,
&mut self.primitives, &mut self.layers,
&mut self.active, &mut self.active,
&mut self.textures, &mut self.textures,
&mut self.text, &mut self.text,
@@ -152,7 +152,7 @@ impl<Ctx> Ui<Ctx> {
fn redraw_updates(&mut self) { fn redraw_updates(&mut self) {
let mut ctx = PainterCtx::new( let mut ctx = PainterCtx::new(
&self.widgets, &self.widgets,
&mut self.primitives, &mut self.layers,
&mut self.active, &mut self.active,
&mut self.textures, &mut self.textures,
&mut self.text, &mut self.text,
@@ -343,7 +343,7 @@ impl<Ctx> Default for Ui<Ctx> {
root: Default::default(), root: Default::default(),
widgets: Widgets::new(), widgets: Widgets::new(),
updates: Default::default(), updates: Default::default(),
primitives: Default::default(), layers: Default::default(),
textures: Textures::new(), textures: Textures::new(),
text: TextData::default(), text: TextData::default(),
full_redraw: false, full_redraw: false,

View File

@@ -3,6 +3,7 @@ use std::num::NonZero;
use crate::{ use crate::{
layout::Ui, layout::Ui,
render::{data::PrimitiveInstance, texture::GpuTextures, util::ArrBuf}, render::{data::PrimitiveInstance, texture::GpuTextures, util::ArrBuf},
util::HashMap,
}; };
use data::WindowUniform; use data::WindowUniform;
use wgpu::{ use wgpu::{
@@ -23,38 +24,76 @@ const SHAPE_SHADER: &str = include_str!("./shader.wgsl");
pub struct UiRenderer { pub struct UiRenderer {
uniform_group: BindGroup, uniform_group: BindGroup,
primitive_layout: BindGroupLayout, primitive_layout: BindGroupLayout,
primitive_group: BindGroup,
rsc_layout: BindGroupLayout, rsc_layout: BindGroupLayout,
rsc_group: BindGroup, rsc_group: BindGroup,
pipeline: RenderPipeline, pipeline: RenderPipeline,
layers: HashMap<usize, RenderLayer>,
active: Vec<usize>,
window_buffer: Buffer, window_buffer: Buffer,
textures: GpuTextures,
}
struct RenderLayer {
instance: ArrBuf<PrimitiveInstance>, instance: ArrBuf<PrimitiveInstance>,
primitives: PrimitiveBuffers, primitives: PrimitiveBuffers,
textures: GpuTextures, primitive_group: BindGroup,
} }
impl UiRenderer { impl UiRenderer {
pub fn draw<'a>(&'a self, pass: &mut RenderPass<'a>) { pub fn draw<'a>(&'a self, pass: &mut RenderPass<'a>) {
if self.instance.len() == 0 {
return;
}
pass.set_pipeline(&self.pipeline); pass.set_pipeline(&self.pipeline);
pass.set_bind_group(0, &self.uniform_group, &[]); pass.set_bind_group(0, &self.uniform_group, &[]);
pass.set_bind_group(1, &self.primitive_group, &[]);
pass.set_bind_group(2, &self.rsc_group, &[]); pass.set_bind_group(2, &self.rsc_group, &[]);
pass.set_vertex_buffer(0, self.instance.buffer.slice(..)); for i in &self.active {
pass.draw(0..4, 0..self.instance.len() as u32); let layer = &self.layers[i];
if layer.instance.len() == 0 {
continue;
}
pass.set_bind_group(1, &layer.primitive_group, &[]);
pass.set_vertex_buffer(0, layer.instance.buffer.slice(..));
pass.draw(0..4, 0..layer.instance.len() as u32);
}
} }
pub fn update<Ctx>(&mut self, device: &Device, queue: &Queue, ui: &mut Ui<Ctx>) { pub fn update<Ctx>(&mut self, device: &Device, queue: &Queue, ui: &mut Ui<Ctx>) {
if ui.primitives.updated { self.active.clear();
self.instance for (i, primitives) in ui.layers.iter_mut() {
.update(device, queue, ui.primitives.instances()); self.active.push(i);
self.primitives.update(device, queue, ui.primitives.data()); for change in primitives.apply_free() {
self.primitive_group = if let Some(inst) = ui.active.widgets.get_mut(&change.id) {
Self::primitive_group(device, &self.primitive_layout, self.primitives.buffers()) for h in &mut inst.primitives {
if h.inst_idx == change.old {
h.inst_idx = change.new;
break;
}
}
}
}
let layer = self.layers.entry(i).or_insert_with(|| {
let primitives = PrimitiveBuffers::new(device);
let primitive_group =
Self::primitive_group(device, &self.primitive_layout, primitives.buffers());
RenderLayer {
instance: ArrBuf::new(
device,
BufferUsages::VERTEX | BufferUsages::COPY_DST,
"instance",
),
primitives,
primitive_group,
}
});
if primitives.updated {
layer.instance.update(device, queue, primitives.instances());
layer.primitives.update(device, queue, primitives.data());
layer.primitive_group = Self::primitive_group(
device,
&self.primitive_layout,
layer.primitives.buffers(),
)
}
} }
if self.textures.update(&mut ui.textures) { if self.textures.update(&mut ui.textures) {
self.rsc_group = Self::rsc_group(device, &self.rsc_layout, &self.textures) self.rsc_group = Self::rsc_group(device, &self.rsc_layout, &self.textures)
@@ -87,13 +126,6 @@ impl UiRenderer {
usage: BufferUsages::UNIFORM | BufferUsages::COPY_DST, usage: BufferUsages::UNIFORM | BufferUsages::COPY_DST,
}); });
let instance = ArrBuf::new(
device,
BufferUsages::VERTEX | BufferUsages::COPY_DST,
"instance",
);
let primitives = PrimitiveBuffers::new(device);
let uniform_layout = device.create_bind_group_layout(&BindGroupLayoutDescriptor { let uniform_layout = device.create_bind_group_layout(&BindGroupLayoutDescriptor {
entries: &[BindGroupLayoutEntry { entries: &[BindGroupLayoutEntry {
binding: 0, binding: 0,
@@ -126,9 +158,6 @@ impl UiRenderer {
label: Some("primitive"), label: Some("primitive"),
}); });
let primitive_group =
Self::primitive_group(device, &primitive_layout, primitives.buffers());
let tex_manager = GpuTextures::new(device, queue); let tex_manager = GpuTextures::new(device, queue);
let rsc_layout = Self::rsc_layout(device, &limits); let rsc_layout = Self::rsc_layout(device, &limits);
let rsc_group = Self::rsc_group(device, &rsc_layout, &tex_manager); let rsc_group = Self::rsc_group(device, &rsc_layout, &tex_manager);
@@ -179,13 +208,12 @@ impl UiRenderer {
Self { Self {
uniform_group, uniform_group,
primitive_layout, primitive_layout,
primitive_group,
rsc_layout, rsc_layout,
rsc_group, rsc_group,
pipeline, pipeline,
window_buffer, window_buffer,
instance, layers: HashMap::default(),
primitives, active: Vec::new(),
textures: tex_manager, textures: tex_manager,
} }
} }

View File

@@ -1,4 +1,4 @@
use std::ops::{Deref, DerefMut, Range}; use std::ops::{Deref, DerefMut};
use crate::{ use crate::{
layout::{Color, UiRegion}, layout::{Color, UiRegion},
@@ -8,30 +8,22 @@ use crate::{
use bytemuck::Pod; use bytemuck::Pod;
use wgpu::*; use wgpu::*;
#[derive(Default)]
struct Instances {
data: Vec<PrimitiveInstance>,
assoc: Vec<Id>,
}
pub struct Primitives { pub struct Primitives {
instances: Instances, instances: Vec<PrimitiveInstance>,
run: Instances, assoc: Vec<Id>,
pos: usize,
data: PrimitiveData, data: PrimitiveData,
free: Vec<usize>,
pub updated: bool, pub updated: bool,
run_start: usize,
} }
impl Default for Primitives { impl Default for Primitives {
fn default() -> Self { fn default() -> Self {
Self { Self {
instances: Default::default(), instances: Default::default(),
run: Default::default(), assoc: Default::default(),
pos: 0,
data: Default::default(), data: Default::default(),
free: Vec::new(),
updated: true, updated: true,
run_start: 0,
} }
} }
} }
@@ -104,7 +96,13 @@ macro_rules! primitives {
} }
impl Primitives { impl Primitives {
pub fn write<P: Primitive>(&mut self, id: Id, data: P, region: UiRegion) -> PrimitiveHandle { pub fn write<P: Primitive>(
&mut self,
layer: usize,
id: Id,
data: P,
region: UiRegion,
) -> PrimitiveHandle {
let vec = P::vec(&mut self.data); let vec = P::vec(&mut self.data);
let i = vec.add(data); let i = vec.add(data);
let inst = PrimitiveInstance { let inst = PrimitiveInstance {
@@ -112,69 +110,37 @@ impl Primitives {
idx: i as u32, idx: i as u32,
binding: P::BINDING, binding: P::BINDING,
}; };
if self.running() { let inst_i = if let Some(i) = self.free.pop() {
self.run.push(id, inst); self.instances[i] = inst;
} else if self.instances.assoc.get(self.pos).is_some_and(|i| *i == id) { self.assoc[i] = id;
self.instances.data[self.pos] = inst; i
} else { } else {
self.run_start = self.pos; let i = self.instances.len();
self.run.push(id, inst); self.instances.push(inst);
} self.assoc.push(id);
self.pos += 1; i
PrimitiveHandle::new::<P>(i) };
PrimitiveHandle::new::<P>(layer, inst_i, i)
} }
fn running(&self) -> bool { /// returns (old index, new index)
self.run.len() != 0 pub fn apply_free(&mut self) -> impl Iterator<Item = PrimitiveChange> {
} self.free.sort_by(|a, b| b.cmp(a));
self.free.drain(..).filter_map(|i| {
pub fn skip(&mut self, range: &mut Range<usize>) { self.instances.swap_remove(i);
if self.running() { self.assoc.swap_remove(i);
self.run.data.extend(&self.instances.data[range.clone()]); if i == self.instances.len() {
self.run.assoc.extend( return None;
self.instances.assoc[range.clone()] }
.iter() let id = self.assoc[i].duplicate();
.map(|i| i.duplicate()), let old = self.instances.len();
); Some(PrimitiveChange { id, old, new: i })
} })
range.start = self.pos;
self.pos += range.len();
range.end = self.pos;
}
pub(crate) fn clear(&mut self) {
self.updated = true;
self.instances.clear();
self.run.clear();
self.data.clear();
self.pos = 0;
}
pub fn apply(&mut self, span: Range<usize>) -> isize {
let delta = self.pos as isize - span.end as isize;
if self.run.len() == 0 {
self.run_start = self.pos;
}
let span = self.run_start..span.end;
self.instances.splice(span, &mut self.run);
delta
}
pub fn set_pos(&mut self, p: usize) {
self.pos = p;
} }
pub fn free(&mut self, h: &PrimitiveHandle) { pub fn free(&mut self, h: &PrimitiveHandle) {
self.data.free(h.binding, h.idx); self.data.free(h.binding, h.data_idx);
} self.free.push(h.inst_idx);
pub fn replace(&mut self) {
std::mem::swap(&mut self.run, &mut self.instances);
self.run.clear();
}
pub fn cur_pos(&self) -> usize {
self.pos
} }
pub fn data(&self) -> &PrimitiveData { pub fn data(&self) -> &PrimitiveData {
@@ -182,20 +148,30 @@ impl Primitives {
} }
pub fn instances(&self) -> &Vec<PrimitiveInstance> { pub fn instances(&self) -> &Vec<PrimitiveInstance> {
&self.instances.data &self.instances
} }
} }
pub struct PrimitiveChange {
pub id: Id,
pub old: usize,
pub new: usize,
}
#[derive(Debug)] #[derive(Debug)]
pub struct PrimitiveHandle { pub struct PrimitiveHandle {
idx: usize, pub layer: usize,
binding: u32, pub inst_idx: usize,
pub data_idx: usize,
pub binding: u32,
} }
impl PrimitiveHandle { impl PrimitiveHandle {
fn new<P: Primitive>(idx: usize) -> Self { fn new<P: Primitive>(layer: usize, inst_idx: usize, data_idx: usize) -> Self {
Self { Self {
idx, layer,
inst_idx,
data_idx,
binding: P::BINDING, binding: P::BINDING,
} }
} }
@@ -283,21 +259,3 @@ impl<T> DerefMut for PrimitiveVec<T> {
&mut self.vec &mut self.vec
} }
} }
impl Instances {
pub fn clear(&mut self) {
self.data.clear();
self.assoc.clear();
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn push(&mut self, id: Id, inst: PrimitiveInstance) {
self.assoc.push(id);
self.data.push(inst);
}
pub fn splice(&mut self, span: Range<usize>, other: &mut Instances) {
self.data.splice(span.clone(), other.data.drain(..));
self.assoc.splice(span, other.assoc.drain(..));
}
}