diff options
| author | Felix Morgner <felix.morgner@gmail.com> | 2025-05-23 12:26:50 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@gmail.com> | 2025-05-23 12:26:50 +0200 |
| commit | d1d171775f768be1dcdee194be5134f334c63347 (patch) | |
| tree | 46e3ddc8d84c68d86293462f8d0c7eb8ffa85473 /lib | |
| parent | 260df0a1158385736b2da24a2e4a14e365d1ec92 (diff) | |
| download | turns-d1d171775f768be1dcdee194be5134f334c63347.tar.xz turns-d1d171775f768be1dcdee194be5134f334c63347.zip | |
lib: add empty property to TurnOrder
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/src/turns-turn-order.c | 33 | ||||
| -rw-r--r-- | lib/src/turns-turn-order.h | 21 | ||||
| -rw-r--r-- | lib/src/turnsmm/turn-order.cpp | 20 | ||||
| -rw-r--r-- | lib/src/turnsmm/turn-order.hpp | 2 | ||||
| -rw-r--r-- | lib/tests/turns-turn-order.cpp | 82 |
5 files changed, 148 insertions, 10 deletions
diff --git a/lib/src/turns-turn-order.c b/lib/src/turns-turn-order.c index 9a08d2e..abc22c4 100644 --- a/lib/src/turns-turn-order.c +++ b/lib/src/turns-turn-order.c @@ -13,7 +13,8 @@ enum { - PROP_RUNNING = 1, + PROP_EMPTY = 1, + PROP_RUNNING, PROP_SORT_MODE, N_PROPERTIES, }; @@ -79,6 +80,8 @@ static void clear_participants(TurnsTurnOrder * self) g_slist_free_full(self->participants, g_object_unref); self->participants = nullptr; + + g_object_notify_by_pspec(G_OBJECT(self), properties[PROP_EMPTY]); } static void set_running(TurnsTurnOrder * self, gboolean value) @@ -105,6 +108,9 @@ static void turns_turn_order_get_property(GObject * self, guint id, GValue * val switch (id) { + case PROP_EMPTY: + g_value_set_boolean(value, turns_turn_order_get_empty(instance)); + return; case PROP_RUNNING: g_value_set_boolean(value, turns_turn_order_get_running(instance)); return; @@ -154,6 +160,12 @@ static void turns_turn_order_class_init(TurnsTurnOrderClass * klass) object_class->get_property = turns_turn_order_get_property; object_class->set_property = turns_turn_order_set_property; + properties[PROP_EMPTY] = g_param_spec_boolean("empty", + "Empty", + "Whether the turn order is empty.", + TRUE, + G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY); + properties[PROP_RUNNING] = g_param_spec_boolean("running", "Running", "Whether or not the turn order is running (e.g. has been started)", @@ -207,10 +219,16 @@ void turns_turn_order_add(TurnsTurnOrder * self, TurnsParticipant * participant) auto sort_mode = turns_turn_order_get_sort_mode(self); + auto old_head = self->participants; self->participants = g_slist_insert_sorted_with_data(self->participants, g_object_ref(participant), compare_participant, (void *)sort_mode); auto position = g_slist_index(self->participants, participant); + if (old_head == nullptr && !turns_turn_order_get_empty(self)) + { + g_object_notify_by_pspec(G_OBJECT(self), properties[PROP_EMPTY]); + } + g_list_model_items_changed(G_LIST_MODEL(self), position, 0, 1); } @@ -242,11 +260,24 @@ void turns_turn_order_remove_at(TurnsTurnOrder * self, guint position) } g_object_unref(element->data); + auto old_head = self->participants; self->participants = g_slist_delete_link(self->participants, element); + if (old_head != nullptr && turns_turn_order_get_empty(self)) + { + g_object_notify_by_pspec(G_OBJECT(self), properties[PROP_EMPTY]); + set_running(self, false); + } + g_list_model_items_changed(G_LIST_MODEL(self), position, 1, 0); } +gboolean turns_turn_order_get_empty(TurnsTurnOrder const * self) +{ + g_return_val_if_fail(TURNS_IS_TURN_ORDER((TurnsTurnOrder *)self), true); + return self->participants == nullptr; +} + gsize turns_turn_order_get_participant_count(TurnsTurnOrder const * self) { g_return_val_if_fail(TURNS_IS_TURN_ORDER((TurnsTurnOrder *)self), 0); diff --git a/lib/src/turns-turn-order.h b/lib/src/turns-turn-order.h index 91220b9..5e34405 100644 --- a/lib/src/turns-turn-order.h +++ b/lib/src/turns-turn-order.h @@ -47,7 +47,8 @@ G_DECLARE_FINAL_TYPE(TurnsTurnOrder, turns_turn_order, TURNS, TURN_ORDER, GObjec * * Returns: (transfer full): a new `TurnsTurnOrder`. */ -TurnsTurnOrder * turns_turn_order_new(void) G_GNUC_WARN_UNUSED_RESULT; +G_GNUC_WARN_UNUSED_RESULT +TurnsTurnOrder * turns_turn_order_new(void); /** * turns_turn_order_add: @@ -75,12 +76,22 @@ void turns_turn_order_clear(TurnsTurnOrder * self); void turns_turn_order_remove_at(TurnsTurnOrder * self, guint position); /** + * turns_turn_order_get_empty: (get-property empty): + * @self: a turn order. + * + * Gets whether the turn order is empty. + */ +G_GNUC_WARN_UNUSED_RESULT +gboolean turns_turn_order_get_empty(TurnsTurnOrder const * self); + +/** * turns_turn_order_get_participant_count: * @self: a turn order. * * Gets the number of participants in the turn order. */ -gsize turns_turn_order_get_participant_count(TurnsTurnOrder const * self) G_GNUC_WARN_UNUSED_RESULT; +G_GNUC_WARN_UNUSED_RESULT +gsize turns_turn_order_get_participant_count(TurnsTurnOrder const * self); /** * turns_turn_order_get_running: (get-property running): @@ -88,7 +99,8 @@ gsize turns_turn_order_get_participant_count(TurnsTurnOrder const * self) G_GNUC * * Gets whether the turn order is currently running. */ -gboolean turns_turn_order_get_running(TurnsTurnOrder const * self) G_GNUC_WARN_UNUSED_RESULT; +G_GNUC_WARN_UNUSED_RESULT +gboolean turns_turn_order_get_running(TurnsTurnOrder const * self); /** * turns_turn_order_get_sort_mode: (get-property sort-mode): @@ -96,7 +108,8 @@ gboolean turns_turn_order_get_running(TurnsTurnOrder const * self) G_GNUC_WARN_U * * Gets whether higher priority values are sorted before or after lower ones. */ -TurnsTurnOrderSortMode turns_turn_order_get_sort_mode(TurnsTurnOrder const * self) G_GNUC_WARN_UNUSED_RESULT; +G_GNUC_WARN_UNUSED_RESULT +TurnsTurnOrderSortMode turns_turn_order_get_sort_mode(TurnsTurnOrder const * self); /** * turns_turn_order_set_sort_mode: (set-property sort-mode): diff --git a/lib/src/turnsmm/turn-order.cpp b/lib/src/turnsmm/turn-order.cpp index 3767817..5f38ded 100644 --- a/lib/src/turnsmm/turn-order.cpp +++ b/lib/src/turnsmm/turn-order.cpp @@ -104,6 +104,11 @@ namespace Turns return turns_turn_order_remove_at(unwrap(this), position); } + auto TurnOrder::get_empty() const noexcept -> bool + { + return turns_turn_order_get_empty(Glib::unwrap(this)); + } + auto TurnOrder::get_participant_count() const noexcept -> std::size_t { return turns_turn_order_get_participant_count(unwrap(this)); @@ -114,11 +119,6 @@ namespace Turns return turns_turn_order_get_running(unwrap(this)); } - auto TurnOrder::property_running() const noexcept -> Glib::PropertyProxy_ReadOnly<bool> - { - return {this, "running"}; - } - auto TurnOrder::get_sort_mode() const noexcept -> SortMode { return static_cast<SortMode>(turns_turn_order_get_sort_mode(unwrap(this))); @@ -129,6 +129,16 @@ namespace Turns turns_turn_order_set_sort_mode(unwrap(this), static_cast<TurnsTurnOrderSortMode>(value)); } + auto TurnOrder::property_empty() const noexcept -> Glib::PropertyProxy_ReadOnly<bool> + { + return {this, "empty"}; + } + + auto TurnOrder::property_running() const noexcept -> Glib::PropertyProxy_ReadOnly<bool> + { + return {this, "running"}; + } + auto TurnOrder::property_sort_mode() noexcept -> Glib::PropertyProxy<SortMode> { return {this, "sort_mode"}; diff --git a/lib/src/turnsmm/turn-order.hpp b/lib/src/turnsmm/turn-order.hpp index fe8c756..3fb55e4 100644 --- a/lib/src/turnsmm/turn-order.hpp +++ b/lib/src/turnsmm/turn-order.hpp @@ -53,12 +53,14 @@ namespace Turns auto clear() noexcept -> void; auto remove_at(guint position) noexcept -> void; + [[nodiscard]] auto get_empty() const noexcept -> bool; [[nodiscard]] auto get_participant_count() const noexcept -> std::size_t; [[nodiscard]] auto get_running() const noexcept -> bool; [[nodiscard]] auto get_sort_mode() const noexcept -> SortMode; auto set_sort_mode(SortMode value) noexcept -> void; + [[nodiscard]] auto property_empty() const noexcept -> Glib::PropertyProxy_ReadOnly<bool>; [[nodiscard]] auto property_running() const noexcept -> Glib::PropertyProxy_ReadOnly<bool>; [[nodiscard]] auto property_sort_mode() noexcept -> Glib::PropertyProxy<SortMode>; [[nodiscard]] auto property_sort_mode() const noexcept -> Glib::PropertyProxy_ReadOnly<SortMode>; diff --git a/lib/tests/turns-turn-order.cpp b/lib/tests/turns-turn-order.cpp index 2e11b52..0c1afcc 100644 --- a/lib/tests/turns-turn-order.cpp +++ b/lib/tests/turns-turn-order.cpp @@ -24,6 +24,13 @@ namespace { list_model_notification = std::tuple{position, removed, added}; } + + auto empty_notification = std::optional<bool>{}; + + auto on_empty_notification(TurnsTurnOrder const * instance, GParamSpec *, void *) -> void + { + empty_notification = turns_turn_order_get_empty(instance); + } } // namespace SCENARIO("Creating a turn order", "[lib][object][lifetime]") @@ -62,6 +69,16 @@ SCENARIO("Creating a turn order", "[lib][object][lifetime]") REQUIRE(g_list_model_get_item(G_LIST_MODEL(instance), 0) == nullptr); REQUIRE(g_list_model_get_object(G_LIST_MODEL(instance), 0) == nullptr); } + + THEN("it's empty") + { + REQUIRE(turns_turn_order_get_empty(instance)); + + auto property_value = decltype(turns_turn_order_get_empty(instance)){}; + g_object_get(instance, "empty", &property_value, nullptr); + + REQUIRE(property_value); + } } } @@ -73,10 +90,12 @@ SCENARIO("Modifying a turn order", "[lib][object][data]") CHECK(turns_turn_order_get_participant_count(instance) == 0); g_signal_connect(instance, "items-changed", reinterpret_cast<GCallback>(on_list_model_notification), nullptr); + g_signal_connect(instance, "notify::empty", reinterpret_cast<GCallback>(on_empty_notification), nullptr); WHEN("a participant is added") { g_autoptr(TurnsParticipant) participant = turns_participant_new_with("Test Participant", 10.0f, TURNS_PARTICIPANT_DISPOSITION_FRIENDLY); + empty_notification.reset(); turns_turn_order_add(instance, participant); THEN("its participant count is 1") @@ -103,9 +122,25 @@ SCENARIO("Modifying a turn order", "[lib][object][data]") REQUIRE(TURNS_PARTICIPANT(object) == participant); } + THEN("it's not empty") + { + REQUIRE_FALSE(turns_turn_order_get_empty(instance)); + + auto property_value = decltype(turns_turn_order_get_empty(instance)){}; + g_object_get(instance, "empty", &property_value, nullptr); + + REQUIRE_FALSE(property_value); + } + + THEN("the empty property is notified") + { + REQUIRE(empty_notification.has_value()); + } + AND_WHEN("calling clear") { list_model_notification.reset(); + empty_notification.reset(); turns_turn_order_clear(instance); THEN("its participant count is 0") @@ -142,11 +177,27 @@ SCENARIO("Modifying a turn order", "[lib][object][data]") REQUIRE(removed == 1); REQUIRE(added == 0); } + + THEN("it's empty") + { + REQUIRE(turns_turn_order_get_empty(instance)); + + auto property_value = decltype(turns_turn_order_get_empty(instance)){}; + g_object_get(instance, "empty", &property_value, nullptr); + + REQUIRE(property_value); + } + + THEN("the empty property is notified") + { + REQUIRE(empty_notification.has_value()); + } } AND_WHEN("removing the first element") { list_model_notification.reset(); + empty_notification.reset(); turns_turn_order_remove_at(instance, 0); THEN("its participant count is 0") @@ -168,9 +219,25 @@ SCENARIO("Modifying a turn order", "[lib][object][data]") REQUIRE(added == 0); } + THEN("it's empty") + { + REQUIRE(turns_turn_order_get_empty(instance)); + + auto property_value = decltype(turns_turn_order_get_empty(instance)){}; + g_object_get(instance, "empty", &property_value, nullptr); + + REQUIRE(property_value); + } + + THEN("the empty property is notified") + { + REQUIRE(empty_notification.has_value()); + } + AND_WHEN("removing the first element again") { list_model_notification.reset(); + empty_notification.reset(); turns_turn_order_remove_at(instance, 0); THEN("its participant count is 0") @@ -182,6 +249,21 @@ SCENARIO("Modifying a turn order", "[lib][object][data]") { REQUIRE(!list_model_notification.has_value()); } + + THEN("it's empty") + { + REQUIRE(turns_turn_order_get_empty(instance)); + + auto property_value = decltype(turns_turn_order_get_empty(instance)){}; + g_object_get(instance, "empty", &property_value, nullptr); + + REQUIRE(property_value); + } + + THEN("the empty property is not notified") + { + REQUIRE_FALSE(empty_notification.has_value()); + } } } } |
