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. Subject()28Subject::Subject() {} 29 ~Subject()30Subject::~Subject() 31 { 32 resetObservers(); 33 } 34 hasObservers() const35bool Subject::hasObservers() const 36 { 37 return !mObservers.empty(); 38 } 39 onStateChange(SubjectMessage message) const40void 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 resetObservers()51void Subject::resetObservers() 52 { 53 for (angle::ObserverBindingBase *binding : mObservers) 54 { 55 binding->onSubjectReset(); 56 } 57 mObservers.clear(); 58 } 59 60 // ObserverBinding implementation. ObserverBinding()61ObserverBinding::ObserverBinding() : ObserverBindingBase(nullptr, 0), mSubject(nullptr) {} 62 ObserverBinding(ObserverInterface * observer,SubjectIndex index)63ObserverBinding::ObserverBinding(ObserverInterface *observer, SubjectIndex index) 64 : ObserverBindingBase(observer, index), mSubject(nullptr) 65 { 66 ASSERT(observer); 67 } 68 ~ObserverBinding()69ObserverBinding::~ObserverBinding() 70 { 71 reset(); 72 } 73 ObserverBinding(const ObserverBinding & other)74ObserverBinding::ObserverBinding(const ObserverBinding &other) 75 : ObserverBindingBase(other), mSubject(nullptr) 76 { 77 bind(other.mSubject); 78 } 79 operator =(const ObserverBinding & other)80ObserverBinding &ObserverBinding::operator=(const ObserverBinding &other) 81 { 82 reset(); 83 ObserverBindingBase::operator=(other); 84 bind(other.mSubject); 85 return *this; 86 } 87 bind(Subject * subject)88void 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 onStateChange(SubjectMessage message) const104void ObserverBinding::onStateChange(SubjectMessage message) const 105 { 106 getObserver()->onSubjectStateChange(getSubjectIndex(), message); 107 } 108 onSubjectReset()109void ObserverBinding::onSubjectReset() 110 { 111 mSubject = nullptr; 112 } 113 } // namespace angle 114