Repository: servo/servo
File: ports/servoshell/running_app_state.rs (Rust)

Code before:
        self.activate_webview(
            *self
                .creation_order
                .get(index)
                .expect("Tried to activate an unknown WebView"),
        );
    }
}

/// A command received via the user interacting with the user interface.
#[cfg_attr(any(target_os = "android", target_env = "ohos"), expect(dead_code))]
pub(crate) enum UserInterfaceCommand {
    Go(String),
    Back,
    Forward,
    Reload,
    ReloadAll,
    NewWebView,
    CloseWebView(WebViewId),
    NewWindow,
}

#[cfg(feature = "gamepad")]
pub(crate) struct ServoshellGamepadProvider {
    gamepad_support: Rc<RefCell<Option<GamepadSupport>>>,
}

#[cfg(feature = "gamepad")]
impl ServoshellGamepadProvider {
    pub(crate) fn new() -> Self {
        let gamepad_support = if pref!(dom_gamepad_enabled) {
            GamepadSupport::maybe_new()
        } else {
            None
        };
        Self {
            gamepad_support: Rc::new(RefCell::new(gamepad_support)),
        }
    }

    pub(crate) fn gamepad_support(&self) -> Rc<RefCell<Option<GamepadSupport>>> {
        self.gamepad_support.clone()
    }
}

#[cfg(feature = "gamepad")]
impl GamepadProvider for ServoshellGamepadProvider {
    fn play_haptic_effect(
        &self,
        _webview: WebView,
        gamepad_index: usize,

Review comment (suggestion):
Instead of wrapping a `GamepadSupport` make `GamepadSuport` the actual implementation of `GamepadProvider` and just don't set it if it is `None`.

Code after:
    pub(crate) fn activate_webview_by_index(&mut self, index: usize) {
        self.activate_webview(
            *self
                .creation_order
                .get(index)
                .expect("Tried to activate an unknown WebView"),
        );
    }
}

/// A command received via the user interacting with the user interface.
#[cfg_attr(any(target_os = "android", target_env = "ohos"), expect(dead_code))]
pub(crate) enum UserInterfaceCommand {
    Go(String),
    Back,
    Forward,
    Reload,
    ReloadAll,
    NewWebView,
    CloseWebView(WebViewId),
    NewWindow,
}

pub(crate) struct RunningAppState {
    /// The gamepad provider, used for handling gamepad events and set on each WebView.
    /// May be `None` if gamepad support is disabled or failed to initialize.
    #[cfg(all(
        feature = "gamepad",
        not(any(target_os = "android", target_env = "ohos"))
    ))]
    gamepad_provider: Option<Rc<ServoshellGamepadProvider>>,

    /// The [`WebDriverSenders`] used to reply to pending WebDriver requests.
    pub(crate) webdriver_senders: RefCell<WebDriverSenders>,

    /// When running in WebDriver mode, [`WebDriverEmbedderControls`] is a virtual container
    /// for all embedder controls. This overrides the normal behavior where these controls
    /// are shown in the GUI or not processed at all in headless mode.
    pub(crate) webdriver_embedder_controls: WebDriverEmbedderControls,

    /// A [`HashMap`] of pending WebDriver events. It is the WebDriver embedder's responsibility
    /// to inform the WebDriver server when the event has been fully handled. This map is used
    /// to report back to WebDriver when that happens.
    pub(crate) pending_webdriver_events: RefCell<HashMap<InputEventId, Sender<()>>>,

    /// A [`Receiver`] for receiving commands from a running WebDriver server, if WebDriver
    /// was enabled.
    pub(crate) webdriver_receiver: Option<Receiver<WebDriverCommandMsg>>,

    /// servoshell specific preferences created during startup of the application.
    pub(crate) servoshell_preferences: ServoShellPreferences,