• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
2 // reserved. Use of this source code is governed by a BSD-style license that
3 // can be found in the LICENSE file.
4 
5 #include "libcef/common/value_base.h"
6 
CefValueController()7 CefValueController::CefValueController()
8     : owner_value_(nullptr), owner_object_(nullptr) {}
9 
~CefValueController()10 CefValueController::~CefValueController() {
11   // Everything should already have been removed.
12   DCHECK(!owner_value_ && !owner_object_);
13   DCHECK(reference_map_.empty());
14   DCHECK(dependency_map_.empty());
15 }
16 
SetOwner(void * value,Object * object)17 void CefValueController::SetOwner(void* value, Object* object) {
18   DCHECK(value && object);
19 
20   // Controller should already be locked.
21   DCHECK(locked());
22 
23   // Owner should only be set once.
24   DCHECK(!owner_value_ && !owner_object_);
25 
26   owner_value_ = value;
27   owner_object_ = object;
28 }
29 
AddReference(void * value,Object * object)30 void CefValueController::AddReference(void* value, Object* object) {
31   DCHECK(value && object);
32 
33   // Controller should already be locked.
34   DCHECK(locked());
35 
36   // Controller should currently have an owner.
37   DCHECK(owner_value_);
38 
39   // Values should only be added once.
40   DCHECK(reference_map_.find(value) == reference_map_.end());
41   DCHECK(value != owner_value_);
42 
43   reference_map_.insert(std::make_pair(value, object));
44 }
45 
Remove(void * value,bool notify_object)46 void CefValueController::Remove(void* value, bool notify_object) {
47   DCHECK(value);
48 
49   // Controller should already be locked.
50   DCHECK(locked());
51 
52   // Controller should currently have an owner.
53   DCHECK(owner_value_);
54 
55   if (value == owner_value_) {
56     // Should never notify when removing the owner object.
57     DCHECK(!notify_object);
58 
59     owner_value_ = nullptr;
60     owner_object_ = nullptr;
61 
62     // Remove all references.
63     if (reference_map_.size() > 0) {
64       ReferenceMap::iterator it = reference_map_.begin();
65       for (; it != reference_map_.end(); ++it)
66         it->second->OnControlRemoved();
67       reference_map_.clear();
68     }
69 
70     // Remove all dependencies.
71     dependency_map_.clear();
72   } else {
73     ReferenceMap::iterator it = reference_map_.find(value);
74     if (it != reference_map_.end()) {
75       // Remove the reference.
76       if (notify_object)
77         it->second->OnControlRemoved();
78       reference_map_.erase(it);
79     }
80   }
81 }
82 
Get(void * value)83 CefValueController::Object* CefValueController::Get(void* value) {
84   DCHECK(value);
85 
86   // Controller should already be locked.
87   DCHECK(locked());
88 
89   if (value == owner_value_) {
90     return owner_object_;
91   } else {
92     ReferenceMap::iterator it = reference_map_.find(value);
93     if (it != reference_map_.end())
94       return it->second;
95     return nullptr;
96   }
97 }
98 
AddDependency(void * parent,void * child)99 void CefValueController::AddDependency(void* parent, void* child) {
100   DCHECK(parent && child && parent != child);
101 
102   // Controller should already be locked.
103   DCHECK(locked());
104 
105   DependencyMap::iterator it = dependency_map_.find(parent);
106   if (it == dependency_map_.end()) {
107     // New set.
108     DependencySet set;
109     set.insert(child);
110     dependency_map_.insert(std::make_pair(parent, set));
111   } else if (it->second.find(child) == it->second.end()) {
112     // Update existing set.
113     it->second.insert(child);
114   }
115 }
116 
RemoveDependencies(void * value)117 void CefValueController::RemoveDependencies(void* value) {
118   DCHECK(value);
119 
120   // Controller should already be locked.
121   DCHECK(locked());
122 
123   if (dependency_map_.empty())
124     return;
125 
126   DependencyMap::iterator it_dependency = dependency_map_.find(value);
127   if (it_dependency == dependency_map_.end())
128     return;
129 
130   // Start with the set of dependencies for the current value.
131   DependencySet remove_set = it_dependency->second;
132   dependency_map_.erase(it_dependency);
133 
134   DependencySet::iterator it_value;
135   ReferenceMap::iterator it_reference;
136 
137   while (remove_set.size() > 0) {
138     it_value = remove_set.begin();
139     value = *it_value;
140     remove_set.erase(it_value);
141 
142     // Does the current value have dependencies?
143     it_dependency = dependency_map_.find(value);
144     if (it_dependency != dependency_map_.end()) {
145       // Append the dependency set to the remove set.
146       remove_set.insert(it_dependency->second.begin(),
147                         it_dependency->second.end());
148       dependency_map_.erase(it_dependency);
149     }
150 
151     // Does the current value have a reference?
152     it_reference = reference_map_.find(value);
153     if (it_reference != reference_map_.end()) {
154       // Remove the reference.
155       it_reference->second->OnControlRemoved();
156       reference_map_.erase(it_reference);
157     }
158   }
159 }
160 
TakeFrom(CefValueController * other)161 void CefValueController::TakeFrom(CefValueController* other) {
162   DCHECK(other);
163 
164   // Both controllers should already be locked.
165   DCHECK(locked());
166   DCHECK(other->locked());
167 
168   if (!other->reference_map_.empty()) {
169     // Transfer references from the other to this.
170     ReferenceMap::iterator it = other->reference_map_.begin();
171     for (; it != other->reference_map_.end(); ++it) {
172       // References should only be added once.
173       DCHECK(reference_map_.find(it->first) == reference_map_.end());
174       reference_map_.insert(std::make_pair(it->first, it->second));
175     }
176     other->reference_map_.clear();
177   }
178 
179   if (!other->dependency_map_.empty()) {
180     // Transfer dependencies from the other to this.
181     DependencyMap::iterator it_other = other->dependency_map_.begin();
182     for (; it_other != other->dependency_map_.end(); ++it_other) {
183       DependencyMap::iterator it_me = dependency_map_.find(it_other->first);
184       if (it_me == dependency_map_.end()) {
185         // All children are new.
186         dependency_map_.insert(
187             std::make_pair(it_other->first, it_other->second));
188       } else {
189         // Evaluate each child.
190         DependencySet::iterator it_other_set = it_other->second.begin();
191         for (; it_other_set != it_other->second.end(); ++it_other_set) {
192           if (it_me->second.find(*it_other_set) == it_me->second.end())
193             it_me->second.insert(*it_other_set);
194         }
195       }
196     }
197   }
198 }
199 
Swap(void * old_value,void * new_value)200 void CefValueController::Swap(void* old_value, void* new_value) {
201   DCHECK(old_value && new_value && old_value != new_value);
202 
203   // Controller should already be locked.
204   DCHECK(locked());
205 
206   if (owner_value_ == old_value)
207     owner_value_ = new_value;
208 
209   if (!reference_map_.empty()) {
210     ReferenceMap::iterator it = reference_map_.find(old_value);
211     if (it != reference_map_.end()) {
212       // References should only be added once.
213       DCHECK(reference_map_.find(new_value) == reference_map_.end());
214       reference_map_.insert(std::make_pair(new_value, it->second));
215       reference_map_.erase(it);
216     }
217   }
218 
219   if (!dependency_map_.empty()) {
220     DependencyMap::iterator it = dependency_map_.find(old_value);
221     if (it != dependency_map_.end()) {
222       dependency_map_.insert(std::make_pair(new_value, it->second));
223       dependency_map_.erase(it);
224     }
225 
226     it = dependency_map_.begin();
227     for (; it != dependency_map_.end(); ++it) {
228       DependencySet::iterator dit = it->second.find(old_value);
229       if (dit != it->second.end()) {
230         it->second.insert(new_value);
231         it->second.erase(dit);
232       }
233     }
234   }
235 }
236