void CDA_CellMLElement::addEventListener ( const std::wstring& aType, iface::events::EventListener* aListener, bool aUseCapture ) throw(std::exception&) { // Only bubbling is supported, as these events can't be cancelled. if (aUseCapture) throw iface::cellml_api::CellMLException(L"Only bubbling events are supported."); int32_t event = FindEventByName(aType); // Unknown events are silently ignored, as per the DOM Events specification. if (event == -1) return; // Find the adaptor, if there is one... ListenerToAdaptor_t::iterator i = mListenerToAdaptor.find(aListener); ObjRef<CDA_CellMLElementEventAdaptor> adaptor; if (i == mListenerToAdaptor.end()) { // We add a refcount, putting the total to 2... adaptor = new CDA_CellMLElementEventAdaptor(this, aListener); // One refcount is used for the map, the other belongs to the ObjRef and // will be automatically dropped. mListenerToAdaptor.insert(std::pair<iface::events::EventListener*, CDA_CellMLElementEventAdaptor*> (aListener, adaptor) ); } else adaptor = (*i).second; try { adaptor->newEventType(event); } catch (std::exception& e) { adaptor->considerDestruction(); throw e; } }