【03】Cockatrice应用入口与标准初始化流程

目录

简介

源码分析

[1]Qt应用程序标准框架

[2]日志管理模块

[3]配置管理模块

[4]主题管理模块

[5]音频引擎模块

[6]数据库引擎模块

[7]翻译(Qt国际化)模块

[8]RNG_SFMT模块(不知道干啥的,以后慢慢分析)


简介

一般源码分析都是从main开始的,此次自然也不例外。我们来分析/Cockatrice/cockatrice/src/main.cpp。main()中主要实现了Qt应用程序的标准流程,并初始化了一些程序模块。我们也得以管中窥豹,从中初步了解Cockatrice的模块划分与设计思路。

源码分析

主要模块如下所示:

[1]Qt应用程序标准框架

标准的Qt GUI应用程序写法,很传统但也很经典。main中主要实现了界面参数初始化,资源加载与功能模块实例化。

QSystemTrayIcon *trayIcon;

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);---->在栈上创建QApplication实例

    QObject::connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));---->绑定lastWindowClosed()信号,保证最后一个窗口关闭时触发quit()最终退出程序

    qInstallMessageHandler(CockatriceLogger);---->注册日志处理函数

#ifdef Q_OS_WIN
    app.addLibraryPath(app.applicationDirPath() + "/plugins");---->添加指定的函数库加载路径
#endif

    // These values are only used by the settings loader/saver
    // Wrong or outdated values are kept to not break things
    QCoreApplication::setOrganizationName("Cockatrice");---->设置组织,公司,应用,版本名称
    QCoreApplication::setOrganizationDomain("cockatrice.de");
    QCoreApplication::setApplicationName("Cockatrice");
    QCoreApplication::setApplicationVersion(VERSION_STRING);

#ifdef Q_OS_MAC
    qApp->setAttribute(Qt::AA_DontShowIconsInMenus, true);---->设置是否在菜单中添加本应用
#endif

    。。。

    QCommandLineParser parser;---->用QCommandLineParser来设置并处理用户传参
    parser.setApplicationDescription("Cockatrice");---->设置应用描述
    parser.addHelpOption();---->添加帮助选项("-h" 或 "--help")
    parser.addVersionOption();---->添加版本选项("-v" 或 "--version") 

    parser.addOptions(
        {{{"c", "connect"}, QCoreApplication::translate("main", "Connect on startup"), "user:pass@host:port"},
         {{"d", "debug-output"}, QCoreApplication::translate("main", "Debug to file")}});---->添加用户自定义选项

    parser.process(app);---->将以上所有解析选项添加到QApplication实例

    if (parser.isSet("debug-output")) {
        Logger::getInstance().logToFile(true);---->如果用户输入-d则启用日志
    }

    。。。

    QLocale::setDefault(QLocale::English);---->设置默认语言环境为English

    qsrand(QDateTime::currentDateTime().toTime_t());---->调用系统当前时间生成随机数种子
    qDebug("main(): starting main program");

    MainWindow ui;---->在栈上创建MainWindow实例
    if (parser.isSet("connect")) {
        ui.setConnectTo(parser.value("connect"));---->如果用户输入-c参数,将该参数传入MainWindow实例
    }
    qDebug("main(): MainWindow constructor finished");

    ui.setWindowIcon(QPixmap("theme:cockatrice"));---->设置应用程序左上角显示的图标

    。。。

    ui.show();---->显示MainWindow
    qDebug("main(): ui.show() finished");

    app.setAttribute(Qt::AA_UseHighDpiPixmaps);---->启动针对高分辨率Retina的显示支持
    app.exec();---->运行QApplication实例,开启事件循环,程序阻塞在此处直到quit()

    qDebug("Event loop finished, terminating...");

    。。。

    PingPixmapGenerator::clear();---->
    CountryPixmapGenerator::clear();---->
    UserLevelPixmapGenerator::clear();---->

    return 0;
}

[2]日志管理模块

调用了Qt提供的logger handle来实现日志功能。

后续单独分析Qt的日志管理。

