Original Post
Over the last several months I have read numerous articles both here and on other development forums and blogs where programmers advocate the use of function pointer callbacks for event handling, particularly in the cases of things like an entity-component framework. So in my game engine, I have implemented such an event framework and my component systems use this event processing heavily. These component systems provide an event type and a callback function pointer during their initialization phase and as particular events are sent for various entities from other systems, the receiving systems receive the events and update the appropriate entity accordingly.
When I went to implement movement, my concern is the sheer number of event callbacks being fired to manage a player's movement. When the player controller receives a movement action request, it updates an internal movement vector it manages. So by processing the forward key once, the vector will set the current forward facing movement vector to +1. When I depress the forward key, it changes the value to 0. I have implemented bullet as my physics engine and so my motion state object's set world transform method is constantly being called and an update is being dispatched back to the transform component as an event for the entity to set the position and orientation accordingly.
The solution obviously works, but I am only talking about a single character in a world that will eventually be filled with numerous other objects that move such as NPCs. For a single player moving across the play field, I can easily see the number of callbacks fired from the motion state climb to 10,000 in a matter of ~10 seconds of play. Now what happens in this chain of events is that physics notify the transform to update, the transform in turn dispatches an an event (transform broadcast) that it was updated and those registered are informed.
The benefit here is that everything is entirely decoupled. One system does not know who dispatches events to it and why and it doesn't care what anyone else does with the events that it dispatches when certain internal states are reached, which ultimately I believe is part of the goal of composition and reuse of code.
However, I do have concern with so many function callbacks. Internally, the event system has a map keyed off the event type and the value of the map is a list of function pointers to be invoked when that event occurs. So the look-up and dispatch is fast. The functions simply do a static cast from the base event class to the event class they expect and then perform whatever task are necessary. I'm concerned that this, while it seems fast and reliable, may become a bottleneck compared to other means like using component references or having one system invoke updates to data on another system and live with the idea that each system knows about one another but the components are oblivious to this "outside" world.
When I went to implement movement, my concern is the sheer number of event callbacks being fired to manage a player's movement. When the player controller receives a movement action request, it updates an internal movement vector it manages. So by processing the forward key once, the vector will set the current forward facing movement vector to +1. When I depress the forward key, it changes the value to 0. I have implemented bullet as my physics engine and so my motion state object's set world transform method is constantly being called and an update is being dispatched back to the transform component as an event for the entity to set the position and orientation accordingly.
The solution obviously works, but I am only talking about a single character in a world that will eventually be filled with numerous other objects that move such as NPCs. For a single player moving across the play field, I can easily see the number of callbacks fired from the motion state climb to 10,000 in a matter of ~10 seconds of play. Now what happens in this chain of events is that physics notify the transform to update, the transform in turn dispatches an an event (transform broadcast) that it was updated and those registered are informed.
The benefit here is that everything is entirely decoupled. One system does not know who dispatches events to it and why and it doesn't care what anyone else does with the events that it dispatches when certain internal states are reached, which ultimately I believe is part of the goal of composition and reuse of code.
However, I do have concern with so many function callbacks. Internally, the event system has a map keyed off the event type and the value of the map is a list of function pointers to be invoked when that event occurs. So the look-up and dispatch is fast. The functions simply do a static cast from the base event class to the event class they expect and then perform whatever task are necessary. I'm concerned that this, while it seems fast and reliable, may become a bottleneck compared to other means like using component references or having one system invoke updates to data on another system and live with the idea that each system knows about one another but the components are oblivious to this "outside" world.