/*
* Copyright (c) 2013, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
package com.marshalchen.common.uimodule.rebound;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* Because Java doesn't permit additions/removals to a list while iterating, a callback cannot
* remove itself when it is being called.
*
* This class makes it safe for Callbacks to remove themselves. Also, it is thread-safe.
*
* Implementation detail: This class works by storing an inner set that will be modified by the
* calls to add/removeListener. When getListeners() or iterator() is called, an immutable copy from
* the inner set is returned. That copy will be reused if no changes have been done to the set since
* last request for it.
*/
public class ReentrantCallback<CallbackClass> implements Iterable<CallbackClass> {
private final Set<CallbackClass> mListeners;
private Set<CallbackClass> mReturnSet;
/**
* Creates a reentrant set of callbacks.
*/
public ReentrantCallback() {
mListeners = new HashSet<CallbackClass>();
mReturnSet = null;
}
/**
* Returns an immutable set of Callbacks.
*/
public synchronized Set<CallbackClass> getListeners() {
if (mReturnSet == null) {
mReturnSet = Collections.unmodifiableSet(mListeners);
}
return mReturnSet;
}
@Override
public synchronized Iterator<CallbackClass> iterator() {
if (mReturnSet == null) {
mReturnSet = Collections.unmodifiableSet(mListeners);
}
return mReturnSet.iterator();
}
/**
* Add a listener
*
* @param listener The listener
*/
public synchronized void addListener(CallbackClass listener) {
mListeners.add(listener);
mReturnSet = null;
}
/**
* Remove a listener
*
* @param listener The listener
*/
public synchronized void removeListener(CallbackClass listener) {
mListeners.remove(listener);
mReturnSet = null;
}
/**
* Gets a count of all listeners.
*/
public synchronized int count() {
return mListeners.size();
}
/**
* Clears all listeners
*/
public synchronized void clear() {
mListeners.clear();
mReturnSet = null;
}
}