summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/libANGLE/signal_utils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/src/libANGLE/signal_utils.cpp')
-rwxr-xr-xgfx/angle/src/libANGLE/signal_utils.cpp103
1 files changed, 103 insertions, 0 deletions
diff --git a/gfx/angle/src/libANGLE/signal_utils.cpp b/gfx/angle/src/libANGLE/signal_utils.cpp
new file mode 100755
index 000000000..62d45b953
--- /dev/null
+++ b/gfx/angle/src/libANGLE/signal_utils.cpp
@@ -0,0 +1,103 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// signal_utils:
+// Helper classes for tracking dependent state changes between objects.
+// These changes are signaled to the dependent class via channels.
+
+#include "libANGLE/signal_utils.h"
+
+#include <algorithm>
+
+#include "common/debug.h"
+
+namespace angle
+{
+
+BroadcastChannel::BroadcastChannel()
+{
+}
+
+BroadcastChannel::~BroadcastChannel()
+{
+ reset();
+}
+
+void BroadcastChannel::addReceiver(ChannelBinding *receiver)
+{
+ ASSERT(std::find(mReceivers.begin(), mReceivers.end(), receiver) == mReceivers.end());
+ mReceivers.push_back(receiver);
+}
+
+void BroadcastChannel::removeReceiver(ChannelBinding *receiver)
+{
+ auto iter = std::find(mReceivers.begin(), mReceivers.end(), receiver);
+ ASSERT(iter != mReceivers.end());
+ mReceivers.erase(iter);
+}
+
+void BroadcastChannel::signal() const
+{
+ if (mReceivers.empty())
+ return;
+
+ for (const auto *receiver : mReceivers)
+ {
+ receiver->signal();
+ }
+}
+
+void BroadcastChannel::reset()
+{
+ for (auto receiver : mReceivers)
+ {
+ receiver->onChannelClosed();
+ }
+ mReceivers.clear();
+}
+
+ChannelBinding::ChannelBinding(SignalReceiver *receiver, SignalToken token)
+ : mChannel(nullptr), mReceiver(receiver), mToken(token)
+{
+ ASSERT(receiver);
+}
+
+ChannelBinding::~ChannelBinding()
+{
+ reset();
+}
+
+void ChannelBinding::bind(BroadcastChannel *channel)
+{
+ ASSERT(mReceiver);
+ if (mChannel)
+ {
+ mChannel->removeReceiver(this);
+ }
+
+ mChannel = channel;
+
+ if (mChannel)
+ {
+ mChannel->addReceiver(this);
+ }
+}
+
+void ChannelBinding::reset()
+{
+ bind(nullptr);
+}
+
+void ChannelBinding::signal() const
+{
+ mReceiver->signal(mToken);
+}
+
+void ChannelBinding::onChannelClosed()
+{
+ mChannel = nullptr;
+}
+
+} // namespace angle