Branch data Line data Source code
1 : : /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2 : : *
3 : : * Copyright 2025 GNOME Foundation, Inc.
4 : : *
5 : : * SPDX-License-Identifier: LGPL-2.1-or-later
6 : : *
7 : : * This library is free software; you can redistribute it and/or
8 : : * modify it under the terms of the GNU Lesser General Public
9 : : * License as published by the Free Software Foundation; either
10 : : * version 2.1 of the License, or (at your option) any later version.
11 : : *
12 : : * This library is distributed in the hope that it will be useful,
13 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : : * Lesser General Public License for more details.
16 : : *
17 : : * You should have received a copy of the GNU Lesser General Public
18 : : * License along with this library; if not, write to the Free Software
19 : : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 : : *
21 : : * Authors:
22 : : * - Philip Withnall <pwithnall@gnome.org>
23 : : */
24 : :
25 : : #pragma once
26 : :
27 : : #include <glib.h>
28 : : #include <glib-object.h>
29 : :
30 : : G_BEGIN_DECLS
31 : :
32 : : /**
33 : : * MctOperationCounter:
34 : : *
35 : : * Helper struct used to increment a counter when it’s created and decrement
36 : : * when it’s destroyed.
37 : : *
38 : : * This helps tie a counter to the lifecycles of the operations being counted by
39 : : * it. It is designed to be used inline within another struct.
40 : : *
41 : : * Since: 0.14.0
42 : : */
43 : : typedef struct
44 : : {
45 : : /*< private >*/
46 : : unsigned int *counter; /* (not nullable) */
47 : : GObject *object; /* (owned) (nullable) */
48 : : GParamSpec *pspec; /* (not owned) (nullable) */
49 : : } MctOperationCounter;
50 : :
51 : : /**
52 : : * mct_operation_counter_init_and_hold:
53 : : * @self: an operation counter struct, already allocated within another struct
54 : : * @counter: (inout): counter variable to increment
55 : : * @object: (transfer none) (nullable): object to notify when counter changes
56 : : * @pspec: (transfer none) (nullable): param spec within @object to notify when
57 : : * counter changes
58 : : *
59 : : * Inits the [struct@Mct.OperationCounter] and increments @counter.
60 : : *
61 : : * If @object and @pspec are provided, `g_object_notify_by_pspec()` will be
62 : : * called on them to notify of the change in value to @counter.
63 : : *
64 : : * Since: 0.14.0
65 : : */
66 : : static inline void
67 : 0 : mct_operation_counter_init_and_hold (MctOperationCounter *self,
68 : : unsigned int *counter,
69 : : GObject *object,
70 : : GParamSpec *pspec)
71 : : {
72 : 0 : self->counter = counter;
73 [ # # # # ]: 0 : self->object = (object != NULL && pspec != NULL) ? g_object_ref (object) : NULL;
74 [ # # # # ]: 0 : self->pspec = (object != NULL && pspec != NULL) ? pspec : NULL;
75 : :
76 : 0 : g_assert (*(self->counter) < UINT_MAX);
77 : 0 : *(self->counter) = *(self->counter) + 1;
78 [ # # ]: 0 : if (self->object != NULL)
79 : 0 : g_object_notify_by_pspec (self->object, self->pspec);
80 : 0 : }
81 : :
82 : : /**
83 : : * mct_operation_counter_init_and_hold:
84 : : * @self: an operation counter struct, already allocated within another struct
85 : : *
86 : : * Decrements the counter and clears the [struct@Mct.OperationCounter].
87 : : *
88 : : * The counter variable is the one provided when @self was initialised.
89 : : *
90 : : * If @object and @pspec were provided when @self was initialised,
91 : : * `g_object_notify_by_pspec()` will be called on them to notify of the change
92 : : * in value to @counter.
93 : : *
94 : : * Since: 0.14.0
95 : : */
96 : : static inline void
97 : 0 : mct_operation_counter_release_and_clear (MctOperationCounter *self)
98 : : {
99 : 0 : g_assert (*(self->counter) > 0);
100 : 0 : *(self->counter) = *(self->counter) - 1;
101 [ # # ]: 0 : if (self->object != NULL)
102 : 0 : g_object_notify_by_pspec (self->object, self->pspec);
103 : :
104 [ # # ]: 0 : g_clear_object (&self->object);
105 : 0 : self->pspec = NULL;
106 : 0 : self->counter = NULL;
107 : 0 : }
108 : :
109 : : G_END_DECLS
|