• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(ObserverInterface * observer,SubjectIndex index)61 ObserverBinding::ObserverBinding(ObserverInterface *observer, SubjectIndex index)
62     : ObserverBindingBase(observer, index), mSubject(nullptr)
63 {
64     ASSERT(observer);
65 }
66 
~ObserverBinding()67 ObserverBinding::~ObserverBinding()
68 {
69     reset();
70 }
71 
72 ObserverBinding::ObserverBinding(const ObserverBinding &other) = default;
73 
74 ObserverBinding &ObserverBinding::operator=(const ObserverBinding &other) = default;
75 
bind(Subject * subject)76 void ObserverBinding::bind(Subject *subject)
77 {
78     ASSERT(getObserver());
79     if (mSubject)
80     {
81         mSubject->removeObserver(this);
82     }
83 
84     mSubject = subject;
85 
86     if (mSubject)
87     {
88         mSubject->addObserver(this);
89     }
90 }
91 
onStateChange(SubjectMessage message) const92 void ObserverBinding::onStateChange(SubjectMessage message) const
93 {
94     getObserver()->onSubjectStateChange(getSubjectIndex(), message);
95 }
96 
onSubjectReset()97 void ObserverBinding::onSubjectReset()
98 {
99     mSubject = nullptr;
100 }
101 }  // namespace angle
102