Is there a way to bind owner functions from a component? (Fully encapsulated)

I wonder if there is a way to bind a component’s functions to its owner’s functions.

I know I can do it using delegates but it’s not the idea.
The idea is to have everything encapsulated inside the component.

The owner should never know that the component exists.

So…
1 - The component already has a pointer to its owner. (GetOwner())
2 - The component can already get a reference to the owner function (&APlayerController::BeginPlay)
3 - The component already knows the signature of the owner function.

I only need to know one thing.
How to bind the component’s function so that it runs at the same time as its owner’s and receives the same arguments.
Any way to do that?

Thank you so much!!


Same question in Stack Overflow

This isn’t really possible directly thanks to how C++ functions fundamentally work.

Your best alternative is to use public delegates that are bound to that owner’s functions.
Meaning the owner binds their functions to the appropriate delegates and then only calls the delegates (never the functions directly). You’d be able to bind your own function in a component without the owner ever knowing.

Though your best bet is probably a different system. If you provide details on what these functions are and what the component/owner does, I can try to think of a solution that avoids your problem.

1 Like

It’s a matter of organization. To keep a clean and tidy code.
To avoid having a gigantic class with thousands of lines I am using the actor components. Basically I use each one to do a specific task.

To avoid dependencies I use abstraction as much as possible.

The actor component already implements some events like TakeAnyDamage, OnActorHit, OnTakePointDamage… This is very convenient.

Unfortunately the same does not happen when the actor is a PlayerController, a GameState, a GameMode or a PlayerState.
The UPlayerControllerComponent and the UGameStateComponent class is practically empty.

I need to handle some events of these classes inside the actor components.

Like for example these:

	virtual void SetPlayer( UPlayer* InPlayer ) override;
	virtual void PostInitializeComponents() override; 
	virtual void BeginReplication() override;
	virtual void OnRep_Pawn() override;
	virtual void OnRep_PlayerState() override;
	virtual void FailedToSpawnPawn() override;

To execute these events inside the actor components I need a large number of delegates.
This creates dependency with the current owner class. So the actor component loses its main reason, which is portability.
Being able to reuse the code in other actors and not having to write a single line.

All these problems would be largely solved if you could bind the functions from within the component

The owner would only be in charge of creating the instances and the components do the rest of the work.

I think that’s ideal.
Thanks for offering your help.

Oh- I thought you were doing this with your own functions.

Keeping one class from being thousands of lines of code only makes sense when your delegation makes sense. Sometimes it makes perfect sense for a single class to be a behemoth.
You don’t split a function into smaller functions just because the first one was getting kinda big- you only do it when you want that functionality outside the function or multiple places inside it.

It makes perfect sense to have an inventory component, stat component, and interaction component. It doesn’t make sense to have a possessor component. An object should rarely ever just be a collection of components- they should do something themselves.

Abstraction wouldn’t reduce dependencies. It may make them harder for you to know about the dependencies, but they’re still there.

PlayerControllers have all of these excluding OnActorHit (they shouldn’t have anything physical in them anyways). All actors (which APlayerController is) support the damage system.

There is no such thing as UPlayerControllerComponent. PlayerControllers are actors (APlayerController).

Again this isn’t possible- functions are effectively just pointers to machine code. That’s why we have delegates. Though those wouldn’t even work in this case since these aren’t your functions.




Don’t over-compartmentalize. If they’re functions on the player controller, let the player controller handle them- don’t try to put the logic in a component.

1 Like

That is true… i wanted to say this
https://docs.unrealengine.com/4.27/en-US/API/Plugins/ModularGameplay/Components/UControllerComponent/

That is true also… i’m using a inteface now. That’s the only dependency I have right now.

TArray<UActorComponent*> ActorComponents = GetComponentsByInterface( UPlayerControllerInterface::StaticClass() );

But I still have to call the functions for them to be executed

If I do this I can’t share (reuse) the logic with other controllers… I would have to write the whole code again. Some of these components I plan to use in AAIController as well.

It is generic code :slight_smile:

Thank you very much for your advice!! :heart: