/** ******************************************************************************* * Copyright (C) 2001-2003, International Business Machines Corporation and * * others. All Rights Reserved. * ******************************************************************************* */ #ifndef ICUNOTIF_H #define ICUNOTIF_H #include "unicode/utypes.h" #if UCONFIG_NO_SERVICE U_NAMESPACE_BEGIN /* * Allow the declaration of APIs with pointers to BreakIterator * even when break iteration is removed from the build. */ class ICUNotifier; U_NAMESPACE_END #else #include "unicode/uobject.h" #include "unicode/unistr.h" #include "mutex.h" #include "uvector.h" U_NAMESPACE_BEGIN class U_COMMON_API EventListener : public UObject { public: virtual ~EventListener() {} public: static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; } virtual UClassID getDynamicClassID() const { return getStaticClassID(); } public: virtual UnicodeString& debug(UnicodeString& result) const { return debugClass(result); } virtual UnicodeString& debugClass(UnicodeString& result) const { return result.append("Key"); } private: static const char fgClassID; }; /** *
Abstract implementation of a notification facility. Clients add * EventListeners with addListener and remove them with removeListener. * Notifiers call notifyChanged when they wish to notify listeners. * This queues the listener list on the notification thread, which * eventually dequeues the list and calls notifyListener on each * listener in the list.
* *Subclasses override acceptsListener and notifyListener * to add type-safe notification. AcceptsListener should return * true if the listener is of the appropriate type; ICUNotifier * itself will ensure the listener is non-null and that the * identical listener is not already registered with the Notifier. * NotifyListener should cast the listener to the appropriate * type and call the appropriate method on the listener. */ class U_COMMON_API ICUNotifier : public UMemory { private: UMTX notifyLock; private: UVector* listeners; public: ICUNotifier(void) : notifyLock(0), listeners(NULL) { } virtual ~ICUNotifier(void) { { Mutex lmx(¬ifyLock); delete listeners; listeners = NULL; } umtx_destroy(¬ifyLock); } /** * Add a listener to be notified when notifyChanged is called. * The listener must not be null. AcceptsListener must return * true for the listener. Attempts to concurrently * register the identical listener more than once will be * silently ignored. */ virtual void addListener(const EventListener* l, UErrorCode& status); /** * Stop notifying this listener. The listener must * not be null. Attemps to remove a listener that is * not registered will be silently ignored. */ virtual void removeListener(const EventListener* l, UErrorCode& status); /** * ICU doesn't spawn its own threads. All listeners are notified in * the thread of the caller. Misbehaved listeners can therefore * indefinitely block the calling thread. Callers should beware of * deadlock situations. */ virtual void notifyChanged(void); protected: /** * Subclasses implement this to return TRUE if the listener is * of the appropriate type. */ virtual UBool acceptsListener(const EventListener& l) const = 0; /** * Subclasses implement this to notify the listener. */ virtual void notifyListener(EventListener& l) const = 0; }; U_NAMESPACE_END /* UCONFIG_NO_SERVICE */ #endif /* ICUNOTIF_H */ #endif