tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Observer.cpp (2417B)


      1 //
      2 // Copyright 2018 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 // Observer:
      7 //   Implements the Observer pattern for sending state change notifications
      8 //   from Subject objects to dependent Observer objects.
      9 //
     10 //   See design document:
     11 //   https://docs.google.com/document/d/15Edfotqg6_l1skTEL8ADQudF_oIdNa7i8Po43k6jMd4/
     12 
     13 #include "libANGLE/Observer.h"
     14 
     15 #include <algorithm>
     16 
     17 #include "common/debug.h"
     18 
     19 namespace angle
     20 {
     21 namespace
     22 {}  // anonymous namespace
     23 
     24 // Observer implementation.
     25 ObserverInterface::~ObserverInterface() = default;
     26 
     27 // Subject implementation.
     28 Subject::Subject() {}
     29 
     30 Subject::~Subject()
     31 {
     32    resetObservers();
     33 }
     34 
     35 bool Subject::hasObservers() const
     36 {
     37    return !mObservers.empty();
     38 }
     39 
     40 void Subject::onStateChange(SubjectMessage message) const
     41 {
     42    if (mObservers.empty())
     43        return;
     44 
     45    for (const ObserverBindingBase *binding : mObservers)
     46    {
     47        binding->getObserver()->onSubjectStateChange(binding->getSubjectIndex(), message);
     48    }
     49 }
     50 
     51 void Subject::resetObservers()
     52 {
     53    for (angle::ObserverBindingBase *binding : mObservers)
     54    {
     55        binding->onSubjectReset();
     56    }
     57    mObservers.clear();
     58 }
     59 
     60 // ObserverBinding implementation.
     61 ObserverBinding::ObserverBinding() : ObserverBindingBase(nullptr, 0), mSubject(nullptr) {}
     62 
     63 ObserverBinding::ObserverBinding(ObserverInterface *observer, SubjectIndex index)
     64    : ObserverBindingBase(observer, index), mSubject(nullptr)
     65 {
     66    ASSERT(observer);
     67 }
     68 
     69 ObserverBinding::~ObserverBinding()
     70 {
     71    reset();
     72 }
     73 
     74 ObserverBinding::ObserverBinding(const ObserverBinding &other)
     75    : ObserverBindingBase(other), mSubject(nullptr)
     76 {
     77    bind(other.mSubject);
     78 }
     79 
     80 ObserverBinding &ObserverBinding::operator=(const ObserverBinding &other)
     81 {
     82    reset();
     83    ObserverBindingBase::operator=(other);
     84    bind(other.mSubject);
     85    return *this;
     86 }
     87 
     88 void ObserverBinding::bind(Subject *subject)
     89 {
     90    ASSERT(getObserver() || !subject);
     91    if (mSubject)
     92    {
     93        mSubject->removeObserver(this);
     94    }
     95 
     96    mSubject = subject;
     97 
     98    if (mSubject)
     99    {
    100        mSubject->addObserver(this);
    101    }
    102 }
    103 
    104 void ObserverBinding::onStateChange(SubjectMessage message) const
    105 {
    106    getObserver()->onSubjectStateChange(getSubjectIndex(), message);
    107 }
    108 
    109 void ObserverBinding::onSubjectReset()
    110 {
    111    mSubject = nullptr;
    112 }
    113 }  // namespace angle