diff options
| author | Felix Morgner <felix.morgner@gmail.com> | 2024-07-17 01:07:22 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@gmail.com> | 2024-07-17 01:07:22 +0200 |
| commit | 1435da0c878b705035fda0dfbdb31013645ce2f9 (patch) | |
| tree | 09cc77f78544b6f21c6bc635722e6fdcf8b26c67 /domain | |
| parent | 225bfa26409243db96a0d36100561c257d0488f9 (diff) | |
| download | turns-1435da0c878b705035fda0dfbdb31013645ce2f9.tar.xz turns-1435da0c878b705035fda0dfbdb31013645ce2f9.zip | |
app/ui: implement basic turn tracking
Diffstat (limited to 'domain')
| -rw-r--r-- | domain/include/turns/domain/turn_order.hpp | 47 | ||||
| -rw-r--r-- | domain/src/turn_order.cpp | 142 |
2 files changed, 169 insertions, 20 deletions
diff --git a/domain/include/turns/domain/turn_order.hpp b/domain/include/turns/domain/turn_order.hpp index d3f74eb..59438d6 100644 --- a/domain/include/turns/domain/turn_order.hpp +++ b/domain/include/turns/domain/turn_order.hpp @@ -14,31 +14,56 @@ namespace turns::domain struct turn_order : Glib::Object { + using active_participant_type = unsigned int; + using empty_type = bool; + using has_next_type = bool; + using has_previous_type = bool; + using running_type = bool; + using round_type = unsigned int; + auto static create() -> Glib::RefPtr<turn_order>; turn_order(); - auto add(Glib::ustring const & name, float priority, disposition disposition) -> void; + /** Modifiers */ + auto add(Glib::ustring const & name, float priority, disposition disposition) -> void; auto clear() -> void; - - auto empty() const noexcept -> bool; - - auto get(unsigned int index) -> Glib::RefPtr<participant>; - + auto next() -> void; + auto previous() -> void; auto remove(unsigned int index) -> void; - - auto size() -> unsigned int; - + auto reset() -> void; auto start() -> void; + auto stop() -> void; + + /** Querries */ + auto active_participant() const noexcept -> active_participant_type; + auto empty() const noexcept -> empty_type; + auto get(unsigned int index) const noexcept -> Glib::RefPtr<participant>; auto list_model() -> Glib::RefPtr<Gio::ListModel>; + auto round() const noexcept -> round_type; + auto running() const noexcept -> running_type; + auto size() const noexcept -> unsigned int; - auto property_empty() const -> Glib::PropertyProxy_ReadOnly<bool>; + /** Properties */ + + auto property_active_participant() const -> Glib::PropertyProxy_ReadOnly<active_participant_type>; + auto property_empty() const -> Glib::PropertyProxy_ReadOnly<empty_type>; + auto property_has_next() const -> Glib::PropertyProxy_ReadOnly<has_next_type>; + auto property_has_previous() const -> Glib::PropertyProxy_ReadOnly<has_previous_type>; + auto property_running() const -> Glib::PropertyProxy_ReadOnly<running_type>; + auto property_round() const -> Glib::PropertyProxy_ReadOnly<round_type>; private: Glib::RefPtr<Gio::ListStore<participant>> m_model; - Glib::Property<bool> m_empty; + + Glib::Property<active_participant_type> m_active_participant; + Glib::Property<empty_type> m_empty; + Glib::Property<has_next_type> m_has_next; + Glib::Property<has_previous_type> m_has_previous; + Glib::Property<running_type> m_running; + Glib::Property<round_type> m_round; }; } // namespace turns::domain diff --git a/domain/src/turn_order.cpp b/domain/src/turn_order.cpp index 990e9c1..595b55d 100644 --- a/domain/src/turn_order.cpp +++ b/domain/src/turn_order.cpp @@ -3,6 +3,7 @@ #include "turns/domain/participant.hpp" #include <compare> +#include <limits> #include <typeinfo> #include <glibmm/binding.h> @@ -39,50 +40,121 @@ namespace turns::domain turn_order::turn_order() : Glib::ObjectBase{typeid(turn_order)} , m_model{Gio::ListStore<participant>::create()} + , m_active_participant(*this, "active_participant", std::numeric_limits<active_participant_type>::max()) , m_empty{*this, "empty", true} + , m_has_next{*this, "has-next", false} + , m_has_previous{*this, "has-previous", false} + , m_running{*this, "running", false} + , m_round{*this, "round", 0} { Glib::Binding::bind_property(m_model->property_n_items(), m_empty.get_proxy(), Glib::Binding::Flags::DEFAULT, [](auto n) { return n == 0; }); } + /** Modifiers */ + auto turn_order::add(Glib::ustring const & name, float priority, disposition disposition) -> void { auto participant = participant::create(name, priority, disposition); if (auto [found, index] = m_model->find(participant, equal_comparator); !found) { - m_model->insert_sorted(participant, comparator); + auto position = m_model->insert_sorted(participant, comparator); participant->property_priority().signal_changed().connect([this] { m_model->sort(comparator); }); + + if (m_active_participant != std::numeric_limits<active_participant_type>::max() && position <= m_active_participant) + { + m_active_participant = m_active_participant + 1; + } } } - auto turn_order::get(unsigned int index) -> Glib::RefPtr<participant> + auto turn_order::clear() -> void { - return m_model->get_item(index); + m_model->remove_all(); + m_active_participant = std::numeric_limits<active_participant_type>::max(); + m_has_next = false; + m_has_previous = false; + m_running = false; } - auto turn_order::list_model() -> Glib::RefPtr<Gio::ListModel> + auto turn_order::next() -> void { - return m_model; + m_active_participant = (m_active_participant + 1) % size(); + if (!m_active_participant) + { + m_round = round() + 1; + } + m_has_previous = m_active_participant || m_round; } - auto turn_order::size() -> unsigned int + auto turn_order::previous() -> void { - return m_model->get_n_items(); + if (!m_has_previous) + { + return; + } + + if (m_active_participant) + { + m_active_participant = m_active_participant - 1; + } + else if (m_round) + { + m_round = round() - 1; + m_active_participant = size() - 1; + } + + m_has_previous = m_active_participant || m_round; } auto turn_order::remove(unsigned int index) -> void { m_model->remove(index); + if (empty()) + { + m_active_participant = std::numeric_limits<active_participant_type>::max(); + m_has_next = false; + m_has_previous = false; + m_running = false; + } + else if (m_active_participant >= size() - 1) + { + m_active_participant = size() - 1; + } + else if (index <= m_active_participant) + { + m_active_participant = m_active_participant - 1; + } } - auto turn_order::clear() -> void + auto turn_order::reset() -> void { - m_model->remove_all(); + m_running = false; + m_active_participant = 0; } auto turn_order::start() -> void { + if (m_active_participant == std::numeric_limits<active_participant_type>::max()) + { + m_active_participant = 0; + } + m_running = true; + m_has_next = true; + } + + auto turn_order::stop() -> void + { + m_running = false; + m_has_next = false; + } + + /** Querries */ + + auto turn_order::active_participant() const noexcept -> active_participant_type + { + return m_active_participant; } auto turn_order::empty() const noexcept -> bool @@ -90,9 +162,61 @@ namespace turns::domain return m_empty; } + auto turn_order::get(unsigned int index) const noexcept -> Glib::RefPtr<participant> + { + return m_model->get_item(index); + } + + auto turn_order::list_model() -> Glib::RefPtr<Gio::ListModel> + { + return m_model; + } + + auto turn_order::round() const noexcept -> round_type + { + return m_round; + } + + auto turn_order::running() const noexcept -> running_type + { + return m_running; + } + + auto turn_order::size() const noexcept -> unsigned int + { + return m_model->get_n_items(); + } + + /** Properties */ + + auto turn_order::property_active_participant() const -> Glib::PropertyProxy_ReadOnly<active_participant_type> + { + return m_active_participant.get_proxy(); + } + auto turn_order::property_empty() const -> Glib::PropertyProxy_ReadOnly<bool> { return m_empty.get_proxy(); } + auto turn_order::property_has_next() const -> Glib::PropertyProxy_ReadOnly<has_next_type> + { + return m_has_next.get_proxy(); + } + + auto turn_order::property_has_previous() const -> Glib::PropertyProxy_ReadOnly<has_previous_type> + { + return m_has_previous.get_proxy(); + } + + auto turn_order::property_running() const -> Glib::PropertyProxy_ReadOnly<running_type> + { + return m_running.get_proxy(); + } + + auto turn_order::property_round() const -> Glib::PropertyProxy_ReadOnly<round_type> + { + return m_round.get_proxy(); + } + } // namespace turns::domain
\ No newline at end of file |
