changed object api, rewrote more event-driven