1 /*
2  * Copyright (C) 2008-2020 by the Widelands Development Team
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  *
18  */
19 
20 #ifndef WL_LOGIC_MAP_OBJECTS_FINDIMMOVABLE_H
21 #define WL_LOGIC_MAP_OBJECTS_FINDIMMOVABLE_H
22 
23 #include "logic/map_objects/map_object.h"
24 
25 namespace Widelands {
26 
27 struct BaseImmovable;
28 class ImmovableDescr;
29 
30 struct FindImmovable {
31 private:
32 	struct BaseCapsule {
BaseCapsuleFindImmovable::BaseCapsule33 		BaseCapsule() : refcount(1) {
34 		}
~BaseCapsuleFindImmovable::BaseCapsule35 		virtual ~BaseCapsule() {
36 		}
37 
addrefFindImmovable::BaseCapsule38 		void addref() {
39 			++refcount;
40 		}
derefFindImmovable::BaseCapsule41 		void deref() {
42 			if (--refcount == 0)
43 				delete this;
44 		}
45 		virtual bool accept(const BaseImmovable&) const = 0;
46 
47 		int refcount;
48 	};
49 	template <typename T> struct Capsule : public BaseCapsule {
CapsuleFindImmovable::Capsule50 		explicit Capsule(const T& init_op) : op(init_op) {
51 		}
acceptFindImmovable::Capsule52 		bool accept(const BaseImmovable& imm) const override {
53 			return op.accept(imm);
54 		}
55 
56 		const T op;
57 	};
58 
59 	BaseCapsule* capsule;
60 
61 public:
FindImmovableFindImmovable62 	explicit FindImmovable(const FindImmovable& o) {
63 		capsule = o.capsule;
64 		capsule->addref();
65 	}
~FindImmovableFindImmovable66 	~FindImmovable() {
67 		capsule->deref();
68 		capsule = nullptr;
69 	}
70 	FindImmovable& operator=(const FindImmovable& o) {
71 		capsule->deref();
72 		capsule = o.capsule;
73 		capsule->addref();
74 		return *this;
75 	}
76 
FindImmovableFindImmovable77 	template <typename T> FindImmovable(const T& op) {
78 		capsule = new Capsule<T>(op);
79 	}
80 
81 	// Return true if this node should be returned by find_fields()
acceptFindImmovable82 	bool accept(const BaseImmovable& imm) const {
83 		return capsule->accept(imm);
84 	}
85 };
86 
87 const FindImmovable& find_immovable_always_true();
88 
89 // FindImmovable functor
90 struct FindImmovableSize {
FindImmovableSizeFindImmovableSize91 	FindImmovableSize(int32_t const init_min, int32_t const init_max)
92 	   : min(init_min), max(init_max) {
93 	}
94 
95 	bool accept(const BaseImmovable&) const;
96 
97 private:
98 	int32_t min, max;
99 };
100 struct FindImmovableType {
FindImmovableTypeFindImmovableType101 	explicit FindImmovableType(MapObjectType const init_type) : type(init_type) {
102 	}
103 
104 	bool accept(const BaseImmovable&) const;
105 
106 private:
107 	MapObjectType type;
108 };
109 struct FindImmovableAttribute {
FindImmovableAttributeFindImmovableAttribute110 	explicit FindImmovableAttribute(uint32_t const init_attrib) : attrib(init_attrib) {
111 	}
112 
113 	bool accept(const BaseImmovable&) const;
114 
115 private:
116 	int32_t attrib;
117 };
118 struct FindImmovablePlayerImmovable {
FindImmovablePlayerImmovableFindImmovablePlayerImmovable119 	FindImmovablePlayerImmovable() {
120 	}
121 
122 	bool accept(const BaseImmovable&) const;
123 };
124 struct FindImmovablePlayerMilitarySite {
FindImmovablePlayerMilitarySiteFindImmovablePlayerMilitarySite125 	explicit FindImmovablePlayerMilitarySite(const Player& init_player) : player(init_player) {
126 	}
127 
128 	bool accept(const BaseImmovable&) const;
129 
130 	const Player& player;
131 };
132 struct FindImmovableAttackTarget {
FindImmovableAttackTargetFindImmovableAttackTarget133 	FindImmovableAttackTarget() {
134 	}
135 
136 	bool accept(const BaseImmovable&) const;
137 };
138 struct FindForeignMilitarysite {
FindForeignMilitarysiteFindForeignMilitarysite139 	explicit FindForeignMilitarysite(const Player& init_player) : player(init_player) {
140 	}
141 	bool accept(const BaseImmovable&) const;
142 	const Player& player;
143 };
144 
145 struct FindImmovableByDescr {
FindImmovableByDescrFindImmovableByDescr146 	explicit FindImmovableByDescr(const ImmovableDescr& init_descr) : descr(init_descr) {
147 	}
148 
149 	bool accept(const BaseImmovable&) const;
150 
151 	const ImmovableDescr& descr;
152 };
153 struct FindFlagOf {
FindFlagOfFindFlagOf154 	explicit FindFlagOf(const FindImmovable& init_finder) : finder(init_finder) {
155 	}
156 
157 	bool accept(const BaseImmovable&) const;
158 
159 	const FindImmovable finder;
160 };
161 
162 }  // namespace Widelands
163 
164 #endif  // end of include guard: WL_LOGIC_MAP_OBJECTS_FINDIMMOVABLE_H
165