Skip to content

Commit 7b36e32

Browse files
authored
Feat: Logging without store (#500)
* feat: decouple ModLoaderLog from ModLoaderStore * feat: decouple ModLoaderLog from ModLoaderStore
1 parent fa50dab commit 7b36e32

File tree

3 files changed

+114
-91
lines changed

3 files changed

+114
-91
lines changed

addons/mod_loader/api/deprecated.gd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,6 @@ static func deprecated_message(msg: String, since_version: String = "") -> void:
6767
## - [code]void[/code]
6868
static func _deprecated_log(msg: String) -> void:
6969
if ModLoaderStore and ModLoaderStore.ml_options.ignore_deprecated_errors or OS.has_feature("standalone"):
70-
ModLoaderLog.warning(msg, LOG_NAME)
70+
ModLoaderLog.warning(msg, LOG_NAME, true)
7171
else:
72-
ModLoaderLog.fatal(msg, LOG_NAME)
72+
ModLoaderLog.fatal(msg, LOG_NAME, true)

addons/mod_loader/api/log.gd

Lines changed: 88 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
@tool
12
class_name ModLoaderLog
23
extends Object
34
##
@@ -7,15 +8,41 @@ extends Object
78
# Path to the latest log file.
89
const MOD_LOG_PATH := "user://logs/modloader.log"
910

10-
const LOG_NAME := "ModLoader:Log"
11+
const _LOG_NAME := "ModLoader:Log"
1112

13+
## Denotes the severity of a log entry
1214
enum VERBOSITY_LEVEL {
13-
ERROR,
14-
WARNING,
15-
INFO,
16-
DEBUG,
15+
ERROR, ## For errors and fatal errors
16+
WARNING, ## For warnings
17+
INFO, ## For everything informational and successes
18+
DEBUG, ## For debugging, can get quite verbose
1719
}
1820

21+
## Keeps track of logged messages, to avoid flooding the log with duplicate notices
22+
## Can also be used by mods, eg. to create an in-game developer console that
23+
## shows messages
24+
static var logged_messages := {
25+
"all": {},
26+
"by_mod": {},
27+
"by_type": {
28+
"fatal-error": {},
29+
"error": {},
30+
"warning": {},
31+
"info": {},
32+
"success": {},
33+
"debug": {},
34+
}
35+
}
36+
37+
## Verbosity/Logging level.
38+
## Used to filter out messages below the set level
39+
## (if the [enum VERBOSITY_LEVEL] int of a new entry is larger than the [member verbosity] it is ignored)
40+
static var verbosity: VERBOSITY_LEVEL = VERBOSITY_LEVEL.DEBUG
41+
42+
## Array of mods that should be ignored when logging messages (contains mod IDs as strings)
43+
static var ignored_mods: Array[String] = []
44+
45+
1946
## This Sub-Class represents a log entry in ModLoader.
2047
class ModLoaderLogEntry:
2148
extends Resource
@@ -45,10 +72,10 @@ class ModLoaderLogEntry:
4572
## Initialize a ModLoaderLogEntry object with provided values.[br]
4673
##[br]
4774
## [b]Parameters:[/b][br]
48-
## - [code]_mod_name[/code] ([String]): Name of the mod or ModLoader class this entry refers to.[br]
49-
## - [code]_message[/code] ([String]): The message of the log entry.[br]
50-
## - [code]_type[/code] ([String]): The log type, which indicates the verbosity level of this entry.[br]
51-
## - [code]_time[/code] ([String]): The readable format of the time when this log entry was created.[br]
75+
## [param _mod_name] ([String]): Name of the mod or ModLoader class this entry refers to.[br]
76+
## [param _message] ([String]): The message of the log entry.[br]
77+
## [param _type] ([String]): The log type, which indicates the verbosity level of this entry.[br]
78+
## [param _time] ([String]): The readable format of the time when this log entry was created.[br]
5279
##[br]
5380
## [b]Returns:[/b] [code]void[/code]
5481
func _init(_mod_name: String, _message: String, _type: String, _time: String) -> void:
@@ -99,9 +126,9 @@ class ModLoaderLogEntry:
99126
## [i]Note: Stops the execution in editor[/i][br]
100127
## [br]
101128
## [b]Parameters:[/b][br]
102-
## - [code]message[/code] ([String]): The message to be logged as an error.[br]
103-
## - [code]mod_name[/code] ([String]): The name of the mod or ModLoader class associated with this log entry.[br]
104-
## - [code]only_once[/code] ([bool]): (Optional) If true, the log entry will only be logged once, even if called multiple times. Default is false.[br]
129+
## [param message] ([String]): The message to be logged as an error.[br]
130+
## [param mod_name] ([String]): The name of the mod or ModLoader class associated with this log entry.[br]
131+
## [param only_once] ([bool]): (Optional) If true, the log entry will only be logged once, even if called multiple times. Default is false.[br]
105132
## [br]
106133
## [b]Returns:[/b] [code]void[/code]
107134
static func fatal(message: String, mod_name: String, only_once := false) -> void:
@@ -113,9 +140,9 @@ static func fatal(message: String, mod_name: String, only_once := false) -> void
113140
## [i]Note: Always logged[/i][br]
114141
## [br]
115142
## [b]Parameters:[/b][br]
116-
## - [code]message[/code] ([String]): The message to be logged as an error.[br]
117-
## - [code]mod_name[/code] ([String]): The name of the mod or ModLoader class associated with this log entry.[br]
118-
## - [code]only_once[/code] ([bool]): (Optional) If true, the log entry will only be logged once, even if called multiple times. Default is false.[br]
143+
## [param message] ([String]): The message to be logged as an error.[br]
144+
## [param mod_name] ([String]): The name of the mod or ModLoader class associated with this log entry.[br]
145+
## [param only_once] ([bool]): (Optional) If true, the log entry will only be logged once, even if called multiple times. Default is false.[br]
119146
## [br]
120147
## [b]Returns:[/b] [code]void[/code]
121148
static func error(message: String, mod_name: String, only_once := false) -> void:
@@ -127,9 +154,9 @@ static func error(message: String, mod_name: String, only_once := false) -> void
127154
## [i]Note: Logged with verbosity level at or above warning (-v).[/i][br]
128155
## [br]
129156
## [b]Parameters:[/b][br]
130-
## - [code]message[/code] ([String]): The message to be logged as a warning.[br]
131-
## - [code]mod_name[/code] ([String]): The name of the mod or ModLoader class associated with this log entry.[br]
132-
## - [code]only_once[/code] ([bool]): (Optional) If true, the log entry will only be logged once, even if called multiple times. Default is false.[br]
157+
## [param message] ([String]): The message to be logged as a warning.[br]
158+
## [param mod_name] ([String]): The name of the mod or ModLoader class associated with this log entry.[br]
159+
## [param only_once] ([bool]): (Optional) If true, the log entry will only be logged once, even if called multiple times. Default is false.[br]
133160
## [br]
134161
## [b]Returns:[/b] [code]void[/code]
135162
static func warning(message: String, mod_name: String, only_once := false) -> void:
@@ -141,9 +168,9 @@ static func warning(message: String, mod_name: String, only_once := false) -> vo
141168
## [i]Note: Logged with verbosity level at or above info (-vv).[/i][br]
142169
## [br]
143170
## [b]Parameters:[/b][br]
144-
## - [code]message[/code] ([String]): The message to be logged as an information.[br]
145-
## - [code]mod_name[/code] ([String]): The name of the mod or ModLoader class associated with this log entry.[br]
146-
## - [code]only_once[/code] ([bool]): (Optional) If true, the log entry will only be logged once, even if called multiple times. Default is false.[br]
171+
## [param message] ([String]): The message to be logged as an information.[br]
172+
## [param mod_name] ([String]): The name of the mod or ModLoader class associated with this log entry.[br]
173+
## [param only_once] ([bool]): (Optional) If true, the log entry will only be logged once, even if called multiple times. Default is false.[br]
147174
## [br]
148175
## [b]Returns:[/b] [code]void[/code]
149176
static func info(message: String, mod_name: String, only_once := false) -> void:
@@ -155,9 +182,9 @@ static func info(message: String, mod_name: String, only_once := false) -> void:
155182
## [i]Note: Logged with verbosity level at or above info (-vv).[/i][br]
156183
## [br]
157184
## [b]Parameters:[/b][br]
158-
## - [code]message[/code] ([String]): The message to be logged as a success.[br]
159-
## - [code]mod_name[/code] ([String]): The name of the mod or ModLoader class associated with this log entry.[br]
160-
## - [code]only_once[/code] ([bool]): (Optional) If true, the log entry will only be logged once, even if called multiple times. Default is false.[br]
185+
## [param message] ([String]): The message to be logged as a success.[br]
186+
## [param mod_name] ([String]): The name of the mod or ModLoader class associated with this log entry.[br]
187+
## [param only_once] ([bool]): (Optional) If true, the log entry will only be logged once, even if called multiple times. Default is false.[br]
161188
## [br]
162189
## [b]Returns:[/b] [code]void[/code]
163190
static func success(message: String, mod_name: String, only_once := false) -> void:
@@ -169,9 +196,9 @@ static func success(message: String, mod_name: String, only_once := false) -> vo
169196
## [i]Note: Logged with verbosity level at or above debug (-vvv).[/i][br]
170197
## [br]
171198
## [b]Parameters:[/b][br]
172-
## - [code]message[/code] ([String]): The message to be logged as a debug.[br]
173-
## - [code]mod_name[/code] ([String]): The name of the mod or ModLoader class associated with this log entry.[br]
174-
## - [code]only_once[/code] ([bool]): (Optional) If true, the log entry will only be logged once, even if called multiple times. Default is false.[br]
199+
## [param message] ([String]): The message to be logged as a debug.[br]
200+
## [param mod_name] ([String]): The name of the mod or ModLoader class associated with this log entry.[br]
201+
## [param only_once] ([bool]): (Optional) If true, the log entry will only be logged once, even if called multiple times. Default is false.[br]
175202
## [br]
176203
## [b]Returns:[/b] [code]void[/code]
177204
static func debug(message: String, mod_name: String, only_once := false) -> void:
@@ -183,10 +210,10 @@ static func debug(message: String, mod_name: String, only_once := false) -> void
183210
## [i]Note: Logged with verbosity level at or above debug (-vvv).[/i] [br]
184211
## [br]
185212
## [b]Parameters:[/b][br]
186-
## - [code]message[/code] ([String]): The message to be logged as a debug.[br]
187-
## - [code]json_printable[/code] (Variant): The variable to be formatted and printed using [method JSON.print].[br]
188-
## - [code]mod_name[/code] ([String]): The name of the mod or ModLoader class associated with this log entry.[br]
189-
## - [code]only_once[/code] ([bool]): (Optional) If true, the log entry will only be logged once, even if called multiple times. Default is false.[br]
213+
## [param message] ([String]): The message to be logged as a debug.[br]
214+
## [param json_printable] (Variant): The variable to be formatted and printed using [method JSON.print].[br]
215+
## [param mod_name] ([String]): The name of the mod or ModLoader class associated with this log entry.[br]
216+
## [param only_once] ([bool]): (Optional) If true, the log entry will only be logged once, even if called multiple times. Default is false.[br]
190217
##
191218
## [b]Returns:[/b] [code]void[/code]
192219
static func debug_json_print(message: String, json_printable, mod_name: String, only_once := false) -> void:
@@ -218,7 +245,7 @@ static func get_all_as_string() -> Array:
218245
## Returns an array of log entries as a resource for a specific mod_name.[br]
219246
## [br]
220247
## [b]Parameters:[/b][br]
221-
## - [code]mod_name[/code] ([String]): The name of the mod or ModLoader class associated with the log entries.[br]
248+
## [param mod_name] ([String]): The name of the mod or ModLoader class associated with the log entries.[br]
222249
## [br]
223250
## [b]Returns:[/b][br]
224251
## - [Array]: An array of log entries represented as resource for the specified [code]mod_name[/code].
@@ -229,7 +256,7 @@ static func get_by_mod_as_resource(mod_name: String) -> Array:
229256
## Returns an array of log entries as a string for a specific mod_name.[br]
230257
## [br]
231258
## [b]Parameters:[/b][br]
232-
## - [code]mod_name[/code] ([String]): The name of the mod or ModLoader class associated with the log entries.[br]
259+
## [param mod_name] ([String]): The name of the mod or ModLoader class associated with the log entries.[br]
233260
## [br]
234261
## [b]Returns:[/b][br]
235262
## - [Array]: An array of log entries represented as strings for the specified [code]mod_name[/code].
@@ -241,7 +268,7 @@ static func get_by_mod_as_string(mod_name: String) -> Array:
241268
## Returns an array of log entries as a resource for a specific type.[br]
242269
## [br]
243270
## [b]Parameters:[/b][br]
244-
## - [code]type[/code] ([String]): The log type associated with the log entries.[br]
271+
## [param type] ([String]): The log type associated with the log entries.[br]
245272
## [br]
246273
## [b]Returns:[/b][br]
247274
## - [Array]: An array of log entries represented as resource for the specified [code]type[/code].
@@ -252,7 +279,7 @@ static func get_by_type_as_resource(type: String) -> Array:
252279
## Returns an array of log entries as a string for a specific type.[br]
253280
## [br]
254281
## [b]Parameters:[/b][br]
255-
## - [code]type[/code] ([String]): The log type associated with the log entries.[br]
282+
## [param type] ([String]): The log type associated with the log entries.[br]
256283
## [br]
257284
## [b]Returns:[/b][br]
258285
## - [Array]: An array of log entries represented as strings for the specified [code]type[/code].
@@ -269,8 +296,8 @@ static func get_all() -> Array:
269296
var log_entries := []
270297

271298
# Get all log entries
272-
for entry_key in ModLoaderStore.logged_messages.all.keys():
273-
var entry: ModLoaderLogEntry = ModLoaderStore.logged_messages.all[entry_key]
299+
for entry_key in logged_messages.all.keys():
300+
var entry: ModLoaderLogEntry = logged_messages.all[entry_key]
274301
log_entries.append_array(entry.get_all_entries())
275302

276303
# Sort them by time
@@ -282,19 +309,19 @@ static func get_all() -> Array:
282309
## Returns an array of log entries for a specific mod_name.[br]
283310
## [br]
284311
## [b]Parameters:[/b][br]
285-
## - [code]mod_name[/code] ([String]): The name of the mod or ModLoader class associated with the log entries.[br]
312+
## [param mod_name] ([String]): The name of the mod or ModLoader class associated with the log entries.[br]
286313
## [br]
287314
## [b]Returns:[/b][br]
288315
## - [Array]: An array of log entries for the specified [code]mod_name[/code].
289316
static func get_by_mod(mod_name: String) -> Array:
290317
var log_entries := []
291318

292-
if not ModLoaderStore.logged_messages.by_mod.has(mod_name):
293-
error("\"%s\" not found in logged messages." % mod_name, LOG_NAME)
319+
if not logged_messages.by_mod.has(mod_name):
320+
error("\"%s\" not found in logged messages." % mod_name, _LOG_NAME)
294321
return []
295322

296-
for entry_key in ModLoaderStore.logged_messages.by_mod[mod_name].keys():
297-
var entry: ModLoaderLogEntry = ModLoaderStore.logged_messages.by_mod[mod_name][entry_key]
323+
for entry_key in logged_messages.by_mod[mod_name].keys():
324+
var entry: ModLoaderLogEntry = logged_messages.by_mod[mod_name][entry_key]
298325
log_entries.append_array(entry.get_all_entries())
299326

300327
return log_entries
@@ -303,15 +330,15 @@ static func get_by_mod(mod_name: String) -> Array:
303330
## Returns an array of log entries for a specific type.[br]
304331
## [br]
305332
## [b]Parameters:[/b][br]
306-
## - [code]type[/code] ([String]): The log type associated with the log entries.[br]
333+
## [param type] ([String]): The log type associated with the log entries.[br]
307334
## [br]
308335
## [b]Returns:[/b][br]
309336
## - [Array]: An array of log entries for the specified [code]type[/code].
310337
static func get_by_type(type: String) -> Array:
311338
var log_entries := []
312339

313-
for entry_key in ModLoaderStore.logged_messages.by_type[type].keys():
314-
var entry: ModLoaderLogEntry = ModLoaderStore.logged_messages.by_type[type][entry_key]
340+
for entry_key in logged_messages.by_type[type].keys():
341+
var entry: ModLoaderLogEntry = logged_messages.by_type[type][entry_key]
315342
log_entries.append_array(entry.get_all_entries())
316343

317344
return log_entries
@@ -320,7 +347,7 @@ static func get_by_type(type: String) -> Array:
320347
## Returns an array of log entries represented as strings.[br]
321348
## [br]
322349
## [b]Parameters:[/b][br]
323-
## - [code]log_entries[/code] ([Array]): An array of ModLoaderLogEntry Objects.[br]
350+
## [param log_entries] ([Array]): An array of ModLoaderLogEntry Objects.[br]
324351
## [br]
325352
## [b]Returns:[/b][br]
326353
## - [Array]: An array of log entries represented as strings.
@@ -349,8 +376,7 @@ static func _log(message: String, mod_name: String, log_type: String = "info", o
349376
if only_once and _is_logged_before(log_entry):
350377
return
351378

352-
if ModLoaderStore:
353-
_store_log(log_entry)
379+
_store_log(log_entry)
354380

355381
# Check if the scene_tree is available
356382
if Engine.get_main_loop() and ModLoader:
@@ -375,65 +401,56 @@ static func _log(message: String, mod_name: String, log_type: String = "info", o
375401
push_error(message)
376402
_write_to_log_file(log_entry.get_entry())
377403
"warning":
378-
if _get_verbosity() >= VERBOSITY_LEVEL.WARNING:
404+
if verbosity >= VERBOSITY_LEVEL.WARNING:
379405
print(log_entry.get_prefix() + message)
380406
push_warning(message)
381407
_write_to_log_file(log_entry.get_entry())
382408
"info", "success":
383-
if _get_verbosity() >= VERBOSITY_LEVEL.INFO:
409+
if verbosity >= VERBOSITY_LEVEL.INFO:
384410
print(log_entry.get_prefix() + message)
385411
_write_to_log_file(log_entry.get_entry())
386412
"debug":
387-
if _get_verbosity() >= VERBOSITY_LEVEL.DEBUG:
413+
if verbosity >= VERBOSITY_LEVEL.DEBUG:
388414
print(log_entry.get_prefix() + message)
389415
_write_to_log_file(log_entry.get_entry())
390416

391417

392418
static func _is_mod_name_ignored(mod_name: String) -> bool:
393-
if not ModLoaderStore:
419+
if ignored_mods.is_empty():
394420
return false
395421

396-
var ignored_mod_names := ModLoaderStore.ml_options.ignored_mod_names_in_log as Array
422+
if mod_name in ignored_mods:
423+
return true
397424

398-
if not ignored_mod_names.size() == 0:
399-
if mod_name in ignored_mod_names:
400-
return true
401425
return false
402426

403427

404-
static func _get_verbosity() -> int:
405-
if not ModLoaderStore:
406-
return VERBOSITY_LEVEL.DEBUG
407-
408-
return ModLoaderStore.ml_options.log_level
409-
410-
411428
static func _store_log(log_entry: ModLoaderLogEntry) -> void:
412429
var existing_entry: ModLoaderLogEntry
413430

414431
# Store in all
415432
# If it's a new entry
416-
if not ModLoaderStore.logged_messages.all.has(log_entry.get_md5()):
417-
ModLoaderStore.logged_messages.all[log_entry.get_md5()] = log_entry
433+
if not logged_messages.all.has(log_entry.get_md5()):
434+
logged_messages.all[log_entry.get_md5()] = log_entry
418435
# If it's a existing entry
419436
else:
420-
existing_entry = ModLoaderStore.logged_messages.all[log_entry.get_md5()]
437+
existing_entry = logged_messages.all[log_entry.get_md5()]
421438
existing_entry.time = log_entry.time
422439
existing_entry.stack.push_back(log_entry)
423440

424441
# Store in by_mod
425442
# If the mod is not yet in "by_mod" init the entry
426-
if not ModLoaderStore.logged_messages.by_mod.has(log_entry.mod_name):
427-
ModLoaderStore.logged_messages.by_mod[log_entry.mod_name] = {}
443+
if not logged_messages.by_mod.has(log_entry.mod_name):
444+
logged_messages.by_mod[log_entry.mod_name] = {}
428445

429-
ModLoaderStore.logged_messages.by_mod[log_entry.mod_name][log_entry.get_md5()] = log_entry if not existing_entry else existing_entry
446+
logged_messages.by_mod[log_entry.mod_name][log_entry.get_md5()] = log_entry if not existing_entry else existing_entry
430447

431448
# Store in by_type
432-
ModLoaderStore.logged_messages.by_type[log_entry.type.to_lower()][log_entry.get_md5()] = log_entry if not existing_entry else existing_entry
449+
logged_messages.by_type[log_entry.type.to_lower()][log_entry.get_md5()] = log_entry if not existing_entry else existing_entry
433450

434451

435452
static func _is_logged_before(entry: ModLoaderLogEntry) -> bool:
436-
if not ModLoaderStore.logged_messages.all.has(entry.get_md5()):
453+
if not logged_messages.all.has(entry.get_md5()):
437454
return false
438455

439456
return true

0 commit comments

Comments
 (0)