Skip to content
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

Add templated handler for manual hooks #150

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

mixern6
Copy link

@mixern6 mixern6 commented Dec 3, 2023

Add templated wrapper for manual hooks. Simple hooks are not supported yet and will be added later.
The handler supports any return type and arbitrary number of arguments.
A hook can be defined like this:
// void - return type
// const char* - first argument
SourceHook::ManualHookHandler<void, const char*> setEntityModelHook;
Then it can be reconfigured:
setEntityModelHook.Reconfigure(offset);
And this way it can be connected to a callback method:
const int hookID = setEntityModelHook.Add(baseEntityPtr, this, &MyClass::OnSetEntityModel, true);
Remove the hook:
g_SHPtr->RemoveHookByID(hookID);

the Recall method can be used instead of the RETURN_META* macros.

@mixern6
Copy link
Author

mixern6 commented Dec 3, 2023

@psychonic what would you suggest to fix the tests?

@dvander
Copy link
Member

dvander commented Dec 4, 2023

At a glance, this looks ABI-safe and source compatible which is my main concern. I'll take a more in-depth look soon.

@dvander
Copy link
Member

dvander commented Dec 4, 2023

Looks like there are some build failures in the tests that need to be resolved, too.

@mixern6
Copy link
Author

mixern6 commented Dec 4, 2023

@dvander can't figure out the right way for sorting out the compilation errors. It looks like I can't simply rename the variables or place them into separate name spaces and yet I have to keep the extern ones in the header. What would you suggest?

Do you think it is important to have the void Reconfigure() method? It seems to me the method and the related variables are not actually required.

I'd like to make the constructor constexpr, but this playing with the memory addresses in msProto_ makes me fill uncomfortable. Would be nice to have something like ProtoInfo<Params..> : public IProtoInfo instead

@mixern6 mixern6 force-pushed the templated_vhooks branch 5 times, most recently from e15241b to 80d9750 Compare December 4, 2023 16:59
@mixern6
Copy link
Author

mixern6 commented Dec 7, 2023

@dvander all the errors are fixed. Could you have a look please?

@mixern6 mixern6 marked this pull request as draft December 10, 2023 02:35
@dvander dvander marked this pull request as ready for review December 11, 2023 03:53
, pAssignOperator(assignOperator)
{
}

void *pNormalCtor;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd assign nullptr to these fields rather than use a constructor.

PassInfo()
: size(0)
, type(0)
, flags(0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd assign zero to the fields in-line rather than use a constructor.


int operator()(bool store, IHookManagerInfo *hi) const
{
if(staticFunc_ != nullptr)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: space between "if" and "(".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like staticFunc_ and memberFunc_ are mutually exclusive here.

Can we assert((staticFunc_ && !memberFunc_) || (!staticFunc_ && memberFunc_)), use else instead, and eliminate the default return?

return *this;
}

operator bool() const
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be marked "explicit"?

private:
static void DeleteDelegate(ISHDelegate* delegate)
{
if(delegate)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space between "if" and "("

}

private:
std::shared_ptr<ISHDelegate> ptr_;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be a shared_ptr? Can it be unique_ptr?

struct IHookManagerInfo
{
virtual void SetInfo(int hookman_version, int vtbloffs, int vtblidx,
ProtoInfo *proto, void *hookfunc_vfnptr) = 0;

virtual void SetInfo(int hookman_version, int vtbloffs, int vtblidx,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overloads of virtual methods need to have a new name to avoid breaking compatibility on MSVC (it does a weird thing where it inverts the order). SetInfo2 is fine if you're feeling uncreative.

* @param post Set to true if you want a post handler
*/

virtual int AddHook(Plugin plug, AddHookMode mode, void *iface, int thisptr_offs, const HookManagerPubFuncHandler &myHookMan,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, needs a new name unfortunately. "AddNewHook", "AddHook2", "NewHook", "CreateHook", "Hook" - off the top of my head, some mediocre ideas.

@dvander
Copy link
Member

dvander commented Dec 11, 2023

This is a huge improvement to the API, thanks for working on this! I'm up against some tight deadlines this week so I was only able to get halfway through the review. I'll try to do the rest as soon as I can.

Mostly, I'm looking for compatibility issues that would break existing binaries, and for any maintenance/readability issues in the new code. There's not much: it's a great change, but it's also a big one and I want to do it justice.

Please do include tests for the new API. test2.cpp and testmanual.cpp could probably be copy & pasted and refactored into the new world order. (That will also help me validate with valgrind/asan).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants