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