static void CockatriceLogger(QtMsgType type, const QMessageLogContext &ctx, const QString &message)
{
    Logger::getInstance().log(type, ctx, message);
}

int main(int argc, char *argv[])
{
    。。。

    qInstallMessageHandler(CockatriceLogger);

    。。。
}

[3]配置管理模块

SettingCache作为一个独立的功能模块,后续单独分析。

这里用设备MAC地址生成了hash摘要作为用户ID,也是很经典的写法。

SettingsCache *settingsCache;

QString const generateClientID()
{
    QString macList;
    foreach (QNetworkInterface interface, QNetworkInterface::allInterfaces()) {
        if (interface.hardwareAddress() != "")
            if (interface.hardwareAddress() != "00:00:00:00:00:00:00:E0")
                macList += interface.hardwareAddress() + ".";
    }
    QString strClientID = QCryptographicHash::hash(macList.toUtf8(), QCryptographicHash::Sha1).toHex().right(15);
    return strClientID;
}

int main(int argc, char *argv[])
{
    。。。

    settingsCache = new SettingsCache;

    。。。

    settingsCache->setClientID(generateClientID());

    。。。

    app.exec();

    。。。
    
    delete settingsCache;

    。。。
}

[4]主题管理模块

ThemeManager作为一个独立的功能模块,后续单独分析。

ThemeManager *themeManager;

int main(int argc, char *argv[])
{
    。。。

    themeManager = new ThemeManager;

    。。。

    app.exec();

    。。。

    delete themeManager;

    。。。
}

[5]音频引擎模块

SoundEngine作为一个独立的功能模块,后续单独分析。

SoundEngine *soundEngine;

int main(int argc, char *argv[])
{
    。。。

    soundEngine = new SoundEngine;

    。。。

    app.exec();

    。。。

    delete soundEngine;

    。。。
}

[6]数据库引擎模块

CardDatabase作为一个独立的功能模块,后续单独分析。

SpoilerBackgroundUpdater用来干什么呢?后续再分析。

CardDatabase *db;

int main(int argc, char *argv[])
{
    。。。

    db = new CardDatabase;

    。。。

    // If spoiler mode is enabled, we will download the spoilers
    // then reload the DB. otherwise just reload the DB
    SpoilerBackgroundUpdater spoilerBackgroundUpdater;    

    。。。

    app.exec();

    。。。

    delete db;

    。。。
}

[7]翻译(Qt国际化)模块

调用了Qt提供的QTranslator来实现日志功能。

后续单独分析Qt国际化。

QTranslator *translator, *qtTranslator;
const QString translationPrefix = "cockatrice";
QString translationPath;

void installNewTranslator()
{
    QString lang = settingsCache->getLang();

    qtTranslator->load("qt_" + lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath));
    qApp->installTranslator(qtTranslator);
    translator->load(translationPrefix + "_" + lang, translationPath);
    qApp->installTranslator(translator);
    qDebug() << "Language changed:" << lang;
}

int main(int argc, char *argv[])
{
    。。。

#ifdef Q_OS_MAC
    translationPath = qApp->applicationDirPath() + "/../Resources/translations";---->设置翻译文件加载路径
#elif defined(Q_OS_WIN)
    translationPath = qApp->applicationDirPath() + "/translations";
#else // linux
    translationPath = qApp->applicationDirPath() + "/../share/cockatrice/translations";
#endif

    。。。

    qtTranslator = new QTranslator;
    translator = new QTranslator;
    installNewTranslator();

    。。。

    app.exec();

    。。。

    delete qtTranslator;
    delete translator;

    。。。
}

[8]RNG_SFMT模块(不知道干啥的,以后慢慢分析)

RNG_Abstract *rng;

int main(int argc, char *argv[])
{
    。。。

    rng = new RNG_SFMT;

    。。。

    app.exec();

    。。。

    delete rng;

    。。。
}

下一篇我们来分析Cockatrice的Client端界面结构。

发布了12 篇原创文章 · 获赞 0 · 访问量 219

猜你喜欢

转载自blog.csdn.net/wa0jixu/article/details/104347164