Improve a simple event handler

Hipreme msnmancini at hotmail.com
Wed Jan 19 11:17:10 UTC 2022


On Sunday, 16 January 2022 at 20:01:09 UTC, JN wrote:
> On Saturday, 15 January 2022 at 23:15:16 UTC, JN wrote:
>>
>> Is there some way I could improve this with some D features? 
>> My main gripes with it are:
>>
>
> Managed to dramatically simplify it to 10 lines of code with 
> variadic templates.
>
> ```d
> import std.stdio;
>
> struct Event(T...)
> {
>     void function(T)[] listeners;
>
>     void addListener(void function(T) handler)
>     {
>         listeners ~= handler;
>     }
>
>     void emit(T args)
>     {
>         foreach (listener; listeners)
>         {
>             listener(args);
>         }
>     }
> }
>
> void onResize(uint newWidth, uint newHeight)
> {
>     writefln("Resized: %d %d", newWidth, newHeight);
> }
>
> void main()
> {
>     Event!(uint, uint) windowResizeEvent;
>     windowResizeEvent.addListener(&onResize);
>
>     windowResizeEvent.emit(1000, 2000);
> }
> ```
>
> I am very happy with this solution.


My advice is to make your listeners return a boolean. This 
boolean is used to basically stop propagating the event. And 
debugging it seems really hard to be honest, so, incrementing it 
a little, I would do:


```d

struct ListenerInfo
{
   string name;
   string file;
   uint line;
   string registeredAt;
}
struct Event(T...)
{
   bool function(T)[] listeners;
   ListenerInfo[] info;
   void addListener(bool function(T) handler, string name, string 
file = __FILE__, uint line = __LINE__, string registeredAt = 
__PRETTY_FUNCTION__)
   {
      listeners~= handler;
      info~= ListenerInfo(name, file, line, registeredAt);
   }

   void emit(T args)
   {
     foreach(i, l; listeners)
     {
       if(l(args))
       {
         writeln(info[i]);
         break;
       }
     }
   }
}

```

You could even extend this concept further by making it return an 
enum value for actually removing the listener when executed, 
stopping propagation. Or you could have access to the listener 
info inside the arguments too.



More information about the Digitalmars-d-learn mailing list