aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.vscode/settings.json3
-rw-r--r--app/include/turns/app/widgets/turn_order_view.hpp1
-rw-r--r--app/include/turns/app/windows/participant_editor.hpp6
-rw-r--r--app/src/widgets/participant_row.cpp19
-rw-r--r--app/src/widgets/turn_order_view.cpp20
-rw-r--r--app/src/windows/participant_editor.cpp12
-rw-r--r--app/src/windows/tracker.cpp26
-rw-r--r--app/tests/windows/participant_editor.cpp4
-rw-r--r--domain/CMakeLists.txt2
-rw-r--r--domain/include/turns/domain/participant.hpp46
-rw-r--r--domain/include/turns/domain/turn_order.hpp111
-rw-r--r--domain/src/participant.cpp76
-rw-r--r--domain/src/turn_order.cpp237
-rw-r--r--domain/tests/participant.cpp90
-rw-r--r--domain/tests/register_types.cpp13
-rw-r--r--domain/tests/turn_order.cpp434
-rw-r--r--test_support/CMakeLists.txt1
-rw-r--r--test_support/src/glib_main.cpp9
18 files changed, 390 insertions, 720 deletions
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 3073d74..b1a65b9 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -9,7 +9,8 @@
"gobj",
"refptr",
"sigc",
- "ustring"
+ "ustring",
+ "vfunc"
],
"editor.tabSize": 2,
diff --git a/app/include/turns/app/widgets/turn_order_view.hpp b/app/include/turns/app/widgets/turn_order_view.hpp
index 7b7556f..15524a9 100644
--- a/app/include/turns/app/widgets/turn_order_view.hpp
+++ b/app/include/turns/app/widgets/turn_order_view.hpp
@@ -27,7 +27,6 @@ namespace turns::app::widgets
explicit turn_order_view(Glib::RefPtr<model_type> model = {});
private:
- auto handle_active_participant_changed() -> void;
auto handle_create_row(Glib::RefPtr<Glib::Object> const item) -> Gtk::Widget *;
Glib::RefPtr<model_type> m_model;
diff --git a/app/include/turns/app/windows/participant_editor.hpp b/app/include/turns/app/windows/participant_editor.hpp
index 764b9ba..23d0569 100644
--- a/app/include/turns/app/windows/participant_editor.hpp
+++ b/app/include/turns/app/windows/participant_editor.hpp
@@ -21,9 +21,9 @@ namespace turns::app::windows
struct participant_editor : Gtk::Widget
{
- using signal_finished_type = sigc::signal<void(decltype(std::declval<domain::participant const>().get_name()),
- decltype(std::declval<domain::participant const>().get_priority()),
- decltype(std::declval<domain::participant const>().get_disposition()))>;
+ using signal_finished_type = sigc::signal<void(decltype(std::declval<domain::participant const>().name().get_value()),
+ decltype(std::declval<domain::participant const>().priority().get_value()),
+ decltype(std::declval<domain::participant const>().disposition().get_value()))>;
participant_editor(BaseObjectType * base, Glib::RefPtr<Gtk::Builder> const builder, Glib::RefPtr<domain::participant> obj = {});
diff --git a/app/src/widgets/participant_row.cpp b/app/src/widgets/participant_row.cpp
index 3494834..87cc217 100644
--- a/app/src/widgets/participant_row.cpp
+++ b/app/src/widgets/participant_row.cpp
@@ -73,14 +73,14 @@ namespace turns::app::widgets
if (participant)
{
- Glib::Binding::bind_property(participant->property_name(), m_title->property_label(), Glib::Binding::Flags::SYNC_CREATE);
+ Glib::Binding::bind_property(participant->name(), m_title->property_label(), Glib::Binding::Flags::SYNC_CREATE);
- Glib::Binding::bind_property(participant->property_priority(),
+ Glib::Binding::bind_property(participant->priority(),
m_subtitle->property_label(),
Glib::Binding::Flags::SYNC_CREATE,
[](auto n) { return std::vformat(_(lang::priority_number), std::make_format_args(n)); });
- Glib::Binding::bind_property(participant->property_disposition(),
+ Glib::Binding::bind_property(participant->disposition(),
m_toggle_defeated->property_css_classes(),
Glib::Binding::Flags::SYNC_CREATE,
[this](auto value) {
@@ -92,6 +92,19 @@ namespace turns::app::widgets
classes.push_back(css_class_for(value));
return classes;
});
+
+ Glib::Binding::bind_property(participant->is_active(), property_css_classes(), Glib::Binding::Flags::SYNC_CREATE, [this](auto value) {
+ auto classes = get_css_classes();
+ if (!value)
+ {
+ std::erase(classes, "active-participant");
+ }
+ else
+ {
+ classes.push_back("active-participant");
+ }
+ return classes;
+ });
}
}
diff --git a/app/src/widgets/turn_order_view.cpp b/app/src/widgets/turn_order_view.cpp
index ccc6d25..67e0afa 100644
--- a/app/src/widgets/turn_order_view.cpp
+++ b/app/src/widgets/turn_order_view.cpp
@@ -25,35 +25,21 @@ namespace turns::app::widgets
{
if (model)
{
- m_view->bind_model(m_model->list_model(), sigc::mem_fun(*this, &turn_order_view::handle_create_row));
- m_model->property_active_participant().signal_changed().connect(
- sigc::mem_fun(*this, &turn_order_view::handle_active_participant_changed));
+ m_view->bind_model(m_model, sigc::mem_fun(*this, &turn_order_view::handle_create_row));
}
}
- auto turn_order_view::handle_active_participant_changed() -> void
- {
- std::ranges::for_each(m_view->get_children(), [](auto c) { c->remove_css_class("active-participant"); });
-
- auto index = m_model->active_participant();
- if (index != std::numeric_limits<domain::turn_order::active_participant_type>::max())
- {
- auto row = m_view->get_row_at_index(index);
- row->add_css_class("active-participant");
- row->grab_focus();
- }
- }
auto turn_order_view::handle_create_row(Glib::RefPtr<Glib::Object> const item) -> Gtk::Widget *
{
auto participant = std::dynamic_pointer_cast<domain::participant>(item);
auto row = Gtk::make_managed<widgets::participant_row>(participant);
- Glib::Binding::bind_property(m_model->property_running(),
+ Glib::Binding::bind_property(m_model->is_running(),
row->property_delete_enabled(),
Glib::Binding::Flags::SYNC_CREATE | Glib::Binding::Flags::INVERT_BOOLEAN);
- Glib::Binding::bind_property(m_model->property_running(),
+ Glib::Binding::bind_property(m_model->is_running(),
row->property_edit_enabled(),
Glib::Binding::Flags::SYNC_CREATE | Glib::Binding::Flags::INVERT_BOOLEAN);
diff --git a/app/src/windows/participant_editor.cpp b/app/src/windows/participant_editor.cpp
index 1c97442..0b35c72 100644
--- a/app/src/windows/participant_editor.cpp
+++ b/app/src/windows/participant_editor.cpp
@@ -42,9 +42,9 @@ namespace turns::app::windows
if (m_participant)
{
- gtk_editable_set_text(GTK_EDITABLE(m_name), m_participant->property_name().get_value().c_str());
- adw_spin_row_set_value(m_priority, m_participant->property_priority().get_value());
- adw_combo_row_set_selected(m_disposition, static_cast<unsigned>(m_participant->get_disposition()));
+ gtk_editable_set_text(GTK_EDITABLE(m_name), m_participant->name().get_value().c_str());
+ adw_spin_row_set_value(m_priority, m_participant->priority());
+ adw_combo_row_set_selected(m_disposition, static_cast<unsigned>(m_participant->disposition().get_value()));
}
}
@@ -66,9 +66,9 @@ namespace turns::app::windows
if (m_participant)
{
- m_participant->set_name(name);
- m_participant->set_priority(priority);
- m_participant->set_disposition(disposition);
+ m_participant->name() = name;
+ m_participant->priority() = priority;
+ m_participant->disposition() = disposition;
}
m_signal_finished.emit(name, priority, disposition);
diff --git a/app/src/windows/tracker.cpp b/app/src/windows/tracker.cpp
index b7520dd..11f4642 100644
--- a/app/src/windows/tracker.cpp
+++ b/app/src/windows/tracker.cpp
@@ -51,16 +51,16 @@ namespace turns::app::windows
m_stack->add(*m_turn_order_view);
// clang-format off
- Glib::Binding::bind_property(m_turn_order->property_empty(),
+ Glib::Binding::bind_property(m_turn_order->is_empty(),
m_stack->property_visible_child(),
Glib::Binding::Flags::SYNC_CREATE,
[this](auto empty) { return empty ? m_empty : m_turn_order_view; });
- Glib::Binding::bind_property(m_turn_order->property_running(),
+ Glib::Binding::bind_property(m_turn_order->is_running(),
m_controls->property_reveal_child(),
Glib::Binding::Flags::SYNC_CREATE);
- Glib::Binding::bind_property(m_turn_order->property_empty(),
+ Glib::Binding::bind_property(m_turn_order->is_empty(),
m_subtitle,
Glib::Binding::Flags::SYNC_CREATE,
[](auto empty) { return empty ? _(lang::no_active_turn_order) : ""; });
@@ -84,7 +84,7 @@ namespace turns::app::windows
{
static_cast<void>(param);
auto index = Glib::VariantBase::cast_dynamic<Glib::Variant<int>>(param);
- auto participant = m_turn_order->get(index.get());
+ auto participant = m_turn_order->get_typed_object<domain::participant>(index.get());
auto [lifeline, dialog] = editor_for(participant);
dialog->present(this);
}
@@ -112,17 +112,17 @@ namespace turns::app::windows
{
auto action = add_action("add_participant", sigc::mem_fun(*this, &tracker::handle_add_participant));
- Glib::Binding::bind_property(m_turn_order->property_running(),
+ Glib::Binding::bind_property(m_turn_order->is_running(),
action->property_enabled(),
Glib::Binding::Flags::SYNC_CREATE | Glib::Binding::Flags::INVERT_BOOLEAN);
}
// win.clear
- // depends-on: turn_order:empty == false
+ // depends-on: turn_order:is_empty == false
{
auto action = add_action("clear", sigc::mem_fun(*m_turn_order, &domain::turn_order::clear));
- Glib::Binding::bind_property(m_turn_order->property_empty(),
+ Glib::Binding::bind_property(m_turn_order->is_empty(),
action->property_enabled(),
Glib::Binding::Flags::SYNC_CREATE | Glib::Binding::Flags::INVERT_BOOLEAN);
}
@@ -132,7 +132,7 @@ namespace turns::app::windows
{
auto action = add_action("next", sigc::mem_fun(*m_turn_order, &domain::turn_order::next));
- Glib::Binding::bind_property(m_turn_order->property_running(), action->property_enabled(), Glib::Binding::Flags::SYNC_CREATE);
+ Glib::Binding::bind_property(m_turn_order->is_running(), action->property_enabled(), Glib::Binding::Flags::SYNC_CREATE);
}
// win.previous
@@ -140,19 +140,19 @@ namespace turns::app::windows
{
auto action = add_action("previous", sigc::mem_fun(*m_turn_order, &domain::turn_order::previous));
- Glib::Binding::bind_property(m_turn_order->property_has_previous(), action->property_enabled(), Glib::Binding::Flags::SYNC_CREATE);
+ Glib::Binding::bind_property(m_turn_order->has_previous(), action->property_enabled(), Glib::Binding::Flags::SYNC_CREATE);
}
// win.start
- // depends-on: turn_order:empty == false
+ // depends-on: turn_order:is_empty == false
{
auto action = add_action("start", sigc::mem_fun(*m_turn_order, &domain::turn_order::start));
- Glib::Binding::bind_property(m_turn_order->property_empty(),
+ Glib::Binding::bind_property(m_turn_order->is_running(),
action->property_enabled(),
Glib::Binding::Flags::SYNC_CREATE | Glib::Binding::Flags::INVERT_BOOLEAN);
- Glib::Binding::bind_property(m_turn_order->property_running(),
+ Glib::Binding::bind_property(m_turn_order->is_running(),
m_start->property_visible(),
Glib::Binding::Flags::SYNC_CREATE | Glib::Binding::Flags::INVERT_BOOLEAN);
}
@@ -162,7 +162,7 @@ namespace turns::app::windows
{
auto action = add_action("stop", sigc::mem_fun(*this, &tracker::handle_stop));
- Glib::Binding::bind_property(m_turn_order->property_running(), action->property_enabled(), Glib::Binding::Flags::SYNC_CREATE);
+ Glib::Binding::bind_property(m_turn_order->is_running(), action->property_enabled(), Glib::Binding::Flags::SYNC_CREATE);
}
// win.delete
diff --git a/app/tests/windows/participant_editor.cpp b/app/tests/windows/participant_editor.cpp
index 5808740..9f73861 100644
--- a/app/tests/windows/participant_editor.cpp
+++ b/app/tests/windows/participant_editor.cpp
@@ -95,13 +95,13 @@ namespace turns::app::windows::tests
SECTION("has its name field set according to its participant")
{
auto widget = GTK_EDITABLE(builder->get_widget<Gtk::ListBoxRow>("name")->gobj());
- REQUIRE(gtk_editable_get_text(widget) == participant->get_name());
+ REQUIRE(gtk_editable_get_text(widget) == participant->name().get_value());
}
SECTION("has its priority field set according to its participant")
{
auto widget = ADW_SPIN_ROW(builder->get_widget<Gtk::ListBoxRow>("priority")->gobj());
- REQUIRE(adw_spin_row_get_value(widget) == participant->get_priority());
+ REQUIRE(adw_spin_row_get_value(widget) == participant->priority());
}
SECTION("allows binding to the finished signal")
diff --git a/domain/CMakeLists.txt b/domain/CMakeLists.txt
index 58a7900..ec9eb62 100644
--- a/domain/CMakeLists.txt
+++ b/domain/CMakeLists.txt
@@ -37,6 +37,8 @@ target_link_options("domain" PRIVATE
# Tests
add_executable("domain-tests"
+ "tests/register_types.cpp"
+
"tests/disposition.cpp"
"tests/participant.cpp"
"tests/turn_order.cpp"
diff --git a/domain/include/turns/domain/participant.hpp b/domain/include/turns/domain/participant.hpp
index d845c77..b51425d 100644
--- a/domain/include/turns/domain/participant.hpp
+++ b/domain/include/turns/domain/participant.hpp
@@ -13,34 +13,44 @@
namespace turns::domain
{
-
struct participant : Glib::Object
{
auto static create(Glib::ustring name, float priority, disposition disposition) -> Glib::RefPtr<participant>;
+ participant();
participant(Glib::ustring name, float priority, disposition disposition);
auto operator<=>(participant const & other) const noexcept -> std::partial_ordering;
- auto property_disposition() -> Glib::PropertyProxy<disposition>;
- auto property_disposition() const -> Glib::PropertyProxy_ReadOnly<disposition>;
- auto get_disposition() const noexcept -> disposition;
- auto set_disposition(disposition value) -> void;
-
- auto property_name() -> Glib::PropertyProxy<Glib::ustring>;
- auto property_name() const -> Glib::PropertyProxy_ReadOnly<Glib::ustring>;
- auto get_name() const -> Glib::ustring;
- auto set_name(Glib::ustring value) -> void;
-
- auto property_priority() -> Glib::PropertyProxy<float>;
- auto property_priority() const -> Glib::PropertyProxy_ReadOnly<float>;
- auto get_priority() const noexcept -> float;
- auto set_priority(float value) -> void;
+ template<typename Self>
+ auto disposition(this Self && self)
+ {
+ return self.m_disposition.get_proxy();
+ }
+
+ template<typename Self>
+ auto is_active(this Self && self)
+ {
+ return self.m_is_active.get_proxy();
+ }
+
+ template<typename Self>
+ auto name(this Self && self)
+ {
+ return self.m_name.get_proxy();
+ }
+
+ template<typename Self>
+ auto priority(this Self && self)
+ {
+ return self.m_priority.get_proxy();
+ }
private:
- Glib::Property<disposition> m_disposition;
- Glib::Property<Glib::ustring> m_name;
- Glib::Property<float> m_priority;
+ Glib::Property<domain::disposition> m_disposition{*this, "disposition", domain::disposition::neutral};
+ Glib::Property<bool> m_is_active{*this, "active", false};
+ Glib::Property<Glib::ustring> m_name{*this, "name", ""};
+ Glib::Property<float> m_priority{*this, "priority", 0.0f};
};
} // namespace turns::domain
diff --git a/domain/include/turns/domain/turn_order.hpp b/domain/include/turns/domain/turn_order.hpp
index 3b42562..ca44b62 100644
--- a/domain/include/turns/domain/turn_order.hpp
+++ b/domain/include/turns/domain/turn_order.hpp
@@ -4,9 +4,12 @@
#include "turns/domain/disposition.hpp"
#include "turns/domain/participant.hpp"
+#include <initializer_list>
#include <limits>
+#include <optional>
+#include <vector>
-#include <giomm/liststore.h>
+#include <giomm/listmodel.h>
#include <glibmm/property.h>
#include <glibmm/refptr.h>
#include <glibmm/ustring.h>
@@ -14,91 +17,67 @@
namespace turns::domain
{
- struct turn_order : Glib::Object
+ struct turn_order : Gio::ListModel,
+ Glib::Object
{
+ using value_type = Glib::RefPtr<participant>;
+ using container_type = std::vector<value_type>;
+ using iterator = container_type::iterator;
+ using const_iterator = container_type::const_iterator;
+
using active_participant_type = unsigned int;
- using empty_type = bool;
+ using is_empty_type = bool;
using has_next_type = bool;
using has_previous_type = bool;
- using running_type = bool;
- using round_type = unsigned int;
+ using is_running_type = bool;
+ using round_number_type = unsigned int;
auto static constexpr invalid_participant_index = std::numeric_limits<active_participant_type>::max();
+ auto static constexpr invalid_round_number = std::numeric_limits<round_number_type>::max();
- auto static create() -> Glib::RefPtr<turn_order>;
-
+ /** Life-time */
turn_order();
- /** Modifiers */
+ auto static create() -> Glib::RefPtr<turn_order>;
+
+ /** Properties */
+ auto is_empty() const -> Glib::PropertyProxy_ReadOnly<is_empty_type>;
+ auto has_next() const -> Glib::PropertyProxy_ReadOnly<has_next_type>;
+ auto has_previous() const -> Glib::PropertyProxy_ReadOnly<has_previous_type>;
+ auto is_running() const -> Glib::PropertyProxy_ReadOnly<is_running_type>;
+ auto round_number() const -> Glib::PropertyProxy_ReadOnly<round_number_type>;
+ /** Element Modifications */
auto add(Glib::ustring const & name, float priority, disposition disposition) -> void;
auto clear() -> void;
+ auto remove(unsigned index) -> void;
+
+ /** Turn Modification */
auto next() -> void;
auto previous() -> void;
- auto remove(unsigned int index) -> void;
- auto reset() -> void;
auto start() -> void;
auto stop() -> void;
- /** Querries */
-
- /**
- * Get the index of the currently active participant of this turn order, if any.
- *
- * @returns an unsigned integer in the range [0, size()) if there is an active participant, or turn_order::invalid_participant_index otherwise.
- */
- auto active_participant() const noexcept -> active_participant_type;
-
- /**
- * Check if this turn order is empty.
- */
- auto empty() const noexcept -> empty_type;
-
- /**
- * Get the actor at the specified position in this turn order.
- *
- * @return a valid pointer to a participant object if the index was valid, nullptr otherwise.
- */
- auto get(unsigned int index) const noexcept -> Glib::RefPtr<participant>;
-
- /**
- * Get the underlying list model, to be used with list views.
- */
- auto list_model() -> Glib::RefPtr<Gio::ListModel>;
-
- /**
- * Get the current round.
- */
- auto round() const noexcept -> round_type;
-
- /**
- * Check if this turn order is currently running.
- */
- auto running() const noexcept -> running_type;
-
- /**
- * Get the size of this turn order
- */
- auto size() const noexcept -> unsigned int;
+ private:
+ auto get_item_type_vfunc() -> GType override;
+ auto get_n_items_vfunc() -> unsigned override;
+ auto get_item_vfunc(unsigned position) -> void * override;
- /** Properties */
+ /** Signal handlers */
+ auto handle_priority_changed(value_type entry) -> void;
- 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>;
+ /** Data management */
+ auto find(value_type entry) const -> const_iterator;
+ auto insert(value_type entry) -> const_iterator;
- private:
- Glib::RefPtr<Gio::ListStore<participant>> m_model;
-
- 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;
+ container_type m_data{};
+ std::optional<unsigned> m_active{};
+
+ Glib::Property<has_next_type> m_has_next{*this, "has-next", false};
+ Glib::Property<has_previous_type> m_has_previous{*this, "has-previous", false};
+ Glib::Property<is_empty_type> m_is_empty{*this, "is-empty", true};
+ Glib::Property<is_running_type> m_is_running{*this, "is-running", false};
+ Glib::Property<round_number_type> m_round_number{*this, "round-number", invalid_round_number};
};
} // namespace turns::domain
diff --git a/domain/src/participant.cpp b/domain/src/participant.cpp
index 5265eb3..6f0efb1 100644
--- a/domain/src/participant.cpp
+++ b/domain/src/participant.cpp
@@ -3,87 +3,33 @@
#include <typeinfo>
#include <utility>
+#include <glibmm/class.h>
#include <glibmm/refptr.h>
namespace turns::domain
{
-
- auto participant::create(Glib::ustring name, float priority, disposition disposition) -> Glib::RefPtr<participant>
+ auto participant::create(Glib::ustring name, float priority, domain::disposition disposition) -> Glib::RefPtr<participant>
{
return Glib::make_refptr_for_instance(new participant{name, priority, disposition});
}
- participant::participant(Glib::ustring name, float priority, disposition disposition)
+ participant::participant()
: Glib::ObjectBase{typeid(participant)}
- , m_disposition{*this, "disposition", disposition}
- , m_name{*this, "name", name}
- , m_priority{*this, "priority", priority}
- {
- }
-
- auto participant::operator<=>(participant const & other) const noexcept -> std::partial_ordering
- {
- return m_priority <=> other.m_priority;
- }
-
- auto participant::get_disposition() const noexcept -> disposition
- {
- return m_disposition;
- }
-
- auto participant::set_disposition(disposition value) -> void
- {
- m_disposition = value;
- }
-
- auto participant::get_name() const -> Glib::ustring
- {
- return m_name;
- }
-
- auto participant::set_name(Glib::ustring value) -> void
- {
- m_name = value;
- }
-
- auto participant::get_priority() const noexcept -> float
- {
- return m_priority;
- }
-
- auto participant::set_priority(float value) -> void
+ , Glib::Object{}
{
- m_priority = value;
}
- auto participant::property_disposition() -> Glib::PropertyProxy<disposition>
+ participant::participant(Glib::ustring name, float priority, domain::disposition disposition)
+ : participant()
{
- return m_disposition.get_proxy();
+ m_name = name;
+ m_priority = priority;
+ m_disposition = disposition;
}
- auto participant::property_disposition() const -> Glib::PropertyProxy_ReadOnly<disposition>
- {
- return m_disposition.get_proxy();
- }
-
- auto participant::property_name() -> Glib::PropertyProxy<Glib::ustring>
- {
- return m_name.get_proxy();
- }
-
- auto participant::property_name() const -> Glib::PropertyProxy_ReadOnly<Glib::ustring>
- {
- return m_name.get_proxy();
- }
-
- auto participant::property_priority() -> Glib::PropertyProxy<float>
- {
- return m_priority.get_proxy();
- }
-
- auto participant::property_priority() const -> Glib::PropertyProxy_ReadOnly<float>
+ auto participant::operator<=>(participant const & other) const noexcept -> std::partial_ordering
{
- return m_priority.get_proxy();
+ return m_priority <=> other.m_priority;
}
} // namespace turns::domain \ No newline at end of file
diff --git a/domain/src/turn_order.cpp b/domain/src/turn_order.cpp
index 61ccdca..0f8b6e8 100644
--- a/domain/src/turn_order.cpp
+++ b/domain/src/turn_order.cpp
@@ -2,11 +2,11 @@
#include "turns/domain/participant.hpp"
+#include <algorithm>
#include <compare>
#include <limits>
#include <typeinfo>
-#include <glibmm/binding.h>
#include <glibmm/refptr.h>
namespace turns::domain
@@ -32,194 +32,203 @@ namespace turns::domain
};
} // namespace
+ /** Construction */
+
+ turn_order::turn_order()
+ : Glib::ObjectBase{typeid(turn_order)}
+ , Gio::ListModel{}
+ {
+ }
+
auto turn_order::create() -> Glib::RefPtr<turn_order>
{
return Glib::make_refptr_for_instance(new turn_order{});
}
- turn_order::turn_order()
- : Glib::ObjectBase{typeid(turn_order)}
- , m_model{Gio::ListStore<participant>::create()}
- , m_active_participant(*this, "active_participant", invalid_participant_index)
- , 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}
+ /** Queries */
+
+ auto turn_order::is_empty() const -> Glib::PropertyProxy_ReadOnly<is_empty_type>
+ {
+ return m_is_empty.get_proxy();
+ }
+
+ auto turn_order::has_next() const -> Glib::PropertyProxy_ReadOnly<has_next_type>
+ {
+ return m_has_next.get_proxy();
+ }
+
+ auto turn_order::has_previous() const -> Glib::PropertyProxy_ReadOnly<has_previous_type>
+ {
+ return m_has_previous.get_proxy();
+ }
+
+ auto turn_order::is_running() const -> Glib::PropertyProxy_ReadOnly<is_running_type>
{
- Glib::Binding::bind_property(m_model->property_n_items(), m_empty.get_proxy(), Glib::Binding::Flags::DEFAULT, [](auto n) {
- return n == 0;
- });
+ return m_is_running.get_proxy();
+ }
+
+ auto turn_order::round_number() const -> Glib::PropertyProxy_ReadOnly<round_number_type>
+ {
+ return m_round_number.get_proxy();
}
/** 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)
- {
- auto position = m_model->insert_sorted(participant, comparator);
- participant->property_priority().signal_changed().connect([this] { m_model->sort(comparator); });
+ auto entry = participant::create(name, priority, disposition);
+ entry->priority().signal_changed().connect(sigc::bind(sigc::mem_fun(*this, &turn_order::handle_priority_changed), entry));
+ auto position = std::distance(m_data.cbegin(), insert(entry));
+ items_changed(position, 0, 1);
- if (m_active_participant != invalid_participant_index && position <= m_active_participant)
- {
- m_active_participant = m_active_participant + 1;
- }
+ if (get_n_items() == 1)
+ {
+ m_is_empty = false;
+ m_has_next = true;
}
}
auto turn_order::clear() -> void
{
- m_model->remove_all();
- m_active_participant = invalid_participant_index;
+ m_is_running = false;
+ m_is_empty = true;
m_has_next = false;
m_has_previous = false;
- m_running = false;
+ m_active.reset();
+ m_round_number = invalid_round_number;
+
+ auto old_size = get_n_items();
+ m_data.clear();
+ items_changed(0, old_size, 0);
}
auto turn_order::next() -> void
{
- m_active_participant = (m_active_participant + 1) % size();
- if (!m_active_participant)
+ auto old_active = *m_active;
+ m_active = m_active.transform([this](auto index) { return (index + 1) % get_n_items(); });
+
+ m_has_previous = true;
+ m_data[old_active]->is_active() = false;
+ m_data[*m_active]->is_active() = true;
+
+ if (m_active == 0)
{
- m_round = round() + 1;
+ m_round_number = m_round_number + 1;
}
- m_has_previous = m_active_participant || m_round;
}
auto turn_order::previous() -> void
{
- if (!m_has_previous)
+ if (!(m_has_previous && m_is_running))
{
return;
}
- if (m_active_participant)
- {
- m_active_participant = m_active_participant - 1;
- }
- else if (m_round)
+ auto old_active = *m_active;
+ m_active = m_active.transform([this](auto index) { return index ? index - 1 : get_n_items() - 1; });
+
+ m_has_previous = m_round_number > 0 || m_active > 0;
+ m_data[old_active]->is_active() = false;
+ m_data[*m_active]->is_active() = true;
+
+ if (m_active == 0)
{
- m_round = round() - 1;
- m_active_participant = size() - 1;
+ m_round_number = m_round_number - 1;
}
-
- m_has_previous = m_active_participant || m_round;
}
- auto turn_order::remove(unsigned int index) -> void
+ auto turn_order::remove(unsigned index) -> void
{
- m_model->remove(index);
- if (empty())
+ if (index >= get_n_items())
{
- m_active_participant = invalid_participant_index;
- m_has_next = false;
- m_has_previous = false;
- m_running = false;
+ return;
}
- else if (m_active_participant != invalid_participant_index)
+
+ auto position = m_data.begin() + index;
+ m_data.erase(position);
+ items_changed(index, 1, 0);
+ if (get_n_items() == 0)
{
- if (m_active_participant > size() - 1)
- {
- m_active_participant = size() - 1;
- }
- else if (index <= m_active_participant)
- {
- m_active_participant = m_active_participant - 1;
- }
+ m_is_empty = true;
+ m_is_running = false;
+ m_has_next = false;
}
}
- auto turn_order::reset() -> void
- {
- m_running = false;
- m_active_participant = 0;
- }
-
auto turn_order::start() -> void
{
- if (m_active_participant == invalid_participant_index)
+ if (!m_active)
{
- m_active_participant = 0;
+ m_active = 0;
+ m_data[*m_active]->is_active() = true;
}
- m_running = true;
- m_has_next = true;
+ if (m_round_number == invalid_round_number)
+ {
+ m_round_number = 0;
+ }
+ m_is_running = 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
- {
- return m_empty;
- }
-
- auto turn_order::get(unsigned int index) const noexcept -> Glib::RefPtr<participant>
- {
- return m_model->get_item(index);
+ m_is_running = false;
}
- auto turn_order::list_model() -> Glib::RefPtr<Gio::ListModel>
- {
- return m_model;
- }
+ /** ListModel implementation */
- auto turn_order::round() const noexcept -> round_type
+ auto turn_order::get_item_type_vfunc() -> GType
{
- return m_round;
+ return participant::get_type();
}
- auto turn_order::running() const noexcept -> running_type
+ auto turn_order::get_n_items_vfunc() -> unsigned
{
- return m_running;
+ return m_data.size();
}
- auto turn_order::size() const noexcept -> unsigned int
+ auto turn_order::get_item_vfunc(unsigned position) -> void *
{
- return m_model->get_n_items();
+ if (position >= get_n_items())
+ {
+ return nullptr;
+ }
+ auto item = m_data[position];
+ item->reference();
+ return item->gobj();
}
- /** Properties */
+ /** Signal handlers */
- auto turn_order::property_active_participant() const -> Glib::PropertyProxy_ReadOnly<active_participant_type>
+ auto turn_order::handle_priority_changed(value_type entry) -> void
{
- return m_active_participant.get_proxy();
- }
-
- auto turn_order::property_empty() const -> Glib::PropertyProxy_ReadOnly<bool>
- {
- return m_empty.get_proxy();
- }
+ auto original_position = find(entry);
+ auto original_index = distance(m_data.cbegin(), original_position);
+ auto target_position = std::ranges::upper_bound(m_data, entry, comparator);
+ if (original_position == target_position)
+ {
+ return;
+ }
- auto turn_order::property_has_next() const -> Glib::PropertyProxy_ReadOnly<has_next_type>
- {
- return m_has_next.get_proxy();
+ m_data.erase(original_position);
+ auto inserted_position = insert(entry);
+ items_changed(0, get_n_items(), get_n_items());
+ if (m_active == original_index)
+ {
+ m_active = distance(m_data.cbegin(), inserted_position);
+ m_has_previous = m_round_number > 0 || m_active > 0;
+ }
}
- auto turn_order::property_has_previous() const -> Glib::PropertyProxy_ReadOnly<has_previous_type>
- {
- return m_has_previous.get_proxy();
- }
+ /** Data management */
- auto turn_order::property_running() const -> Glib::PropertyProxy_ReadOnly<running_type>
+ auto turn_order::find(value_type entry) const -> const_iterator
{
- return m_running.get_proxy();
+ return std::ranges::find(m_data, entry);
}
- auto turn_order::property_round() const -> Glib::PropertyProxy_ReadOnly<round_type>
+ auto turn_order::insert(value_type entry) -> const_iterator
{
- return m_round.get_proxy();
+ return m_data.insert(std::ranges::upper_bound(m_data, entry, comparator), entry);
}
} // namespace turns::domain \ No newline at end of file
diff --git a/domain/tests/participant.cpp b/domain/tests/participant.cpp
index dd244f4..e4e185c 100644
--- a/domain/tests/participant.cpp
+++ b/domain/tests/participant.cpp
@@ -22,123 +22,63 @@ namespace turns::domain::tests
REQUIRE(participant::create(constructed_name, constructed_priority, constructed_disposition));
}
- SECTION("allows access to its disposition via the associated accessors")
+ SECTION("allows access to its disposition")
{
SECTION("allowing to get it")
{
- REQUIRE(instance.get_disposition() == constructed_disposition);
+ REQUIRE(instance.disposition() == constructed_disposition);
}
SECTION("allowing to get it via a constant object")
{
auto const & cref = instance;
- REQUIRE(cref.get_disposition() == constructed_disposition);
+ REQUIRE(cref.disposition() == constructed_disposition);
}
SECTION("allowing to set it")
{
- instance.set_disposition(disposition::hostile);
- REQUIRE(instance.get_disposition() == disposition::hostile);
+ instance.disposition() = disposition::hostile;
+ REQUIRE(instance.disposition() == disposition::hostile);
}
}
- SECTION("allows access to its disposition via the associated property")
+ SECTION("allows access to its name")
{
SECTION("allowing to get it")
{
- REQUIRE(instance.property_disposition() == constructed_disposition);
+ REQUIRE(instance.name() == constructed_name);
}
SECTION("allowing to get it via a constant object")
{
auto const & cref = instance;
- REQUIRE(cref.property_disposition() == constructed_disposition);
+ REQUIRE(cref.name() == constructed_name);
}
SECTION("allowing to set it")
{
- instance.property_disposition() = disposition::hostile;
- REQUIRE(instance.get_disposition() == disposition::hostile);
+ instance.name() = "replaced";
+ REQUIRE(instance.name() == "replaced");
}
}
- SECTION("allows access to its name via the associated accessors")
+ SECTION("allows access to its priority")
{
SECTION("allowing to get it")
{
- REQUIRE(instance.get_name() == constructed_name);
+ REQUIRE(instance.priority() == constructed_priority);
}
SECTION("allowing to get it via a constant object")
{
auto const & cref = instance;
- REQUIRE(cref.get_name() == constructed_name);
+ REQUIRE(cref.priority() == constructed_priority);
}
SECTION("allowing to set it")
{
- instance.set_name("replaced");
- REQUIRE(instance.get_name() == "replaced");
- }
- }
-
- SECTION("allows access to its name via the associated property")
- {
- SECTION("allowing to get it")
- {
- REQUIRE(instance.property_name() == constructed_name);
- }
-
- SECTION("allowing to get it via a constant object")
- {
- auto const & cref = instance;
- REQUIRE(cref.property_name() == constructed_name);
- }
-
- SECTION("allowing to set it")
- {
- instance.property_name() = "replaced";
- REQUIRE(instance.get_name() == "replaced");
- }
- }
-
- SECTION("allows access to its priority via the associated accessors")
- {
- SECTION("allowing to get it")
- {
- REQUIRE(instance.get_priority() == constructed_priority);
- }
-
- SECTION("allowing to get it via a constant object")
- {
- auto const & cref = instance;
- REQUIRE(cref.get_priority() == constructed_priority);
- }
-
- SECTION("allowing to set it")
- {
- instance.set_priority(3);
- REQUIRE(instance.get_priority() == 3);
- }
- }
-
- SECTION("allows access to its priority via the associated property")
- {
- SECTION("allowing to get it")
- {
- REQUIRE(instance.property_priority() == constructed_priority);
- }
-
- SECTION("allowing to get it via a constant object")
- {
- auto const & cref = instance;
- REQUIRE(cref.property_priority() == constructed_priority);
- }
-
- SECTION("allowing to set it")
- {
- instance.property_priority() = 4;
- REQUIRE(instance.get_priority() == 4);
+ instance.priority() = 4;
+ REQUIRE(instance.priority() == 4);
}
}
diff --git a/domain/tests/register_types.cpp b/domain/tests/register_types.cpp
new file mode 100644
index 0000000..de8bb52
--- /dev/null
+++ b/domain/tests/register_types.cpp
@@ -0,0 +1,13 @@
+#include "turns/domain/participant.hpp"
+#include "turns/domain/turn_order.hpp"
+
+namespace turns::tests
+{
+
+ auto register_types() -> void
+ {
+ static_cast<void>(domain::participant{});
+ static_cast<void>(domain::turn_order{});
+ }
+
+} // namespace turns::tests \ No newline at end of file
diff --git a/domain/tests/turn_order.cpp b/domain/tests/turn_order.cpp
index de1689c..eb05581 100644
--- a/domain/tests/turn_order.cpp
+++ b/domain/tests/turn_order.cpp
@@ -1,459 +1,221 @@
#include "turns/domain/turn_order.hpp"
+#include "turns/domain/participant.hpp"
+
#include <catch2/catch_test_macros.hpp>
-#include <glibmm/ustring.h>
+#include <giomm/liststore.h>
namespace turns::domain::tests
{
-
SCENARIO("Queries on a fresh turn_order instance", "[turn_order]")
{
GIVEN("an empty turn_order")
{
auto instance = turn_order::create();
- THEN("active_participant() is turn_order::invalid_participant_index")
+ THEN("get_n_items() returns 0")
{
- REQUIRE(instance->active_participant() == turn_order::invalid_participant_index);
+ auto str = Gio::ListStore<Glib::Object>::create();
+ REQUIRE(instance->get_n_items() == str->get_n_items());
}
- THEN("empty() is true")
+ THEN("get_type() returns participant::get_type()")
{
- REQUIRE(instance->empty());
+ REQUIRE(instance->get_item_type() == participant::get_type());
}
- THEN("get() returns a nullptr")
+ THEN("get_typed_object(0) returns nullptr")
{
- REQUIRE(instance->get(0) == nullptr);
+ REQUIRE(instance->get_typed_object<participant>(0) == nullptr);
}
- THEN("list_model() returns a non-null pointer")
+ THEN("has_next() returns false")
{
- REQUIRE(instance->list_model());
+ REQUIRE_FALSE(instance->has_next());
}
- THEN("round() returns 0")
+ THEN("has_previous() returns false")
{
- REQUIRE(instance->round() == 0);
+ REQUIRE_FALSE(instance->has_previous());
}
- THEN("running() returns false")
+ THEN("is_empty() returns true")
{
- REQUIRE_FALSE(instance->running());
+ REQUIRE(instance->is_empty());
}
- THEN("size() returns 0")
+ THEN("is_running() returns false")
{
- REQUIRE(instance->size() == 0);
+ REQUIRE_FALSE(instance->is_running());
}
- THEN("size() returns the same value as list_model()->get_n_item()")
+ THEN("round_number() returns invalid_round_number")
{
- REQUIRE(instance->size() == instance->list_model()->get_n_items());
+ REQUIRE(instance->round_number() == turn_order::invalid_round_number);
}
+ }
+ }
- WHEN("accessing turn_order:active-participant")
- {
- THEN("get() returns turn_order::invalid_participant_index")
- {
- REQUIRE(instance->property_active_participant().get_value() == turn_order::invalid_participant_index);
- }
+ SCENARIO("Adding participants")
+ {
+ auto instance = turn_order::create();
- THEN("get_object() returns a pointer to the instance")
- {
- REQUIRE(instance->property_active_participant().get_object() == instance.get());
- }
+ GIVEN("a participant has been added to a turn_order")
+ {
+ instance->add("Participant #0", 0, disposition::neutral);
- THEN("get_name() returns \"active-participant\"")
- {
- REQUIRE(instance->property_active_participant().get_name() == Glib::ustring{"active-participant"});
- }
+ THEN("get_n_items() returns 1")
+ {
+ REQUIRE(instance->get_n_items() == 1);
}
- WHEN("accessing turn_order:empty")
+ THEN("get_typed_object(0) returns a non-null pointer")
{
- THEN("get() returns true")
- {
- REQUIRE(instance->property_empty().get_value());
- }
-
- THEN("get_object() returns a pointer to the instance")
- {
- REQUIRE(instance->property_empty().get_object() == instance.get());
- }
-
- THEN("get_name() returns \"empty\"")
- {
- REQUIRE(instance->property_empty().get_name() == Glib::ustring{"empty"});
- }
+ REQUIRE(instance->get_typed_object<participant>(0) != nullptr);
}
- WHEN("accessing turn_order:has-next")
+ THEN("has_next() returns true")
{
- THEN("get() returns false")
- {
- REQUIRE_FALSE(instance->property_has_next().get_value());
- }
-
- THEN("get_object() returns a pointer to the instance")
- {
- REQUIRE(instance->property_has_next().get_object() == instance.get());
- }
+ REQUIRE(instance->has_next());
+ }
- THEN("get_name() returns \"has-next\"")
- {
- REQUIRE(instance->property_has_next().get_name() == Glib::ustring{"has-next"});
- }
+ THEN("has_previous() returns false")
+ {
+ REQUIRE_FALSE(instance->has_previous());
}
- WHEN("accessing turn_order:has-previous")
+ THEN("is_empty() returns false")
{
- THEN("get() returns false")
- {
- REQUIRE_FALSE(instance->property_has_previous().get_value());
- }
+ REQUIRE_FALSE(instance->is_empty());
+ }
- THEN("get_object() returns a pointer to the instance")
- {
- REQUIRE(instance->property_has_previous().get_object() == instance.get());
- }
+ THEN("is_running() returns false")
+ {
+ REQUIRE_FALSE(instance->is_running());
+ }
- THEN("get_name() returns \"has-previous\"")
- {
- REQUIRE(instance->property_has_previous().get_name() == Glib::ustring{"has-previous"});
- }
+ THEN("round_number() returns invalid_round_number")
+ {
+ REQUIRE(instance->round_number() == turn_order::invalid_round_number);
}
- WHEN("accessing turn_order:running")
+ WHEN("the turn_order is start()ed")
{
- THEN("get() returns false")
+ instance->start();
+
+ THEN("get_n_items() still returns 1")
{
- REQUIRE_FALSE(instance->property_running().get_value());
+ REQUIRE(instance->get_n_items() == 1);
}
- THEN("get_object() returns a pointer to the instance")
+ THEN("get_typed_object(0) still returns a non-null pointer")
{
- REQUIRE(instance->property_running().get_object() == instance.get());
+ REQUIRE(instance->get_typed_object<participant>(0) != nullptr);
}
- THEN("get_name() returns \"running\"")
+ THEN("has_next() still returns true")
{
- REQUIRE(instance->property_running().get_name() == Glib::ustring{"running"});
+ REQUIRE(instance->has_next());
}
- }
- WHEN("accessing turn_order:running")
- {
- THEN("get() returns 0")
+ THEN("has_previous() still returns false")
{
- REQUIRE(instance->property_round().get_value() == 0);
+ REQUIRE_FALSE(instance->has_previous());
}
- THEN("get_object() returns a pointer to the instance")
+ THEN("is_empty() still returns false")
{
- REQUIRE(instance->property_round().get_object() == instance.get());
+ REQUIRE_FALSE(instance->is_empty());
}
- THEN("get_name() returns \"round\"")
+ THEN("is_running() returns true")
{
- REQUIRE(instance->property_round().get_name() == Glib::ustring{"round"});
+ REQUIRE(instance->is_running());
}
- }
- }
- }
-
- SCENARIO("Modification of an empty turn_order", "[turn_order]")
- {
- auto instance = turn_order::create();
-
- GIVEN("a single participant was added")
- {
- auto constexpr priority = 12.0f;
- instance->add("Participant #0", priority, disposition::friendly);
- AND_GIVEN("the turn_order was never started")
- {
- WHEN("no other modification occurs")
+ THEN("round_number() returns 0")
{
- THEN("active_participant() returns turn_order::invalid_participant_index")
- {
- REQUIRE(instance->active_participant() == turn_order::invalid_participant_index);
- }
-
- THEN("empty() returns false")
- {
- REQUIRE_FALSE(instance->empty());
- }
-
- THEN("get() returns a valid pointer for index 0")
- {
- REQUIRE(instance->get(0));
- }
-
- THEN("get() returns a nullptr for an index greater than 0")
- {
- REQUIRE(instance->get(1) == nullptr);
- }
-
- THEN("round() returns 0")
- {
- REQUIRE(instance->round() == 0);
- }
-
- THEN("running() returns false")
- {
- REQUIRE_FALSE(instance->running());
- }
-
- THEN("size() returns 1")
- {
- REQUIRE(instance->size() == 1);
- }
-
- THEN("turn_order:has-next is false")
- {
- REQUIRE(instance->property_has_next() == false);
- }
-
- THEN("turn_order:has-previous is false")
- {
- REQUIRE(instance->property_has_previous() == false);
- }
-
- THEN("turn_order:running is false")
- {
- REQUIRE(instance->property_running() == false);
- }
+ REQUIRE(instance->round_number() == 0);
}
- WHEN("the participant is removed again")
+ AND_WHEN("invoking previous()")
{
- instance->remove(0);
-
- THEN("active_participant() returns turn_order::invalid_participant_index")
- {
- REQUIRE(instance->active_participant() == turn_order::invalid_participant_index);
- }
-
- THEN("empty() returns true")
- {
- REQUIRE(instance->empty());
- }
+ instance->previous();
- THEN("get() returns a nullptr for index 0")
+ THEN("get_n_items() still returns 1")
{
- REQUIRE(instance->get(0) == nullptr);
+ REQUIRE(instance->get_n_items() == 1);
}
- THEN("round() returns 0")
+ THEN("get_typed_object(0) still returns a non-null pointer")
{
- REQUIRE(instance->round() == 0);
+ REQUIRE(instance->get_typed_object<participant>(0) != nullptr);
}
- THEN("running() returns false")
+ THEN("has_next() still returns true")
{
- REQUIRE_FALSE(instance->running());
+ REQUIRE(instance->has_next());
}
- THEN("size() returns 0")
+ THEN("has_previous() still returns false")
{
- REQUIRE(instance->size() == 0);
+ REQUIRE_FALSE(instance->has_previous());
}
- THEN("turn_order:has-next is false")
+ THEN("is_empty() still returns false")
{
- REQUIRE(instance->property_has_next() == false);
+ REQUIRE_FALSE(instance->is_empty());
}
- THEN("turn_order:has-previous is false")
+ THEN("is_running() returns true")
{
- REQUIRE(instance->property_has_previous() == false);
+ REQUIRE(instance->is_running());
}
- THEN("turn_order:running is false")
+ THEN("round_number() returns 0")
{
- REQUIRE(instance->property_running() == false);
+ REQUIRE(instance->round_number() == 0);
}
}
- WHEN("another participant with the same priority is added")
+ AND_WHEN("invoking next()")
{
- instance->add("Participant #1", priority, disposition::friendly);
-
- THEN("active_participant() returns turn_order::invalid_participant_index")
- {
- REQUIRE(instance->active_participant() == turn_order::invalid_participant_index);
- }
-
- THEN("empty() returns false")
- {
- REQUIRE_FALSE(instance->empty());
- }
-
- THEN("get() returns a valid pointer for index 0")
- {
- REQUIRE(instance->get(0));
- }
-
- THEN("get() returns a valid pointer for index 1")
- {
- REQUIRE(instance->get(1));
- }
-
- THEN("get() returns a nullptr for an index greater than 1")
- {
- REQUIRE(instance->get(2) == nullptr);
- }
-
- THEN("get(0) returns the participant that was added first")
- {
- REQUIRE(instance->get(0)->get_name() == "Participant #0");
- }
-
- THEN("get(1) returns the participant that was added second")
- {
- REQUIRE(instance->get(1)->get_name() == "Participant #1");
- }
-
- THEN("round() returns 0")
- {
- REQUIRE(instance->round() == 0);
- }
+ instance->next();
- THEN("running() returns false")
+ THEN("get_n_items() still returns 1")
{
- REQUIRE_FALSE(instance->running());
+ REQUIRE(instance->get_n_items() == 1);
}
- THEN("size() returns 2")
+ THEN("get_typed_object(0) still returns a non-null pointer")
{
- REQUIRE(instance->size() == 2);
+ REQUIRE(instance->get_typed_object<participant>(0) != nullptr);
}
- THEN("turn_order:has-next is false")
+ THEN("has_next() still returns true")
{
- REQUIRE(instance->property_has_next() == false);
+ REQUIRE(instance->has_next());
}
- THEN("turn_order:has-previous is false")
+ THEN("has_previous() returns true")
{
- REQUIRE(instance->property_has_previous() == false);
+ REQUIRE(instance->has_previous());
}
- THEN("turn_order:running is false")
+ THEN("is_empty() still returns false")
{
- REQUIRE(instance->property_running() == false);
+ REQUIRE_FALSE(instance->is_empty());
}
- AND_WHEN("the participant at index 0 is removed")
+ THEN("is_running() returns true")
{
- instance->remove(0);
-
- THEN("active_participant() returns turn_order::invalid_participant_index")
- {
- REQUIRE(instance->active_participant() == turn_order::invalid_participant_index);
- }
-
- THEN("empty() returns false")
- {
- REQUIRE_FALSE(instance->empty());
- }
-
- THEN("get() returns a valid pointer for index 0")
- {
- REQUIRE(instance->get(0));
- }
-
- THEN("get() returns a nullptr for an index greater than 0")
- {
- REQUIRE(instance->get(1) == nullptr);
- }
-
- THEN("get(0) returns the participant that was added second")
- {
- REQUIRE(instance->get(0)->get_name() == "Participant #1");
- }
-
- THEN("round() returns 0")
- {
- REQUIRE(instance->round() == 0);
- }
-
- THEN("running() returns false")
- {
- REQUIRE_FALSE(instance->running());
- }
-
- THEN("size() returns 1")
- {
- REQUIRE(instance->size() == 1);
- }
-
- THEN("turn_order:has-next is false")
- {
- REQUIRE(instance->property_has_next() == false);
- }
-
- THEN("turn_order:has-previous is false")
- {
- REQUIRE(instance->property_has_previous() == false);
- }
-
- THEN("turn_order:running is false")
- {
- REQUIRE(instance->property_running() == false);
- }
+ REQUIRE(instance->is_running());
}
- AND_WHEN("the turn_order is cleared")
+ THEN("round_number() returns 1")
{
- instance->clear();
-
- THEN("active_participant() returns turn_order::invalid_participant_index")
- {
- REQUIRE(instance->active_participant() == turn_order::invalid_participant_index);
- }
-
- THEN("empty() returns true")
- {
- REQUIRE(instance->empty());
- }
-
- THEN("get() returns a nullptr pointer for index 0")
- {
- REQUIRE(instance->get(0) == nullptr);
- }
-
- THEN("round() returns 0")
- {
- REQUIRE(instance->round() == 0);
- }
-
- THEN("running() returns false")
- {
- REQUIRE_FALSE(instance->running());
- }
-
- THEN("size() returns 0")
- {
- REQUIRE(instance->size() == 0);
- }
-
- THEN("turn_order:has-next is false")
- {
- REQUIRE(instance->property_has_next() == false);
- }
-
- THEN("turn_order:has-previous is false")
- {
- REQUIRE(instance->property_has_previous() == false);
- }
-
- THEN("turn_order:running is false")
- {
- REQUIRE(instance->property_running() == false);
- }
+ REQUIRE(instance->round_number() == 1);
}
}
}
diff --git a/test_support/CMakeLists.txt b/test_support/CMakeLists.txt
index ce77a90..447032d 100644
--- a/test_support/CMakeLists.txt
+++ b/test_support/CMakeLists.txt
@@ -18,6 +18,7 @@ target_compile_definitions("test_support-glib" PUBLIC
target_link_libraries("test_support-glib" PUBLIC
"PkgConfig::glibmm"
+ "PkgConfig::giomm"
)
# GTK test support
diff --git a/test_support/src/glib_main.cpp b/test_support/src/glib_main.cpp
index d224bad..b9dc858 100644
--- a/test_support/src/glib_main.cpp
+++ b/test_support/src/glib_main.cpp
@@ -1,10 +1,19 @@
#include <catch2/catch_session.hpp>
+#include <giomm/init.h>
#include <glibmm/init.h>
+namespace turns::tests
+{
+ auto register_types() -> void;
+} // namespace turns::tests
+
auto main(int argc, char * argv[]) -> int
{
+ Gio::init();
Glib::init();
+ turns::tests::register_types();
+
return Catch::Session().run(argc, argv);
} \ No newline at end of file