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