游戏引擎从零开始(3)-日志系统spdlog

前言

日志系统是所有程序中的刚需,本章节将开源的spdlog集成到引擎中。

spdlog是一个只有头文件,性能很好的C++日志库

集成spdlog

spdlog以submodule的形式集成到项目中。

所有的第三方库我们放到/Sanbox/Hazel/vendor下面

vendor供应商的意思,也可以表示第三方库

download spdlog

在项目根目录下执行下面命令:

bash 复制代码
git submodule add https://github.com/gabime/spdlog.git Sanbox/Hazel/vendor/spdlog

在根目录下会生成一个.gitmodules文件,而spdlog并不会加入到本项目的git记录中。

.gitmodules

ini 复制代码
[submodule "Sandbox/Hazel/vendor/spdlog"]
	path = Sandbox/Hazel/vendor/spdlog
	url = https://github.com/gabime/spdlog.git

增加了一些ignore

Hazel/.gitignore

bash 复制代码
/Sandbox/cmake-build-debug/
.idea/
build

更新Hazel引擎的CMake

更新CMake文件,增加spdlog引用

参考diff,修改的地方一目了然

实现Log封装

Log.h

声明两个静态的log实例,分别用于引擎内核的日志打印,和业务层的日志打印。这样做可以设置不同的tag,以及设置不同的日志策略。

两个Log对应两个静态的获取实例的函数。

c++ 复制代码
namespace Hazel {
    class Log {
    public:

        static void Init();

        inline static std::shared_ptr<spdlog::logger>& GetCoreLogger(){
            return s_CoreLogger;
        }

        inline static std::shared_ptr<spdlog::logger>& GetClientLogger(){
            return s_ClientLogger;
        };

    private:
        static std::shared_ptr<spdlog::logger> s_CoreLogger;
        static std::shared_ptr<spdlog::logger> s_ClientLogger;
    };
}

Log.cpp中初始化spdlog。

spdlog的使用可以参考官方文档,有详细的说明,此处不做展开spdlog文档

c++ 复制代码
#include "Log.h"

namespace Hazel{
    std::shared_ptr<spdlog::logger> Log::s_CoreLogger;
    std::shared_ptr<spdlog::logger> Log::s_ClientLogger;

    void Log::Init() {
        spdlog::set_pattern("%^[%T] %n : %v%$");
        Log::s_CoreLogger = spdlog::stdout_color_mt("HAZEL", spdlog::color_mode::always);
        Log::s_CoreLogger->set_level(spdlog::level::trace);

        Log::s_ClientLogger = spdlog::stdout_color_mt("APP", spdlog::color_mode::always);
        Log::s_ClientLogger->set_level(spdlog::level::trace);
    }
}

这里我们两个日志等级都设置成trace级别,tag分别设置为"HAZEL"和"APP"

注意,C++中,静态变量定义和声明需要分开写。

如Log::s_CoreLogger和Log::s_ClientLogger声明和定义。

Hazel.h文件中增加Log.h的引用

c++ 复制代码
#ifndef SANBOX_HAZEL_H
#define SANBOX_HAZEL_H

#include <stdio.h>
#include "Hazel/Application.h"
#include "Hazel/Log.h"

// -----Entry Point-------
#include "Hazel/EntryPoint.h"

#endif //SANBOX_HAZEL_H

Log的使用及优化

回到EntryPoint.h文件中,使用Log打印日志

c++ 复制代码
int main(int argc, char** argv) {
    Hazel::Log::Init();
    Hazel::Log::GetCoreLogger()->warn("Initialized Log!");
    Hazel::Log::GetClientLogger()->info("Hello!");

    auto app = Hazel::CreateApplication();
    app->Run();
    delete app;
}

可以看到虽然可以用了,但是打印一行日志的代码有点啰嗦,用宏定义简化。

回到Log.h中,在末尾增加宏定义

c++ 复制代码
// Core log macros
#define HZ_CORE_TRACE(...)  ::Hazel::Log::GetCoreLogger()->trace(__VA_ARGS__)
#define HZ_CORE_INFO(...)   ::Hazel::Log::GetCoreLogger()->info(__VA_ARGS__)
#define HZ_CORE_WARN(...)   ::Hazel::Log::GetCoreLogger()->warn(__VA_ARGS__)
#define HZ_CORE_ERROR(...)  ::Hazel::Log::GetCoreLogger()->error(__VA_ARGS__)
#define HZ_CORE_FATAL(...)  ::Hazel::Log::GetCoreLogger()->fatal(__VA_ARGS__)


// Client log macros
#define HZ_TRACE(...)  ::Hazel::Log::GetClientLogger()->trace(__VA_ARGS__)
#define HZ_INFO(...)   ::Hazel::Log::GetClientLogger()->info(__VA_ARGS__)
#define HZ_WARN(...)   ::Hazel::Log::GetClientLogger()->warn(__VA_ARGS__)
#define HZ_ERROR(...)  ::Hazel::Log::GetClientLogger()->error(__VA_ARGS__)
#define HZ_FATAL(...)  ::Hazel::Log::GetClientLogger()->fatal(__VA_ARGS__)

EntryPoint.h中的调用就简单多了

c++ 复制代码
int main(int argc, char** argv) {
    Hazel::Log::Init();
//    Hazel::Log::GetCoreLogger()->warn("Initialized Log!");
//    Hazel::Log::GetClientLogger()->info("Hello!");
    HZ_CORE_WARN("Initialed Log!");
    int a = 5;
    HZ_INFO("Hello! Var={0}", a);

    auto app = Hazel::CreateApplication();
    app->Run();
    delete app;
}

基于宏定义的日志除了简化调用逻辑,还有个重要的作用,区分不同包做不同的逻辑,比如在正式版本不希望打印调试日志,可以增加宏定义:

#define HZ_TRACE(...)

这样预编译的时候替换成空,相当于什么都没干。

完整代码commit参考:

commit-include spdlog into Hazel

相关推荐
开开心心就好11 小时前
无需安装的单机塔防游戏轻松畅玩
人工智能·游戏·pdf·音视频·智能家居·语音识别·媒体
开开心心就好11 小时前
这款工具批量卸载软件并清理残留文件
人工智能·游戏·音视频·语音识别·媒体·程序员创富·高考
谭欣辰12 小时前
C++ 控制台跑酷小游戏
c++·游戏
好家伙VCC12 小时前
**发散创新:用 Rust实现游戏日引擎核心模块——从事件驱动到多线程调度的实战
java·开发语言·python·游戏·rust
SmalBox15 小时前
【节点】[Lerp节点]原理解析与实际应用
unity3d·游戏开发·图形学
游了个戏16 小时前
OPC × AI × 快手:小游戏蓝海中的第三极突围
人工智能·游戏
王杨游戏养站系统17 小时前
王杨安企cms:批量3000个游戏下载指定链接导入方法!
游戏·游戏下载站养站系统·游戏养站系统
游了个戏18 小时前
用AI做了个小游戏(二)
人工智能·游戏·微信
glimix1 天前
Word-Pop:使用C语言开发打单词游戏
c语言·游戏
上海云盾-小余1 天前
DDoS 攻击应急响应全流程:从告警触发到业务恢复的黄金 15 分钟
服务器·安全·游戏·ddos