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