Skip to main content

ferroui_base/media/
i_immutable_glyph_run_reference.rs

1use std::cell::RefCell;
2
3use crate::platform::IGlyphRunImpl;
4
5/// An immutable reference to the platform resources of a glyph run, usable
6/// after the glyph run itself changed or was disposed.
7pub trait IImmutableGlyphRunReference {
8    /// The referenced platform glyph run, until disposed.
9    fn glyph_run(&self) -> Option<std::sync::Arc<dyn IGlyphRunImpl>>;
10
11    /// Releases the reference (C# `IDisposable.Dispose`).
12    fn dispose(&self);
13}
14
15pub(crate) struct ImmutableGlyphRunReference {
16    glyph_run: RefCell<Option<std::sync::Arc<dyn IGlyphRunImpl>>>,
17}
18
19impl ImmutableGlyphRunReference {
20    pub fn new(glyph_run: Option<std::sync::Arc<dyn IGlyphRunImpl>>) -> Self {
21        Self { glyph_run: RefCell::new(glyph_run) }
22    }
23}
24
25impl IImmutableGlyphRunReference for ImmutableGlyphRunReference {
26    fn glyph_run(&self) -> Option<std::sync::Arc<dyn IGlyphRunImpl>> {
27        self.glyph_run.borrow().clone()
28    }
29
30    fn dispose(&self) {
31        let glyph_run = self.glyph_run.borrow_mut().take();
32        release_platform_impl(glyph_run);
33    }
34}
35
36/// Drops one reference to a platform glyph run, disposing the implementation
37/// when it was the last one (the counterpart of disposing an `IRef<T>`).
38pub(crate) fn release_platform_impl(platform_impl: Option<std::sync::Arc<dyn IGlyphRunImpl>>) {
39    if let Some(platform_impl) = platform_impl {
40        if std::sync::Arc::strong_count(&platform_impl) == 1 {
41            platform_impl.dispose();
42        }
43    }
44}