# eventually.rs - source
Source of the Rust file `maplibre/src/render/eventually.rs`.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84

    use std::mem;

    use crate::{coords::WorldTileCoords, render::tile_view_pattern::HasTile, tcs::world::World};

    /// Wrapper around a resource which can be initialized or uninitialized.
    /// Uninitialized resourced can be initialized by calling [`Eventually::initialize()`].
    pub enum Eventually<T> {
        Initialized(T),
        Uninitialized,
    }

    pub trait HasChanged {
        type Criteria: Eq;

        fn has_changed(&self, criteria: &Self::Criteria) -> bool;
    }

    impl<T> HasChanged for Option<T>
    where
        T: HasChanged,
    {
        type Criteria = T::Criteria;

        fn has_changed(&self, criteria: &Self::Criteria) -> bool {
            match self {
                None => true,
                Some(value) => value.has_changed(criteria),
            }
        }
    }

    impl<T> Eventually<T>
    where
        T: HasChanged,
    {
        #[tracing::instrument(name = "reinitialize", skip_all)]
        pub fn reinitialize(&mut self, f: impl FnOnce() -> T, criteria: &T::Criteria) {
            let should_replace = match &self {
                Eventually::Initialized(current) => current.has_changed(criteria),
                Eventually::Uninitialized => true,
            };

            if should_replace {
                *self = Eventually::Initialized(f());
            }
        }
    }
    impl<T> Eventually<T> {
        #[tracing::instrument(name = "initialize", skip_all)]
        pub fn initialize(&mut self, f: impl FnOnce() -> T) {
            if let Eventually::Uninitialized = self {
                *self = Eventually::Initialized(f());
            }
        }

        pub fn take(&mut self) -> Eventually<T> {
            mem::replace(self, Eventually::Uninitialized)
        }

        pub fn expect_initialized_mut(&mut self, message: &str) -> &mut T {
            match self {
                Eventually::Initialized(value) => value,
                Eventually::Uninitialized => panic!("{message}"),
            }
        }
    }

    impl<T> Default for Eventually<T> {
        fn default() -> Self {
            Eventually::Uninitialized
        }
    }

    impl<T> HasTile for Eventually<T>
    where
        T: HasTile,
    {
        fn has_tile(&self, coords: WorldTileCoords, world: &World) -> bool {
            match self {
                Eventually::Initialized(value) => value.has_tile(coords, world),
                Eventually::Uninitialized => false,
            }
        }
    }