Przekazanie zmiennych enum przez template?

0

bool KeyboardSpecifier::concern(const sf::Event& event) const
{
	return binds.find(event.key.code) != binds.end();
}
bool MouseSpecifier::concern(const sf::Event& event) const
{
	return binds.find(event.mouseButton.button) != binds.end();
}

event.key.code jak i event.mouseButton.button są zmiennymi o typie dwóch niezwiązanych ze sobą enum.
Czy jest możliwe przekształcić ten kod, aby się nie powtarzać? Używając np. template? Obie klasy są dziedziczone z tej samej klasy bazowej.

0

Daj więcej kodu, coś co teraz nakreślę(nakreślimy) może nawet nie mijać się w drzwiach z tym, czego oczekujesz.
Na pierwszy rzut oka przydatnym może się okazać jakiś szablonowy broadcaster, jak tu http://stackoverflow.com/questions/15028609/event-handling-using-templates

0

Naskrob templatowy rejestr event handlerów. Niech (templatowa) klasa bazowa obu tych klas asocjuje ten rejestr i implementuje wołanie odpowiedniego handlera. Poszczególne klasy dziedziczą po specjalizacji klasy bazowej i rejestrują odpowiednie callbacki.

A jak chcesz to napisać bardzo ładnie to użyj boost::signal2.

0

sf::Event to w skrócie jedno enum i jedna unia (https://github.com/SFML/SFML/blob/master/include/SFML/Window/Event.hpp)
Sprawdzam enum i odwołuje się do odpowiedniej zmiennej w uni.
Klasa bazowa dwóch poprzednich:

class Specifier
{
public:
	virtual bool concern(const sf::Event&) const = 0;
};

Specifier wywołuję na podstawie czy jakiś event w ogóle mnie interesuje, jeśli tak następuje sprawdzenie czy chodzi o konkretny przycisk / klawisz / etc

std::map<sf::Event::EventType, std::unique_ptr<Specifier>>;

Może robię to w całkiem złym kierunku, nie wiem, pierwszy raz.

0

Możesz tak zrobić tylko przenieść logikę sprawdzania, czy na dany event jest zarejestrowany handler do klasy bazowej.

2

@abbq np tak:

namespace application {
    template <typename T, typename U>
    class event_registry {
    public:
        using event_handler = std::function<bool(const U&)>;

        void register_handler(const T& event_type, const event_handler& handler);
        void unregister_handler(const T& event_type);
        bool call_handler(const T& event_type, const U& window_event) const;

    private:
        using registry_handler = std::unordered_map<T, event_handler>;
        registry_handler registry;
    };

    template <typename T, typename U>
    inline void event_registry<T, U>::register_handler(const T& event_type, const event_handler& handler) {
        registry[event_type] = handler;
    }

    template <typename T, typename U>
    inline void event_registry<T, U>::unregister_handler(const T& event_type) {
        auto handler = registry.find(event_type);
        if (handler != std::end(registry))
            registry.erase(handler);
    }

    template<typename T, typename U>
    inline bool event_registry<T, U>::call_handler(const T& event_type, const U& window_event) const {
        auto handler = registry.find(event_type);
        if (handler == std::end(registry))
            return false;
        return handler->second(window_event);
    }

    template <typename T, typename U>
    class event_registrar {
    public:
        virtual ~event_registrar() = default;
        virtual bool handle_event(const T& event_type, const U& event) const;

    protected:
        event_registry<T, U> event_handler_registry;
    };

    template <typename T, typename U>
    inline bool event_registrar<T, U>::handle_event(const T& event_type, const U& event) const {
        return event_handler_registry.call_handler(event_type, event);
    }

    class sfml_window;

    class sfml_event_registrar : public event_registrar<sf::Event::EventType, sf::Event> {
    public:
        sfml_event_registrar(const std::shared_ptr<sfml_window>& window_handler);

    private:
        std::shared_ptr<sfml_window> window_handler;
    };

    sfml_event_registrar::sfml_event_registrar(const std::shared_ptr<sfml_window>& _window_handler)
        : window_handler(_window_handler) {

        event_handler_registry.register_handler(sf::Event::Closed, [this](const sf::Event& event) {
            window_handler->close();
            return true;
        });
    }
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1