xref: /aosp_15_r20/external/angle/src/libANGLE/Observer.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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 Worker Subject::Subject() {}
29*8975f5c5SAndroid Build Coastguard Worker 
~Subject()30*8975f5c5SAndroid Build Coastguard Worker Subject::~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 Worker bool 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 Worker void 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 Worker void 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 Worker ObserverBinding::ObserverBinding() : ObserverBindingBase(nullptr, 0), mSubject(nullptr) {}
62*8975f5c5SAndroid Build Coastguard Worker 
ObserverBinding(ObserverInterface * observer,SubjectIndex index)63*8975f5c5SAndroid Build Coastguard Worker ObserverBinding::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 Worker ObserverBinding::~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 Worker ObserverBinding::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 Worker ObserverBinding &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 Worker void 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 Worker void 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 Worker void 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