Archive 17/01/2023.

LogicComponent update function not called

throwawayerino

With or without setting the update mask, no matter what I try the update function is never called. I made sure it’s the same signature, I made it public and private, but it just won’t run. Subscribing to my own custom HandleUpdate method works, but the inherited virtual function doesn’t. Am I missing something?

Lumak

Be sure to set the correct bitmask. There are four types:

And each corresponds to specific virtual fn.

Take a look at some samples that make use of LogicComponents:

Modanung

Since C++11 you can make sure you’re not creating a new base virtual function by appending the override keyword instead of prepending virtual to a function declaration. This will cause a compiler error when no superclass has a virtual function with a matching signature.
The default update event mask of a LogicComponent should do.

throwawayerino

I set the bitmask to USE_UPDATE and made sure I was overriding a function. No compiler errors, and the debugger shows that the function is never called

throwawayerino

What’s even more annoying is that other components have their virtual functions called normally

Modanung

Is there an URHO3D_OBJECT(SubClass, SuperClass) inside your class declaration?
`

throwawayerino

Yes
20 character limit

Modanung

I think I’m out of guesses; could you share some code?

throwawayerino

I can’t guess what could be wrong too
Header:

class GameManager : public LogicComponent
{
	URHO3D_OBJECT(GameManager, LogicComponent)

public:
	explicit GameManager(Context* context);
	~GameManager() = default;

	static void RegisterObject(Context* context);

	virtual void OnSceneSet(Scene* scene) override;

	virtual void Update(float Timestep) override;
}

Cpp file:

GameManager::GameManager(Context* context)
	: LogicComponent(context)
{
	// Unsubscribe from all but update
	// For some reason no functions are called
	//SetUpdateEventMask(USE_UPDATE);
	URHO3D_LOGDEBUG("Game manager constructor called");
}

void GameManager::Update(float Timestep)
{
	if (timer->GetMSec(false) >= 500 && CurrentControl != nullptr) {
		URHO3D_LOGINFO(String("500ms have passed!");
		timer->Reset();
	}
}

How it’s made in main.cpp:

GameManage = MainScene->CreateComponent<GameManager>();	
Modanung

Prepending virtual nullifies the override keyword. They should not be used on the same declaration.

Could you try logging the update outside of the timer check? Just to make sure the if isn’t to blame.

throwawayerino

The if is correct, because I’ve put it in a seperate HandleUpdate I made before and it worked. Still, I put it out of the if and yet it didn’t work
Either way, it’s just a little inconvenience. Manually subscribing to Update events works and I can live with it.

Modanung

Also no errors or warnings being logged? Maybe something about a failed instantiation of an unknown component. Though I guess the “Game manager constructor called” should exclude that possibility, does it show up? It just seems strange for a simple setup like this to not work.

throwawayerino

Nothing related to it is logged. Logging from constructor works and I used the component successfuly for other things. Actually, I don’t think I need it to be a logic component either way. Thanks for the help

guk_alex

Do you have RegisterObject defined in your cpp code?

lezak

Do You call LogicComponent::OnSceneSet here? Events subscriptions are set in this method, so if You override it, this may be the reason of Your problem.

Lumak

Need to uncomment the line in your ctor:

//SetUpdateEventMask(USE_UPDATE);
throwawayerino

I can’t believe I forgot this. Thanks!

Modanung

That should not be required…

Lumak

Ha, I forgot that’s how it works. I wonder why it’s defaulted to calling all four empty functions?
But thx Modanung!

Modanung

I guess it’s the more convenient default that makes sure you don’t forget setting the right update event mask, instead of leaving you guessing why things don’t work as expected? :wink:

“97% of the time premature optimization is the root of all evil.” – Donald Knuth

Alternatively one can use the Component class to inherit from. The main difference is that it lacks this update event mask and the associated virtual functions.