Good question. Our game libraries usually do not provide many events on purpose.
There are specific reasons for avoiding event systems: Multithreading and input routing.
In a multithreaded game the game subsystems (input, graphics, physics, animation, particles, network, AI, ...) should be able to execute in parallel. While these systems are running in parallel, it is not allowed to influence their states from outside (e.g. while the physics simulation is updating another subsystem must not change the rigid body states because that would be a write-write conflict).
Now, if those systems raise events (like keyboard events, collision events, etc.) while they are running, then the event listener can receive the event but is not currently allowed to react on the event. For example, a game object listens to the left mouse button event and wants to move a rigid body in response. When the game object receives the event, it cannot immediately change the physics state because the physics is currently updating.
That means, subsystem events have to be deferrred until the execution is thread-safe, or the event listeners must only note the occurance of the event and react to it later when it is thread-safe. Both options kind of defeat the purpose of an event system.
Also, the game logic might want to consume the events in a specific order. The window that is currently on top should handle input first. Or while a game object is executing a drag-and-drop operation, it should receive the input before the top-most window.
It is difficult for the input system to push the information in the correct order. But it is easy for game objects to pull informations in a specific, dynamic order - even in parallel.
Further, some game objects might want to react to device input even if this device input was already handled by another game object.
Event-driven architectures work great for desktop application but are limiting for game-loop-driven systems. With our current design it is still possible to add an event system if needed. (After the input manager has finished, simply iterate over the state and raise some events.)
This is a complicated topic, and to summarize: I don't know how to use an event system without limiting parallelism or introducing multi-threading problems and other headaches. We have settled on the current design after researching and testing parallel game architecture options (double-buffering, pipelining, etc.).