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:
parent
f4e6c3876c
commit
fb8e23f08f
src/Core/Crawl
tests/units
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user