4
1
mirror of https://github.com/QuasarApp/Heart.git synced 2025-05-02 12:39:39 +00:00

Merge pull request from QuasarApp/productions_fixes - Map generation

The "Productions" Game fixes
This commit is contained in:
Andrei Yankovich 2025-03-06 18:44:22 +01:00 committed by GitHub
commit d32293be33
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 158 additions and 29 deletions

@ -7,6 +7,7 @@
#include "asyncrenderloop.h" #include "asyncrenderloop.h"
#include <QThread> #include <QThread>
#include <qdebug.h>
namespace QH { namespace QH {
@ -14,7 +15,16 @@ AsyncRenderLoop::AsyncRenderLoop(QThread *thread, QObject *ptr): Async(thread, p
} }
AsyncRenderLoop::~AsyncRenderLoop() { AsyncRenderLoop::~AsyncRenderLoop() {
#ifdef QT_DEBUG
Q_ASSERT_X(!isRun(), __FUNCTION__, "try to delete runned render loop! Please stop before delete."
"If you the SharedPointer,"
" it should be stoped monualy Or You can use AsyncRenderLoop::MainSharedPtr class");
#endif
AsyncRenderLoop::stop(); AsyncRenderLoop::stop();
delete thread();
} }
void QH::AsyncRenderLoop::run() { void QH::AsyncRenderLoop::run() {
@ -31,9 +41,12 @@ void QH::AsyncRenderLoop::run() {
} }
void QH::AsyncRenderLoop::stop() { void QH::AsyncRenderLoop::stop() {
m_run = false; if (isRun()) {
thread()->quit(); m_run = false;
thread()->wait(); thread()->quit();
thread()->wait();
}
} }
bool AsyncRenderLoop::isRun() const { bool AsyncRenderLoop::isRun() const {

@ -16,7 +16,7 @@ namespace QH {
* @brief The AsyncRenderLoop is a class for asynchronous rendering. * @brief The AsyncRenderLoop is a class for asynchronous rendering.
* This class is used to create a render loop that is executed in a separate thread. * This class is used to create a render loop that is executed in a separate thread.
* To use this class, you must inherit from it and implement the renderIteration method. * To use this class, you must inherit from it and implement the renderIteration method.
* @example : * **example:** :
* @code{cpp} * @code{cpp}
* class MyRenderLoop: public AsyncRenderLoop * class MyRenderLoop: public AsyncRenderLoop
* { * {
@ -35,11 +35,92 @@ namespace QH {
* *
* return app.exec(); * return app.exec();
* @endcode * @endcode
*
* @warning This class may be broken if you use it as a QSharedPointer and push WeackPointer to the child objects. To solve this issue use the @a AsyncRenderLoop::MainSharedPtr class.
*
* Example:
*
* @code{cpp}
* class MyRenderLoop: public AsyncRenderLoop
* {
* ...
* };
*
* int main (int argc, char* argv[]) {
* auto loop = QSharedPointer<MyRenderLoop>(new MyRenderLoop(new QThread())); // wrong! it will be broken
* auto loop = MyRenderLoop::MainSharedPtr<MyRenderLoop>>(new QThread()); // right!
* auto loop = MyRenderLoop::createMainPtr<MyRenderLoop>(new QThread()); // this is short version of initialization Main pointer
* ...
* return app.exec();
* }
* @endcode
*/ */
class HEARTSHARED_EXPORT AsyncRenderLoop: public Async class HEARTSHARED_EXPORT AsyncRenderLoop: public Async
{ {
Q_OBJECT Q_OBJECT
public: public:
/**
* @brief The MainSharedPtr class is a helper class for creating a shared pointer to the render loop.
* @tparam T type of the render loop object.
* This class make main sharedPointer of your render loop object. it is used to solve issue with deleting object in self thread.
*
* if you use the AsyncRenderLoop as a QSharedPointer and push WeackPointer to the child objects, you must use this wrapper class.
*/
template<typename T>
class MainSharedPtr {
public:
MainSharedPtr() {
static_assert(std::is_base_of_v<AsyncRenderLoop, T>,
"T must be derived from AsyncRenderLoop");
}
MainSharedPtr(const QSharedPointer<T>& ptr): _ptr(ptr) {
static_assert(std::is_base_of_v<AsyncRenderLoop, T>,
"T must be derived from AsyncRenderLoop");
}
~MainSharedPtr() {
if (_ptr) {
_ptr->stop();
}
}
T* operator->() const {
return _ptr.operator->();
}
/**
* @brief get This is a alias of the QSharedPointer::get method.
* @return pointer to the object.
*/
T* get() const {
return _ptr.get();
}
/**
* @brief create This method creates a shared pointer to the render loop.
* @param arguments arguments for the constructor of the render loop object.
* @return shared pointer to the render loop.
*/
template <typename... Args>
[[nodiscard]] static MainSharedPtr create(Args && ...arguments) {
return MainSharedPtr(QSharedPointer<T>::create(std::forward<Args>(arguments)...));
}
/**
* @brief getShared This method return child shared pointer. You can use them as a general shared pointer of the object.
* @return reference to the object.
*/
const QSharedPointer<T>& getShared() const {
return _ptr;
}
private:
QSharedPointer<T> _ptr;
};
AsyncRenderLoop(QThread* thread, QObject* ptr = nullptr); AsyncRenderLoop(QThread* thread, QObject* ptr = nullptr);
~AsyncRenderLoop(); ~AsyncRenderLoop();
@ -59,6 +140,18 @@ public:
*/ */
bool isRun() const; bool isRun() const;
/**
* @brief createMainPtr This method creates a shared pointer to the render loop.
* @tparam Type type of the render loop object.
* @tparam Args arguments for the constructor of the render loop object.
* @param arguments arguments for the constructor of the render loop object.
* @return shared pointer to the render loop.
*/
template<typename Type, typename... Args>
static MainSharedPtr<Type> createMainPtr(Args && ...arguments) {
return MainSharedPtr<Type>(QSharedPointer<Type>::create(std::forward<Args>(arguments)...));
};
protected: protected:
/** /**
@ -79,4 +172,5 @@ private:
}; };
} }
#endif // ASYNCRENDERLOOP_H #endif // ASYNCRENDERLOOP_H

@ -7,18 +7,19 @@ StreamMultiversion::StreamMultiversion() {
} }
QDataStream &StreamMultiversion::fromStream(QDataStream &stream) { StreamMultiversion::~StreamMultiversion() {
stream >> _realVersion ;
return stream;
} }
QDataStream &StreamMultiversion::toStream(QDataStream &stream) const { void StreamMultiversion::saveVersion(char version, QDataStream &stream) const {
stream << _realVersion; stream << version;
return stream;
} }
int StreamMultiversion::realVersion() const { char StreamMultiversion::readVersion(QDataStream &stream) {
return _realVersion; char version;
stream >> version;
return version;
} }
} }

@ -14,34 +14,55 @@ namespace QH {
/** /**
* @brief The StreamMultiversion class this parser works with simple multiversion packages. * @brief The StreamMultiversion class this parser works with simple multiversion packages.
*
* This class used to save and read version of the object in file.
*
* @see StreamBase
*
* @code{cpp}
* class myClass: public StreamMultiversion {
* protected:
* QDataStream &fromStream(QDataStream &stream) override {
* char version = readVersion();
* return stream;
* }
*
* QDataStream &toStream(QDataStream &stream) const override {
* saveVersion(1, stream);
* return stream;
* }
*
* }
*
*/ */
class HEARTSHARED_EXPORT StreamMultiversion: public StreamBase class HEARTSHARED_EXPORT StreamMultiversion: public StreamBase
{ {
public: public:
StreamMultiversion(); StreamMultiversion();
~StreamMultiversion();
// StreamBase interface // StreamBase interface
/**
* @brief version override this method to sets version of package.
* @return
*/
virtual int version() const = 0;
/** /**
* @brief realVersion This method return value of the version that was be saved in the bytes array. * @brief saveVersion save version of the object to the stream.
* @return * @param version - version of the object.
* @note use this method to check version of read package in the fromStream method.. * @param stream - stream to save.
*
* This method used to save version of the object in file.
* @see toStream
*/ */
virtual int realVersion() const; void saveVersion(char version, QDataStream &stream) const;
protected:
QDataStream &fromStream(QDataStream &stream) override; /**
QDataStream &toStream(QDataStream &stream) const override; * @brief readVersion read version of the object from the stream.
* @param stream - stream to read.
* @return version of the object.
* @see fromStream
*/
char readVersion(QDataStream &stream);
private:
int _realVersion = 0;
}; };
} }
#endif // STREAMMULTIVERSION_H #endif // STREAMMULTIVERSION_H