Ion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
resourceholder.cc
Go to the documentation of this file.
1 
18 #include "ion/gfx/resourceholder.h"
19 
20 #include <algorithm>
21 
22 namespace ion {
23 namespace gfx {
24 
26  : resources_(*this),
27  resource_count_(0),
28  fields_(*this),
29  label_(kLabelChanged, std::string(), this) {}
30 
42  for (const auto& group : resources_)
43  for (const auto& entry : group)
44  entry.second->holder_ = nullptr;
45 
46  for (const auto& group : resources_)
47  for (const auto& entry : group)
48  entry.second->OnDestroyed();
49 }
50 
52  ResourceBase* resource) const {
53  if (resource) {
54  DCHECK_EQ(resource->GetKey(), key);
55  DCHECK(resource->holder_ == nullptr || resource->holder_ == this);
57  const size_t num_fields = fields_.size();
58  for (size_t i = 0; i < num_fields; ++i)
59  resource->OnChanged(fields_[i]->GetBit());
60  }
61 
62  ResourceBase* old_resource = nullptr;
63  base::WriteLock write_lock(&lock_);
64  base::WriteGuard guard(&write_lock);
65 
68  if (index >= resources_.size()) {
69  if (resource) {
71  resources_.resize(index + 1U, ResourceGroup(*this));
72  } else {
75  return;
76  }
77  }
78 
80  auto found = resources_[index].find(key);
81  old_resource = (found == resources_[index].end() ? nullptr : found->second);
82 
84  if (resource) {
86  resource->holder_ = this;
87  if (old_resource) {
90  old_resource->holder_ = nullptr;
91  found->second = resource;
92  } else {
94  resources_[index].emplace(key, resource);
95  }
96  } else if (old_resource) {
98  old_resource->holder_ = nullptr;
99  resources_[index].erase(found);
100  if (index + 1 == resources_.size()) {
102  auto first_nonempty = std::find_if(resources_.rbegin(), resources_.rend(),
103  [](const ResourceGroup& group) { return !group.empty(); });
104  resources_.resize(std::distance(first_nonempty, resources_.rend()),
105  ResourceGroup(*this));
106  }
107  }
109 
113  if (resource && !old_resource)
114  ++resource_count_;
115  else if (!resource && old_resource)
116  --resource_count_;
117 
119  DCHECK(resources_.empty() || !resources_.back().empty());
120 }
121 
123  const size_t count = resources_.size();
124  if (index >= count) return nullptr;
125  auto found = resources_[index].find(key);
126  return found == resources_[index].end() ? nullptr : found->second;
127 }
128 
130 
131 } // namespace gfx
132 } // namespace ion
This class can be used in place of std::unordered_map to allow an Ion Allocator to be used for memory...
void SetResource(size_t index, ResourceKey key, ResourceBase *resource) const
Sets the resource at the passed index and key.
#define DCHECK(expr)
Definition: logging.h:331
ResourceHolder()
The constructor is protected because this is an abstract base class.
~ResourceHolder() override
The destructor invokes the resource callback.
A LockGuard locks a mutex when created, and unlocks it when destroyed.
Definition: lockguards.h:90
ResourceKey GetKey() const
Retrieve a key that disambiguates between multiple resources created for the same holder by the same ...
Definition: resourcebase.h:51
A WriteLock obtains a write lock, but has a similar interface to a Mutex and can be used with a Write...
#define DCHECK_EQ(val1, val2)
Definition: logging.h:332
ResourceBase * GetResource(size_t index, ResourceKey key) const
Returns the Resource at the given index and key, or NULL if no resource was previously set at that lo...
intptr_t ResourceKey
Type of identifiers used to disambiguate between multiple resources created for the same Ion object b...
Definition: resourcebase.h:27
ResourceBase is an internal abstract base class for managed resources.
Definition: resourcebase.h:36
virtual void OnChanged(const int bit)=0
Informs the resource that something has changed and that it needs to update itself.