main loop event handling using callbacks