зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1361259. P1 - let ListenerBase inherit RevocableToken. r=gerald
This is needed by P2 where |Listener| must be ref-counted so we can use NewRunnableMethod() to pass event data to the listener function. MozReview-Commit-ID: CpAgOmxcijc --HG-- extra : rebase_source : f80a302788f6312a912d710262322b30b2bce4c0 extra : source : 4ce544aacca4897bc3d2bb25fd415df93dc940b4
This commit is contained in:
Родитель
3b7d5554e3
Коммит
93fb1e26e2
|
@ -13,7 +13,6 @@
|
|||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/Tuple.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsTArray.h"
|
||||
|
@ -44,8 +43,12 @@ public:
|
|||
return mRevoked;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Virtual destructor is required since we might delete a Listener object
|
||||
// through its base type pointer.
|
||||
virtual ~RevocableToken() { }
|
||||
|
||||
private:
|
||||
~RevocableToken() {}
|
||||
Atomic<bool> mRevoked;
|
||||
};
|
||||
|
||||
|
@ -213,17 +216,13 @@ enum class EventPassMode : int8_t {
|
|||
Move
|
||||
};
|
||||
|
||||
class ListenerBase {
|
||||
public:
|
||||
ListenerBase() : mToken(new RevocableToken()) {}
|
||||
~ListenerBase() {
|
||||
MOZ_ASSERT(Token()->IsRevoked(), "Must disconnect the listener.");
|
||||
class ListenerBase : public RevocableToken
|
||||
{
|
||||
protected:
|
||||
virtual ~ListenerBase()
|
||||
{
|
||||
MOZ_ASSERT(IsRevoked(), "Must disconnect the listener.");
|
||||
}
|
||||
RevocableToken* Token() const {
|
||||
return mToken;
|
||||
}
|
||||
private:
|
||||
const RefPtr<RevocableToken> mToken;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -232,16 +231,16 @@ private:
|
|||
* to provide different Dispatch() overloads depending on EventPassMode.
|
||||
*/
|
||||
template <EventPassMode Mode, typename... As>
|
||||
class Listener : public ListenerBase {
|
||||
class Listener : public ListenerBase
|
||||
{
|
||||
public:
|
||||
virtual ~Listener() {}
|
||||
virtual void Dispatch(const As&... aEvents) = 0;
|
||||
};
|
||||
|
||||
template <typename... As>
|
||||
class Listener<EventPassMode::Move, As...> : public ListenerBase {
|
||||
class Listener<EventPassMode::Move, As...> : public ListenerBase
|
||||
{
|
||||
public:
|
||||
virtual ~Listener() {}
|
||||
virtual void Dispatch(As... aEvents) = 0;
|
||||
};
|
||||
|
||||
|
@ -253,7 +252,7 @@ template <typename Target, typename Function, EventPassMode, typename... As>
|
|||
class ListenerImpl : public Listener<EventPassMode::Copy, As...> {
|
||||
public:
|
||||
ListenerImpl(Target* aTarget, const Function& aFunction)
|
||||
: mHelper(ListenerBase::Token(), aTarget, aFunction) {}
|
||||
: mHelper(this, aTarget, aFunction) {}
|
||||
void Dispatch(const As&... aEvents) override {
|
||||
mHelper.Dispatch(aEvents...);
|
||||
}
|
||||
|
@ -266,7 +265,7 @@ class ListenerImpl<Target, Function, EventPassMode::Move, As...>
|
|||
: public Listener<EventPassMode::Move, As...> {
|
||||
public:
|
||||
ListenerImpl(Target* aTarget, const Function& aFunction)
|
||||
: mHelper(ListenerBase::Token(), aTarget, aFunction) {}
|
||||
: mHelper(this, aTarget, aFunction) {}
|
||||
void Dispatch(As... aEvents) override {
|
||||
mHelper.Dispatch(Move(aEvents)...);
|
||||
}
|
||||
|
@ -378,7 +377,7 @@ class MediaEventSourceImpl {
|
|||
void PruneListeners() {
|
||||
int32_t last = static_cast<int32_t>(mListeners.Length()) - 1;
|
||||
for (int32_t i = last; i >= 0; --i) {
|
||||
if (mListeners[i]->Token()->IsRevoked()) {
|
||||
if (mListeners[i]->IsRevoked()) {
|
||||
mListeners.RemoveElementAt(i);
|
||||
}
|
||||
}
|
||||
|
@ -391,8 +390,8 @@ class MediaEventSourceImpl {
|
|||
PruneListeners();
|
||||
MOZ_ASSERT(Lp == ListenerPolicy::NonExclusive || mListeners.IsEmpty());
|
||||
auto l = mListeners.AppendElement();
|
||||
l->reset(new ListenerImpl<Target, Function>(aTarget, aFunction));
|
||||
return MediaEventListener((*l)->Token());
|
||||
*l = new ListenerImpl<Target, Function>(aTarget, aFunction);
|
||||
return MediaEventListener(*l);
|
||||
}
|
||||
|
||||
// |Method| takes one or more arguments.
|
||||
|
@ -472,7 +471,7 @@ protected:
|
|||
auto&& l = mListeners[i];
|
||||
// Remove disconnected listeners.
|
||||
// It is not optimal but is simple and works well.
|
||||
if (l->Token()->IsRevoked()) {
|
||||
if (l->IsRevoked()) {
|
||||
mListeners.RemoveElementAt(i);
|
||||
continue;
|
||||
}
|
||||
|
@ -482,7 +481,7 @@ protected:
|
|||
|
||||
private:
|
||||
Mutex mMutex;
|
||||
nsTArray<UniquePtr<Listener>> mListeners;
|
||||
nsTArray<RefPtr<Listener>> mListeners;
|
||||
};
|
||||
|
||||
template <typename... Es>
|
||||
|
|
Загрузка…
Ссылка в новой задаче