Skip to main content
Edited example
Source Link
Zik332
  • 53
  • 1
  • 5

I made this simple event system:

template<typename Func, typename Args>
class Event
{
public:
    static void dispatch(Args args) noexcept
    {
        for (auto listener : listeners)
            listener.second(args);
    }

    static void attach(const std::string& id, Func func) noexcept
    {
        listeners.insert({ id, func });
    }

    static void dettach(const std::string& id) noexcept
    {
        listeners.erase(id);
    }

private:
    static std::unordered_map<std::string, Func> listeners;
};

template<typename Func, typename Args>
std::unordered_map<std::string, Func> Event<Func, Args>::listeners;

What I wanted to do is to let me create any sort of event without needing to do a lot more code.

so for example in this code, if I want to add a KeyEvent, for example, I could do this:

struct KeyArguments {
    Pointint point;key;
    int someInt;state;
};

class KeyEvent : public Event<std::function<void(const KeyArguments&)>, KeyArguments>
{
};

And to use such code:

PointKeyArguments tempPoint{args;
args.key 1,2= };Key::A;
args.state = State::KeyUp;

KeyEvent::attach("new", func);
KeyEvent::attach("new2", [](KeyArguments args) { std::cout << "Hello\n";});"The 
args.pointkey =that tempPoint;
was pressed is " << args.someIntkey;}); = 20;  
KeyEvent::dispatch(args);
KeyEvent::dettach("new2");
KeyEvent::dispatch(args);

I also wanted to make the design reachable from anywhere in the code, this is why I used static keyword, and this is the part that doesn't really "feel" good.

Should I really be using static in this case? Is there any cons in using such design?

