0

I have this class in my project:

class InputReactor
{
public:
    //Input reactor needs pointer to  Input
    InputReactor(Input* input_) :
        m_input(input_)
    {
    }

    virtual void input_quit(const float scale_);
    virtual void input_left(const float scale_);
    virtual void input_right(const float scale_);
    virtual void input_up(const float scale_);
    virtual void input_down(const float scale_);
    virtual void input_axisupd(const float scale_);
    virtual void input_ok(const float scale_);
    virtual void input_cancel(const float scale_);
    virtual void input_shift(const float scale_);
    virtual void input_ctrl(const float scale_);

    //All events reactor is subscribed at
    std::vector<EVENTS> subscribed_at;

    void setInputEnabled(bool inputEnabled_);
    bool isInputEnabled();

    //InputReactor automatically removes itself from subscribers
    virtual ~InputReactor()
    {
        for (EVENTS ev : subscribed_at)
        {
            m_input->unsubscribe(ev, this);
        }
    }

private:
    Input* m_input = nullptr;
    bool m_inputEnabled = false;

};

Any object that is derived from InputReactor can subscribe to different types of events (enum class EVENTS) in Input class and override required input_event function. Input class keeps InputReactor*. The problem is this part:

    //That could be a meme
    virtual void input_quit(const float scale_);
    virtual void input_left(const float scale_);
    virtual void input_right(const float scale_);
    virtual void input_up(const float scale_);
    virtual void input_down(const float scale_);
    virtual void input_axisupd(const float scale_);
    virtual void input_ok(const float scale_);
    virtual void input_cancel(const float scale_);
    virtual void input_shift(const float scale_);
    virtual void input_ctrl(const float scale_);

Making just a single regular method with switch inside would ruin the whole point, and it's impossible to override template method so i cannot simply make a single method like this:

template<EVENTS ev>
void input(const float scale_);

Probably I also could make a single template class for each EVENT and simply inherit all required, but that would make class definitions have tons of parents, and i wouldn't be able to enable / disable input with a single bool variable, so it's not better at all. Is there any way I can at least make it less ugly?

SavedowW
  • 39
  • 5
  • Inherit type list won't be too ugly with c++11, see this: https://stackoverflow.com/a/7352569/1292791 – prehistoricpenguin Jun 18 '21 at 07:46
  • In my opinion this is not really the correct usage of a reactor. The reactor class should not know about specific events. That should be handled in the event class. You may look a the following link, so see a reactor implementation according to the original definition. https://github.com/Armin-Montigny/SmlParser Please look in the reactor source files – A M Jun 18 '21 at 09:40
  • @ArminMontigny , I didn't even knew about reactor pattern, but, if i got it's point correctly, I actually do the same. InputReactor class here is an EventHandler, and it is concreted in derived classes – SavedowW Jun 18 '21 at 12:14
  • @prehistoricpenguin , thanks, that looks like a good solution. One more question: how can I override pure virtual functions with same names from different classes if these classes are defined with a list? Solution like this - https://stackoverflow.com/questions/3150310/c-virtual-override-functions-with-same-name - does not work, compiler does not know about specific base classes – SavedowW Jun 18 '21 at 13:05
  • If you want to switch to the same function name, then we can't use inheritance and virtual function. We can consider somewhat like std::variant and type erasure. Actually, this kind of design will be faster than virtual functions. – prehistoricpenguin Jun 19 '21 at 07:35

0 Answers0