suli
suli

Reputation: 41

Template to replace the namespace of a callback ? cpp

I have a class called Menu. Here is the header implementation of it.

class Menu{
private:
    int last_mouse_active_hold_x;
    int last_mouse_active_hold_y;

public:
    float   x;
    float   y;
    float   width;
    float   height;
    int     x_full;
    int     y_full;
    int     width_full;
    int     height_full;
    bool    is_shown;

    int     num_of_items_shown;
    int     height_per_item_full;
    float   height_per_item;
    int     item_offset;
    int     selected_index;
    float   outside_scroll_speed;
    int     scroll_speed;
    int     scroll_counter;


    std::string     name;
    unsigned char   shortcut;
    std::string     search_term;

    MenuItem *  items;
    int         items_len;
    MenuItem *  items_full;
    int         items_full_len;

                Menu();
    void        render();
    void        set_pos( float x, float y );
    void        set_pos( int x, int y );
    void        set_width( float w );
    void        set_name( std::string _name );
    void        reshape();
    void        show();
    void        hide();
    void        toggle_show();
    void        add( std::string _name, int (*_callback)(std::string), std::string _callback_param );
    void        select( int _index );
    void        set_number_of_items( int _n );
    void        set_height( int _h );
    void        set_width( int _w );
    void        set_shortcut( unsigned char c );
    void        mouse_move_passive( int _x, int _y );
    void        mouse_move_active( int _x, int _y );
    void        mouse_press( int _button, int _state, int _x, int _y );
    void        key_press( unsigned char _key, int _x, int _y );
    void        key_press_special( unsigned char _key, int _x, int _y );
    void        scroll( int _ammount );
    void        search();
    void        refill_items();
    void        pop_item( int _i );
    void        trigger();

As you can see the Menu has a list of MenuItems. I don't think the extra data is relevant to this problem.

Here is the MenuItem header file:

class MenuItem{
public:
    std::string     name;
    int             (* callback)(std::string);
    std::string     callback_param;
    int             x_full;
    int             y_full;
    int             width_full;
    int             height_full;
    float           x;
    float           y;
    float           width;
    float           height;
    float           text_size;
    float           text_margin_left;
    float           text_margin_bottom;
    bool            selected;

            MenuItem( );
    void    create( std::string _name, int (*callback)(std::string)  );
    void    render( float _x, float _y, float _z );
    void    reshape();
    void    set_size( int _w, int _h );
    void    set_height( int _h );
    void    set_param( std::string _p );
    int     trigger();

};

Now that this is out of the way, I can get to my actual problem. The problem lies within the callback function in the MenuItem class. The callback expects something of type

int (*callback(std::string a))

This is all nice and works fine if the function I am giving it is part of the main code, or is a static within a class. However, my goal is to be able to store this menu within other classes and have them pass some of their own methods to it. This is a problem, since for most my classes that would like to use it, they pass in a callback of type

int (* BaseClass::callback(std::string a))

Therefore I get a compile error, saying that I am passing an incorrect type to the Menu as a callback object.

How do I work around this ? one option I looked into is adding templated to the Menu and MenuItem class. I would like to avoid this option as I have already written a bunch of code, admittedly a bit too stupidly(without thinking ahead) and refactoring would waste a lot of time. Would this even be possible with templates ? can i use the template as a namespace and not an object type ?

What other options to I have here ?

Upvotes: 0

Views: 84

Answers (1)

Jarod42
Jarod42

Reputation: 218098

You might use std::function:

std::function<int(std::string)> callback;

User can still pass lambda/Functor as

menuItem.setCallback([this](std::string a) { return this->my_callback(a); }

Upvotes: 1

Related Questions