diff options
Diffstat (limited to 'gfx/angle/checkout/src/libANGLE/Observer.cpp')
-rw-r--r-- | gfx/angle/checkout/src/libANGLE/Observer.cpp | 113 |
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 |