The Battle for Wesnoth  1.17.0-dev
filter.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2021
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 
29 #include "units/ptr.hpp"
30 #include "utils/make_enum.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 
49 {
50  MAKE_ENUM (CONDITIONAL_TYPE,
51  (AND, "and")
52  (OR, "or")
53  (NOT, "not")
54  );
55  struct filter_error : public game::error
56  {
57  explicit filter_error(const std::string& message = "filter error")
58  : game::error(message)
59  {
60  }
61  };
62 
64  {
65  const unit& u;
67  const unit* u2;
70 
71  const filter_context& context() const
72  {
73  if(fc) {
74  return *fc;
75  }
76  throw filter_error();
77  }
78  // This constructor is here to shut down warnings that the default constructor couldn't be generated.
79  // It's technically unnecessary since lacking of a default constructor doesn't prevent aggregate-initialization, but...
80  unit_filter_args(const unit& u, map_location loc, const unit* u2, const filter_context* fc, bool use_flat_tod)
81  : u(u), loc(loc), u2(u2), fc(fc), use_flat_tod(use_flat_tod)
82  {}
83  };
84 
86  {
87  virtual bool matches(const unit_filter_args&) const = 0;
88  virtual ~unit_filter_base() {}
89  };
90 
92  {
94 
95  template<typename C, typename F>
96  void create_attribute(const config::attribute_value c, C conv, F func);
97  template<typename F>
98  void create_child(const vconfig& c, F func);
99 
100  void fill(vconfig cfg);
101 
102  virtual bool matches(const unit_filter_args& u) const override;
103  bool filter_impl(const unit_filter_args& u) const;
104 
105  std::vector<std::shared_ptr<unit_filter_base>> children_;
106  std::vector<std::pair<CONDITIONAL_TYPE, unit_filter_compound>> cond_children_;
107  };
108 
109 }
110 
112 {
113 public:
114  explicit unit_filter(vconfig cfg);
115 
116  unit_filter(const unit_filter&) = default;
117  unit_filter& operator=(const unit_filter&) = default;
118 
119  unit_filter(unit_filter&&) = default;
120  unit_filter& operator=(unit_filter&&) = default;
121 
123  use_flat_tod_ = value;
124  return *this;
125  }
126 
127  /**
128  * Determine if *this matches @a filter at a specified location.
129  * Use this for units on a recall list, or to test for a match if
130  * a unit is hypothetically moved.
131  */
132  bool matches(const unit & u, const map_location & loc) const {
133  return impl_.matches(unit_filter_impl::unit_filter_args{u, loc, nullptr, fc_, use_flat_tod_});
134  }
135 
136  /**
137  * Determine if *this matches @a filter at its current location.
138  * (Only use for units currently on the map; otherwise use the overload
139  * that takes a location, possibly with a null location.)
140  */
141  bool matches(const unit & u) const;
142 
143  bool matches(const unit & u, const map_location & loc, const unit & u2) const {
144  return impl_.matches(unit_filter_impl::unit_filter_args{u, loc, &u2, fc_, use_flat_tod_});
145  }
146 
147  bool matches(const unit & u, const unit & u2) const;
148 
149  bool operator()(const unit & u, const map_location & loc) const {
150  return matches(u, loc);
151  }
152 
153  bool operator()(const unit & u) const {
154  return matches(u);
155  }
156 
157  bool operator()(const unit & u, const map_location & loc, const unit & u2) const {
158  return matches(u, loc, u2);
159  }
160 
161  bool operator()(const unit & u, const unit & u2) const {
162  return matches(u, u2);
163  }
164 
165  std::vector<const unit *> all_matches_on_map(const map_location* loc = nullptr, const unit* other_unit = nullptr) const;
166 
167  std::vector<const unit*> all_matches_at(const map_location& loc) const {
168  return all_matches_on_map(&loc);
169  }
170 
171  std::vector<const unit*> all_matches_with_unit(const unit& u) const {
172  return all_matches_on_map(nullptr, &u);
173  }
174 
175  std::vector<const unit*> all_matches_with_unit_at(const unit& u, const map_location& loc) const {
176  return all_matches_on_map(&loc, &u);
177  }
178 
179  unit_const_ptr first_match_on_map() const;
180 
181  config to_config() const {
182  return cfg_.get_config();
183  }
184 
185  bool empty() const {
186  return cfg_.get_config().empty();
187  }
188 
189 private:
190 
196 };
bool empty() const
Definition: filter.hpp:185
filter_error(const std::string &message="filter error")
Definition: filter.hpp:57
const filter_context * fc_
Definition: filter.hpp:192
This class represents a single unit of a specific type.
Definition: unit.hpp:121
int max_matches_
Definition: filter.hpp:195
unit_filter & set_use_flat_tod(bool value)
Definition: filter.hpp:122
Variant for storing WML attributes.
MAKE_ENUM(CONDITIONAL_TYPE,(AND, "and")(OR, "or")(NOT, "not"))
bool operator()(const unit &u, const map_location &loc) const
Definition: filter.hpp:149
vconfig cfg_
Definition: filter.hpp:191
bool matches(const unit &u, const map_location &loc) const
Determine if *this matches filter at a specified location.
Definition: filter.hpp:132
const filter_context & context() const
Definition: filter.hpp:71
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:171
std::vector< const unit * > all_matches_with_unit_at(const unit &u, const map_location &loc) const
Definition: filter.hpp:175
unit_filter_impl::unit_filter_compound impl_
Definition: filter.hpp:194
bool use_flat_tod_
Definition: filter.hpp:193
bool operator()(const unit &u) const
Definition: filter.hpp:153
const terrain_code NOT
bool operator()(const unit &u, const map_location &loc, const unit &u2) const
Definition: filter.hpp:157
config to_config() const
Definition: filter.hpp:181
const filter_context * fc
Definition: filter.hpp:68
Encapsulates the map of the game.
Definition: location.hpp:38
std::vector< std::shared_ptr< unit_filter_base > > children_
Definition: filter.hpp:105
pump_impl & impl_
Definition: pump.cpp:135
std::vector< std::pair< CONDITIONAL_TYPE, unit_filter_compound > > cond_children_
Definition: filter.hpp:106
bool matches(const unit &u, const map_location &loc, const unit &u2) const
Definition: filter.hpp:143
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:161
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:61
mock_char c
Defines the MAKE_ENUM macro.
std::vector< const unit * > all_matches_at(const map_location &loc) const
Definition: filter.hpp:167
unit_filter_args(const unit &u, map_location loc, const unit *u2, const filter_context *fc, bool use_flat_tod)
Definition: filter.hpp:80