uses callbacks for event handling