Event-based main loop