Event System Implementation Issues

Hey everybody, lately I've been working with game engines, trying to understand how they work, starting to make my own, etc. However, I've decided not to start with OpenGL or anything like that, I initially planned on starting with the Component Entity System. And I succeeded. I made a full Component Entity System and I'm very proud of it. And then it was time to make the event system. Oh dear.

You see, good programming practices, complex topics, actual knowledge of programming, and other things relating to these phrases are things that do not agree with me. So when it came time to make this, I found myself somewhat confused. Therefore, I made the decision to see how some other Event systems worked, and found one that I was a huge fan of. It belongs to the Amazon Lumberyard engine, and I'm very interested in replicating a very small, lightweight, simple version of it.

On to the problem. I learned how to use the LY event system, and in my multiple weeks of attempts, I just can't seem to figure it out. For starters, I'll explain how someone goes about using this sytem:

To make a Bus to use events with, it's very simple!

1
2
3
4
5
6
7
8
9
10
11
12
class NewBus
    : public EBus
{
public:
    static const EBus::HandlerPolicy HandlerPolicy = EBus::HandlerPolicy::Multiple // This means that any number of handlers can connect to a given address on the bus.
    static const EBus::AddressPolicy AddressPolicy = EBus::AddressPolicy::Single // Only one address will be enabled on this bus, which means that if you call Broadcast (send an event), it will be sent to every handler.
    //This is the equivalent setup I'd like for my system as of this moment. I may add addressing etc. in the future, but at the moment I don't really want to complicate things more than they already are, so for my bus these will not be present.

    //This is the first bit of black magic. In order to "register" an event persay, all you need to do is make a pure virtual function for it.
    virtual void OnThingHappening(/*Args go here if you want them*/) = 0; //Non pure virtual is also allowed
    //Once this is done, it's like magic. The bus automatically puts this into the "Event"... Something... On the bus. I'll show you what I mean in a moment.
}

Now onto how one listens to a bus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class ListenerComponent
    : public NewBus::Handler
{
public:
    void WhenYouWantToConnect()
    {
        NewBus::Handler::BusConnect();
    }
    void WhenYouWantToDisconnect()
    {
        NewBus::Handler::BusDisconnect();
    }

    //And presto. Like magic, OnThingHappening is an overrideable function. However, you'll notice that I didn't inherit from NewBus. I inherited from NewBus::Handler. How can OnThingHappening be in Handler if it was in NewBus when it was declared? This is brick wall #1 for me.
    void OnThingHappening(/*Args*/) override
    {
        //Do stuff.
    }
}

And how you send an event:

1
2
3
4
5
6
7
8
class SenderComponent
{
    void IEventInYourGeneralDirection()
    {
        //How did OnThingHappening suddenly be accessible through "NewBus::Events"!? Wut. 
        NewBus::Broadcast(&NewBus::Events::OnThingHappening, /*List your args here*/)
    }
}


All I can think is that Handler must be nested inside of EBus, but then how can override a virtual function created in something inheriting from EBus if you're inheriting from EBus::Handler? How can it exist in two places when you've only written it in one? On top of that, how is it suddenly in "EBus::Events"? I'm so confused!

I understand that some of these questions are hard to answer as the source for their EBus sytem isn't posted along with all of this, but then again I'm trying to make a dumbed down version for learning purposes. I've tried to read through the actual source, but I'd rather not copy their code if I don't have to, the whole point of doing this was to learn, and as I don't fully understand what their code does, I don't feel that it will help me understand it to any reasonable degree to just copy it in and hope it works.
Last edited on
According to the documentation I found on line, you made a small mistake in your first snippet. It should be:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class NewBusInterface  // note: this should be an Interface class, not the bus class
    : public AZ::EBusInterface
{
public:
    // you also got these named incorrectly.  The namespace is AZ, not EBus.
    static const AZ::EBusHandlerPolicy HandlerPolicy = EBus::HandlerPolicy::Multiple 
    static const AZ::EBusAddressPolicy AddressPolicy = EBus::AddressPolicy::Single 
    

    virtual void OnThingHappening(/*Args go here if you want them*/) = 0; 
}

using NewBus = AZ::EBus<NewBusInterface>;  // Here you define the bus.  It takes 1 or 2
                                           // arguments, the first of which is an Interface. 


I suspect that AZ::EBus< Interface, BusTraits > has the following declaration (or something similar) in it.

class Handler : pubic Interface { ... };

Now, the Handler class nested within your NewBus class is derived from NewBusInterface, which is where you declared OnThingHappening.


Topic archived. No new replies allowed.