-
Notifications
You must be signed in to change notification settings - Fork 90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Templated SourceHook #176
base: master
Are you sure you want to change the base?
Templated SourceHook #176
Conversation
Introduces one massive template for generating SourceHook managers. The goal is for this to simplify the definition of SourceHooks long-term by replacing macros with templates. This introduces some new templates for metaprogramming, but they're hidden away in the SourceHook::metaprogramming namespace. Tested on Windows 32 bit and Linux 32 bit TF2.
…feat/templated-sourcehook Sometimes my vast intellect... it scares me. # Conflicts: # core/provider/source/provider_source.cpp
This allows us to specify the SH pointer and the Plugin ID pointer in the template, so when the plugin uses Hook<> it doesn't have to touch g_PLID or g_SHPtr. Also added a little struct that wraps ISourceHook->xHookById methods.
Very neat stuff, but would throw my 2 cents here, what do you think on renaming exposed struct |
How about "HookFactory" or "SourceHookFactory", since that's effectively what it is? |
Thanks for doing this! Will take a look this weekend hopefully. Namespaces are good avoiding for name collisions. |
This is a large refactor that splits our mega-template into a few smaller ones. First off, the PLUGIN_GLOBALVARS() helpers were put in the SourceHook namespace. - HookHandlerImpl: Responsible for the lowered delegates (post-vafmt), can be used independently of other templates added here. Relies on parent HookManager class to handle the unlowered original invocation logic. (As a template parameter) - HookCoreImpl: Adds a public interface & glue layer beterrn managers and HookHandlerImpl - HookImpl: non-varardic hook manager - FmtHookImpl: format-string hook manager FmtHookImpl was tested by hooking IVEngineServer::ClientCommand.
Added varardic hook macros, and I decided to just put the helpers into the Split the original As a result of this, varfmt hooks are now supported, with similar handling to macro varfmt hooks: auto OnClientCommand = SourceHook::FmtHook<IVEngineServer, &IVEngineServer::ClientCommand, void, edict_t*>::Make();
void SamplePlugin::Hook_SendClientCommand(edict_t* pEntity, const char* pszCommand)
{
// pszCommand = printf(fmt, ...)
} Still thinking about how I want to tackle manual hooks; open to suggestions. |
Not everything has to be solved in one PR! Happy to take incremental improvements. API changes don't get frozen until release. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First thing first, that's an awesome PR everything is thoroughly documented. And SourceHook really needed a makeover with templates, this is amazing.
Also since I happen to also be modifying SourceHook in another PR. I think I'm familiar enough with the framework to give a tiny review. There's one problem spotted, everything else is nitpicks, I might do another review if I've time to try this out in a project.
On another note, are the test cases still maintained and regularly built? I’m getting some errors in the macros on MSVC and on GCC all of the tests fail. I was able to get it to build on windows by gutting some of the tests and all the tests passed there. Linux was WSL Debian x64 with G++ multilib (-m32) |
Turns out this isn't true. Yay! Less work for me :^)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is absolutely fantastic! I'm impressed with how straightforward it is and how much nicer the actual interface is. Best of all it does not touch the ABI as far as I can tell.
Aside from some minor nits, I'd be happy to take this on 2.0 and/or 1.12 (though you probably want to bake it for a little bit before doing a backport).
I think one thing is needed before committing to this on 2.0: some tests. They don't have to be that advanced, but some kind of addition to the SourceHook test suite would be great. If for no other reason to document the new API a little.
And to commit on 1.12: Take a new MM:S and old SourceMod and make sure they run together, as a smoke test that the ABI hasn't changed.
|
||
// You're probably wondering what the hell this does. | ||
// https://stackoverflow.com/questions/11709859/how-to-have-static-data-members-in-a-header-only-library/11711082#11711082 | ||
// I hate C++. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we assume C++17 now, does that help?
(Alternately, I'm not above requiring linking to a libsourcehook, but the hack is so small that that seems like overkill)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this was back when I was trying to get this to work on C++11, before I realized that was plain impossible. I'll look into an inline static
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Going to keep this as a hack for the time being just because I don't understand the semantic differences between this and inline static
. Would be more than willing to do either I just dont know what is and isn't UD these days :/
There's also a build error:
I'm not sure why this didn't get pulled in as part of |
- A few style improvements - Add & correct some documentation - Change AddHook signature to not allow DVP as an option (for now!) - Fix cstdio not being pulled in on linux (bleh) - Add some more static_asserts to make errors easier to interpret (yay)
Fixed. Hopefully. I think. |
* Replace protobuf 2.6.1 with 3.21.8 * Update/add protobuf libs * Add CS2 protos * Remove old csgo/dota protos * Add versioned protoc bin * Comment out Valve's `schema` define for now * Use ENetworkDisconnectionReason * Fix-up `offsetof` to avoid errors on some Clang versions
LGTM! |
Introduces one massive template for generating SourceHook managers. The goal is for this to simplify the definition of SourceHooks long-term by replacing macros with templates.
Draft until API is settled upon, but is most likely merge-able now.
Introducing SourceHook::HookImpl
SourceHook::HookImpl is a template that implements the previous functionality of the
SH_DECL
macros. It uses the following template parameters in it's implementation:ISourceHook** SH
- Pointer to SourceHook (eg&g_SHPtr
)Plugin* PL
- Pointer to global PluginId value (eg&g_PLID
)typename Interface
- The interface to hookResult (Interface::Method)(Args...)
- The argument to hook (eg&IEngine::DoThing
typename Result
- the return type orvoid
typename ...Args
- all arguments, specified as a varardic type pack.The macro
PLUGIN_GLOBALVARS()
now exposes theHook
template with theSH
andPL
fields filled in from the global variables--so all plugin authors need to do to get started is specify `Hook<Interface, Method, Return, Args...>::Make().Example usage: