From 842097d321e2ad9eedd7a171cdcca001d112de55 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 16 May 2025 18:39:44 +0200 Subject: lib: implement addition of participants --- lib/src/turns-turn-order.cpp | 27 ++++++++++++++++++- lib/src/turns-turn-order.h | 4 +++ lib/src/turnsmm/turn-order.cpp | 10 +++++-- lib/src/turnsmm/turn-order.hpp | 4 +++ lib/tests/turns-turn-order.cpp | 56 +++++++++++++++++++++++++++++++++------- lib/tests/turnsmm/turn-order.cpp | 50 +++++++++++++++++++++++++++++++---- 6 files changed, 133 insertions(+), 18 deletions(-) diff --git a/lib/src/turns-turn-order.cpp b/lib/src/turns-turn-order.cpp index 407ac3b..46ea0e6 100644 --- a/lib/src/turns-turn-order.cpp +++ b/lib/src/turns-turn-order.cpp @@ -39,6 +39,25 @@ namespace auto static constinit properties = std::array(property::N_PROPERTIES)>{}; + auto compare_participant(TurnsParticipant const * lhs, TurnsParticipant const * rhs) + { + auto left_priority = turns_participant_get_priority(lhs); + auto right_priority = turns_participant_get_priority(rhs); + + if (left_priority < right_priority) + { + return -1; + } + else if (left_priority > right_priority) + { + return 1; + } + else + { + return 0; + } + } + auto finalize(GObject * self) { auto instance = TURNS_TURN_ORDER(self); @@ -91,7 +110,7 @@ static void turns_turn_order_init(TurnsTurnOrder * self) static gpointer turns_turn_order_list_model_get_item(TurnsTurnOrder * self, guint position) { g_return_val_if_fail(position < turns_turn_order_get_participant_count(self), nullptr); - return g_slist_nth_data(self->participants, position); + return g_object_ref(g_slist_nth_data(self->participants, position)); } static guint turns_turn_order_list_model_get_n_items(TurnsTurnOrder * self) @@ -117,6 +136,12 @@ TurnsTurnOrder * turns_turn_order_new() return TURNS_TURN_ORDER(g_object_new(TURNS_TYPE_TURN_ORDER, nullptr)); } +void turns_turn_order_add(TurnsTurnOrder * self, TurnsParticipant * participant) +{ + g_return_if_fail(participant != nullptr); + self->participants = g_slist_insert_sorted(self->participants, g_object_ref(participant), std::bit_cast(&compare_participant)); +} + gsize turns_turn_order_get_participant_count(TurnsTurnOrder const * self) { g_return_val_if_fail(TURNS_IS_TURN_ORDER(const_cast(self)), 0); diff --git a/lib/src/turns-turn-order.h b/lib/src/turns-turn-order.h index 3af566b..4b1b61a 100644 --- a/lib/src/turns-turn-order.h +++ b/lib/src/turns-turn-order.h @@ -1,6 +1,8 @@ #ifndef TURNS_TURN_ORDER_H #define TURNS_TURN_ORDER_H +#include "turns-participant.h" + #include #include @@ -11,6 +13,8 @@ G_DECLARE_FINAL_TYPE(TurnsTurnOrder, turns_turn_order, TURNS, TURN_ORDER, GObjec TurnsTurnOrder * turns_turn_order_new(void) G_GNUC_WARN_UNUSED_RESULT; +void turns_turn_order_add(TurnsTurnOrder * self, TurnsParticipant * participant); + gsize turns_turn_order_get_participant_count(TurnsTurnOrder const * self) G_GNUC_WARN_UNUSED_RESULT; gboolean turns_turn_order_get_running(TurnsTurnOrder const * self) G_GNUC_WARN_UNUSED_RESULT; diff --git a/lib/src/turnsmm/turn-order.cpp b/lib/src/turnsmm/turn-order.cpp index b29589e..c89bd92 100644 --- a/lib/src/turnsmm/turn-order.cpp +++ b/lib/src/turnsmm/turn-order.cpp @@ -1,6 +1,7 @@ #include "turnsmm/turn-order.hpp" #include "turns-turn-order.h" +#include "turnsmm/participant.hpp" #include "turnsmm/private/turn-order_p.hpp" #include @@ -79,14 +80,19 @@ namespace Turns return gobj(); } + auto TurnOrder::add(Glib::RefPtr const & participant) noexcept -> void + { + return turns_turn_order_add(unwrap(this), unwrap(participant)); + } + auto TurnOrder::get_participant_count() const noexcept -> std::size_t { - return turns_turn_order_get_participant_count(const_cast(unwrap(this))); + return turns_turn_order_get_participant_count(unwrap(this)); } auto TurnOrder::get_running() const noexcept -> bool { - return turns_turn_order_get_running(const_cast(unwrap(this))); + return turns_turn_order_get_running(unwrap(this)); } auto TurnOrder::property_running() const noexcept -> Glib::PropertyProxy_ReadOnly diff --git a/lib/src/turnsmm/turn-order.hpp b/lib/src/turnsmm/turn-order.hpp index 8e6cdb3..9485275 100644 --- a/lib/src/turnsmm/turn-order.hpp +++ b/lib/src/turnsmm/turn-order.hpp @@ -2,6 +2,7 @@ #define TURNSMM_TURN_ORDER_HPP #include "turns-turn-order.h" +#include "turnsmm/participant.hpp" #include #include @@ -9,6 +10,7 @@ #include #include + #include #include @@ -34,6 +36,8 @@ namespace Turns [[nodiscard]] auto gobj() const -> BaseObjectType const *; [[nodiscard]] auto gobj_copy() noexcept -> BaseObjectType *; + auto add(Glib::RefPtr const & participant) noexcept -> void; + [[nodiscard]] auto get_participant_count() const noexcept -> std::size_t; [[nodiscard]] auto get_running() const noexcept -> bool; diff --git a/lib/tests/turns-turn-order.cpp b/lib/tests/turns-turn-order.cpp index e0ee431..05e3b07 100644 --- a/lib/tests/turns-turn-order.cpp +++ b/lib/tests/turns-turn-order.cpp @@ -6,6 +6,8 @@ #include #include +#include +#include SCENARIO("Creating a turn order", "[lib][object][lifetime]") { @@ -13,17 +15,12 @@ SCENARIO("Creating a turn order", "[lib][object][lifetime]") { g_autoptr(TurnsTurnOrder) instance = turns_turn_order_new(); - THEN("it's participant count is 0") + THEN("its participant count is 0") { REQUIRE(turns_turn_order_get_participant_count(instance) == 0uz); - - auto property_value = decltype(turns_turn_order_get_participant_count(instance)){}; - g_object_get(instance, "participant-count", &property_value, nullptr); - - REQUIRE(property_value == 0); } - THEN("it's running state is false") + THEN("its running state is false") { REQUIRE_FALSE(turns_turn_order_get_running(instance)); @@ -33,20 +30,59 @@ SCENARIO("Creating a turn order", "[lib][object][lifetime]") REQUIRE_FALSE(property_value); } - THEN("it's item count is 0") + THEN("its item count is 0") { REQUIRE(g_list_model_get_n_items(G_LIST_MODEL(instance)) == 0); } - THEN("it's item type is Turns.Participant") + THEN("its item type is Turns.Participant") { REQUIRE(g_list_model_get_item_type(G_LIST_MODEL(instance)) == turns_participant_get_type()); } - THEN("it's first item is NULL") + THEN("its first item is NULL") { REQUIRE(g_list_model_get_item(G_LIST_MODEL(instance), 0) == nullptr); REQUIRE(g_list_model_get_object(G_LIST_MODEL(instance), 0) == nullptr); } } +} + +SCENARIO("Modifying a turn order", "[lib][object][data]") +{ + GIVEN("An empty turn order") + { + g_autoptr(TurnsTurnOrder) instance = turns_turn_order_new(); + CHECK(turns_turn_order_get_participant_count(instance) == 0); + + WHEN("a participant is added") + { + g_autoptr(TurnsParticipant) participant = turns_participant_new_with("Test Participant", 10.0f, TURNS_DISPOSITION_FRIENDLY); + turns_turn_order_add(instance, participant); + + THEN("its participant count is 1") + { + REQUIRE(turns_turn_order_get_participant_count(instance) == 1); + } + + THEN("its running state is false") + { + REQUIRE_FALSE(turns_turn_order_get_running(instance)); + } + + THEN("its item count is 1") + { + REQUIRE(g_list_model_get_n_items(G_LIST_MODEL(instance)) == 1); + } + + THEN("its first item is the same participant") + { + g_autoptr(TurnsParticipant) item = TURNS_PARTICIPANT(g_list_model_get_item(G_LIST_MODEL(instance), 0)); + REQUIRE(item == participant); + + g_autoptr(TurnsParticipant) object = TURNS_PARTICIPANT(g_list_model_get_object(G_LIST_MODEL(instance), 0)); + REQUIRE(TURNS_PARTICIPANT(object) == participant); + } + } + } } \ No newline at end of file diff --git a/lib/tests/turnsmm/turn-order.cpp b/lib/tests/turnsmm/turn-order.cpp index ed9d586..089e6eb 100644 --- a/lib/tests/turnsmm/turn-order.cpp +++ b/lib/tests/turnsmm/turn-order.cpp @@ -4,6 +4,8 @@ #include +#include + #include SCENARIO("Creating a turn order", "[lib][object][lifetime]") @@ -12,32 +14,70 @@ SCENARIO("Creating a turn order", "[lib][object][lifetime]") { auto instance = Turns::TurnOrder{}; - THEN("it's participant count is 0") + THEN("its participant count is 0") { REQUIRE(instance.get_participant_count() == 0uz); REQUIRE(instance.get_property("participant-count") == 0); } - THEN("it's running state is false") + THEN("its running state is false") { REQUIRE_FALSE(instance.get_running()); REQUIRE_FALSE(instance.get_property("running")); } - THEN("it's item count is 0") + THEN("its item count is 0") { REQUIRE(instance.get_n_items() == 0); } - THEN("it's item type is Turns.Participant") + THEN("its item type is Turns.Participant") { REQUIRE(instance.get_item_type() == Turns::Participant::get_type()); } - THEN("it's first item is NULL") + THEN("its first item is NULL") { REQUIRE(instance.get_object(0) == nullptr); REQUIRE(instance.get_typed_object(0) == nullptr); } } +} + +SCENARIO("Modifying a turn order", "[lib][object][data]") +{ + GIVEN("An empty turn order") + { + auto instance = Turns::TurnOrder{}; + CHECK(instance.get_participant_count() == 0); + + WHEN("a participant is added") + { + auto participant = Turns::Participant::create("Test Participant", 10.0f, Turns::Disposition::Friendly); + instance.add(participant); + + THEN("its participant count is 1") + { + REQUIRE(instance.get_participant_count() == 1); + } + + THEN("its running state is false") + { + REQUIRE_FALSE(instance.get_running()); + } + + THEN("its item count is 1") + { + REQUIRE(instance.get_n_items() == 1); + } + + THEN("its first item is the same participant") + { + auto obj = instance.get_object(0); + auto cnt = obj->gobj()->ref_count; + REQUIRE(cnt > 0); + REQUIRE(obj == participant); + } + } + } } \ No newline at end of file -- cgit v1.2.3