summaryrefslogtreecommitdiff
path: root/domain
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@gmail.com>2024-07-17 01:07:22 +0200
committerFelix Morgner <felix.morgner@gmail.com>2024-07-17 01:07:22 +0200
commit1435da0c878b705035fda0dfbdb31013645ce2f9 (patch)
tree09cc77f78544b6f21c6bc635722e6fdcf8b26c67 /domain
parent225bfa26409243db96a0d36100561c257d0488f9 (diff)
downloadturns-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.hpp47
-rw-r--r--domain/src/turn_order.cpp142
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