diff options
| author | Felix Morgner <felix.morgner@gmail.com> | 2025-05-16 11:12:43 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@gmail.com> | 2025-05-16 11:12:43 +0200 |
| commit | 84fb875123201f28a3333285b6323037b08accb4 (patch) | |
| tree | d588328fbb4ffcfc803d4cde7f749566984ea28c | |
| parent | 06200268231281ce925c8eea83cfd30fa824af2b (diff) | |
| download | turns-84fb875123201f28a3333285b6323037b08accb4.tar.xz turns-84fb875123201f28a3333285b6323037b08accb4.zip | |
lib: implement ListModel interface for TurnOrder
| -rw-r--r-- | .vscode/launch.json | 2 | ||||
| -rw-r--r-- | .vscode/settings.json | 1 | ||||
| -rw-r--r-- | CMakeLists.txt | 1 | ||||
| -rw-r--r-- | lib/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | lib/src/turns-turn-order.cpp | 41 | ||||
| -rw-r--r-- | lib/src/turnsmm/participant.cpp | 10 | ||||
| -rw-r--r-- | lib/src/turnsmm/participant.hpp | 4 | ||||
| -rw-r--r-- | lib/src/turnsmm/turn-order.cpp | 12 | ||||
| -rw-r--r-- | lib/src/turnsmm/turn-order.hpp | 9 | ||||
| -rw-r--r-- | lib/tests/turns-turn-order.cpp | 19 | ||||
| -rw-r--r-- | lib/tests/turnsmm/turn-order.cpp | 18 |
11 files changed, 117 insertions, 2 deletions
diff --git a/.vscode/launch.json b/.vscode/launch.json index 29733b3..84c2b3d 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,6 +8,8 @@ "target": "${command:cmake.launchTargetPath}", "cwd": "${workspaceFolder}", "debugger_args": ["-nx"], + "preLaunchTask": "CMake: build", + "valuesFormatting": "prettyPrinters", "autorun": [ "-enable-pretty-printing", "-gdb-set disassembly-flavor intel", diff --git a/.vscode/settings.json b/.vscode/settings.json index a31f5db..8db8f7a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -15,6 +15,7 @@ "gint", "gobj", "gobject", + "gpointer", "gtkmm", "gtype", "guint", diff --git a/CMakeLists.txt b/CMakeLists.txt index a6db0f4..d2d1fd0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,7 @@ FetchContent_Declare( FetchContent_MakeAvailable("Catch2" "nlohmann_json") +pkg_check_modules("gio" IMPORTED_TARGET REQUIRED "gio-2.0>=${GLIB_MINIMUM_VERSION}") pkg_check_modules("giomm" IMPORTED_TARGET REQUIRED "giomm-2.68>=${GLIB_MINIMUM_VERSION}") pkg_check_modules("glibmm" IMPORTED_TARGET REQUIRED "glibmm-2.68>=${GLIB_MINIMUM_VERSION}") pkg_check_modules("gtkmm" IMPORTED_TARGET REQUIRED "gtkmm-4.0>=${GTK4_MINIMUM_VERSION}") diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 3342c30..a550629 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -39,6 +39,7 @@ target_include_directories("lib" PUBLIC ) target_link_libraries("lib" PUBLIC + "PkgConfig::gio" "PkgConfig::gobject" ) @@ -108,6 +109,7 @@ target_include_directories("libmm" PUBLIC ) target_link_libraries("libmm" PUBLIC + "PkgConfig::giomm" "PkgConfig::glibmm" "turns::lib" diff --git a/lib/src/turns-turn-order.cpp b/lib/src/turns-turn-order.cpp index 287e19c..3d1b4eb 100644 --- a/lib/src/turns-turn-order.cpp +++ b/lib/src/turns-turn-order.cpp @@ -1,9 +1,13 @@ #include "turns-turn-order.h" +#include "turns-participant.h" + +#include <gio/gio.h> #include <glib-object.h> #include <glib.h> #include <array> +#include <bit> #include <cstddef> #include <limits> @@ -13,11 +17,17 @@ struct _TurnsTurnOrder { GObject parent_instance; + GList participants; gsize participant_count; gboolean running; }; -G_DEFINE_FINAL_TYPE(TurnsTurnOrder, turns_turn_order, G_TYPE_OBJECT); +static void turns_turn_order_list_model_init(GListModelInterface * iface); + +G_DEFINE_FINAL_TYPE_WITH_CODE(TurnsTurnOrder, + turns_turn_order, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(G_TYPE_LIST_MODEL, turns_turn_order_list_model_init)); G_END_DECLS @@ -78,10 +88,39 @@ static void turns_turn_order_class_init(TurnsTurnOrderClass * klass) static void turns_turn_order_init(TurnsTurnOrder * self) { + self->participants = { + .data = nullptr, + .next = nullptr, + .prev = nullptr, + }; self->participant_count = 0; self->running = false; } +static gpointer turns_turn_order_list_model_get_item(TurnsTurnOrder * self, guint position) +{ + g_return_val_if_fail(position < self->participant_count, nullptr); + return g_list_nth_data(&self->participants, position); +} + +static guint turns_turn_order_list_model_get_n_items(TurnsTurnOrder * self) +{ + return turns_turn_order_get_participant_count(self); +} + +static GType turns_turn_order_list_model_get_item_type(TurnsTurnOrder * self) +{ + static_cast<void>(self); + return TURNS_TYPE_PARTICIPANT; +} + +static void turns_turn_order_list_model_init(GListModelInterface * iface) +{ + iface->get_item = std::bit_cast<decltype(iface->get_item)>(&turns_turn_order_list_model_get_item); + iface->get_item_type = std::bit_cast<decltype(iface->get_item_type)>(&turns_turn_order_list_model_get_item_type); + iface->get_n_items = std::bit_cast<decltype(iface->get_n_items)>(&turns_turn_order_list_model_get_n_items); +} + TurnsTurnOrder * turns_turn_order_new() { return TURNS_TURN_ORDER(g_object_new(TURNS_TYPE_TURN_ORDER, nullptr)); diff --git a/lib/src/turnsmm/participant.cpp b/lib/src/turnsmm/participant.cpp index 5cc3db6..2c7ca08 100644 --- a/lib/src/turnsmm/participant.cpp +++ b/lib/src/turnsmm/participant.cpp @@ -48,6 +48,16 @@ namespace Turns return new Participant(TURNS_PARTICIPANT(object)); } + auto Participant::get_base_type() -> GType + { + return turns_participant_get_type(); + } + + auto Participant::get_type() -> GType + { + return _class.init().get_type(); + } + Participant::Participant() : Glib::ObjectBase{nullptr} , Glib::Object{Glib::ConstructParams{_class.init()}} diff --git a/lib/src/turnsmm/participant.hpp b/lib/src/turnsmm/participant.hpp index b41c64b..04c4fe8 100644 --- a/lib/src/turnsmm/participant.hpp +++ b/lib/src/turnsmm/participant.hpp @@ -8,6 +8,7 @@ #include <glibmm/propertyproxy.h> #include <glibmm/refptr.h> #include <glibmm/ustring.h> +#include <glib-object.h> namespace Turns { @@ -20,6 +21,9 @@ namespace Turns using CppClassType = class Participant_Class; using CppObjectType = Participant; + auto static get_base_type() -> GType; + auto static get_type() -> GType; + Participant(); Participant(Glib::ustring const & name, float priority, Disposition disposition); diff --git a/lib/src/turnsmm/turn-order.cpp b/lib/src/turnsmm/turn-order.cpp index 8e1914d..8ff7210 100644 --- a/lib/src/turnsmm/turn-order.cpp +++ b/lib/src/turnsmm/turn-order.cpp @@ -11,6 +11,8 @@ #include <glibmm/refptr.h> #include <glibmm/wrap.h> +#include <giomm/listmodel.h> + #include <glib-object.h> #include <bit> @@ -45,6 +47,16 @@ namespace Turns return new TurnOrder(TURNS_TURN_ORDER(object)); } + auto TurnOrder::get_base_type() -> GType + { + return turns_turn_order_get_type(); + } + + auto TurnOrder::get_type() -> GType + { + return _class.init().get_type(); + } + TurnOrder::TurnOrder() : Glib::ObjectBase{nullptr} , Glib::Object{Glib::ConstructParams{_class.init()}} diff --git a/lib/src/turnsmm/turn-order.hpp b/lib/src/turnsmm/turn-order.hpp index 25fc0b5..2dfa2ca 100644 --- a/lib/src/turnsmm/turn-order.hpp +++ b/lib/src/turnsmm/turn-order.hpp @@ -8,12 +8,16 @@ #include <glibmm/refptr.h> #include <glibmm/ustring.h> +#include <giomm/listmodel.h> +#include <glib-object.h> + #include <cstddef> namespace Turns { - class TurnOrder final : public Glib::Object + class TurnOrder final : public Glib::Object, + public Gio::ListModel { public: using BaseClassType = TurnsTurnOrderClass; @@ -21,6 +25,9 @@ namespace Turns using CppClassType = class TurnOrder_Class; using CppObjectType = TurnOrder; + auto static get_base_type() -> GType; + auto static get_type() -> GType; + TurnOrder(); [[nodiscard]] auto gobj() noexcept -> BaseObjectType *; diff --git a/lib/tests/turns-turn-order.cpp b/lib/tests/turns-turn-order.cpp index f204847..e0ee431 100644 --- a/lib/tests/turns-turn-order.cpp +++ b/lib/tests/turns-turn-order.cpp @@ -1,7 +1,10 @@ #include "turns-turn-order.h" +#include "turns-participant.h" + #include <catch2/catch_test_macros.hpp> +#include <gio/gio.h> #include <glib-object.h> SCENARIO("Creating a turn order", "[lib][object][lifetime]") @@ -29,5 +32,21 @@ SCENARIO("Creating a turn order", "[lib][object][lifetime]") REQUIRE_FALSE(property_value); } + + THEN("it's item count is 0") + { + REQUIRE(g_list_model_get_n_items(G_LIST_MODEL(instance)) == 0); + } + + THEN("it's 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") + { + REQUIRE(g_list_model_get_item(G_LIST_MODEL(instance), 0) == nullptr); + REQUIRE(g_list_model_get_object(G_LIST_MODEL(instance), 0) == nullptr); + } } }
\ No newline at end of file diff --git a/lib/tests/turnsmm/turn-order.cpp b/lib/tests/turnsmm/turn-order.cpp index ad8306b..ed9d586 100644 --- a/lib/tests/turnsmm/turn-order.cpp +++ b/lib/tests/turnsmm/turn-order.cpp @@ -1,5 +1,7 @@ #include "turnsmm/turn-order.hpp" +#include "turnsmm/participant.hpp" + #include <catch2/catch_test_macros.hpp> #include <cstddef> @@ -21,5 +23,21 @@ SCENARIO("Creating a turn order", "[lib][object][lifetime]") REQUIRE_FALSE(instance.get_running()); REQUIRE_FALSE(instance.get_property<std::size_t>("running")); } + + THEN("it's item count is 0") + { + REQUIRE(instance.get_n_items() == 0); + } + + THEN("it's item type is Turns.Participant") + { + REQUIRE(instance.get_item_type() == Turns::Participant::get_type()); + } + + THEN("it's first item is NULL") + { + REQUIRE(instance.get_object(0) == nullptr); + REQUIRE(instance.get_typed_object<Turns::Participant>(0) == nullptr); + } } }
\ No newline at end of file |
