Implement hook stacking and priorities #1843
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Hook stacking without having multiple managed to native and native to managed transitions was the primary objective here, but priorities were relatively easy to implement on top of that.
Currently this implements the following priority bands:
Normal priority hooks convert to Dalamud internal ones automatically based on the calling assembly. For fine grained control inside a priority band, the optional
precedence
parameter can be used to lower or raise the effective priority.This also makes some locking a bit stricter (like making sure jumps are followed only under the global hook lock).
There is some IL dynamically generated in 3 places (most of the time only in 1), I don't believe there is a reasonably performant alternative to that unfortunately.
When stacking hooks of incompatible signatures (like ST
private delegate void* GlobalEventDelegate(AtkUnitBase* atkUnitBase, AtkEventType eventType, uint eventParam, AtkResNode** eventData, uint* a5)
and Dalamudsprivate delegate IntPtr AtkUnitBaseReceiveGlobalEvent(AtkUnitBase* thisPtr, ushort cmd, uint a3, IntPtr a4, uint* a5)
) a warning is logged and IL thunks are generated inside aCastingHook<,>
.AsmHook
seem to exist a bit outside the other hooks, so these currently do not stack, but are now also under the global hook lock.This also fixes the
callingAssembly
not resolving to the actual plugin and marking all hooks as "Dalamud Hooks".