4
1
mirror of https://github.com/QuasarApp/Snake.git synced 2025-05-06 06:29:47 +00:00

added clasters tests

This commit is contained in:
Andrei Yankovich 2021-06-20 12:48:08 +03:00
parent f4e6c3876c
commit fb8e23f08f
7 changed files with 224 additions and 33 deletions

@ -23,7 +23,7 @@ Claster::~Claster() {
void Claster::add(ClasterItem *object) {
_objects.insert(object->guiId(), object);
if (auto singlClasterObject = dynamic_cast<SingleClasterWorldItem*>(object)) {
if (auto singlClasterObject = dynamic_cast<ClasterItem*>(object)) {
singlClasterObject->setClaster(this);
}
}

@ -16,8 +16,8 @@ ClasterItem::ClasterItem(const QString &name,
}
ClasterItem::~ClasterItem() {
if (parentClasters().size() && *parentClasters().begin()) {
(*parentClasters().begin())->remove(this);
for (auto claster : qAsConst(_parentClasters)) {
claster->remove(this);
}
}

@ -82,7 +82,7 @@ void IWorld::setPlayer(QObject *newPlayer) {
}
if (_player) {
removeIAtomictem(_player->guiId());
removeIAtomicItem(_player->guiId());
}
_player = newPlayerObject;
@ -91,6 +91,10 @@ void IWorld::setPlayer(QObject *newPlayer) {
emit playerChanged();
}
IWorldItem *IWorld::generate(const QString &objectType) const {
return _registeredTypes.value(objectType, [](){return nullptr;}).operator()();
}
bool IWorld::stop() {
start();
@ -177,13 +181,14 @@ void IWorld::removeItem(int id, QList<int> *removedObjectsList) {
// Work wih claster
if (auto claster = dynamic_cast<Claster*>(obj)) {
for (auto item : claster->objects()) {
if (!item || item->parentClastersCount())
auto copyOfObjectsList = claster->objects();
for (auto item : copyOfObjectsList) {
if (!item || !item->parentClastersCount())
continue;
int id = item->guiId();
removeIAtomictem(item);
removeIAtomicItem(item);
if (removedObjectsList)
removedObjectsList->push_back(id);
@ -191,7 +196,8 @@ void IWorld::removeItem(int id, QList<int> *removedObjectsList) {
}
addAtomicItem(obj);
removedObjectsList->push_back(obj->guiId());
if (removedObjectsList)
removedObjectsList->push_back(obj->guiId());
}
@ -230,7 +236,7 @@ void IWorld::addAtomicItem(IWorldItem* obj) {
_itemsGroup.insert(obj->className(), obj->guiId());
}
bool IWorld::removeIAtomictem(int id) {
bool IWorld::removeIAtomicItem(int id) {
auto obj = _items.value(id);
if (!obj) {
@ -245,7 +251,7 @@ bool IWorld::removeIAtomictem(int id) {
return true;
}
bool IWorld::removeIAtomictem(IWorldItem *obj) {
bool IWorld::removeIAtomicItem(IWorldItem *obj) {
if (!obj) {
return false;
}
@ -341,3 +347,4 @@ void IWorld::setWorldStatus(int newWorldStatus) {
_worldStatus = newWorldStatus;
emit worldStatusChanged();
}

@ -63,11 +63,27 @@ public:
/**
* @brief initWorldRules The implementation of this interface must be retun initialized list of the world rules.
* For more information see the WorldRules map.
*
* Example of use :
*
* ```cpp
* WorldRule *World::initWorldRules() {
* return new WorldRule {
* {
* 0, {{registerObject<Box>(), 10}},
* 100, {{registerObject<Box>(), 10}, {registerObject<Round>(), 1}},
* }
* };
* }
* ```
*
* @return a raw pointer to world a rules map.
* @note The Palyer object will be deleted when wold distroed.
* So do not delete your created player pbject yuorself.
*
*
*/
virtual WorldRule* initWorldRules() const = 0;
virtual WorldRule* initWorldRules() = 0;
/**
* @brief initUserInterface This method should be return point to userInterface object.
@ -253,25 +269,22 @@ protected:
/**
* @brief generate This method shold be generate object from the @a objectType.
* Override this method for add support yourown objects.
* @note If your objects not requre custom setting then use the default implementation of the generate method.
* @param objectType This is string type name of the object,
* @return pointer to the object.
*
* **Example**
* ```cpp
* IWorldItem* generate(const QString& objectType)) const {
* if (auto obj = IWorld::generate(objectType)) {
* return obj;
* auto registeredObject = IWorld::generate(objectType);
* if (registeredObject) {
* // process creating of object.
* }
*
* ...
* // custom implementation
* ...
*
* return nullptr;
* return registeredObject;
* }
* ```
*/
virtual IWorldItem* generate(const QString& objectType) const = 0;
virtual IWorldItem* generate(const QString& objectType) const;
/**
* @brief setCameraReleativePosition This method update camera position
@ -285,6 +298,40 @@ protected:
*/
void setCameraRatation(const QQuaternion &newCameraRatation);
template<class Type>
/**
* @brief registerObject This method will register object type for generation on the world.
*
* Example of use:
*
* ```cpp
* ...
* QString className = registerObject<MyType>();
* ...
* ```
*
* @return name of registered class.
*/
QString registerObject() {
static_assert(std::is_base_of_v<IWorldItem, Type>,
"You try register no IWorldItem class. Please inherit of IWorldItem class and try again");
QString type = Type().className();
if (!_registeredTypes.contains(type)) {
auto wraper = []() {
return new Type();
};
_registeredTypes.insert(type, wraper);
}
return type;
}
private slots:
/**
@ -331,14 +378,14 @@ private:
* @param id This is id of removed objects.
* @return return true if object remove successul
*/
bool removeIAtomictem(int id);
bool removeIAtomicItem(int id);
/**
* @brief removeIAtomictem This method remove object @a obj. This method work with atomic objects only. If you rty remove claster objects then it will be ramoved witohout child objects.
* @brief removeIAtomicItem This method remove object @a obj. This method work with atomic objects only. If you rty remove claster objects then it will be ramoved witohout child objects.
* @param obj This is id of removed objects.
* @return return true if object remove successul
*/
bool removeIAtomictem(IWorldItem *obj);
bool removeIAtomicItem(IWorldItem *obj);
/**
* @brief removeAnyItemFromGroup This method remove any object from group and return id of removed object. If The objec are claster then this method remove all child objects.
@ -359,9 +406,15 @@ private:
IPlayer *_player = nullptr;
IControl *_userInterface = nullptr;
IAI *_backgroundAI = nullptr;
friend class Engine;
int _worldStatus = 0;
QHash<QString, std::function<IWorldItem*()>> _registeredTypes;
// engine
friend class Engine;
// testing
friend class ClastersTest;
};
#endif // IWORLD_H

@ -19,8 +19,6 @@ SingleClasterWorldItem::SingleClasterWorldItem(const QString &name,
void SingleClasterWorldItem::setClaster(Claster *claster) {
if (parentClasters().size() > 0) {
debug_assert(parentClasters().size() > 1, "Internal error occured, The singleClaster object have multiple claster parents!!");
Claster* parent = *parentClasters().begin();
parent->remove(this);
removeClaster(parent);

@ -7,12 +7,137 @@
#include "clasterstest.h"
#include <QtTest>
#include <Crawl/claster.h>
#include <Crawl/clasteritem.h>
#include <Crawl/singleclasterworlditem.h>
#include <Crawl/iworld.h>
ClastersTest::ClastersTest()
{
// Test claster object.
class TestClasterObject: public Claster {
public:
TestClasterObject(): Claster("TestClaster"){};
protected:
void onIntersects(const IWorldItem *) {};
};
// Test single claster item
class TestClasterSingleItem: public SingleClasterWorldItem {
public:
TestClasterSingleItem(): SingleClasterWorldItem("TestClasterSingleItem"){};
protected:
void onIntersects(const IWorldItem *) {};
};
// Test claster item
class TestClasterItem: public ClasterItem {
public:
TestClasterItem(): ClasterItem("TestClasterItem"){};
protected:
void onIntersects(const IWorldItem *) {};
};
// Test world of clasters
class TestWorld: public IWorld {
public:
TestWorld(): IWorld(){};
// IWorld interface
public:
IPlayer *initPlayer() const {return nullptr;};
WorldRule *initWorldRules() {return nullptr;};
QString initHdrBackGround() const {return "";};
QString description() const {return "";};
QString imagePreview() const {return "";};
QString name() const {return "TestWorld";};
int costToUnlock() const {return 0;};
friend class ClastersTest;
};
ClastersTest::ClastersTest() {
}
void ClastersTest::test() {
QVERIFY(false);
// test clasters
testOneClaster();
testClastersWithWorld();
}
void ClastersTest::testOneClaster() const {
TestClasterItem item;
TestClasterSingleItem singleItem;
// life of the clasters
{
TestClasterObject claster, claster2;
// Add items to first clasters
claster.add(&item);
claster.add(&singleItem);
// in the first claster should be 2 objects
QVERIFY(claster.objects().size() == 2);
// item sould be contains oly one parents claster object.
QVERIFY(item.parentClastersCount() == 1);
QVERIFY(singleItem.parentClastersCount() == 1);
// Add items into second claster object
claster2.add(&item);
claster2.add(&singleItem);
// in the second claster should be 2 objects
QVERIFY(claster2.objects().size() == 2);
// but first claster should be contains only one claster item because the singleclater item cannot are child of the two clasters.
QVERIFY(claster.objects().size() == 1);
// item sould be contains two parents claster object.
QVERIFY(item.parentClastersCount() == 2);
// item sould be contains oly one parents claster object.
QVERIFY(singleItem.parentClastersCount() == 1);
}
// after distrou clasters objects the parents list size should be equals 0
QVERIFY(item.parentClastersCount() == 0);
QVERIFY(singleItem.parentClastersCount() == 0);
}
void ClastersTest::testClastersWithWorld() const {
TestWorld world;
TestClasterObject *claster = new TestClasterObject(),
*claster2 = new TestClasterObject();
TestClasterItem *item = new TestClasterItem(),
*item2 = new TestClasterItem;
// Add to first claster two items.
claster->add(item);
claster->add(item2);
// The claster 2 contains item 2 only.
claster2->add(item2);
// Add claster item to world
world.addItem(claster);
// After adding claster object ito world child objects should be addeed automaticaly
QVERIFY(world._items.size() == 3);
// add second claster ot world
world.addItem(claster2);
QVERIFY(world._items.size() == 4);
// remove claster with 2 items from world
world.removeItem(claster->guiId());
// after removing claster ovject child items should be removed too. but ony items that contains one parent claster.
QVERIFY(world._items.size() == 2);
world.removeItem(claster2->guiId());
}

@ -18,10 +18,18 @@ class ClastersTest: public Test, protected TestUtils
{
public:
ClastersTest();
// Test interface
public:
void test() override;
private:
/**
* @brief testOneClaster This test check functionality of the claster class.
*/
void testOneClaster() const;
/**
* @brief testClastersWithWorld This test check clasters integrarion on the world
*/
void testClastersWithWorld() const;
};
#endif // CLASTERSTEST_H