mirror of
https://github.com/JHDev2006/Super-Mario-Bros.-Remastered-Public.git
synced 2025-10-23 07:58:09 +00:00
added the game
This commit is contained in:
83
addons/mod_loader/api/hook_chain.gd
Normal file
83
addons/mod_loader/api/hook_chain.gd
Normal file
@@ -0,0 +1,83 @@
|
||||
class_name ModLoaderHookChain
|
||||
extends RefCounted
|
||||
## Small class to keep the state of hook execution chains and move between mod hook calls.[br]
|
||||
## For examples, see [method ModLoaderMod.add_hook].
|
||||
|
||||
|
||||
## The reference object is usually the [Node] that the vanilla script is attached to. [br]
|
||||
## If the hooked method is [code]static[/code], it will contain the [GDScript] itself.
|
||||
var reference_object: Object
|
||||
|
||||
var _callbacks: Array[Callable] = []
|
||||
var _callback_index := -1
|
||||
|
||||
|
||||
const LOG_NAME := "ModLoaderHookChain"
|
||||
|
||||
|
||||
# `callbacks` is kept as untyped Array for simplicity when creating a new chain.
|
||||
# This approach allows direct use of `[vanilla_method] + hooks` without the need to cast types with Array.assign().
|
||||
func _init(reference_object: Object, callbacks: Array) -> void:
|
||||
self.reference_object = reference_object
|
||||
_callbacks.assign(callbacks)
|
||||
_callback_index = callbacks.size()
|
||||
|
||||
|
||||
## Will execute the next mod hook callable or vanilla method and return the result.[br]
|
||||
## [br]
|
||||
## [br][b]Parameters:[/b][br]
|
||||
## - [param args] ([Array]): An array of all arguments passed into the vanilla function. [br]
|
||||
## [br]
|
||||
## [br][b]Returns:[/b][br]
|
||||
## - [Variant]: Return value of the next function in the chain.[br]
|
||||
## [br]
|
||||
## Make sure to call this method [i][color=orange]once[/color][/i] somewhere in the [param mod_callable] you pass to [method ModLoaderMod.add_hook]. [br]
|
||||
func execute_next(args := []) -> Variant:
|
||||
var callback := _get_next_callback()
|
||||
if not callback:
|
||||
return
|
||||
|
||||
# Vanilla needs to be called without the hook chain being passed
|
||||
if _is_callback_vanilla():
|
||||
return callback.callv(args)
|
||||
|
||||
return callback.callv([self] + args)
|
||||
|
||||
|
||||
## Same as [method execute_next], but asynchronous - it can be used if a method uses [code]await[/code]. [br]
|
||||
## [br]
|
||||
## [br][b]Parameters:[/b][br]
|
||||
## - [param args] ([Array]): An array of all arguments passed into the vanilla function. [br]
|
||||
## [br]
|
||||
## [br][b]Returns:[/b][br]
|
||||
## - [Variant]: Return value of the next function in the chain.[br]
|
||||
## [br]
|
||||
## This hook needs to be used if the vanilla method uses [code]await[/code] somewhere. [br]
|
||||
## Make sure to call this method [i][color=orange]once[/color][/i] somewhere in the [param mod_callable] you pass to [method ModLoaderMod.add_hook]. [br]
|
||||
func execute_next_async(args := []) -> Variant:
|
||||
var callback := _get_next_callback()
|
||||
if not callback:
|
||||
return
|
||||
|
||||
# Vanilla needs to be called without the hook chain being passed
|
||||
if _is_callback_vanilla():
|
||||
return await callback.callv(args)
|
||||
|
||||
return await callback.callv([self] + args)
|
||||
|
||||
|
||||
func _get_next_callback() -> Variant:
|
||||
_callback_index -= 1
|
||||
if not _callback_index >= 0:
|
||||
ModLoaderLog.fatal(
|
||||
"The hook chain index should never be negative. " +
|
||||
"A mod hook has called execute_next twice or ModLoaderHookChain was modified in an unsupported way.",
|
||||
LOG_NAME
|
||||
)
|
||||
return
|
||||
|
||||
return _callbacks[_callback_index]
|
||||
|
||||
|
||||
func _is_callback_vanilla() -> bool:
|
||||
return _callback_index == 0
|
Reference in New Issue
Block a user