You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: selection_state.rs
    path of file: ./repos/rerun/crates/re_viewer_context/src
    
    the code of the file until where you have to start completion: use ahash::HashMap;
use parking_lot::Mutex;

use re_entity_db::EntityPath;

use crate::{item::resolve_mono_instance_path_item, ViewerContext};

use super::{Item, SelectionHistory};

#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
pub enum SelectedSpaceContext {
    /// Hovering/Selecting in a 2D space.
    TwoD {
        space_2d: EntityPath,

        /// Where in this 2D space (+ depth)?
        pos: glam::Vec3,
    },

    /// Hovering/Selecting in a 3D space.
    ThreeD {
        /// The 3D space with the camera(s)
        space_3d: Ent
    
    pub fn on_frame_start(&mut self, item_retain_condition: impl Fn(&Item) -> bool) {
        // Use a different name so we don't get a collision in puffin.
        re_tracing::profile_scope!("SelectionState::on_frame_start");

        let history = self.history.get_mut();
        history.retain(&item_retain_condition);

        // Hovering needs to be refreshed every frame: If it wasn't hovered last frame, it's no longer hovered!
        self.hovered_previous_frame = std::mem::take(self.hovered_this_frame.get_mut());

        // Selection in contrast, is sticky!
        let selection_this_frame = self.selection_this_frame.get_mut();
        if selection_this_frame != &self.selection_previous_frame {
            history.update_selection(selection_this_frame);
            self.selection_previous_frame = selection_this_frame.clone();
        }
    }