1/**
2 *******************************************************************************
3 * Copyright (C) 2001-2004, International Business Machines Corporation and    *
4 * others. All Rights Reserved.                                                *
5 *******************************************************************************
6 */
7#ifndef ICUNOTIF_H
8#define ICUNOTIF_H
9
10#include "unicode/utypes.h"
11
12#if UCONFIG_NO_SERVICE
13
14U_NAMESPACE_BEGIN
15
16/*
17 * Allow the declaration of APIs with pointers to BreakIterator
18 * even when break iteration is removed from the build.
19 */
20class ICUNotifier;
21
22U_NAMESPACE_END
23
24#else
25
26#include "unicode/uobject.h"
27#include "unicode/unistr.h"
28
29#include "mutex.h"
30#include "uvector.h"
31
32U_NAMESPACE_BEGIN
33
34class U_COMMON_API EventListener : public UObject {
35public:
36    virtual ~EventListener();
37
38public:
39    static UClassID U_EXPORT2 getStaticClassID();
40
41    virtual UClassID getDynamicClassID() const;
42
43public:
44#ifdef SERVICE_DEBUG
45    virtual UnicodeString& debug(UnicodeString& result) const {
46      return debugClass(result);
47    }
48
49    virtual UnicodeString& debugClass(UnicodeString& result) const {
50      return result.append("Key");
51    }
52#endif
53};
54
55/**
56 * <p>Abstract implementation of a notification facility.  Clients add
57 * EventListeners with addListener and remove them with removeListener.
58 * Notifiers call notifyChanged when they wish to notify listeners.
59 * This queues the listener list on the notification thread, which
60 * eventually dequeues the list and calls notifyListener on each
61 * listener in the list.</p>
62 *
63 * <p>Subclasses override acceptsListener and notifyListener
64 * to add type-safe notification.  AcceptsListener should return
65 * true if the listener is of the appropriate type; ICUNotifier
66 * itself will ensure the listener is non-null and that the
67 * identical listener is not already registered with the Notifier.
68 * NotifyListener should cast the listener to the appropriate
69 * type and call the appropriate method on the listener.
70 */
71
72class U_COMMON_API ICUNotifier : public UMemory  {
73private: UMTX notifyLock;
74private: UVector* listeners;
75
76public:
77    ICUNotifier(void);
78
79    virtual ~ICUNotifier(void);
80
81    /**
82     * Add a listener to be notified when notifyChanged is called.
83     * The listener must not be null. AcceptsListener must return
84     * true for the listener.  Attempts to concurrently
85     * register the identical listener more than once will be
86     * silently ignored.
87     */
88    virtual void addListener(const EventListener* l, UErrorCode& status);
89
90    /**
91     * Stop notifying this listener.  The listener must
92     * not be null.  Attemps to remove a listener that is
93     * not registered will be silently ignored.
94     */
95    virtual void removeListener(const EventListener* l, UErrorCode& status);
96
97    /**
98     * ICU doesn't spawn its own threads.  All listeners are notified in
99     * the thread of the caller.  Misbehaved listeners can therefore
100     * indefinitely block the calling thread.  Callers should beware of
101     * deadlock situations.
102     */
103    virtual void notifyChanged(void);
104
105protected:
106    /**
107     * Subclasses implement this to return TRUE if the listener is
108     * of the appropriate type.
109     */
110    virtual UBool acceptsListener(const EventListener& l) const = 0;
111
112    /**
113     * Subclasses implement this to notify the listener.
114     */
115    virtual void notifyListener(EventListener& l) const = 0;
116};
117
118U_NAMESPACE_END
119
120/* UCONFIG_NO_SERVICE */
121#endif
122
123/* ICUNOTIF_H */
124#endif
125