The Battle for Wesnoth  1.17.4+dev
filter.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2022
3  by Chris Beck <render787@gmail.com>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 /**
17  * This namespace contains the function that checks if a unit matches
18  * a filter. It helps by simplifying the unit object (which before now
19  * holds the "match" function).
20  *
21  * TODO:
22  * Make a class that abstracts a unit filter, assembles the constituent
23  * side filters and terrain filters and conditional filters, and caches
24  * these to speed up repeated application of the filter.
25  */
26 
27 #pragma once
28 
30 #include "units/ptr.hpp"
31 
32 #include "display_context.hpp"
33 #include "filter_context.hpp"
34 #include "units/map.hpp"
35 #include "variable.hpp"
36 
37 #include <memory>
38 #include <vector>
39 
40 class filter_context;
41 class unit;
42 class config;
43 class vconfig;
44 struct map_location;
45 
46 
47 
48 namespace unit_filter_impl
49 {
50  struct filter_error : public game::error
51  {
52  explicit filter_error(const std::string& message = "filter error")
53  : game::error(message)
54  {
55  }
56  };
57 
59  {
60  const unit& u;
62  const unit* u2;
65 
66  const filter_context& context() const
67  {
68  if(fc) {
69  return *fc;
70  }
71  throw filter_error();
72  }
73  // This constructor is here to shut down warnings that the default constructor couldn't be generated.
74  // It's technically unnecessary since lacking of a default constructor doesn't prevent aggregate-initialization, but...
75  unit_filter_args(const unit& u, map_location loc, const unit* u2, const filter_context* fc, bool use_flat_tod)
76  : u(u), loc(loc), u2(u2), fc(fc), use_flat_tod(use_flat_tod)
77  {}
78  };
79 
81  {
82  virtual bool matches(const unit_filter_args&) const = 0;
83  virtual ~unit_filter_base() {}
84  };
85 
87  {
89 
90  template<typename C, typename F>
91  void create_attribute(const config::attribute_value c, C conv, F func);
92  template<typename F>
93  void create_child(const vconfig& c, F func);
94 
95  void fill(vconfig cfg);
96 
97  virtual bool matches(const unit_filter_args& u) const override;
98  bool filter_impl(const unit_filter_args& u) const;
99 
100  std::vector<std::shared_ptr<unit_filter_base>> children_;
101  std::vector<std::pair<conditional_type::type, unit_filter_compound>> cond_children_;
102  };
103 
104 }
105 
107 {
108 public:
109  explicit unit_filter(vconfig cfg);
110 
111  unit_filter(const unit_filter&) = default;
112  unit_filter& operator=(const unit_filter&) = default;
113 
114  unit_filter(unit_filter&&) = default;
115  unit_filter& operator=(unit_filter&&) = default;
116 
118  use_flat_tod_ = value;
119  return *this;
120  }
121 
122  /**
123  * Determine if *this matches @a filter at a specified location.
124  * Use this for units on a recall list, or to test for a match if
125  * a unit is hypothetically moved.
126  */
127  bool matches(const unit & u, const map_location & loc) const {
128  return impl_.matches(unit_filter_impl::unit_filter_args{u, loc, nullptr, fc_, use_flat_tod_});
129  }
130 
131  /**
132  * Determine if *this matches @a filter at its current location.
133  * (Only use for units currently on the map; otherwise use the overload
134  * that takes a location, possibly with a null location.)
135  */
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 };
bool empty() const
Definition: filter.hpp:180
filter_error(const std::string &message="filter error")
Definition: filter.hpp:52
const filter_context * fc_
Definition: filter.hpp:187
This class represents a single unit of a specific type.
Definition: unit.hpp:120
int max_matches_
Definition: filter.hpp:190
unit_filter & set_use_flat_tod(bool value)
Definition: filter.hpp:117
Variant for storing WML attributes.
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:127
const filter_context & context() const
Definition: filter.hpp:66
std::shared_ptr< const unit > unit_const_ptr
Definition: ptr.hpp:27
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
std::vector< std::pair< conditional_type::type, unit_filter_compound > > cond_children_
Definition: filter.hpp:101
bool operator()(const unit &u) const
Definition: filter.hpp:148
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:63
Encapsulates the map of the game.
Definition: location.hpp:38
std::vector< std::shared_ptr< unit_filter_base > > children_
Definition: filter.hpp:100
pump_impl & impl_
Definition: pump.cpp:135
bool matches(const unit &u, const map_location &loc, const unit &u2) const
Definition: filter.hpp:138
Base class for all the errors encountered by the engine.
Definition: exceptions.hpp:28
A variable-expanding proxy for the config class.
Definition: variable.hpp:44
std::string message
Definition: exceptions.hpp:30
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:60
mock_char c
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:75