I made an event calling system
Tags: ruby
Published: 2019-10-15 00:41:14

Something I’ve wanted to make ever since I heard there wasn’t an equivalent method in Ruby is an event system. A customizable system that is extremely dynamic and can initiate many methods on many specific objects with just one input. This system should be able to flag many objects by a common attribute regardless of class, like with a tag describing said attribute. The system should also be able to have different types of events that can be made even on the fly that will describe the trigger for the event, which will be defined as the event type. I also had a stretch goal for a priority system that will help an event reduce the many tagged objects to only the one with the highest priority and exclusively execute in them.

This system is very inspired by the concept of events in pretty much every game engine and really assists with controlling method calls on many specific objects.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/9aqaienfsgwfpwv9yimq.png)

I first made the Event class and defined these variables on it: type, targets, and priority which defaults to nil for now. The class is just meant to be an instance of an event that holds the data of an event as its passed around different methods to make and send it to the listening objects.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/hg5rz4ydvgemc6ju40az.png)

I then made an EventSender class that makes new events and sends them to receivers. The sender has a class method to make new events with the type, targets and priority arguments. This way, I can call a new event inside of any other method in another class like a Person or Animal. Once made, the sender class pushes the new event to the EventReceiver class.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/918jd88ahnx36kieapbb.png)

The EventReceiver is currently instanced for every object’s tag. Each receiver gets a tag and owner variable. The receiver class then compares a newly received event and collects every receiver in the @@all with a tag matching the targets variable on the event and then goes through case statements of when different event types are called on the matching tagged objects.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/zqh8z0ki7hnt7diks38n.png)

I later realized you could change the case statement to one comparison: only call the event on receivers with the right tags that have the event type stored in the interactable_events array that will have event types pushed into it on initialization.

...

I’ve modified the event system now to sort the receivers by tag into a hash where each tag is a key pointing to an array of receivers, allowing me to call events on these arrays without enumerating over other irrelevant tags to find them.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/8v8wv5n1qdw420xd4epg.png)

I also added a priority system where both events and receivers have priority ratings and the receivers with priorities equal to or greater than the event demanded priority.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/xfdfwgn56efz0rgzwxy1.png)

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/xc4mwiwn3oqz9o3jflmg.png)

The system now calls the event_call method on the receiver’s owner with the event passed in where you determine behavior of the object based on the event type through case statements.

What I like about these systems is that you can make something up from scratch and pass it like the app knows whats going on. On a whim you make a nighttime event that makes all creatures with a dog trait perform a sleep method or even all dogs with leopard print shoes with a simple tweak and call.