From 93bb943394141a29847e034dd6e032439c21a179 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?kleines=20Filmr=C3=B6llchen?= Date: Sat, 26 Feb 2022 19:41:10 +0100 Subject: [PATCH] Demos/CatDog: Refactor the main states CatDog's state was previously handled by a bunch of booleans that all needed to be in sync pretty accurately, but some of these are exclusive (like alerted and sleeping). This commit introduces a simple enum for the main states of CatDog which exclude the roaming and direction states. The main state determines the standing image of CatDog and will have further effects in the future. --- Userland/Demos/CatDog/CatDog.cpp | 21 +++++++------- Userland/Demos/CatDog/CatDog.h | 47 ++++++++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 13 deletions(-) diff --git a/Userland/Demos/CatDog/CatDog.cpp b/Userland/Demos/CatDog/CatDog.cpp index d17bcf9424..8229bcc389 100644 --- a/Userland/Demos/CatDog/CatDog.cpp +++ b/Userland/Demos/CatDog/CatDog.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2021, Richard Gráčik + * Copyright (c) 2022, kleines Filmröllchen * * SPDX-License-Identifier: BSD-2-Clause */ @@ -85,13 +86,13 @@ void CatDog::timer_event(Core::TimerEvent&) } if (!m_up && !m_down && !m_left && !m_right) { - m_curr_bmp = m_still; - if (m_timer.elapsed() > 5000) { - m_curr_bmp = m_sleep1; - if (m_curr_frame == 2) - m_curr_bmp = m_sleep2; - m_sleeping = true; - } + // Select the movement-free image based on the main state. + if (m_timer.elapsed() > 5000) + m_main_state = MainState::Sleeping; + set_image_by_main_state(); + } else if (is_non_application_state(m_main_state)) { + // If CatDog currently moves, it should be idle the next time it stops. + m_main_state = MainState::Idle; } update(); @@ -113,11 +114,11 @@ void CatDog::track_mouse_move(Gfx::IntPoint const& point) return; m_temp_pos = relative_point; m_timer.start(); - if (m_sleeping) { - m_curr_bmp = m_alert; + if (m_main_state == MainState::Sleeping) { + m_main_state = MainState::Alerted; + set_image_by_main_state(); update(); } - m_sleeping = false; } void CatDog::mousedown_event(GUI::MouseEvent& event) diff --git a/Userland/Demos/CatDog/CatDog.h b/Userland/Demos/CatDog/CatDog.h index 8bcae387a9..f814ad2195 100644 --- a/Userland/Demos/CatDog/CatDog.h +++ b/Userland/Demos/CatDog/CatDog.h @@ -1,13 +1,17 @@ /* * Copyright (c) 2021, Richard Gráčik + * Copyright (c) 2022, kleines Filmröllchen * * SPDX-License-Identifier: BSD-2-Clause */ +#include +#include #include #include #include #include +#include #include #pragma once @@ -17,6 +21,17 @@ class CatDog final : public GUI::Widget C_OBJECT(CatDog); public: + // The general state, does not contain movement direction or whether CatDog is roaming. + enum class MainState { + Idle, // default state + Alerted, // woken by mouse cursor or speaking after being idle + Sleeping, // mouse hasn't moved in some time + }; + static bool is_non_application_state(MainState state) + { + return state == MainState::Idle || state == MainState::Alerted || state == MainState::Sleeping; + } + virtual void timer_event(Core::TimerEvent&) override; virtual void paint_event(GUI::PaintEvent& event) override; virtual void track_mouse_move(Gfx::IntPoint const& point) override; @@ -33,20 +48,25 @@ public: { m_roaming = roaming; if (!roaming) { - m_sleeping = false; + // If we stop CatDog while it's in a program-specific state, we don't want it to be alerted. + if (m_main_state == MainState::Idle || m_main_state == MainState::Sleeping) + m_main_state = MainState::Alerted; m_curr_frame = 0; - m_curr_bmp = m_alert; + set_image_by_main_state(); update(); } } + MainState main_state() const { return m_main_state; } + private: Gfx::IntPoint m_temp_pos; Core::ElapsedTimer m_timer; int m_curr_frame = 1; int m_moveX, m_moveY = 0; - bool m_up, m_down, m_left, m_right, m_sleeping = false; + MainState m_main_state { MainState::Alerted }; + bool m_up, m_down, m_left, m_right; bool m_roaming { true }; NonnullRefPtr m_alert = *Gfx::Bitmap::try_load_from_file("/res/icons/catdog/alert.png").release_value_but_fixme_should_propagate_errors(); @@ -71,8 +91,29 @@ private: NonnullRefPtr m_wrun2 = *Gfx::Bitmap::try_load_from_file("/res/icons/catdog/wrun2.png").release_value_but_fixme_should_propagate_errors(); NonnullRefPtr m_curr_bmp = m_alert; + + // Used if CatDog is still; may also account for animation frames. + void set_image_by_main_state() + { + switch (m_main_state) { + case MainState::Idle: + m_curr_bmp = m_still; + break; + case MainState::Alerted: + m_curr_bmp = m_alert; + break; + case MainState::Sleeping: + if (m_curr_frame == 1) + m_curr_bmp = m_sleep1; + else + m_curr_bmp = m_sleep2; + break; + } + } + CatDog() : m_temp_pos { 0, 0 } { + set_image_by_main_state(); } };