Add an activeobject manager to hold active objects (#7939)
[oweals/minetest.git] / src / unittest / test_serveractiveobjectmgr.cpp
1 /*
2 Minetest
3 Copyright (C) 2018 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "server/activeobjectmgr.h"
21 #include <algorithm>
22 #include <queue>
23 #include "test.h"
24
25 #include "profiler.h"
26
27 class TestServerActiveObject : public ServerActiveObject
28 {
29 public:
30         TestServerActiveObject(const v3f &p = v3f()) : ServerActiveObject(nullptr, p) {}
31         ~TestServerActiveObject() = default;
32         ActiveObjectType getType() const override { return ACTIVEOBJECT_TYPE_TEST; }
33         bool getCollisionBox(aabb3f *toset) const override { return false; }
34         bool getSelectionBox(aabb3f *toset) const override { return false; }
35         bool collideWithObjects() const override { return false; }
36 };
37
38 class TestServerActiveObjectMgr : public TestBase
39 {
40 public:
41         TestServerActiveObjectMgr() { TestManager::registerTestModule(this); }
42         const char *getName() { return "TestServerActiveObjectMgr"; }
43
44         void runTests(IGameDef *gamedef);
45
46         void testFreeID();
47         void testRegisterObject();
48         void testRemoveObject();
49         void testGetObjectsInsideRadius();
50         void testGetAddedActiveObjectsAroundPos();
51 };
52
53 static TestServerActiveObjectMgr g_test_instance;
54
55 void TestServerActiveObjectMgr::runTests(IGameDef *gamedef)
56 {
57         TEST(testFreeID);
58         TEST(testRegisterObject)
59         TEST(testRemoveObject)
60         TEST(testGetObjectsInsideRadius);
61         TEST(testGetAddedActiveObjectsAroundPos);
62 }
63
64 void clearSAOMgr(server::ActiveObjectMgr *saomgr)
65 {
66         auto clear_cb = [](ServerActiveObject *obj, u16 id) {
67                 delete obj;
68                 return true;
69         };
70         saomgr->clear(clear_cb);
71 }
72
73 ////////////////////////////////////////////////////////////////////////////////
74
75 void TestServerActiveObjectMgr::testFreeID()
76 {
77         server::ActiveObjectMgr saomgr;
78         std::vector<u16> aoids;
79
80         u16 aoid = saomgr.getFreeId();
81         // Ensure it's not the same id
82         UASSERT(saomgr.getFreeId() != aoid);
83
84         aoids.push_back(aoid);
85
86         // Register basic objects, ensure we never found
87         for (u8 i = 0; i < UINT8_MAX; i++) {
88                 // Register an object
89                 auto tsao = new TestServerActiveObject();
90                 saomgr.registerObject(tsao);
91                 aoids.push_back(tsao->getId());
92
93                 // Ensure next id is not in registered list
94                 UASSERT(std::find(aoids.begin(), aoids.end(), saomgr.getFreeId()) ==
95                                 aoids.end());
96         }
97
98         clearSAOMgr(&saomgr);
99 }
100
101 void TestServerActiveObjectMgr::testRegisterObject()
102 {
103         server::ActiveObjectMgr saomgr;
104         auto tsao = new TestServerActiveObject();
105         UASSERT(saomgr.registerObject(tsao));
106
107         u16 id = tsao->getId();
108
109         auto tsaoToCompare = saomgr.getActiveObject(id);
110         UASSERT(tsaoToCompare->getId() == id);
111         UASSERT(tsaoToCompare == tsao);
112
113         tsao = new TestServerActiveObject();
114         UASSERT(saomgr.registerObject(tsao));
115         UASSERT(saomgr.getActiveObject(tsao->getId()) == tsao);
116         UASSERT(saomgr.getActiveObject(tsao->getId()) != tsaoToCompare);
117
118         clearSAOMgr(&saomgr);
119 }
120
121 void TestServerActiveObjectMgr::testRemoveObject()
122 {
123         server::ActiveObjectMgr saomgr;
124         auto tsao = new TestServerActiveObject();
125         UASSERT(saomgr.registerObject(tsao));
126
127         u16 id = tsao->getId();
128         UASSERT(saomgr.getActiveObject(id) != nullptr)
129
130         saomgr.removeObject(tsao->getId());
131         UASSERT(saomgr.getActiveObject(id) == nullptr);
132
133         clearSAOMgr(&saomgr);
134 }
135
136 void TestServerActiveObjectMgr::testGetObjectsInsideRadius()
137 {
138         server::ActiveObjectMgr saomgr;
139         static const v3f sao_pos[] = {
140                         v3f(10, 40, 10),
141                         v3f(740, 100, -304),
142                         v3f(-200, 100, -304),
143                         v3f(740, -740, -304),
144                         v3f(1500, -740, -304),
145         };
146
147         for (const auto &p : sao_pos) {
148                 saomgr.registerObject(new TestServerActiveObject(p));
149         }
150
151         std::vector<u16> result;
152         saomgr.getObjectsInsideRadius(v3f(), 50, result);
153         UASSERTCMP(int, ==, result.size(), 1);
154
155         result.clear();
156         saomgr.getObjectsInsideRadius(v3f(), 750, result);
157         UASSERTCMP(int, ==, result.size(), 2);
158
159         clearSAOMgr(&saomgr);
160 }
161
162 void TestServerActiveObjectMgr::testGetAddedActiveObjectsAroundPos()
163 {
164         server::ActiveObjectMgr saomgr;
165         static const v3f sao_pos[] = {
166                         v3f(10, 40, 10),
167                         v3f(740, 100, -304),
168                         v3f(-200, 100, -304),
169                         v3f(740, -740, -304),
170                         v3f(1500, -740, -304),
171         };
172
173         for (const auto &p : sao_pos) {
174                 saomgr.registerObject(new TestServerActiveObject(p));
175         }
176
177         std::queue<u16> result;
178         std::set<u16> cur_objects;
179         saomgr.getAddedActiveObjectsAroundPos(v3f(), 100, 50, cur_objects, result);
180         UASSERTCMP(int, ==, result.size(), 1);
181
182         result = std::queue<u16>();
183         cur_objects.clear();
184         saomgr.getAddedActiveObjectsAroundPos(v3f(), 740, 50, cur_objects, result);
185         UASSERTCMP(int, ==, result.size(), 2);
186
187         clearSAOMgr(&saomgr);
188 }