покритикуйте код; slithercc
Здравствуйте,
сочинил клиента web игры slither.io.
slither.io это мультиплеерная змейка в кот. нельзя врезаться в других игроков.
https://github.com/ivan-matveev/slithercc
Покритикуйте код.
Здравствуйте,
сочинил клиента web игры slither.io.
slither.io это мультиплеерная змейка в кот. нельзя врезаться в других игроков.
https://github.com/ivan-matveev/slithercc
Покритикуйте код.
Вот пример от Макса Шлее:
/* ======================================================================
** main.cpp
** ======================================================================
**
** ======================================================================
** Copyright (c) 2007 by Max Schlee
** ======================================================================
*/
#include <QtGui>
// ======================================================================
class MyThread : public QThread {
Q_OBJECT
private:
int m_nValue;
public:
MyThread() : m_nValue(10)
{
}
void run()
{
QTimer timer;
//^^^^^^^^^^^
//а где будет эта переменная когда run() закончится
//а event loop будет продолжаться и тред должен будет
//дрыгать этим таймером раз в секунду?
connect(&timer, SIGNAL(timeout()), SLOT(slotNextValue()));
timer.start(1000);
exec();
}
signals:
void finished ( );
void currentValue(int);
public slots:
void slotNextValue()
{
emit currentValue(--m_nValue);
if (!m_nValue) {
emit finished();
}
}
};
// ----------------------------------------------------------------------
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QLCDNumber lcd;
MyThread thread;
QObject::connect(&thread, SIGNAL(currentValue(int)),
&lcd, SLOT(display(int))
);
QObject::connect(&thread, SIGNAL(finished()),
&app, SLOT(quit())
);
lcd.setSegmentStyle(QLCDNumber::Filled);
lcd.display(10);
lcd.resize(220, 90);
lcd.show();
thread.start();
return app.exec();
}
#include "main.moc"
Вопрос в коментарии в функции run().
Прочитал у тогоже Шлее что в Qt
в основном передаются ссылки на объекты, а не копии объектов,
и что не надо объявлять статические объекты а надо new и давать им parent чтоб Qt с ними сам разобрался
не недо delete'ать объекты
что Qt ведет счет ссылкам на объект и убьет объект когда ссылки кончатся
Все эти умные(возможно мной не понятые) слова как бы говорят: «Не парься, делай как в примерах, память не потечет и ссылок в никуда не будет».
Но я старый Cшник, и хочу понять где будет жить локальная переменная
QTimer timer;
объявленная в функции run(), когда run() отработает а тред еще бежит.
Смотрю пример применения тредов Mandelbrot.
http://doc.qt.nokia.com/4.6/threads-mandelbrot.html
Написано:
class MandelbrotWidget : public QWidget
{
//...
private slots:
void updatePixmap(const QImage &image, double scaleFactor);
//...
}
class RenderThread : public QThread
{
//...
signals:
void renderedImage(const QImage &image, double scaleFactor);
protected:
void run();
//...
}
MandelbrotWidget::MandelbrotWidget(QWidget *parent)
: QWidget(parent)
{
//...
connect(&thread, SIGNAL(renderedImage(QImage,double)),
this, SLOT(updatePixmap(QImage,double)));
//...
}
void RenderThread::run()
{
QImage image(resultSize, QImage::Format_RGB32);
forever {
//...
emit renderedImage(image, scaleFactor);
//...
}
}
void MandelbrotWidget::updatePixmap(const QImage &image, double scaleFactor)
{
//...
pixmap = QPixmap::fromImage(image);
//...
}
Смущает что в сигнале/слоте передается указатель на локальную переменную image определенную в функции RenderThread::run(). Смущает потому что(на сколько я ничего не понимаю)при передаче сигнала между тредами не известно когда сигнал попадет в слот. Функция к тому времени может закончиться и локальной переменной придет кирдык. Я бы сделал image членом RenderThread чтоб она существовала пока существует объект. В данном случае все скорее будет работать чем нет, т.к. в RenderThread::run() все происходит внутри forever{}, но, кажется еще где то в примерах QT видел такую фигню. Это нормальна практика или проявление особенностей QT(e.g. reference count)?
Еще вопросы.
В этом примере в RenderThread::run() все происходит внутри forever{}. Правильно я понимаю что обработчик событий в этом треде не запущен ведь его запускает exec()?
А нафига треду обработчик событий синалы ведь будут работать по любому?
Как тред прибить по сигналу из другого треда?
Мда, короче ничего не понимаю, может почитать чего?