#include "turns-turn-order.h" #include "turns-participant.h" #include #include #include #include #include #include G_BEGIN_DECLS struct _TurnsTurnOrder { GObject parent_instance; GSList * participants; gboolean running; }; 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 namespace { enum struct property { Running = 1, N_PROPERTIES, }; 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); g_slist_free_full(instance->participants, g_object_unref); G_OBJECT_CLASS(turns_turn_order_parent_class)->finalize(self); } auto get_property(GObject * self, guint id, GValue * value, GParamSpec * specification) -> void { auto instance = TURNS_TURN_ORDER(self); switch (static_cast(id)) { case property::Running: return g_value_set_boolean(value, turns_turn_order_get_running(instance)); default: G_OBJECT_WARN_INVALID_PROPERTY_ID(self, id, specification); } } } // namespace G_BEGIN_DECLS static void turns_turn_order_class_init(TurnsTurnOrderClass * klass) { auto object_class = G_OBJECT_CLASS(klass); object_class->finalize = finalize; object_class->get_property = get_property; properties[static_cast(property::Running)] = g_param_spec_boolean("running", "Running", "Whether or not the turn order is running (e.g. has been started)", false, static_cast(G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY)); g_object_class_install_properties(object_class, properties.size(), properties.data()); } static void turns_turn_order_init(TurnsTurnOrder * self) { self->participants = nullptr; self->running = false; } 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_object_ref(g_slist_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(self); return TURNS_TYPE_PARTICIPANT; } static void turns_turn_order_list_model_init(GListModelInterface * iface) { iface->get_item = std::bit_castget_item)>(&turns_turn_order_list_model_get_item); iface->get_item_type = std::bit_castget_item_type)>(&turns_turn_order_list_model_get_item_type); iface->get_n_items = std::bit_castget_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)); } 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); return g_slist_length(self->participants); } gboolean turns_turn_order_get_running(TurnsTurnOrder const * self) { g_return_val_if_fail(TURNS_IS_TURN_ORDER(const_cast(self)), false); return self->running; } G_END_DECLS