1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Inkscape::Debug::EventTracker - semi-automatically track event lifetimes
4  *
5  * Authors:
6  *   MenTaLguY <mental@rydia.net>
7  *
8  * Copyright (C) 2005 MenTaLguY
9  *
10  * Released under GNU GPL v2+, read the file 'COPYING' for more information.
11  */
12 
13 #ifndef SEEN_INKSCAPE_DEBUG_EVENT_TRACKER_H
14 #define SEEN_INKSCAPE_DEBUG_EVENT_TRACKER_H
15 
16 #include "debug/logger.h"
17 
18 namespace Inkscape {
19 
20 namespace Debug {
21 
22 #ifdef NDEBUG
23 // Make event tracking a no-op for non-debug builds
24 template <typename = void> struct EventTracker {
EventTrackerEventTracker25     template <typename... Args> EventTracker(Args &&...) {}
setEventTracker26     template <typename, typename... Args> void set(Args &&...) {}
clearEventTracker27     void clear() {}
28 };
29 #else
30 
31 struct NoInitialEvent {};
32 
33 template <typename Event=NoInitialEvent> class EventTracker;
34 
35 class EventTrackerBase {
36 public:
37     virtual ~EventTrackerBase() {
38         if (_active) {
39             Logger::finish();
40         }
41     }
42 
43     template <typename EventType>
44     inline void set() {
45         if (_active) {
46             Logger::finish();
47         }
48         Logger::start<EventType>();
49         _active = true;
50     }
51 
52     template <typename EventType, typename A>
53     inline void set(A const &a) {
54         if (_active) {
55             Logger::finish();
56         }
57         Logger::start<EventType>(a);
58         _active = true;
59     }
60 
61     template <typename EventType, typename A, typename B>
62     inline void set(A const &a, B const &b) {
63         if (_active) {
64             Logger::finish();
65         }
66         Logger::start<EventType>(a, b);
67         _active = true;
68     }
69 
70     template <typename EventType, typename A, typename B, typename C>
71     inline void set(A const &a, B const &b, C const &c) {
72         if (_active) {
73             Logger::finish();
74         }
75         Logger::start<EventType>(a, b, c);
76         _active = true;
77     }
78 
79     template <typename EventType, typename A, typename B,
80                                   typename C, typename D>
81     inline void set(A const &a, B const &b, C const &c, D const &d) {
82         if (_active) {
83             Logger::finish();
84         }
85         Logger::start<EventType>(a, b, c, d);
86         _active = true;
87     }
88 
89     template <typename EventType, typename A, typename B, typename C,
90                                   typename D, typename E>
91     inline void set(A const &a, B const &b, C const &c, D const &d, E const &e)
92     {
93         if (_active) {
94             Logger::finish();
95         }
96         Logger::start<EventType>(a, b, c, d, e);
97         _active = true;
98     }
99 
100     template <typename EventType, typename A, typename B, typename C,
101                                   typename D, typename E, typename F>
102     inline void set(A const &a, B const &b, C const &c,
103                     D const &d, E const &e, F const &f)
104     {
105         if (_active) {
106             Logger::finish();
107         }
108         Logger::start<EventType>(a, b, c, d, e, f);
109         _active = true;
110     }
111 
112     template <typename EventType, typename A, typename B, typename C,
113                                   typename D, typename E, typename F,
114                                   typename G>
115     inline void set(A const &a, B const &b, C const &c, D const &d,
116                     E const &e, F const &f, G const &g)
117     {
118         if (_active) {
119             Logger::finish();
120         }
121         Logger::start<EventType>(a, b, c, d, e, f, g);
122         _active = true;
123     }
124 
125     template <typename EventType, typename A, typename B, typename C,
126                                   typename D, typename E, typename F,
127                                   typename G, typename H>
128     inline void set(A const &a, B const &b, C const &c, D const &d,
129                     E const &e, F const &f, G const &g, H const &h)
130     {
131         if (_active) {
132             Logger::finish();
133         }
134         Logger::start<EventType>(a, b, c, d, e, f, g, h);
135         _active = true;
136     }
137 
138     void clear() {
139         if (_active) {
140             Logger::finish();
141             _active = false;
142         }
143     }
144 
145 protected:
146     EventTrackerBase(bool active) : _active(active) {}
147 
148 private:
149     EventTrackerBase(EventTrackerBase const &) = delete; // no copy
150     void operator=(EventTrackerBase const &) = delete; // no assign
151     bool _active;
152 };
153 
154 template <typename EventType> class EventTracker : public EventTrackerBase {
155 public:
156     EventTracker() : EventTrackerBase(true) { Logger::start<EventType>(); }
157 
158     template <typename A>
159     EventTracker(A const &a) : EventTrackerBase(true) {
160         Logger::start<EventType>(a);
161     }
162 
163     template <typename A, typename B>
164     EventTracker(A const &a, B const &b) : EventTrackerBase(true) {
165         Logger::start<EventType>(a, b);
166     }
167 
168     template <typename A, typename B, typename C>
169     EventTracker(A const &a, B const &b, C const &c) : EventTrackerBase(true) {
170         Logger::start<EventType>(a, b, c);
171     }
172 
173     template <typename A, typename B, typename C, typename D>
174     EventTracker(A const &a, B const &b, C const &c, D const &d)
175     : EventTrackerBase(true)
176     {
177         Logger::start<EventType>(a, b, c, d);
178     }
179 
180     template <typename A, typename B, typename C, typename D, typename E>
181     EventTracker(A const &a, B const &b, C const &c, D const &d, E const &e)
182     : EventTrackerBase(true)
183     {
184         Logger::start<EventType>(a, b, c, d, e);
185     }
186 
187     template <typename A, typename B, typename C, typename D,
188               typename E, typename F>
189     EventTracker(A const &a, B const &b, C const &c, D const &d,
190                  E const &e, F const &f)
191     : EventTrackerBase(true)
192     {
193         Logger::start<EventType>(a, b, c, d, e, f);
194     }
195 
196     template <typename A, typename B, typename C, typename D,
197               typename E, typename F, typename G>
198     EventTracker(A const &a, B const &b, C const &c, D const &d,
199                  E const &e, F const &f, G const &g)
200     : EventTrackerBase(true)
201     {
202         Logger::start<EventType>(a, b, c, d, e, f, g);
203     }
204 
205     template <typename A, typename B, typename C, typename D,
206               typename E, typename F, typename G, typename H>
207     EventTracker(A const &a, B const &b, C const &c, D const &d,
208                  E const &e, F const &f, G const &g, H const &h)
209     : EventTrackerBase(true)
210     {
211         Logger::start<EventType>(a, b, c, d, e, f, g, h);
212     }
213 };
214 
215 template <> class EventTracker<NoInitialEvent> : public EventTrackerBase {
216 public:
217     EventTracker() : EventTrackerBase(false) {}
218 };
219 
220 #endif
221 
222 }
223 
224 }
225 
226 #endif
227 /*
228   Local Variables:
229   mode:c++
230   c-file-style:"stroustrup"
231   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
232   indent-tabs-mode:nil
233   fill-column:99
234   End:
235 */
236 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
237