跟着cherno手搓游戏引擎【2】:日志系统spdlog和premake的使用
配置:
日志库文件github:
GitHub - gabime/spdlog: Fast C++ logging library.
新建vendor文件夹
将下载好的spdlog放入

配置YOTOEngine的附加包含目录:

配置Sandbox的附加包含目录:

包装spdlog:
在YOTO文件夹下创建Log.cpp和log.h
log.h:
#pragma once
#include"Core.h"
#include<spdlog/spdlog.h>
#include "spdlog/sinks/stdout_color_sinks.h"
namespace YOTO {class YOTO_API Log{public:static void Init();//inline是为了提高性能,相当于直接把函数里的代码段放在那里//返回的是Logger,分为服务器logger和核心loggerinline 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;};
}
//Core 的log 的简化
#define YT_CORE_ERROR(...) ::YOTO::Log::GetCoreLogger()->error(__VA_ARGS__)
#define YT_CORE_WARN(...) ::YOTO::Log::GetCoreLogger()->warn(__VA_ARGS__)
#define YT_CORE_INFO(...) ::YOTO::Log::GetCoreLogger()->info(__VA_ARGS__)
#define YT_CORE_TRACE(...) ::YOTO::Log::GetCoreLogger()->trace(__VA_ARGS__)
#define YT_CORE_FATAL(...) ::YOTO::Log::GetCoreLogger()->fatal(__VA_ARGS__)
//client 的log的简化
#define YT_CLIENT_ERROR(...) ::YOTO::Log::GetClientLogger()->error(__VA_ARGS__)
#define YT_CLIENT_WARN(...) ::YOTO::Log::GetClientLogger()->warn(__VA_ARGS__)
#define YT_CLIENT_INFO(...) ::YOTO::Log::GetClientLogger()->info(__VA_ARGS__)
#define YT_CLIENT_TRACE(...) ::YOTO::Log::GetClientLogger()->trace(__VA_ARGS__)
#define YT_CLIENT_FATAL(...) ::YOTO::Log::GetClientLogger()->fatal(__VA_ARGS__)
log.cpp:
#include "Log.h"namespace YOTO {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%$");//创建多线程logger,核心logger为YOTOs_CoreLogger = spdlog::stdout_color_mt("YOTO");//设置打印消息的级别,trace是打印所有东西(筛选器)s_CoreLogger->set_level(spdlog::level::level_enum::trace);//客户端的为APPs_ClientLogger= spdlog::stdout_color_mt("APP");s_ClientLogger->set_level(spdlog::level::level_enum::trace);}
}
测试:
在YOTO.h中加入#include "YOTO/Log.h",记得重新生成,把dll加入到Sandbox(后续会使用premake简化该流程,这里暂时手动生成)
我们在入口点修改代码测试:
#pragma once#ifdef YT_PLATFORM_WINDOWS
#include "../YOTO.h"extern YOTO::Application* YOTO::CreateApplication();
void main(int argc,char** argv) {YOTO::Log::Init();YT_CORE_ERROR("测试警告信息");int test = 1;YT_CLIENT_INFO("测试info:test={0}",test);auto app = YOTO::CreateApplication();app->Run();delete app;
}
#endif
输出:
Premake配置安装:
点击下载:https://github.com/premake/premake-core/releases/download/v5.0.0-beta2/premake-5.0.0-beta2-windows.zip
创建vendor文件夹:文件结构如下


