Add cleanup hooking system (closes #24)
This commit is contained in:
parent
0123618214
commit
15d78eb0d7
2 changed files with 74 additions and 3 deletions
|
@ -36,6 +36,11 @@ Used internally for loading, managing and unloading modules.
|
||||||
Do not modify this.
|
Do not modify this.
|
||||||
:::
|
:::
|
||||||
Stores the path to CORE's installation directory.
|
Stores the path to CORE's installation directory.
|
||||||
|
### *Dictionary* <u>cleanup_hooks</u> = *{}*
|
||||||
|
:::danger[Don't modify]
|
||||||
|
Do not modify this.
|
||||||
|
:::
|
||||||
|
Contains a list of all registered cleanup hooks.
|
||||||
### *Dictionary* <u>custom_modules</u> = *{}*
|
### *Dictionary* <u>custom_modules</u> = *{}*
|
||||||
### *void* <u>_ready</u>()
|
### *void* <u>_ready</u>()
|
||||||
:::danger[Don't modify]
|
:::danger[Don't modify]
|
||||||
|
@ -96,6 +101,13 @@ Applies the a configuration.
|
||||||
### *void* <u>cleanup</u>()
|
### *void* <u>cleanup</u>()
|
||||||
Makes sure that CORE does not leak memory on shutdown/unload. \
|
Makes sure that CORE does not leak memory on shutdown/unload. \
|
||||||
Unloads all custom modules, built-in modules, frees any of CORE's classes and lastly itself.
|
Unloads all custom modules, built-in modules, frees any of CORE's classes and lastly itself.
|
||||||
|
### *int* <u>register_cleanup_hook</u>(*Callable* <u>callable</u>)
|
||||||
|
Registers a new cleanup hook. \
|
||||||
|
Returns the hook id.
|
||||||
|
### *bool* <u>unregister_cleanup_hook_by_id</u>(*int* <u>id</u>)
|
||||||
|
Unregisters a cleanup hook by it's id.
|
||||||
|
### *bool* <u>unregister_cleanup_hook_by_ref</u>(*Callable* <u>callable</u>)
|
||||||
|
Unregisters a cleanup hook by it's reference.
|
||||||
### *bool* <u>is_devmode</u>()
|
### *bool* <u>is_devmode</u>()
|
||||||
Returns if the framework is in development mode.
|
Returns if the framework is in development mode.
|
||||||
### *String* <u>get_format_string</u>(*String* <u>string</u>)
|
### *String* <u>get_format_string</u>(*String* <u>string</u>)
|
||||||
|
|
65
src/core.gd
65
src/core.gd
|
@ -57,6 +57,9 @@ var storage: CoreBaseModule
|
||||||
## Stores the path to CORE's installation directory.[br]
|
## Stores the path to CORE's installation directory.[br]
|
||||||
## [b]Danger: [i]Don't modify this.[/i][/b]
|
## [b]Danger: [i]Don't modify this.[/i][/b]
|
||||||
var basepath: String
|
var basepath: String
|
||||||
|
## Contains a list of all registered cleanup hooks.[br]
|
||||||
|
## [b]Danger: [i]Don't modify this.[/i][/b]
|
||||||
|
var cleanup_hooks: Dictionary = {}
|
||||||
## Contains a list of all loaded custom modules.[br]
|
## Contains a list of all loaded custom modules.[br]
|
||||||
## [b]Danger: [i]Don't modify this.[/i][/b]
|
## [b]Danger: [i]Don't modify this.[/i][/b]
|
||||||
var custom_modules: Dictionary = {}
|
var custom_modules: Dictionary = {}
|
||||||
|
@ -223,24 +226,80 @@ func get_custom_module(module_name: String) -> CoreBaseModule:
|
||||||
return null
|
return null
|
||||||
return custom_modules[module_name]
|
return custom_modules[module_name]
|
||||||
|
|
||||||
# +++ etc ++
|
# +++ cleanup ++
|
||||||
## Makes sure that CORE does not leak memory on shutdown/unload.[br]
|
## Makes sure that CORE does not leak memory on shutdown/unload.[br]
|
||||||
## Unloads all custom modules, built-in modules, frees any of CORE's classes and lastly itself.
|
## Unloads all custom modules, built-in modules, frees any of CORE's classes and lastly itself.[br]
|
||||||
|
## Only call this function if you're sure that your application or game no longer uses the CORE Framework.
|
||||||
func cleanup() -> void:
|
func cleanup() -> void:
|
||||||
loggeri.info("Cleaning up")
|
loggeri.info("Cleaning up")
|
||||||
|
loggeri.verb("Calling cleanup hooks")
|
||||||
|
for hook in cleanup_hooks:
|
||||||
|
if !cleanup_hooks[hook].is_valid():
|
||||||
|
loggeri.error("Cleanup hook #" + str(hook) + " is invalid")
|
||||||
|
else:
|
||||||
|
loggeri.diag("Calling cleanup hook #" + str(hook))
|
||||||
|
await cleanup_hooks[hook].call()
|
||||||
|
loggeri.verb("Unregistering custom modules")
|
||||||
for module in custom_modules_node.get_children(): await unregister_custom_module(module.name)
|
for module in custom_modules_node.get_children(): await unregister_custom_module(module.name)
|
||||||
|
loggeri.verb("Removing custom module support")
|
||||||
remove_child(custom_modules_node)
|
remove_child(custom_modules_node)
|
||||||
custom_modules_node.queue_free()
|
custom_modules_node.queue_free()
|
||||||
|
loggeri.verb("Unloading built-in modules")
|
||||||
var modules_reverse: Array[String] = modules.duplicate()
|
var modules_reverse: Array[String] = modules.duplicate()
|
||||||
modules_reverse.reverse()
|
modules_reverse.reverse()
|
||||||
for module in modules_reverse:
|
for module in modules_reverse:
|
||||||
await get(module)._cleanup()
|
await get(module)._cleanup()
|
||||||
get(module).loggeri.queue_free()
|
|
||||||
get(module).queue_free()
|
get(module).queue_free()
|
||||||
|
print("Freeing configuration")
|
||||||
config.queue_free()
|
config.queue_free()
|
||||||
await get_tree().process_frame
|
await get_tree().process_frame
|
||||||
|
print("Freeing")
|
||||||
queue_free()
|
queue_free()
|
||||||
|
|
||||||
|
# Generates a new cleanup hook id
|
||||||
|
func _generate_hook_id() -> int:
|
||||||
|
var id = randi()
|
||||||
|
if cleanup_hooks.has(id):
|
||||||
|
loggeri.warn("New cleanup hook id #" + str(id) + " is already taken")
|
||||||
|
return _generate_hook_id()
|
||||||
|
elif id == -1:
|
||||||
|
loggeri.warn("Invalid cleanup hook id '-1'")
|
||||||
|
return _generate_hook_id()
|
||||||
|
return id
|
||||||
|
|
||||||
|
## Registers a new cleanup hook.[br]
|
||||||
|
## Returns the hook id.
|
||||||
|
func register_cleanup_hook(callable: Callable) -> int:
|
||||||
|
if !callable.is_valid():
|
||||||
|
loggeri.error("Could not add cleanup hook: Callable is not valid")
|
||||||
|
return -1
|
||||||
|
|
||||||
|
var id: int = _generate_hook_id()
|
||||||
|
loggeri.verb("Adding new cleanup hook #" + str(id))
|
||||||
|
cleanup_hooks.merge({ id: callable })
|
||||||
|
return id
|
||||||
|
|
||||||
|
## Unregisters a cleanup hook by it's id.
|
||||||
|
func unregister_cleanup_hook_by_id(id: int) -> bool:
|
||||||
|
if !cleanup_hooks.has(id):
|
||||||
|
loggeri.error("Could not remove cleanup hook (id): Hook #" + str(id) + " does not exist")
|
||||||
|
return false
|
||||||
|
loggeri.verb("Removed cleanup hook #" + str(id) + " (id)")
|
||||||
|
cleanup_hooks.erase(id)
|
||||||
|
return true
|
||||||
|
|
||||||
|
## Unregisters a cleanup hook by it's reference.
|
||||||
|
func unregister_cleanup_hook_by_ref(callable: Callable) -> bool:
|
||||||
|
var id: Variant = cleanup_hooks.find_key(callable)
|
||||||
|
if id == null:
|
||||||
|
loggeri.error("Could not remove cleanup hook (ref): Could not find a matching hook")
|
||||||
|
return false
|
||||||
|
if typeof(id) != TYPE_INT: await loggeri.crash("Could not remove cleanup hook (ref): find_key did not return an integer (returned '" + str(id) + "')")
|
||||||
|
loggeri.verb("Removed cleanup hook #" + str(id) + " (ref)")
|
||||||
|
cleanup_hooks.erase(id)
|
||||||
|
return true
|
||||||
|
|
||||||
|
# +++ etc +++
|
||||||
## Returns if the framework is in development mode.
|
## Returns if the framework is in development mode.
|
||||||
func is_devmode() -> bool:
|
func is_devmode() -> bool:
|
||||||
return config.development
|
return config.development
|
||||||
|
|
Loading…
Reference in a new issue