summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/libANGLE/Observer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/checkout/src/libANGLE/Observer.cpp')
-rw-r--r--gfx/angle/checkout/src/libANGLE/Observer.cpp113
1 files changed, 113 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/libANGLE/Observer.cpp b/gfx/angle/checkout/src/libANGLE/Observer.cpp
new file mode 100644
index 0000000000..75f51648a4
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Observer.cpp
@@ -0,0 +1,113 @@
+//
+// Copyright 2018 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.
+//
+// Observer:
+// Implements the Observer pattern for sending state change notifications
+// from Subject objects to dependent Observer objects.
+//
+// See design document:
+// https://docs.google.com/document/d/15Edfotqg6_l1skTEL8ADQudF_oIdNa7i8Po43k6jMd4/
+
+#include "libANGLE/Observer.h"
+
+#include <algorithm>
+
+#include "common/debug.h"
+
+namespace angle
+{
+namespace
+{} // anonymous namespace
+
+// Observer implementation.
+ObserverInterface::~ObserverInterface() = default;
+
+// Subject implementation.
+Subject::Subject() {}
+
+Subject::~Subject()
+{
+ resetObservers();
+}
+
+bool Subject::hasObservers() const
+{
+ return !mObservers.empty();
+}
+
+void Subject::onStateChange(SubjectMessage message) const
+{
+ if (mObservers.empty())
+ return;
+
+ for (const ObserverBindingBase *binding : mObservers)
+ {
+ binding->getObserver()->onSubjectStateChange(binding->getSubjectIndex(), message);
+ }
+}
+
+void Subject::resetObservers()
+{
+ for (angle::ObserverBindingBase *binding : mObservers)
+ {
+ binding->onSubjectReset();
+ }
+ mObservers.clear();
+}
+
+// ObserverBinding implementation.
+ObserverBinding::ObserverBinding() : ObserverBindingBase(nullptr, 0), mSubject(nullptr) {}
+
+ObserverBinding::ObserverBinding(ObserverInterface *observer, SubjectIndex index)
+ : ObserverBindingBase(observer, index), mSubject(nullptr)
+{
+ ASSERT(observer);
+}
+
+ObserverBinding::~ObserverBinding()
+{
+ reset();
+}
+
+ObserverBinding::ObserverBinding(const ObserverBinding &other)
+ : ObserverBindingBase(other), mSubject(nullptr)
+{
+ bind(other.mSubject);
+}
+
+ObserverBinding &ObserverBinding::operator=(const ObserverBinding &other)
+{
+ reset();
+ ObserverBindingBase::operator=(other);
+ bind(other.mSubject);
+ return *this;
+}
+
+void ObserverBinding::bind(Subject *subject)
+{
+ ASSERT(getObserver() || !subject);
+ if (mSubject)
+ {
+ mSubject->removeObserver(this);
+ }
+
+ mSubject = subject;
+
+ if (mSubject)
+ {
+ mSubject->addObserver(this);
+ }
+}
+
+void ObserverBinding::onStateChange(SubjectMessage message) const
+{
+ getObserver()->onSubjectStateChange(getSubjectIndex(), message);
+}
+
+void ObserverBinding::onSubjectReset()
+{
+ mSubject = nullptr;
+}
+} // namespace angle