Skip to content

SFME::Mediator

Sztergbaum Roman edited this page Feb 11, 2018 · 66 revisions

Welcome to the page of the SFME::Mediator module

Modules contents

A complete example can be found here

Include hierarchy can be found here

Class Diagram

This class represents the SFME EventManager, you will be able to send and receive events through it's class.

Member function : emit

    template <typename TEvent, typename ... Args>
    void emit(Args &&... args) noexcept;
Purpose

This function is used to emit a certain type of event to which all those who have subscribed to this event will receive it.

Template parameters
  • TEvent: The type of event you wish to broadcast.
  • Args: The arguments possibly necessary to the creation of the TEvent object.
Notes
  • TEvent must be a class derived from BaseEvent class.
How can i use it ?
#include <SFME/mediator/mediator.hpp>

//! User Event with non empty constructor
struct InputEvent : sfme::mediator::BaseEvent
{
    InputEvent(char _keycode) noexcept : keycode(_keycode)
    {
    }

    char keycode;
};

//! User Event default constructible.
struct ShutdownEvent : sfme::mediator::BaseEvent
{
};

int main()
{
    sfme::mediator::EventManager evtMgr;
    evtMgr.emit<InputEvent>('a');
    evtMgr.emit<ShutdownEvent>();
    return 0;
}

Member function : subscribe

    template <typename TEvent, typename TReceiver>
    void subscribe(TReceiver &receiver) noexcept;
Purpose

This function is used to subscribe to a certain type of event, when someone will send this type of event, all those who have subscribed to this event will receive it.

Template parameters
  • TEvent: Represents the type of event you want to subscribe.
  • Receiver: Represents the instance of the class that wishes to subscribe to this type of event.
Notes
  • TEvent must be a class derived from BaseEvent class.
  • The instance that uses the subscribe member function must be derived from the Receiver class. The use of the CRTP is here only for readability.
How can i use it ?
#include <SFME/mediator/mediator.hpp>

struct InputEvent : sfme::mediator::BaseEvent
{
};

class Example : public sfme::mediator::Receiver<Example>
{
public:
    Example(sfme::mediator::EventManager &evtMgr) noexcept
    {
        evtMgr.subscribe<InputEvent>(*this);
    }

    void receive([[maybe_unused]] const InputEvent& evt) noexcept
    {
    }
};

int main() 
{
    sfme::mediator::EventManager evtMgr;
    Example ex(evtMgr);
    return 0;
}

This class is the parent class of all SFME events, so if you want to create your own events you must inherit from this class.

Member function : showEvents

void showEvents(std::string_view eventName) const noexcept;
Parameters
  • eventName is the name of the event to display in the logger, when you compile in release no display is performed.
How can i use it ?
#include <SFME/mediator/base_event.hpp>

struct FooEvents : public sfme::mediator::BaseEvent
{
    FooEvents()
    {
        showEvents("FooEvents");
    }
};

int main()
{
    FooEvents evt;
    return 0;
}

This class is the class from which you will inherit if you want to be considered as a receiver by the event manager, then you will be able to register to the types of events that interest you with the function subscribe

Include Hierarchy

Example

//
// Created by milerius on 07/02/18.
//

#include <iostream>
#include <SFME/mediator/mediator.hpp>

namespace example::evt
{
    struct KeyPressed : public sfme::mediator::BaseEvent
    {
        explicit KeyPressed(char _keycode) noexcept : keycode(_keycode)
        {
            showEvents("KeyPressed");
        }

        static std::string_view className() noexcept
        {
            return "KeyPressed";
        }

        char keycode;
    };

    struct StartGame : public sfme::mediator::BaseEvent
    {
        StartGame() noexcept
        {
            showEvents("StartGame");
        }

        static std::string_view className() noexcept
        {
            return "StartGame";
        }
    };
}

namespace example
{
    class GameScene : public sfme::mediator::Receiver<GameScene>
    {
    public:
        explicit GameScene(sfme::mediator::EventManager &evtMgr) noexcept : _evtMgr(evtMgr)
        {
            _evtMgr.subscribe<evt::KeyPressed>(*this);
            _evtMgr.subscribe<evt::StartGame>(*this);
        }

        void receive(const evt::KeyPressed &evt) noexcept
        {
            _log(logging::Info) << "keycode : " << evt.keycode << std::endl;
        }

        void receive([[maybe_unused]] const evt::StartGame &evt) noexcept
        {
            _log(logging::Info) << "Game will start now" << std::endl;
        }

    private:
        sfme::mediator::EventManager &_evtMgr;
        logging::Logger _log{"game-scene", logging::Debug};
    };

    class PauseScene : public sfme::mediator::Receiver<PauseScene>
    {
    public:
        explicit PauseScene(sfme::mediator::EventManager &evtMgr) noexcept : _evtMgr(evtMgr)
        {
            _evtMgr.subscribe<evt::KeyPressed>(*this);
        }

        void receive(const evt::KeyPressed &evt) noexcept
        {
            _log(logging::Info) << "keycode : " << evt.keycode << std::endl;
        }

    private:
        sfme::mediator::EventManager &_evtMgr;
        logging::Logger _log{"pause-scene", logging::Debug};
    };

    class HandleEveryEvents : public sfme::mediator::Receiver<HandleEveryEvents>
    {
    public:
        explicit HandleEveryEvents(sfme::mediator::EventManager &evtMgr) noexcept : _evtMgr(evtMgr)
        {
            _evtMgr.subscribe<evt::KeyPressed>(*this);
            _evtMgr.subscribe<evt::StartGame>(*this);
        }

        template <typename EventType>
        void receive([[maybe_unused]] const EventType &evt) noexcept
        {
            _log(logging::Info) << "Handle event: " << EventType::className() << std::endl;
        }

    private:
        sfme::mediator::EventManager &_evtMgr;
        logging::Logger _log{"handle-every-events", logging::Debug};
    };
}

int main()
{
    sfme::mediator::EventManager evtMgr;

    //! Example fake scenes.
    example::GameScene scene(evtMgr);
    example::PauseScene pauseScene(evtMgr);

    //! Handle every events
    example::HandleEveryEvents handleEveryEvents(evtMgr);

    //! Two Subscriber
    evtMgr.emit<example::evt::KeyPressed>('a');

    //! One Subscriber
    evtMgr.emit<example::evt::StartGame>();
    return 0;
}