Crossfire Server, Trunk
AssetsCollection.h
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 2020 the Crossfire Development Team
5  *
6  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
7  * welcome to redistribute it under certain conditions. For details, please
8  * see COPYING and LICENSE.
9  *
10  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
11  */
12 
13 #ifndef ASSETSCOLLECTION_H
14 #define ASSETSCOLLECTION_H
15 
16 #include <string>
17 #include <unordered_map>
18 #include <set>
19 #include <vector>
20 #include <algorithm>
21 #include <functional>
22 
27 template<class T>
28 extern void asset_destroy(T *asset);
29 
35 template <class T, class Key>
36 extern T *asset_create(const Key &key);
37 
54 template<class T, class Key = std::string>
56 
57  public:
58 
62  virtual ~AssetsCollection() {
63  clear();
64  }
65 
69  void clear() {
70  for (auto asset : m_assets) {
71  asset_destroy(asset.second);
72  }
73  m_assets.clear();
74  }
75 
80  size_t count() const {
81  return m_assets.size();
82  }
83 
89  T *get(const Key& name) {
90  auto asset = m_assets.find(name);
91  if (asset != m_assets.end()) {
92  return asset->second;
93  }
94 
95  T *add = asset_create<T>(name);
96  m_assets[name] = add;
97  m_undefined.insert(name);
98  added(add);
99  return add;
100  }
101 
108  T *find(const Key& name) {
109  auto asset = m_assets.find(name);
110  return asset != m_assets.end() ? asset->second : nullptr;
111  }
112 
120  T *define(const Key& name, T *asset) {
121  m_undefined.erase(name);
122  auto existing = m_assets.find(name);
123  if (existing != m_assets.end()) {
124  replace(existing->second, asset);
125  return existing->second;
126  }
127 
128  m_assets[name] = asset;
129  added(asset);
130  return asset;
131  }
132 
139  T *next(T *current) {
140  if (m_assets.empty()) {
141  return nullptr;
142  }
143  if (current == nullptr) {
144  return m_assets.begin()->second;
145  }
146 
147  auto c = std::find_if(m_assets.begin(), m_assets.end(), [&current](auto& item) { return item.second == current; });
148  if (c == m_assets.end() || (++c) == m_assets.end()) {
149  return nullptr;
150  }
151  return c->second;
152  }
153 
158  void each(std::function<void(T *)> op) {
159  std::for_each(m_assets.begin(), m_assets.end(), [&op] (auto item) { op(item.second); });
160  }
161 
167  T *first(std::function<bool(const T *)> op) {
168  auto found = std::find_if(m_assets.begin(), m_assets.end(), [&op] (auto item) { return op(item.second); });
169  return found == m_assets.end() ? nullptr : found->second;
170  }
171 
177  const std::set<Key>& undefined() const { return m_undefined; }
178 
183  std::vector<Key> keys() const {
184  std::vector<Key> k;
185  std::for_each(m_assets.cbegin(), m_assets.cend(), [&k] (const auto &asset) { k.push_back(asset.first); });
186  return k;
187  }
188 
189  protected:
190  std::unordered_map<Key, T*> m_assets;
191  std::set<Key> m_undefined;
198  virtual void replace(T *existing, T *update) = 0;
199 
203  virtual void added(T *) { }
204 };
205 
206 #endif /* ASSETSCOLLECTION_H */
AssetsCollection::count
size_t count() const
Definition: AssetsCollection.h:80
AssetsCollection::undefined
const std::set< Key > & undefined() const
Definition: AssetsCollection.h:177
AssetsCollection::first
T * first(std::function< bool(const T *)> op)
Definition: AssetsCollection.h:167
c
static event_registration c
Definition: citylife.cpp:425
AssetsCollection::added
virtual void added(T *)
Definition: AssetsCollection.h:203
AssetsCollection::keys
std::vector< Key > keys() const
Definition: AssetsCollection.h:183
AssetsCollection::find
T * find(const Key &name)
Definition: AssetsCollection.h:108
AssetsCollection::replace
virtual void replace(T *existing, T *update)=0
AssetsCollection
Definition: AssetsCollection.h:55
AssetsCollection::define
T * define(const Key &name, T *asset)
Definition: AssetsCollection.h:120
AssetsCollection::m_undefined
std::set< Key > m_undefined
Definition: AssetsCollection.h:191
AssetsCollection::get
T * get(const Key &name)
Definition: AssetsCollection.h:89
AssetsCollection::each
void each(std::function< void(T *)> op)
Definition: AssetsCollection.h:158
AssetsCollection::next
T * next(T *current)
Definition: AssetsCollection.h:139
AssetsCollection::~AssetsCollection
virtual ~AssetsCollection()
Definition: AssetsCollection.h:62
is_valid_types_gen.found
found
Definition: is_valid_types_gen.py:39
asset_destroy
void asset_destroy(T *asset)
item
Definition: item.py:1
give.op
op
Definition: give.py:33
castle_read.key
key
Definition: castle_read.py:64
AssetsCollection::m_assets
std::unordered_map< Key, T * > m_assets
Definition: AssetsCollection.h:190
AssetsCollection::clear
void clear()
Definition: AssetsCollection.h:69
asset_create
T * asset_create(const Key &key)
replace.current
current
Definition: replace.py:64
give.name
name
Definition: give.py:27