放入声明文件LICENSE.txt:
Copyright (c) 2003-2016 Jason Perkins and individual contributors.
All rights reserved.Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:1. Redistributions of source code must retain the above copyright notice,this list of conditions and the following disclaimer.2. Redistributions in binary form must reproduce the above copyright notice,this list of conditions and the following disclaimer in the documentationand/or other materials provided with the distribution.3. Neither the name of Premake nor the names of its contributors may beused to endorse or promote products derived from this software withoutspecific prior written permission.THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
编写premake5.lua文件:
workspace "YOTOEngine" -- sln文件名architecture "x64" configurations{"Debug","Release","Dist"}-- 组成输出目录:Debug-windows-x86_64
outputdir = "%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}"project "YOTOEngine" location "YOTOEngine"--在sln所属文件夹下的Hazel文件夹kind "SharedLib"--dll动态库language "C++"targetdir ("bin/" .. outputdir .. "/%{prj.name}") -- 输出目录objdir ("bin-int/" .. outputdir .. "/%{prj.name}")-- 中间目录-- 包含的所有h和cpp文件files{"%{prj.name}/src/**.h","%{prj.name}/src/**.cpp"}-- 包含目录includedirs{"%{prj.name}/vendor/spdlog-1.x/include"}-- 如果是window系统filter "system:windows"cppdialect "C++17"-- On:代码生成的运行库选项是MTD,静态链接MSVCRT.lib库;-- Off:代码生成的运行库选项是MDD,动态链接MSVCRT.dll库;打包后的exe放到另一台电脑上若无这个dll会报错staticruntime "On" systemversion "latest" -- windowSDK版本-- 预处理器定义defines{"YT_PLATFORM_WINDOWS","YT_BUILD_DLL"}-- 编译好后移动Hazel.dll文件到Sandbox文件夹下postbuildcommands{("{COPY} %{cfg.buildtarget.relpath} ../bin/" .. outputdir .. "/Sandbox")}-- 不同配置下的预定义不同filter "configurations:Debug"defines "YT_DEBUG"symbols "On"filter "configurations:Release"defines "YT_RELEASE"optimize "On"filter "configurations:Dist"defines "YT_DIST"optimize "On"project "Sandbox"location "Sandbox"kind "ConsoleApp"language "C++"targetdir ("bin/" .. outputdir .. "/%{prj.name}")objdir ("bin-int/" .. outputdir .. "/%{prj.name}")files{"%{prj.name}/src/**.h","%{prj.name}/src/**.cpp"}-- 同样包含spdlog头文件includedirs{"YOTOEngine/vendor/spdlog-1.x/include","YOTOEngine/src"}-- 引用YOTOEnginelinks{"YOTOEngine"}filter "system:windows"cppdialect "C++17"staticruntime "On"systemversion "latest"defines{"YT_PLATFORM_WINDOWS"}filter "configurations:Debug"defines "YT_DEBUG"symbols "On"filter "configurations:Release"defines "YT_RELEASE"optimize "On"filter "configurations:Dist"defines "YT_DIST"optimize "On"
创建Generate.bat文件,每次将bin和bin-int删除然后点这个文件就可以自动生成。
call vendor\bin\premake\premake5.exe vs2019
PAUSE
遇到问题不要慌:

这个问题是还没创建完就启动了,只需要等一会儿就好了。
等待10秒钟之后:启动!

