What makes possible some Delegate-objects "member functions" to be shown as C++ macros?

Can you explain what makes possible the AddDynamic macro to be accessible like a member-function of the delegate object OnComponentHit?

Example:
ProjectileMeshComponent->OnComponentHit.AddDynamic(this, &AProjectile::OnHit)

I’m trying to understand the internals of this.

It basically does these steps

  1. Converts your function to function name
  2. Creates a delegate and sets function name
  3. Binds the delegate using Add function.
    It uses Add function and adds type checking layer on top. If you change your function name, compiler will give an error with AddDynamic.
// Helper macro for calling AddDynamic() on dynamic multi-cast delegates.  Automatically generates the function name string.
#define AddDynamic( UserObject, FuncName ) __Internal_AddDynamic( UserObject, FuncName, STATIC_FUNCTION_FNAME( TEXT( #FuncName ) ) )
template <typename TWeakPtr, typename RetValType, typename... ParamTypes>
class TBaseDynamicMulticastDelegate : public TMulticastScriptDelegate<TWeakPtr>
{
public:
        ...

	template< class UserClass >
	void __Internal_AddDynamic( UserClass* InUserObject, typename FDelegate::template TMethodPtrResolver< UserClass >::FMethodPtr InMethodPtr, FName InFunctionName )
	{
		check( InUserObject != nullptr && InMethodPtr != nullptr );

		// NOTE: We're not actually storing the incoming method pointer or calling it.  We simply require it for type-safety reasons.

		FDelegate NewDelegate;
		NewDelegate.__Internal_BindDynamic( InUserObject, InMethodPtr, InFunctionName );

		this->Add( NewDelegate );
	}

        ...
1 Like

Thanks Baylil, very clear now… for those who still don’t get this, check the following snippet that reproduces what unreal does.

#define DoSomethingCool(a, b) Internal_DoSomethingCool(a, (a) + (b))

class MyType
{
public:
    void Internal_DoSomethingCool(int a, int b)
    {
        std::cout << "a(" << a << ") | b(" << b << ")\n";
    }
};

int main()
{
    MyType obj;
    obj.DoSomethingCool(1, 2); // Note that DoSomethingCool is a helper macro that will be replaced by Internal_DoSomethingCool, which is a method, similar to what Unreal does with the AddDynamic macro
}
2 Likes