Welcome to mirror list, hosted at ThFree Co, Russian Federation.

Listeners.java « util « mapswithme « com « src « android - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: e65c63e751287f0d331bbf6a1db608ef732d8478 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package com.mapswithme.util;

import android.support.annotation.NonNull;

import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;

/**
 * `Registrator` pattern implementation which allows to maintain the list of listeners,
 * offers safe adding/removing of listeners during iteration.
 * <br/>{@link #finishIterate()} must be called after iteration is complete.
 */
public final class Listeners<T> implements Iterable<T>
{
  private final Set<T> mListeners = new LinkedHashSet<>();
  private final Set<T> mListenersToAdd = new LinkedHashSet<>();
  private final Set<T> mListenersToRemove = new LinkedHashSet<>();

  private boolean mIterating;

  @Override
  public @NonNull Iterator<T> iterator()
  {
    if (mIterating)
      throw new RuntimeException("finishIterate() must be called before new iteration");

    mIterating = true;
    return mListeners.iterator();
  }

  /**
   * Completes listeners iteration. Must be called after iteration is done.
   */
  public void finishIterate()
  {
    if (!mListenersToRemove.isEmpty())
      mListeners.removeAll(mListenersToRemove);

    if (!mListenersToAdd.isEmpty())
      mListeners.addAll(mListenersToAdd);

    mListenersToAdd.clear();
    mListenersToRemove.clear();
    mIterating = false;
  }

  /**
   * Safely registers new listener. If registered during iteration, new listener will NOT be called before current iteration is complete.
   */
  public void register(T listener)
  {
    if (mIterating)
    {
      mListenersToRemove.remove(listener);
      if (!mListeners.contains(listener))
        mListenersToAdd.add(listener);
    }
    else
      mListeners.add(listener);
  }

  /**
   * Safely unregisters listener. If unregistered during iteration, old listener WILL be called in the current iteration.
   */
  public void unregister(T listener)
  {
    if (mIterating)
    {
      mListenersToAdd.remove(listener);
      if (mListeners.contains(listener))
        mListenersToRemove.add(listener);
    }
    else
      mListeners.remove(listener);
  }

  public int getSize()
  {
    int res = mListeners.size();
    if (mIterating)
    {
      res += mListenersToAdd.size();
      res -= mListenersToRemove.size();
    }

    return res;
  }

  public boolean isEmpty()
  {
    return (getSize() <= 0);
  }
}