File: debug_manager.h

package info (click to toggle)
scummvm 2.9.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 450,580 kB
  • sloc: cpp: 4,299,825; asm: 28,322; python: 12,901; sh: 11,302; java: 9,289; xml: 7,895; perl: 2,639; ansic: 2,465; yacc: 1,670; javascript: 1,020; makefile: 933; lex: 578; awk: 275; objc: 82; sed: 11; php: 1
file content (168 lines) | stat: -rw-r--r-- 6,508 bytes parent folder | download | duplicates (2)
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

//=============================================================================
//
// AGS logging system is built with idea that the engine components should not
// be bothered with specifying particular output method. Instead they use
// generic logging interface, and the actual message printing is done by one
// or more registered handlers.
// Firstly this makes logging functions independent of running platform or
// back-end, secondly it grants end-users ability to configure output according
// to their preference.
//
// To make the logging work we need to register two sets of "entities":
// debug groups and output targets.
// Debug group is an arbitrary object with a name that describes message
// sender.
// Output target defines printing handler and a set of verbosity rules
// one per each known group.
//
// When the message is sent, it is tagged with one of the existing group IDs
// and a message type (debug info, warning, error). This message is sent onto
// each of the registered output targets, which do checks to find out whether
// the message is permitted to be sent further to the printing handler, or not.
//
//=============================================================================

#ifndef AGS_SHARED_DEBUGGING_DEBUG_MANAGER_H
#define AGS_SHARED_DEBUGGING_DEBUG_MANAGER_H

#include "common/std/memory.h"
#include "common/std/map.h"
#include "ags/shared/debugging/out.h"
#include "ags/shared/debugging/output_handler.h"
#include "ags/shared/util/string.h"
#include "ags/shared/util/string_types.h"

namespace AGS3 {
namespace AGS {
namespace Shared {

// DebugGroup is a message sender definition, identified by DebugGroupID
// and providing OutputName that could be used when printing its messages.
// OutputName may or may not be same as DebugGroupID.SID.
struct DebugGroup {
	DebugGroupID    UID;
	String          OutputName;

	DebugGroup() {
	}
	DebugGroup(DebugGroupID id, String out_name) : UID(id), OutputName(out_name) {
	}
};

// DebugOutput is a slot for IOutputHandler with its own group filter
class DebugOutput {
public:
	DebugOutput(const String &id, IOutputHandler *handler, MessageType def_verbosity = kDbgMsg_All, bool enabled = true);

	String          GetID() const;
	IOutputHandler *GetHandler() const;

	bool            IsEnabled() const;
	void            SetEnabled(bool enable);
	// Setup group filter: either allow or disallow a group with the given ID
	void            SetGroupFilter(DebugGroupID id, MessageType verbosity);
	// Assign same verbosity level to all known groups
	void            SetAllGroupFilters(MessageType verbosity);
	// Clear all group filters; this efficiently disables everything
	void            ClearGroupFilters();
	// Try to resolve group filter unknown IDs
	void            ResolveGroupID(DebugGroupID id);
	// Test if given group id is permitted
	bool            TestGroup(DebugGroupID id, MessageType mt) const;

private:
	String          _id;
	IOutputHandler *_handler;
	bool            _enabled;
	MessageType     _defaultVerbosity;
	// Set of permitted groups' numeric IDs
	std::vector<MessageType> _groupFilter;
	// Set of unresolved groups, which numeric IDs are not yet known
	typedef std::unordered_map<String, MessageType, IgnoreCase_Hash, IgnoreCase_EqualTo> GroupNameToMTMap;
	GroupNameToMTMap _unresolvedGroups;
};

typedef std::shared_ptr<DebugOutput> PDebugOutput;


class DebugManager {
	friend class DebugOutput;

public:
	DebugManager();

	// Gets full group ID for any partial one; if the group is not registered returns unset ID
	DebugGroup   GetGroup(DebugGroupID id);
	// Gets output control interface for the given ID
	PDebugOutput GetOutput(const String &id);
	// Registers debugging group with the given string ID; numeric ID
	// will be assigned internally. Returns full ID pair.
	// If the group with such string id already exists, returns existing ID.
	DebugGroup RegisterGroup(const String &id, const String &out_name);
	// Registers output delegate for passing debug messages to;
	// if the output with such id already exists, replaces the old one
	PDebugOutput RegisterOutput(const String &id, IOutputHandler *handler, MessageType def_verbosity = kDbgMsg_All, bool enabled = true);
	// Unregisters all groups and all targets
	void UnregisterAll();
	// Unregisters debugging group with the given ID
	void UnregisterGroup(DebugGroupID id);
	// Unregisters output delegate with the given ID
	void UnregisterOutput(const String &id);

	// Output message of given group and message type
	void Print(DebugGroupID group_id, MessageType mt, const String &text);
	// Send message directly to the output with given id; the message
	// must pass the output's message filter though
	void SendMessage(const String &out_id, const DebugMessage &msg);

private:
	// OutputSlot struct wraps over output target and adds a flag which indicates
	// that this target is temporarily disabled (for internal use only)
	struct OutputSlot {
		PDebugOutput Target;
		bool          Suppressed;

		OutputSlot() : Suppressed(false) {
		}
	};

	typedef std::vector<DebugGroup> GroupVector;
	typedef std::unordered_map<String, DebugGroupID, IgnoreCase_Hash, IgnoreCase_EqualTo> GroupByStringMap;
	typedef std::unordered_map<String, OutputSlot, IgnoreCase_Hash, IgnoreCase_EqualTo> OutMap;

	void RegisterGroup(const DebugGroup &id);
	void SendMessage(OutputSlot &out, const DebugMessage &msg);

	uint32_t            _firstFreeGroupID;
	uint32_t            _lastGroupID;
	GroupVector         _groups;
	GroupByStringMap    _groupByStrLookup;
	OutMap              _outputs;
};

} // namespace Shared
} // namespace AGS
} // namespace AGS3

#endif