今天就看到这里,下一集:事件系统【持续更新中】
相关文章:
跟着cherno手搓游戏引擎【2】:日志系统spdlog和premake的使用
配置: 日志库文件github: GitHub - gabime/spdlog: Fast C logging library. 新建vendor文件夹 将下载好的spdlog放入 配置YOTOEngine的附加包含目录: 配置Sandbox的附加包含目录: 包装spdlog: 在YOTO文件夹下创建…...
Ubuntu20.04 上启用 VCAN 用作本地调试
目录 一、启用本机的 VCAN 编辑 1.1 加载本机的 vcan 1.2 添加本机的 vcan0 1.3 查看添加的 vcan0 1.4 开启本机的 vcan0 1.5 关闭本机的 vcan0 1.6 删除本机的 vcan0 二、测试本机的 VCAN 2.1 CAN 发送数据 代码 2.2 CAN 接收数据 代码 2.3 CMakeLists.…...
LeetCode(31) 下一个排列
整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 例如,arr [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。 整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地…...
Git LFS: 简单高效的大文件版本控制
Git Large File Storage 问题 在使用git上传大文件时候,git push时候会报错: remote: error: File xxx.tar.gz is 135.17 MB; this exceeds GitHubs file size limit of 100 MB可以看到,git限制上传大小是100MB,超过的话就会报错ÿ…...
如何培养用户思维
产品开发是根据用户要求建造出系统的过程,产品开发是一项包括需求捕捉、需求分析、设计、实现和测试的系统工程,一般通过某种程序设计语言来实现。然而用户思维能够帮助企业更好地理解市场需求,进行产品的开发和完善,用户是企业产…...
由浅入深理解C#中的事件
目录 本文较长,给大家提供了目录,可以直接看自己感兴趣的部分。 前言有关事件的概念示例 简单示例 标准 .NET 事件模式 使用泛型版本的标准 .NET 事件模式 补充总结 参考前言 前面介绍了C#中的委托,事件的很多部分都与委托…...
Nginx(十六) 配置文件详解 - server stream服务流
本篇文章主要讲 ngx_stream_core_module 模块下各指令的使用方法,Nginx默认未配置该模块,需要用“--with-stream”配置参数重新编译Nginx。 worker_processes auto;error_log /var/log/nginx/error.log info;events {worker_connections 1024; }stream…...
Css中默认与继承
initial默认样式: initial 用于设置 Css 属性为默认值 h1 {color: initial; }如display或position不能被设置为initial,因为有默认属性。例如:display:inline inherit继承样式: inherit 用于设置 Css 属性应从父元素继承 di…...
gitee上的vue大屏项目
在 Gitee 上,有几个值得注意的 Vue 大屏项目:vue-big-screen-plugin (Gitee): 这是一个基于 Vue3、Typescript、DataV 和 ECharts5 框架的可视化大屏项目。它使用 .vue 和 .tsx 文件构建界面,并采用新版动态屏幕适配方案。这个项目支持数据的动态刷新渲染,内部的 DataV 和 …...
【LeetCode:114. 二叉树展开为链表 | 二叉树 + 递归】
🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…...
社保养老金发放计算方法
退休后养老金计算公式很复杂,自己自行百度查一下,这里说一下男性,女工人,女干部之间计算差别。 退休后,能到手的养老金多少,取决于你的个人账户里的钱,个人账户里的钱越多,到手养老…...
概率论基础复习题
一、填空题 二、选择题 答案:B 答案:C 答案:C 答案:D。统计量不含任何未知参数。 答案:A 答案:C 样本均值是总体均值的无偏估计;样本方差是总体方差的无偏估计。 答案:B。统计值是一…...
c++,mutex,unique_lock,recursive_mutex,shared_mutex对比分析
当处理多线程并发时,正确使用锁是确保线程安全的关键。 1. std::mutex(互斥锁): std::mutex 是C标准库提供的最基本的锁。它的基本使用如下: #include <iostream> #include <mutex> #include <threa…...
MySQL与Oracle数据库在网络安全等级方面用到的命令
MySQL数据库命令集 查看数据库版本 SELECT VERSION(); 空口令查询 SELECT user,host,account_locked FROM mysql.user WHERE user ; SELECT * FROM mysql.user; 查询 用户的密码加密情况 SELECT HOST,USER,PLUGIN FROM mysql.user; 查询是否有空用户 SELECT host,user,plug…...
MySQL——视图
目录 一.视图介绍 二.基本使用 三.视图规则和限制 一.视图介绍 视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。视图的数据变化会影响到基表,基表的数据变化也会影响到视图。 二.基本使用 创…...
【响应式编程-03】Lambda表达式底层实现原理
一、简要描述 Lambda的底层实现原理Lambda表达式编译和运行过程 二、Lambda的底层实现原理 Lambda表达式的本质 函数式接口的匿名子类的匿名对象 反编译:cfr-0.145.jar 反编译:LambdaMetafactory.metafactory() 跟踪调试,转储Lambda类&#x…...
深入理解可变参数
1.C语言方式 目录 1.C语言方式 1.1.宏介绍 1.2.原理详解 1.3.宏的可变参数 1.4.案例分析 1.5.其他实例 2.C之std::initializer_list 2.1.简介 2.2.原理详解 2.3.案例分析 3.C之可变参数模版 3.1.简介 3.2.可变参数个数 3.3.递归包展开 3.4.逗号表达式展开 3.5…...
Centos7.9和Debian12部署Minio详细流程
一、安装minio Centos wget https://dl.min.io/server/minio/release/linux-amd64/archive/minio-20230227181045.0.0.x86_64.rpm -O minio.rpm sudo dnf install minio.rpmDebian wget https://dl.min.io/server/minio/release/linux-amd64/archive/minio_20230227181045.0…...
软件测试|教你如何使用UPDATE修改数据
简介 在SQL(Structured Query Language)中,UPDATE语句用于修改数据库表中的数据。通过UPDATE语句,我们可以更新表中的特定记录或多条记录,从而实现数据的修改和更新。本文将详细介绍SQL UPDATE语句的语法、用法以及一…...
新闻稿发布:媒体重要还是价格重要
在当今信息爆炸的数字时代,企业推广与品牌塑造不可或缺的一环就是新闻稿发布。新闻稿是一种通过媒体渠道传递企业信息、宣传品牌、事件或产品新闻的文本形式。发布新闻稿的过程旨在将企业的声音传递给更广泛的受众,借助媒体平台实现品牌故事的广泛传播。…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
