-
-
Notifications
You must be signed in to change notification settings - Fork 993
/
filter.hpp
122 lines (99 loc) · 3.85 KB
/
filter.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
Copyright (C) 2014 - 2017 by Chris Beck <render787@gmail.com>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
/**
* This namespace contains the function that checks if a unit matches
* a filter. It helps by simplifying the unit object (which before now
* holds the "match" function).
*
* TODO:
* Make a class that abstracts a unit filter, assembles the constituent
* side filters and terrain filters and conditional filters, and caches
* these to speed up repeated application of the filter.
*/
#pragma once
#include "units/ptr.hpp"
#include <memory>
#include <vector>
class filter_context;
class unit;
class config;
class vconfig;
struct map_location;
class unit_filter_abstract_impl {
public:
virtual bool matches(const unit & u, const map_location & loc, const unit * u2 = nullptr) const = 0;
virtual std::vector<const unit*> all_matches_on_map(unsigned max_matches, const map_location* loc = nullptr, const unit* u2 = nullptr) const = 0;
virtual unit_const_ptr first_match_on_map() const = 0;
virtual config to_config() const = 0;
virtual bool empty() const {return false;}
virtual ~unit_filter_abstract_impl() {}
};
class unit_filter {
public:
unit_filter(const vconfig & cfg, const filter_context * fc, bool use_flat_tod = false); //!< Constructs a unit filter from a config and a context. This function should give the most efficient implementation available.
// Copy and Swap Idiom for the interface -- does not copy the underlying impl
unit_filter(const unit_filter & o ) : impl_(o.impl_), max_matches_() {}
void swap(unit_filter & o) {
impl_.swap(o.impl_);
std::swap(max_matches_, o.max_matches_);
}
unit_filter & operator=(unit_filter o) {
swap(o);
return *this;
}
/// Determine if *this matches @a filter at a specified location.
/// Use this for units on a recall list, or to test for a match if
/// a unit is hypothetically moved.
bool matches(const unit & u, const map_location & loc) const {
return impl_->matches(u,loc);
}
/// Determine if *this matches @a filter at its current location.
/// (Only use for units currently on the map; otherwise use the overload
/// that takes a location, possibly with a null location.)
bool matches(const unit & u) const;
bool matches(const unit & u, const map_location & loc, const unit & u2) const;
bool matches(const unit & u, const unit & u2) const;
bool operator()(const unit & u, const map_location & loc) const {
return matches(u,loc);
}
bool operator()(const unit & u) const {
return matches(u);
}
bool operator()(const unit & u, const map_location & loc, const unit & u2) const {
return matches(u,loc,u2);
}
bool operator()(const unit & u, const unit & u2) const {
return matches(u,u2);
}
std::vector<const unit *> all_matches_on_map() const {
return impl_->all_matches_on_map(max_matches_);
}
std::vector<const unit*> all_matches_at(const map_location& loc) const {
return impl_->all_matches_on_map(max_matches_, &loc);
}
std::vector<const unit*> all_matches_with_unit(const unit& u) const {
return impl_->all_matches_on_map(max_matches_, nullptr, &u);
}
std::vector<const unit*> all_matches_with_unit_at(const unit& u, const map_location& loc) const {
return impl_->all_matches_on_map(max_matches_, &loc, &u);
}
unit_const_ptr first_match_on_map() const {
return impl_->first_match_on_map();
}
config to_config() const;
bool empty() const {
return impl_->empty();
}
private:
std::shared_ptr<unit_filter_abstract_impl> impl_;
unsigned max_matches_;
};