The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
property_handler.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2016 by Yurii Chernyi <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 /**
16  * Composite AI component
17  * @file
18  */
19 
20 
21 #ifndef AI_COMPOSITE_PROPERTY_HANDLER_HPP_INCLUDED
22 #define AI_COMPOSITE_PROPERTY_HANDLER_HPP_INCLUDED
23 
24 #include "utils/functional.hpp"
25 #include "config.hpp"
27 
28 namespace ai{
29 
30 template<typename T>
32 public:
34  : count_(0), element_(element)
35  {
36  }
38 
39  bool operator()(const T& t)
40  {
41  if ( (!element_.id.empty()) && (element_.id == t->get_id()) ) {
42  return true;
43  }
44  if (count_ == element_.position) {
45  return true;
46  }
47  count_++;
48  return false;
49  }
50 
51 private:
52  int count_;
54 };
55 
56 
57 class component;
58 
60 public:
61 
63 
64  virtual component* handle_get(const path_element &child) = 0;
65  virtual bool handle_change(const path_element &child, config cfg) = 0;
66  virtual bool handle_add(const path_element &child, const config &cfg) = 0;
67  virtual bool handle_delete(const path_element &child) = 0;
68  virtual std::vector< component* > handle_get_children() = 0;
69 };
70 
72 
73 template<typename T>
75 public:
77  typedef std::vector< boost::shared_ptr<T> > t_ptr_vector;
78 
79  vector_property_handler(const std::string &property, t_ptr_vector &values, std::function<void(t_ptr_vector&, const config&)> &construction_factory)
80  : factory_(construction_factory), property_(property), values_(values){}
81 
82 
84  {
85  typename t_ptr_vector::iterator i = std::find_if(values_.begin(),values_.end(),path_element_matches<t_ptr>(child));
86  if (i!=values_.end()){
87  return &*(*i);
88  }
89  return nullptr;
90  }
91  bool handle_change(const path_element &child, config cfg)
92  {
93  if (!handle_delete(child)) {
94  return false;
95  }
96  if (!cfg.has_attribute("id")) {
97  cfg["id"] = child.id;
98  }
99 
100  return handle_add(child,cfg);
101  }
102  bool handle_add(const path_element &child, const config &cfg)
103  {
104  //if the id is not empty, try to delete all with this id
105  if (!cfg["id"].empty()) {
106  path_element with_same_id;
107  with_same_id.id = cfg["id"].str();
108  with_same_id.property = property_;
109  with_same_id.position=-1;
110  handle_delete(with_same_id);
111  }
112 
113  typename t_ptr_vector::iterator i = std::find_if(values_.begin(),values_.end(),path_element_matches<t_ptr>(child));
114  return do_add(i-values_.begin(),cfg);
115  }
116 
117  bool handle_delete(const path_element &child)
118  {
119  //* is a special case - 'delete all'
120  if (child.id == "*") {
121  values_.clear();
122  return true;
123  }
124 
125  typename t_ptr_vector::iterator i = std::find_if(values_.begin(),values_.end(),path_element_matches<t_ptr>(child));
126  if (i!=values_.end()){
127  values_.erase(i);
128  return true;
129  }
130  return false;
131  }
132 
133 
134  std::vector<component*> handle_get_children()
135  {
136  std::vector<component*> children;
137  for (t_ptr v : values_) {
138  children.push_back(&*v);
139  }
140  return children;
141  }
142 
143 protected:
144  void call_factory(t_ptr_vector& vec, const config& cfg)
145  {
146  factory_(vec, cfg);
147  }
148 private:
149  bool do_add(int pos, const config &cfg)
150  {
151  if (pos<0) {
152  pos = values_.size();
153  }
154  t_ptr_vector values;
155  call_factory(values,cfg);
156  int j=0;
157  for (t_ptr b : values ) {
158  values_.insert(values_.begin()+pos+j,b);
159  j++;
160  }
161  return (j>0);
162  }
163 
164  std::function<void(t_ptr_vector&, const config&)> factory_;
166  t_ptr_vector &values_;
167 
168 };
169 
170 
171 
172 template<typename T>
176 public:
177 
178  facets_property_handler(const std::string &property, t_ptr_vector &values, t_ptr& def, std::function<void(t_ptr_vector&, const config&)> &construction_factory)
179  : vector_property_handler<T>(property, values, construction_factory)
180  , default_(def)
181  {
182  }
183 
185  {
186  // special case - 'get the default facet'
187  if (child.id == "default_facet") {
188  return default_.get();
189  }
191  }
192 
193  bool handle_change(const path_element &child, config cfg)
194  {
195  // special case - 'replace the default facet'
196  if (child.id == "default_facet") {
197  t_ptr_vector values;
198  this->call_factory(values,cfg);
199  default_ = values.back();
200  return true;
201  }
203  }
204 
205  std::vector<component*> handle_get_children()
206  {
207  std::vector<component*> children = vector_property_handler<T>::handle_get_children();
208  children.push_back(default_.get());
209  return children;
210  }
211 
212 private:
213  t_ptr& default_;
214 };
215 
216 
217 
218 template<typename T>
220 public:
222  typedef std::map< std::string, t_ptr > aspect_map;
223 
224  aspect_property_handler(const std::string &property, aspect_map &aspects, std::function<void(aspect_map&, const config&, std::string)> &construction_factory)
225  : property_(property), aspects_(aspects), factory_(construction_factory)
226  {
227  }
228 
229 
231  {
232  typename aspect_map::const_iterator a = aspects_.find(child.id);
233  if (a!=aspects_.end()){
234  return &*a->second;
235  }
236  return nullptr;
237  }
238 
239  bool handle_change(const path_element &child, config cfg)
240  {
241  if (aspects_.find(child.id) == aspects_.end()) {
242  return false;
243  }
244  if (!cfg.has_attribute("name")) {
245  cfg["name"] = "composite_aspect";
246  }
247  cfg["id"] = child.id;
248  factory_(aspects_, cfg, child.id);
249  return true;
250  }
251 
252  bool handle_add(const path_element &/*child*/, const config &/*cfg*/)
253  {
254  return false;
255  }
256 
257  bool handle_delete(const path_element &child)
258  {
259  //* is a special case - 'delete all facets'
260  if (child.id == "*") {
261  bool b = false;
262  for (typename aspect_map::value_type a : aspects_) {
263  b |= a.second->delete_all_facets();
264  }
265  return b;
266  }
267  return false;
268  }
269 
270 
271  std::vector<component*> handle_get_children()
272  {
273  std::vector<component*> children;
274  for (typename aspect_map::value_type a : aspects_) {
275  children.push_back(&*a.second);
276  }
277  return children;
278  }
279 
280 private:
281 
283  aspect_map &aspects_;
284  std::function<void(aspect_map&, const config&, std::string)> factory_;
285 
286 };
287 
288 
289 
290 template<typename X>
291 static void register_vector_property(std::map<std::string,property_handler_ptr> &property_handlers, const std::string &property, std::vector< boost::shared_ptr<X> > &values, std::function<void(std::vector< boost::shared_ptr<X> >&, const config&)> construction_factory)
292 {
293  property_handler_ptr handler_ptr = property_handler_ptr(new vector_property_handler<X>(property,values,construction_factory));
294  property_handlers.insert(std::make_pair(property,handler_ptr));
295 }
296 
297 template<typename X>
298 static void register_facets_property(std::map<std::string,property_handler_ptr> &property_handlers, const std::string &property, std::vector< boost::shared_ptr<X> > &values, boost::shared_ptr<X>& def, std::function<void(std::vector< boost::shared_ptr<X> >&, const config&)> construction_factory)
299 {
300  property_handler_ptr handler_ptr = property_handler_ptr(new facets_property_handler<X>(property,values,def,construction_factory));
301  property_handlers.insert(std::make_pair(property,handler_ptr));
302 }
303 
304 template<typename X>
305 static void register_aspect_property(std::map<std::string,property_handler_ptr> &property_handlers, const std::string &property, std::map< std::string, boost::shared_ptr<X> > &aspects, std::function<void(std::map< std::string, boost::shared_ptr<X> >&, const config&, std::string)> construction_factory)
306 {
307  property_handler_ptr handler_ptr = property_handler_ptr(new aspect_property_handler<X>(property,aspects,construction_factory));
308  property_handlers.insert(std::make_pair(property,handler_ptr));
309 }
310 
311 
312 } //of namespace ai
313 
314 #endif
facets_property_handler(const std::string &property, t_ptr_vector &values, t_ptr &def, std::function< void(t_ptr_vector &, const config &)> &construction_factory)
vector_property_handler< T >::t_ptr_vector t_ptr_vector
std::vector< component * > handle_get_children()
int pos
Definition: formula.cpp:800
boost::shared_ptr< event_handler > handler_ptr
Shared pointer to handler objects.
Definition: handlers.hpp:44
vector_property_handler(const std::string &property, t_ptr_vector &values, std::function< void(t_ptr_vector &, const config &)> &construction_factory)
bool handle_add(const path_element &, const config &)
bool handle_add(const path_element &child, const config &cfg)
static void register_vector_property(std::map< std::string, property_handler_ptr > &property_handlers, const std::string &property, std::vector< boost::shared_ptr< X > > &values, std::function< void(std::vector< boost::shared_ptr< X > > &, const config &)> construction_factory)
void call_factory(t_ptr_vector &vec, const config &cfg)
GLdouble GLdouble t
Definition: glew.h:1366
Definitions for the interface to Wesnoth Markup Language (WML).
std::vector< component * > handle_get_children()
GLboolean GLenum GLenum GLvoid * values
Definition: glew.h:3799
bool handle_delete(const path_element &child)
bool handle_delete(const path_element &child)
GLdouble GLdouble GLdouble b
Definition: glew.h:6966
A small explanation about what's going on here: Each action has access to two game_info objects First...
Definition: actions.cpp:57
vector_property_handler< T >::t_ptr t_ptr
static void register_aspect_property(std::map< std::string, property_handler_ptr > &property_handlers, const std::string &property, std::map< std::string, boost::shared_ptr< X > > &aspects, std::function< void(std::map< std::string, boost::shared_ptr< X > > &, const config &, std::string)> construction_factory)
component * handle_get(const path_element &child)
static void register_facets_property(std::map< std::string, property_handler_ptr > &property_handlers, const std::string &property, std::vector< boost::shared_ptr< X > > &values, boost::shared_ptr< X > &def, std::function< void(std::vector< boost::shared_ptr< X > > &, const config &)> construction_factory)
std::vector< component * > handle_get_children()
const GLdouble * v
Definition: glew.h:1359
path_element_matches(const path_element &element)
A component of the AI framework.
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:7319
boost::shared_ptr< T > t_ptr
INT property
Definition: wglew.h:144
std::map< std::string, t_ptr > aspect_map
bool handle_change(const path_element &child, config cfg)
std::string property
Definition: component.hpp:50
virtual bool handle_change(const path_element &child, config cfg)=0
std::string id
Definition: component.hpp:51
virtual component * handle_get(const path_element &child)=0
size_t i
Definition: function.cpp:1057
virtual bool handle_delete(const path_element &child)=0
bool do_add(int pos, const config &cfg)
component * handle_get(const path_element &child)
bool has_attribute(const std::string &key) const
Definition: config.cpp:514
boost::shared_ptr< T > t_ptr
std::vector< boost::shared_ptr< T > > t_ptr_vector
bool handle_change(const path_element &child, config cfg)
component * handle_get(const path_element &child)
std::function< void(aspect_map &, const config &, std::string)> factory_
virtual bool handle_add(const path_element &child, const config &cfg)=0
boost::shared_ptr< base_property_handler > property_handler_ptr
Definition: component.hpp:55
std::string::const_iterator iterator
Definition: tokenizer.hpp:21
std::function< void(t_ptr_vector &, const config &)> factory_
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
bool handle_change(const path_element &child, config cfg)
virtual std::vector< component * > handle_get_children()=0
GLsizei const GLcharARB ** string
Definition: glew.h:4503
aspect_property_handler(const std::string &property, aspect_map &aspects, std::function< void(aspect_map &, const config &, std::string)> &construction_factory)