游戏引擎从零开始(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

相关推荐
IT从业者张某某10 小时前
基于EGE19.01完成恐龙跳跃游戏-V00-C++使用EGE19.01这个轮子
c++·游戏
SmalBox15 小时前
【节点】[Absolute节点]原理解析与实际应用
unity3d·游戏开发·图形学
Sator118 小时前
Unity关于射击游戏人物动画的设计经验
游戏·unity·游戏引擎
王杨游戏养站系统19 小时前
3分钟搭建1个游戏下载站网站教程!SEO站长养站系统!
开发语言·前端·游戏·游戏下载站养站系统·游戏养站系统
huwuhang1 天前
索尼PS3游戏合集【中文游戏】8.12T 1430个游戏+PS3模拟器
android·游戏·智能手机·游戏机·电视
毕业设计-小慧1 天前
计算机毕业设计springboot游戏数据管理系统 基于SpringBoot的电竞赛事数据管理平台 基于SpringBoot的在线游戏运营数据分析系统
spring boot·游戏·课程设计
黑客说1 天前
AI驱动剧情,解锁无限可能——AI游戏发展解析
人工智能·游戏
智算菩萨1 天前
【OpenGL】10 完整游戏开发实战:基于OpenGL的2D/3D游戏框架、物理引擎集成与AI辅助编程指南
人工智能·python·游戏·3d·矩阵·pygame·opengl
风酥糖1 天前
Godot游戏练习01-第20节-增加亿点点细节
游戏·游戏引擎·godot
聊点儿技术2 天前
游戏账号盗用频发,IP风险等级评估如何成为第一道防线?
安全·游戏·ip地址·风险评估·账号安全·ip风险等级评估