I feel like using template for this case is a bit overkill. For each event create a "new" class (the struct doesn't bother me). Do you think there is a way around that? Is it as bad as I think it is?

EDIT: The design goal was to create an event system that anyone could attach to and get notified when the specific event has happened. For example in a game we would like to distribute an event for KeyPress, so the event system (in the engine) would let the game programmer attach the Player::input function to it, and if he would like, Menu::input as well. Both of them will get notified when a KeyPress event has happened.

I made this simple event system:

template<typename Func, typename Args>
class Event
{
public:
    static void dispatch(Args args) noexcept
    {
        for (auto listener : listeners)
            listener.second(args);
    }

    static void attach(const std::string& id, Func func) noexcept
    {
        listeners.insert({ id, func });
    }

    static void dettach(const std::string& id) noexcept
    {
        listeners.erase(id);
    }

private:
    static std::unordered_map<std::string, Func> listeners;
};

template<typename Func, typename Args>
std::unordered_map<std::string, Func> Event<Func, Args>::listeners;

What I wanted to do is to let me create any sort of event without needing to do a lot more code.

so for example in this code, if I want to add a KeyEvent, for example, I could do this:

struct KeyArguments {
    Point point;
    int someInt;
};

class KeyEvent : public Event<std::function<void(const KeyArguments&)>, KeyArguments>
{
};

And to use such code:

Point tempPoint{ 1,2 };
KeyEvent::attach("new", func);
KeyEvent::attach("new2", [](KeyArguments args) { std::cout << "Hello\n";}); 
args.point = tempPoint;
args.someInt = 20;
KeyEvent::dispatch(args);
KeyEvent::dettach("new2");
KeyEvent::dispatch(args);

I also wanted to make the design reachable from anywhere in the code, this is why I used static keyword, and this is the part that doesn't really "feel" good.

Should I really be using static in this case? Is there any cons in using such design?

I feel like using template for this case is a bit overkill. For each event create a "new" class (the struct doesn't bother me). Do you think there is a way around that? Is it as bad as I think it is?

EDIT: The design goal was to create an event system that anyone could attach to and get notified when the specific event has happened. For example in a game we would like to distribute an event for KeyPress, so the event system (in the engine) would let the game programmer attach the Player::input function to it, and if he would like, Menu::input as well. Both of them will get notified when a KeyPress event has happened.

I made this simple event system:

template<typename Func, typename Args>
class Event
{
public:
    static void dispatch(Args args) noexcept
    {
        for (auto listener : listeners)
            listener.second(args);
    }

    static void attach(const std::string& id, Func func) noexcept
    {
        listeners.insert({ id, func });
    }

    static void dettach(const std::string& id) noexcept
    {
        listeners.erase(id);
    }

private:
    static std::unordered_map<std::string, Func> listeners;
};

template<typename Func, typename Args>
std::unordered_map<std::string, Func> Event<Func, Args>::listeners;

What I wanted to do is to let me create any sort of event without needing to do a lot more code.

so for example in this code, if I want to add a KeyEvent, for example, I could do this:

struct KeyArguments {
    int key;
    int state;
};

class KeyEvent : public Event<std::function<void(const KeyArguments&)>, KeyArguments>
{
};

And to use such code:

KeyArguments args;
args.key = Key::A;
args.state = State::KeyUp;

KeyEvent::attach("new", func);
KeyEvent::attach("new2", [](KeyArguments args) { std::cout << "The key that was pressed is " << args.key;});    
KeyEvent::dispatch(args);
KeyEvent::dettach("new2");
KeyEvent::dispatch(args);

I also wanted to make the design reachable from anywhere in the code, this is why I used static keyword, and this is the part that doesn't really "feel" good.

Should I really be using static in this case? Is there any cons in using such design?

I feel like using template for this case is a bit overkill. For each event create a "new" class (the struct doesn't bother me). Do you think there is a way around that? Is it as bad as I think it is?

EDIT: The design goal was to create an event system that anyone could attach to and get notified when the specific event has happened. For example in a game we would like to distribute an event for KeyPress, so the event system (in the engine) would let the game programmer attach the Player::input function to it, and if he would like, Menu::input as well. Both of them will get notified when a KeyPress event has happened.

Another exmaple
Source Link
Zik332
  • 53
  • 1
  • 5

I made this simple event system:

template<typename Func, typename Args>
class Event
{
public:
    static void dispatch(Args args) noexcept
    {
        for (auto listener : listeners)
            listener.second(args);
    }

    static void attach(const std::string& id, Func func) noexcept
    {
        listeners.insert({ id, func });
    }

    static void dettach(const std::string& id) noexcept
    {
        listeners.erase(id);
    }

private:
    static std::unordered_map<std::string, Func> listeners;
};

template<typename Func, typename Args>
std::unordered_map<std::string, Func> Event<Func, Args>::listeners;

What I wanted to do is to let me create any sort of event without needing to do a lot more code,.

so for example in this code, if I want to add a KeyEvent, for example, I could do this:

struct KeyArguments {
    Point point;
    int someInt;
};

class KeyEvent : public Event<std::function<void(const KeyArguments&)>, KeyArguments>
{
};

And to use such code:

Point tempPoint{ 1,2 };
KeyEvent::attach("new", func);
KeyEvent::attach("new2", [](KeyArguments args) { std::cout << "Hello\n";}); 
args.point = tempPoint;
args.someInt = 20;
KeyEvent::dispatch(args);
KeyEvent::dettach("new2");
KeyEvent::dispatch(args);

I also wanted to make the design reachable from anywhere in the code, this is why I used static keyword, and this is the part that doesn't really "feel" good.

Should I really be using static in this case? Is there any cons in using such design?

I feel like using template for this case is a bit overkill. For each event create a "new" class (the struct doesn't bother me). Do you think there is a way around that? Is it as bad as I think it is?

EDIT: The design goal was to create an event system that anyone could attach to and get notified when the specific event has happened. For example in a game we would like to distribute an event for KeyPress, so the event system (in the engine) would let the game programmer attach the Player::input function to it, and if he would like, Menu::input as well. Both of them will get notified when a KeyPress event has happened.

I made this simple event system:

template<typename Func, typename Args>
class Event
{
public:
    static void dispatch(Args args) noexcept
    {
        for (auto listener : listeners)
            listener.second(args);
    }

    static void attach(const std::string& id, Func func) noexcept
    {
        listeners.insert({ id, func });
    }

    static void dettach(const std::string& id) noexcept
    {
        listeners.erase(id);
    }

private:
    static std::unordered_map<std::string, Func> listeners;
};

template<typename Func, typename Args>
std::unordered_map<std::string, Func> Event<Func, Args>::listeners;

What I wanted to do is to let me create any sort of event without needing to do a lot more code, so for example in this code, if I want to add a KeyEvent, for example, I could do this:

struct KeyArguments {
    Point point;
    int someInt;
};

class KeyEvent : public Event<std::function<void(const KeyArguments&)>, KeyArguments>
{
};

And to use such code:

Point tempPoint{ 1,2 };
KeyEvent::attach("new", func);
KeyEvent::attach("new2", [](KeyArguments args) { std::cout << "Hello\n";}); 
args.point = tempPoint;
args.someInt = 20;
KeyEvent::dispatch(args);
KeyEvent::dettach("new2");
KeyEvent::dispatch(args);

I also wanted to make the design reachable from anywhere in the code, this is why I used static keyword, and this is the part that doesn't really "feel" good.

Should I really be using static in this case? Is there any cons in using such design?

I feel like using template for this case is a bit overkill. For each event create a "new" class (the struct doesn't bother me). Do you think there is a way around that? Is it as bad as I think it is?

I made this simple event system:

template<typename Func, typename Args>
class Event
{
public:
    static void dispatch(Args args) noexcept
    {
        for (auto listener : listeners)
            listener.second(args);
    }

    static void attach(const std::string& id, Func func) noexcept
    {
        listeners.insert({ id, func });
    }

    static void dettach(const std::string& id) noexcept
    {
        listeners.erase(id);
    }

private:
    static std::unordered_map<std::string, Func> listeners;
};

template<typename Func, typename Args>
std::unordered_map<std::string, Func> Event<Func, Args>::listeners;

What I wanted to do is to let me create any sort of event without needing to do a lot more code.

so for example in this code, if I want to add a KeyEvent, for example, I could do this:

struct KeyArguments {
    Point point;
    int someInt;
};

class KeyEvent : public Event<std::function<void(const KeyArguments&)>, KeyArguments>
{
};

And to use such code:

Point tempPoint{ 1,2 };
KeyEvent::attach("new", func);
KeyEvent::attach("new2", [](KeyArguments args) { std::cout << "Hello\n";}); 
args.point = tempPoint;
args.someInt = 20;
KeyEvent::dispatch(args);
KeyEvent::dettach("new2");
KeyEvent::dispatch(args);

I also wanted to make the design reachable from anywhere in the code, this is why I used static keyword, and this is the part that doesn't really "feel" good.

Should I really be using static in this case? Is there any cons in using such design?

I feel like using template for this case is a bit overkill. For each event create a "new" class (the struct doesn't bother me). Do you think there is a way around that? Is it as bad as I think it is?

EDIT: The design goal was to create an event system that anyone could attach to and get notified when the specific event has happened. For example in a game we would like to distribute an event for KeyPress, so the event system (in the engine) would let the game programmer attach the Player::input function to it, and if he would like, Menu::input as well. Both of them will get notified when a KeyPress event has happened.

Fixed code for map update
Source Link
Zik332
  • 53
  • 1
  • 5

I made this simple event system:

template<typename Func, typename Args>
class Event
{
public:
    static void dispatch(Args args) noexcept
    {
        for (auto listener : listeners)
            listener.second(args);
    }

    static void attach(const std::string& id, Func func) noexcept
    {
        listeners.insert({ id, func });
    }

    static void dettach(const std::string& id) noexcept
    {
        listeners.erase(id);
    }

private:
    static std::unordered_map<std::string, Func> listeners;
};

template<typename Func, typename Args>
std::unordered_map<std::string, Func> Event<Func, Args>::listeners;

What I wanted to do is to let me create any sort of event without needing to do a lot more code, so for example in this code, if I want to add a KeyEvent, for example, I could do this:

struct KeyArguments {
    Point point;
    int someInt;
};

class KeyEvent : public Event<std::function<void(KeyArgumentsconst KeyArguments&)>, KeyArguments>
{
};

And to use such code:

Point tempPoint{ 1,2 };
KeyEvent::attach("new", func);
KeyEvent::attach("new2", [](KeyArguments args) { std::cout << "Hello\n";});
KeyArguments args;
args.point = tempPoint;
args.someInt = 20;
KeyEvent::dispatch(args);
KeyEvent::dettach("new2");
KeyEvent::dispatch(args);

I also wanted to make the design reachable from anywhere in the code, this is why I used static keyword, and this is the part that doesn't really "feel" good.

Should I really be using static in this case? Is there any cons in using such design?

I feel like using template for this case is a bit overkill. For each event create a "new" class (the struct doesn't bother me). Do you think there is a way around that? Is it as bad as I think it is?

I made this simple event system:

template<typename Func, typename Args>
class Event
{
public:
    static void dispatch(Args args) noexcept
    {
        for (auto listener : listeners)
            listener.second(args);
    }

    static void attach(const std::string& id, Func func) noexcept
    {
        listeners.insert({ id, func });
    }

    static void dettach(const std::string& id) noexcept
    {
        listeners.erase(id);
    }

private:
    static std::unordered_map<std::string, Func> listeners;
};

template<typename Func, typename Args>
std::unordered_map<std::string, Func> Event<Func, Args>::listeners;

What I wanted to do is to let me create any sort of event without needing to do a lot more code, so for example in this code, if I want to add a KeyEvent, for example, I could do this:

struct KeyArguments {
    Point point;
    int someInt;
};

class KeyEvent : public Event<std::function<void(KeyArguments)>, KeyArguments>
{
};

And to use such code:

Point tempPoint{ 1,2 };
KeyEvent::attach(func);
KeyEvent::attach([](KeyArguments args) { std::cout << "Hello\n";});
KeyArguments args;
args.point = tempPoint;
args.someInt = 20;
KeyEvent::dispatch(args);

I also wanted to make the design reachable from anywhere in the code, this is why I used static keyword, and this is the part that doesn't really "feel" good.

Should I really be using static in this case? Is there any cons in using such design?

I feel like using template for this case is a bit overkill. For each event create a "new" class (the struct doesn't bother me). Do you think there is a way around that? Is it as bad as I think it is?

I made this simple event system:

template<typename Func, typename Args>
class Event
{
public:
    static void dispatch(Args args) noexcept
    {
        for (auto listener : listeners)
            listener.second(args);
    }

    static void attach(const std::string& id, Func func) noexcept
    {
        listeners.insert({ id, func });
    }

    static void dettach(const std::string& id) noexcept
    {
        listeners.erase(id);
    }

private:
    static std::unordered_map<std::string, Func> listeners;
};

template<typename Func, typename Args>
std::unordered_map<std::string, Func> Event<Func, Args>::listeners;

What I wanted to do is to let me create any sort of event without needing to do a lot more code, so for example in this code, if I want to add a KeyEvent, for example, I could do this:

struct KeyArguments {
    Point point;
    int someInt;
};

class KeyEvent : public Event<std::function<void(const KeyArguments&)>, KeyArguments>
{
};

And to use such code:

Point tempPoint{ 1,2 };
KeyEvent::attach("new", func);
KeyEvent::attach("new2", [](KeyArguments args) { std::cout << "Hello\n";}); 
args.point = tempPoint;
args.someInt = 20;
KeyEvent::dispatch(args);
KeyEvent::dettach("new2");
KeyEvent::dispatch(args);

I also wanted to make the design reachable from anywhere in the code, this is why I used static keyword, and this is the part that doesn't really "feel" good.

Should I really be using static in this case? Is there any cons in using such design?

I feel like using template for this case is a bit overkill. For each event create a "new" class (the struct doesn't bother me). Do you think there is a way around that? Is it as bad as I think it is?

Added `noexcept`
Source Link
Zik332
  • 53
  • 1
  • 5
Loading
removed old code; edited tags
Source Link
200_success
  • 144.2k
  • 22
  • 188
  • 473
Loading
Updated the code
Source Link
Zik332
  • 53
  • 1
  • 5
Loading
deleted 47 characters in body
Source Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237
Loading
Source Link
Zik332
  • 53
  • 1
  • 5
Loading