refactor event system