The Battle for Wesnoth  1.15.0+dev
filter.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2018 by Chris Beck <render787@gmail.com>
3  Part of the Battle for Wesnoth Project https://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  * This namespace contains the function that checks if a unit matches
17  * a filter. It helps by simplifying the unit object (which before now
18  * holds the "match" function).
19  *
20  * TODO:
21  * Make a class that abstracts a unit filter, assembles the constituent
22  * side filters and terrain filters and conditional filters, and caches
23  * these to speed up repeated application of the filter.
24  */
25 
26 #pragma once
27 
28 #include "units/ptr.hpp"
29 #include "utils/make_enum.hpp"
30 
31 #include "display_context.hpp"
32 #include "filter_context.hpp"
33 #include "units/map.hpp"
34 #include "variable.hpp"
35 
36 #include <memory>
37 #include <vector>
38 
39 class filter_context;
40 class unit;
41 class config;
42 class vconfig;
43 struct map_location;
44 
45 
46 
48 {
49  MAKE_ENUM (CONDITIONAL_TYPE,
50  (AND, "and")
51  (OR, "or")
52  (NOT, "not")
53  )
54  struct filter_error : public game::error
55  {
56  explicit filter_error(const std::string& message = "filter error")
57  : game::error(message)
58  {
59  }
60  };
61 
63  {
64  const unit& u;
66  const unit* u2;
69 
70  const filter_context& context() const
71  {
72  if(fc) {
73  return *fc;
74  }
75  throw filter_error();
76  }
77  // This constructor is here to shut down warnings that the default constructor couldn't be generated.
78  // It's technically unnecessary since lacking of a default constructor doesn't prevent aggregate-initialization, but...
79  unit_filter_args(const unit& u, map_location loc, const unit* u2, const filter_context* fc, bool use_flat_tod)
80  : u(u), loc(loc), u2(u2), fc(fc), use_flat_tod(use_flat_tod)
81  {}
82  };
83 
85  {
86  virtual bool matches(const unit_filter_args&) const = 0;
87  virtual ~unit_filter_base() {}
88  };
89 
91  {
93 
94  template<typename C, typename F>
95  void create_attribute(const config::attribute_value c, C conv, F func);
96  template<typename F>
97  void create_child(const vconfig& c, F func);
98 
99  void fill(vconfig cfg);
100 
101  virtual bool matches(const unit_filter_args& u) const override;
102  bool filter_impl(const unit_filter_args& u) const;
103 
104  std::vector<std::shared_ptr<unit_filter_base>> children_;
105  std::vector<std::pair<CONDITIONAL_TYPE, unit_filter_compound>> cond_children_;
106  };
107 
108 }
109 
111 {
112 public:
113  explicit unit_filter(vconfig cfg);
114 
115  unit_filter(const unit_filter&) = default;
116  unit_filter& operator=(const unit_filter&) = default;
117 
118  unit_filter(unit_filter&&) = default;
119  unit_filter& operator=(unit_filter&&) = default;
120 
122  use_flat_tod_ = value;
123  return *this;
124  }
125 
126  /// Determine if *this matches @a filter at a specified location.
127  /// Use this for units on a recall list, or to test for a match if
128  /// a unit is hypothetically moved.
129  bool matches(const unit & u, const map_location & loc) const {
130  return impl_.matches(unit_filter_impl::unit_filter_args{u, loc, nullptr, fc_, use_flat_tod_});
131  }
132 
133  /// Determine if *this matches @a filter at its current location.
134  /// (Only use for units currently on the map; otherwise use the overload
135  /// that takes a location, possibly with a null location.)
136  bool matches(const unit & u) const;
137 
138  bool matches(const unit & u, const map_location & loc, const unit & u2) const {
139  return impl_.matches(unit_filter_impl::unit_filter_args{u, loc, &u2, fc_, use_flat_tod_});
140  }
141 
142  bool matches(const unit & u, const unit & u2) const;
143 
144  bool operator()(const unit & u, const map_location & loc) const {
145  return matches(u, loc);
146  }
147 
148  bool operator()(const unit & u) const {
149  return matches(u);
150  }
151 
152  bool operator()(const unit & u, const map_location & loc, const unit & u2) const {
153  return matches(u, loc, u2);
154  }
155 
156  bool operator()(const unit & u, const unit & u2) const {
157  return matches(u, u2);
158  }
159 
160  std::vector<const unit *> all_matches_on_map(const map_location* loc = nullptr, const unit* other_unit = nullptr) const;
161 
162  std::vector<const unit*> all_matches_at(const map_location& loc) const {
163  return all_matches_on_map(&loc);
164  }
165 
166  std::vector<const unit*> all_matches_with_unit(const unit& u) const {
167  return all_matches_on_map(nullptr, &u);
168  }
169 
170  std::vector<const unit*> all_matches_with_unit_at(const unit& u, const map_location& loc) const {
171  return all_matches_on_map(&loc, &u);
172  }
173 
174  unit_const_ptr first_match_on_map() const;
175 
176  config to_config() const {
177  return cfg_.get_config();
178  }
179 
180  bool empty() const {
181  return cfg_.get_config().empty();
182  }
183 
184 private:
185 
191 };
boost::intrusive_ptr< const unit > unit_const_ptr
Definition: ptr.hpp:30
bool empty() const
Definition: filter.hpp:180
const filter_context * fc_
Definition: filter.hpp:187
This class represents a single unit of a specific type.
Definition: unit.hpp:99
int max_matches_
Definition: filter.hpp:190
unit_filter & set_use_flat_tod(bool value)
Definition: filter.hpp:121
Variant for storing WML attributes.
static l_noret error(LoadState *S, const char *why)
Definition: lundump.cpp:39
bool operator()(const unit &u, const map_location &loc) const
Definition: filter.hpp:144
vconfig cfg_
Definition: filter.hpp:186
bool matches(const unit &u, const map_location &loc) const
Determine if *this matches filter at a specified location.
Definition: filter.hpp:129
const filter_context & context() const
Definition: filter.hpp:70
std::vector< const unit * > all_matches_with_unit(const unit &u) const
Definition: filter.hpp:166
std::vector< const unit * > all_matches_with_unit_at(const unit &u, const map_location &loc) const
Definition: filter.hpp:170
unit_filter_impl::unit_filter_compound impl_
Definition: filter.hpp:189
bool use_flat_tod_
Definition: filter.hpp:188
bool operator()(const unit &u) const
Definition: filter.hpp:148
const terrain_code NOT
bool operator()(const unit &u, const map_location &loc, const unit &u2) const
Definition: filter.hpp:152
config to_config() const
Definition: filter.hpp:176
const filter_context * fc
Definition: filter.hpp:67
Encapsulates the map of the game.
Definition: location.hpp:42
std::vector< std::shared_ptr< unit_filter_base > > children_
Definition: filter.hpp:104
pump_impl & impl_
Definition: pump.cpp:134
std::vector< std::pair< CONDITIONAL_TYPE, unit_filter_compound > > cond_children_
Definition: filter.hpp:105
bool matches(const unit &u, const map_location &loc, const unit &u2) const
Definition: filter.hpp:138
MAKE_ENUM(ALIGNMENT_FEMALE_VARIATION,(LAWFUL, N_("female^lawful"))(FEMALE_NEUTRAL, N_("female^neutral"))(CHAOTIC, N_("female^chaotic"))(LIMINAL, N_("female^liminal"))) std
Implementation detail of unit_type::alignment_description.
Definition: types.cpp:909
Base class for all the errors encountered by the engine.
Definition: exceptions.hpp:29
A variable-expanding proxy for the config class.
Definition: variable.hpp:42
bool operator()(const unit &u, const unit &u2) const
Definition: filter.hpp:156
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:92
mock_char c
Defines the MAKE_ENUM macro.
std::vector< const unit * > all_matches_at(const map_location &loc) const
Definition: filter.hpp:162
unit_filter_args(const unit &u, map_location loc, const unit *u2, const filter_context *fc, bool use_flat_tod)
Definition: filter.hpp:79