dynamis-world 0.7.0

Host scene registry, step orchestration, and readback
Documentation
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) struct Run {
    pub(crate) offset: u32,
    pub(crate) len: u32,
}

impl Run {
    pub(crate) const EMPTY: Self = Self { offset: 0, len: 0 };

    pub(crate) fn span(self) -> std::ops::Range<usize> {
        self.offset as usize..(self.offset + self.len) as usize
    }
}

#[derive(Clone)]
pub(crate) struct Arena {
    free: Vec<Run>,
    used: u32,
}

pub(crate) fn merged(mut runs: Vec<Run>, live: u32) -> Vec<Run> {
    runs.retain_mut(|run| {
        if run.offset >= live {
            return false;
        }
        run.len = run.len.min(live - run.offset);
        true
    });
    runs.sort_unstable_by_key(|run| run.offset);
    let mut coalesced: Vec<Run> = Vec::with_capacity(runs.len());
    for run in runs {
        match coalesced.last_mut() {
            Some(previous) if previous.offset + previous.len >= run.offset => {
                previous.len = previous.offset.max(run.offset + run.len) - previous.offset;
            }
            _ => coalesced.push(run),
        }
    }
    coalesced
}

impl Arena {
    pub(crate) const fn new() -> Self {
        Self {
            free: Vec::new(),
            used: 0,
        }
    }

    pub(crate) fn used(&self) -> u32 {
        self.used
    }

    pub(crate) fn take(&mut self, len: u32) -> Run {
        assert!(len > 0, "an arena run must hold at least one slot");
        let recycled = self
            .free
            .iter()
            .position(|run| run.len >= len)
            .map(|index| {
                let run = self.free.swap_remove(index);
                if run.len > len {
                    self.free.push(Run {
                        offset: run.offset + len,
                        len: run.len - len,
                    });
                }
                run.offset
            });
        let offset = recycled.unwrap_or_else(|| {
            let offset = self.used;
            self.used += len;
            offset
        });
        self.used = self.used.max(offset + len);
        Run { offset, len }
    }

    pub(crate) fn release(&mut self, run: Run) {
        assert!(run.len > 0, "an arena run must hold at least one slot");
        assert!(
            run.offset + run.len <= self.used,
            "an arena run must sit below the arena watermark"
        );
        let mut merged = run;
        self.free.retain(|candidate| {
            if candidate.offset + candidate.len == merged.offset {
                merged = Run {
                    offset: candidate.offset,
                    len: candidate.len + merged.len,
                };
                false
            } else if merged.offset + merged.len == candidate.offset {
                merged = Run {
                    offset: merged.offset,
                    len: merged.len + candidate.len,
                };
                false
            } else {
                true
            }
        });
        self.free.push(merged);
        self.trim();
    }

    fn trim(&mut self) {
        while let Some(index) = self
            .free
            .iter()
            .position(|run| run.offset + run.len == self.used)
        {
            let run = self.free.swap_remove(index);
            self.used = run.offset;
        }
    }
}