File: basic-signals.c

package info (click to toggle)
glib2.0 2.84.1-2
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 66,144 kB
  • sloc: ansic: 538,877; python: 9,624; sh: 1,572; xml: 1,482; perl: 1,222; cpp: 535; makefile: 316; javascript: 11
file content (139 lines) | stat: -rw-r--r-- 4,036 bytes parent folder | download | duplicates (12)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* GObject - GLib Type, Object, Parameter and Signal Library
 * Copyright (C) 2013 Red Hat, Inc.
 * Copy and pasted from accumulator.c and modified.
 *
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include <glib-object.h>

#include "testcommon.h"

/* What this test tests is the behavior of signal disconnection
 * from within a signal handler for the signal being disconnected.
 *
 * The test demonstrates that signal handlers disconnected from a signal
 * from an earlier handler in the same emission will not be run.
 *
 * It also demonstrates that signal handlers connected from a signal
 * from an earlier handler in the same emission will not be run.
 */

/* TestObject, a parent class for TestObject */
#define TEST_TYPE_OBJECT         (test_object_get_type ())
typedef struct _TestObject        TestObject;
typedef struct _TestObjectClass   TestObjectClass;

static gboolean callback1_ran = FALSE, callback2_ran = FALSE,
  callback3_ran = FALSE, default_handler_ran = FALSE;

struct _TestObject
{
  GObject parent_instance;
};

struct _TestObjectClass
{
  GObjectClass parent_class;

  void   (*test_signal) (TestObject *object);
};

static GType test_object_get_type (void);

static void
test_object_real_signal (TestObject *object)
{
  default_handler_ran = TRUE;
}

static void
test_object_signal_callback3 (TestObject *object,
                              gpointer    data)
{
  callback3_ran = TRUE;
}

static void
test_object_signal_callback2 (TestObject *object,
                              gpointer    data)
{
  callback2_ran = TRUE;
}

static void
test_object_signal_callback1 (TestObject *object,
                              gpointer    data)
{
  callback1_ran = TRUE;
  g_signal_handlers_disconnect_by_func (G_OBJECT (object),
                                        test_object_signal_callback2,
                                        data);
  g_signal_connect (object, "test-signal",
                    G_CALLBACK (test_object_signal_callback3), NULL);
}

static void
test_object_class_init (TestObjectClass *class)
{
  class->test_signal = test_object_real_signal;

  g_signal_new ("test-signal",
                G_OBJECT_CLASS_TYPE (class),
                G_SIGNAL_RUN_LAST,
                G_STRUCT_OFFSET (TestObjectClass, test_signal),
                NULL, NULL, NULL, G_TYPE_NONE, 0);
}

static DEFINE_TYPE(TestObject, test_object,
                   test_object_class_init, NULL, NULL,
                   G_TYPE_OBJECT)

static void
test_basic_signals (void)
{
  TestObject *object;

  object = g_object_new (TEST_TYPE_OBJECT, NULL);

  g_signal_connect (object, "test-signal",
                    G_CALLBACK (test_object_signal_callback1), NULL);
  g_signal_connect (object, "test-signal",
                    G_CALLBACK (test_object_signal_callback2), NULL);
  g_signal_emit_by_name (object, "test-signal");

  g_assert_true (callback1_ran);
  g_assert_false (callback2_ran);
  g_assert_false (callback3_ran);
  g_assert_true (default_handler_ran);

  g_object_unref (object);
}

int
main (int  argc,
      char *argv[])
{
  g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) |
                          G_LOG_LEVEL_WARNING |
                          G_LOG_LEVEL_CRITICAL);

  g_test_init (&argc, &argv, NULL);

  g_test_add_func ("/gobject/basic-signals", test_basic_signals);

  return g_test_run ();
}