Calling a method from other class

Hi,

This is more a C++ question than an Urho3D one, but maybe someone could point me in the right direction.

Is it possible to call the Test() method declared in the App Class from inside the Char class?
And, if possible, how it should be declared?

Simplified version:

using namespace Urho3D;

class Char : public LogicComponent {

  URHO3D_OBJECT(Char, LogicComponent);

  Char(Context *context_) : LogicComponent(context_) { ... }

  static void RegisterObject(Context *context_) { context_->RegisterFactory<Char>(); }

  virtual void Start() {
    //App::Test(); // Is it possible to call the App::Test() method here?
  }

};

class App : public Application {

  public:

    App(Context *context_) : Application(context_) { Char::RegisterObject(context_); }

    void Setup() { ... }

    void Start() { ... }

    void Test() { printf("Test\n"); }

};

URHO3D_DEFINE_APPLICATION_MAIN(App);

Thanks in advance.

Here are two ways:

  1. Pass a pointer to the Application object into the constructor of Char. Since MyApp is essentially a singleton created as a local variable in main(), you’ll never run into problems with memory safety unless you try to delete it, or try to store the pointer in a smart pointer (shared or unique, which will delete it when the ptr gets destroyed).
  2. Make MyApp an Urho3D::Subsystem, then just call GetSubsystem<MyApp>() whenever you want it. I have been pondering if this is architecturally sound or basically flawed/dangerous OO. Note: executing RemoveSubsystem<MyApp>() will crash your program.

The correct way to do it (pardon my edits viewers) is to add this macro to your application class declaration:

class MyApp final : public Application
{
    URHO3D_OBJECT(MyApp, Application);
    ...
}

Then in the constructor register as a subsystem:

MyApp::MyApp(Context *context) : Application{context}
{
    context_->RegisterSubsystem(this);
}

Then use it as a standard subsystem:

GetSubsystem<MyApp>()->Test();

Note: in your example App::Test() could be declared static, which would allow you to call it from anywhere without needing an instance of App.

2 Likes

You could also do DynamicCast<App>(GetSubsystem<Application>())->Test().

1 Like

Yeah it’s pretty verbose though. Adding the macro is super easy

1 Like

@vmost and @Pencheff, thank you so much for the help. I was really stuck on that.
@vmost, your explanation was super helpful. Thanks for taking the time to detail the subsystem solution, I really appreciate it! Thank you again.

1 Like

Also, welcome to the forums! :confetti_ball: :slightly_smiling_face:

1 Like

Thank you very much!