From 666c8798b676acdd5fb0c080084b89e6f17f4a05 Mon Sep 17 00:00:00 2001
From: Shawqeem <1004837646@qq.com>
Date: Fri, 9 Dec 2022 22:21:22 +0800
Subject: [PATCH 1/8] chore : add map
---
CAPI/API/include/structures.h | 2 +-
dependency/proto/Proto.csproj | 35 +++++++++
dependency/proto/Proto.sln | 25 +++++++
format.sh | 21 ++++++
logic/Client/Client.csproj | 10 +++
logic/Client/Client.sln | 8 +-
logic/Client/MainWindow.xaml | 4 +-
logic/Client/MainWindow.xaml.cs | 127 +++++++++++++++++++++++++++++++-
8 files changed, 226 insertions(+), 6 deletions(-)
create mode 100644 dependency/proto/Proto.csproj
create mode 100644 dependency/proto/Proto.sln
create mode 100644 format.sh
diff --git a/CAPI/API/include/structures.h b/CAPI/API/include/structures.h
index bdeab2e..8505e29 100644
--- a/CAPI/API/include/structures.h
+++ b/CAPI/API/include/structures.h
@@ -87,7 +87,7 @@ namespace THUAI6
ButcherBuffType4 = 4,
};
- //人类状态枚举
+ // 人类状态枚举
enum class HumanState : unsigned char
{
NullHumanState = 0,
diff --git a/dependency/proto/Proto.csproj b/dependency/proto/Proto.csproj
new file mode 100644
index 0000000..394d86e
--- /dev/null
+++ b/dependency/proto/Proto.csproj
@@ -0,0 +1,35 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
diff --git a/dependency/proto/Proto.sln b/dependency/proto/Proto.sln
new file mode 100644
index 0000000..2cdbe95
--- /dev/null
+++ b/dependency/proto/Proto.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.1.32328.378
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Proto", "Proto.csproj", "{B9A3CDD7-7852-4220-A2AA-2B986E0C19E8}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B9A3CDD7-7852-4220-A2AA-2B986E0C19E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B9A3CDD7-7852-4220-A2AA-2B986E0C19E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B9A3CDD7-7852-4220-A2AA-2B986E0C19E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B9A3CDD7-7852-4220-A2AA-2B986E0C19E8}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {CB1C0B2E-5D0E-4420-94B5-FE8AECC7E106}
+ EndGlobalSection
+EndGlobal
diff --git a/format.sh b/format.sh
new file mode 100644
index 0000000..dba6115
--- /dev/null
+++ b/format.sh
@@ -0,0 +1,21 @@
+for i in {1..10}
+do
+find . -iname "*.cs" \
+ -or -iname "*.c" \
+ -or -iname "*.h" \
+ -or -iname "*.C" \
+ -or -iname "*.H" \
+ -or -iname "*.cpp" \
+ -or -iname "*.hpp" \
+ -or -iname "*.cc" \
+ -or -iname "*.hh" \
+ -or -iname "*.c++" \
+ -or -iname "*.h++" \
+ -or -iname "*.cxx" \
+ -or -iname "*.hxx" \
+ -or -iname "*.i" \
+ -or -iname "*.ixx" \
+ -or -iname "*.ipp" \
+ -or -iname "*.i++" \
+ | xargs clang-format -i
+done
diff --git a/logic/Client/Client.csproj b/logic/Client/Client.csproj
index f6e1da0..0de9ead 100644
--- a/logic/Client/Client.csproj
+++ b/logic/Client/Client.csproj
@@ -11,6 +11,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/logic/Client/Client.sln b/logic/Client/Client.sln
index 8a42788..626d667 100644
--- a/logic/Client/Client.sln
+++ b/logic/Client/Client.sln
@@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.1.32328.378
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client", "Client.csproj", "{5AD8481D-90EF-410C-BD48-355DB97EEAB3}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Client", "Client.csproj", "{5AD8481D-90EF-410C-BD48-355DB97EEAB3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Proto", "..\..\dependency\proto\Proto.csproj", "{E445B0DD-D0DF-4413-AE47-1748392843F7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -15,6 +17,10 @@ Global
{5AD8481D-90EF-410C-BD48-355DB97EEAB3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5AD8481D-90EF-410C-BD48-355DB97EEAB3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5AD8481D-90EF-410C-BD48-355DB97EEAB3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E445B0DD-D0DF-4413-AE47-1748392843F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E445B0DD-D0DF-4413-AE47-1748392843F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E445B0DD-D0DF-4413-AE47-1748392843F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E445B0DD-D0DF-4413-AE47-1748392843F7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/logic/Client/MainWindow.xaml b/logic/Client/MainWindow.xaml
index 0f9b41b..e1b69e6 100644
--- a/logic/Client/MainWindow.xaml
+++ b/logic/Client/MainWindow.xaml
@@ -31,8 +31,8 @@
-
-
+
+
diff --git a/logic/Client/MainWindow.xaml.cs b/logic/Client/MainWindow.xaml.cs
index 32af92b..1b465fe 100644
--- a/logic/Client/MainWindow.xaml.cs
+++ b/logic/Client/MainWindow.xaml.cs
@@ -13,6 +13,8 @@ using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Diagnostics;
+using Grpc.Core;
+using Protobuf;
// 留意初始化
// 目前MainWindow还未复现的功能:
@@ -22,7 +24,7 @@ using System.Diagnostics;
// 绘图函数private void DrawLaser(Point source, double theta, double range,double Width)//三个参数分别为攻击者的位置,攻击方位角(窗口坐标)和攻击半径
// private void DrawProp(MessageToClient.Types.GameObjMessage data, string text),
// private void Attack(object sender,RoutedEventArgs e)
-// 地图相关private void ZoomMap(),private void DrawMap()
+// 地图相关private void ZoomMap()
// 交互:private void ClickToSetMode(object sender, RoutedEventArgs e)
// 最近要解决private void ConnectToServer(string[] comInfo)
@@ -42,8 +44,10 @@ namespace Client
{
public MainWindow()
{
+ unitHeight = unitWidth = unit = 13;
InitializeComponent();
SetStatusBar();
+ DrawMap();
isClientStocked = true;
isPlaybackMode = false;
WindowStartupLocation = WindowStartupLocation.CenterScreen;
@@ -61,9 +65,68 @@ namespace Client
}
// 连接Server
- private void ConnectToServer(string[] comInfo)
+ private void ConnectToServer()
{
+ Channel channel = new Channel("127.0.0.1:8888", ChannelCredentials.Insecure);
+ var client = new AvailableService.AvailableServiceClient(channel);
+ PlayerMsg playerMsg = new PlayerMsg();
+ var responseStream = client.AddPlayer(playerMsg);
+
+ // 新建一个线程,处理的时候要上锁
}
+
+ // drawmap,22/11/27ver:丑陋的实现方式,底层为canvas,本身似乎就不太支持缩放,现在主体界面最大化后十分之丑陋,还需在之后的版本进行修复
+ private void DrawMap()
+ {
+ for (int i = 0; i < defaultMap.GetLength(0); i++)
+ {
+ for (int j = 0; j < defaultMap.GetLength(1); j++)
+ {
+ mapPatches[i, j] = new() {
+ Width = unitWidth,
+ Height = unitHeight,
+ // HorizontalAlignment = HorizontalAlignment.Left,
+ // VerticalAlignment = VerticalAlignment.Top,
+ // Margin = new Thickness(Width * (j), Height * (i), 0, 0)
+ };
+ mapPatches[i, j].SetValue(Canvas.LeftProperty, (double)(Width / 65.5 * j));
+ mapPatches[i, j].SetValue(Canvas.TopProperty, (double)(Height / 56.5 * i)); // 用zoommap进行修改
+ switch (defaultMap[i, j])
+ {
+ case 1:
+ mapPatches[i, j].Fill = Brushes.Brown;
+ mapPatches[i, j].Stroke = Brushes.Brown;
+ break;
+ case 2:
+ case 3:
+ case 4:
+ mapPatches[i, j].Fill = Brushes.Green;
+ mapPatches[i, j].Stroke = Brushes.Green;
+ break;
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ mapPatches[i, j].Fill = Brushes.Yellow;
+ mapPatches[i, j].Stroke = Brushes.Yellow;
+ break;
+ case 13:
+ mapPatches[i, j].Fill = Brushes.LightPink;
+ mapPatches[i, j].Stroke = Brushes.LightPink;
+ break;
+ default:
+ break;
+ }
+ UnderLayerOfMap.Children.Add(mapPatches[i, j]);
+ }
+ }
+ hasDrawed = true;
+ }
+
// 之后需要修改,现在只具有修改按钮形状的功能,并不能实现暂停/继续
private void ClickToPauseOrContinue(object sender, RoutedEventArgs e)
{
@@ -179,5 +242,65 @@ namespace Client
private long playerID;
private long teamID;
+
+ private double unit;
+ private double unitHeight;
+ private double unitWidth;
+ private readonly Rectangle[,] mapPatches = new Rectangle[50, 50];
+
+ private bool mapFlag = false;
+ private bool hasDrawed = false;
+ public int[,] defaultMap = new int[,] {
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 13, 13, 13, 13, 13, 1, 1, 1, 1, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 4, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 4, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 4, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 4, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 4, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 4, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 13, 0, 0, 1 },
+ { 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 13, 0, 0, 1 },
+ { 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 13, 0, 0, 1 },
+ { 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 13, 0, 0, 1 },
+ { 1, 0, 1, 1, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 13, 0, 0, 1 },
+ { 1, 0, 1, 1, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 13, 0, 0, 1 },
+ { 1, 0, 1, 1, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 13, 0, 0, 1 },
+ { 1, 0, 1, 1, 13, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 13, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 13, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 13, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 13, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 13, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 13, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 13, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
+ };
}
}
From 7b04b7af7a4092749bee595e26cfe78fb3612659 Mon Sep 17 00:00:00 2001
From: DragonAura
Date: Thu, 12 Jan 2023 00:17:10 +0800
Subject: [PATCH 2/8] feat(CAPI): :loud_sound: use spdlog as logger and finish
logic logger
---
CAPI/API/include/logic.h | 10 +-
CAPI/API/src/logic.cpp | 78 +-
CAPI/API/src/main.cpp | 21 +-
CAPI/CMakeLists.txt | 2 +-
CAPI/spdlog/include/spdlog/async.h | 103 +
CAPI/spdlog/include/spdlog/async_logger-inl.h | 96 +
CAPI/spdlog/include/spdlog/async_logger.h | 68 +
CAPI/spdlog/include/spdlog/cfg/argv.h | 46 +
CAPI/spdlog/include/spdlog/cfg/env.h | 40 +
CAPI/spdlog/include/spdlog/cfg/helpers-inl.h | 125 +
CAPI/spdlog/include/spdlog/cfg/helpers.h | 32 +
CAPI/spdlog/include/spdlog/common-inl.h | 85 +
CAPI/spdlog/include/spdlog/common.h | 420 ++
.../include/spdlog/details/backtracer-inl.h | 77 +
.../include/spdlog/details/backtracer.h | 48 +
.../include/spdlog/details/circular_q.h | 150 +
.../include/spdlog/details/console_globals.h | 34 +
.../include/spdlog/details/file_helper-inl.h | 175 +
.../include/spdlog/details/file_helper.h | 63 +
.../include/spdlog/details/fmt_helper.h | 167 +
.../include/spdlog/details/log_msg-inl.h | 44 +
CAPI/spdlog/include/spdlog/details/log_msg.h | 39 +
.../spdlog/details/log_msg_buffer-inl.h | 60 +
.../include/spdlog/details/log_msg_buffer.h | 35 +
.../include/spdlog/details/mpmc_blocking_q.h | 163 +
.../include/spdlog/details/null_mutex.h | 52 +
CAPI/spdlog/include/spdlog/details/os-inl.h | 605 ++
CAPI/spdlog/include/spdlog/details/os.h | 121 +
.../spdlog/details/periodic_worker-inl.h | 30 +
.../include/spdlog/details/periodic_worker.h | 62 +
.../include/spdlog/details/registry-inl.h | 307 +
CAPI/spdlog/include/spdlog/details/registry.h | 124 +
.../spdlog/details/synchronous_factory.h | 25 +
.../spdlog/details/tcp_client-windows.h | 162 +
.../include/spdlog/details/tcp_client.h | 149 +
.../include/spdlog/details/thread_pool-inl.h | 149 +
.../include/spdlog/details/thread_pool.h | 128 +
.../spdlog/details/udp_client-windows.h | 112 +
.../include/spdlog/details/udp_client.h | 96 +
.../include/spdlog/details/windows_include.h | 11 +
CAPI/spdlog/include/spdlog/fmt/bin_to_hex.h | 251 +
CAPI/spdlog/include/spdlog/fmt/bundled/args.h | 273 +
.../include/spdlog/fmt/bundled/chrono.h | 2732 +++++++++
.../spdlog/include/spdlog/fmt/bundled/color.h | 763 +++
.../include/spdlog/fmt/bundled/compile.h | 763 +++
CAPI/spdlog/include/spdlog/fmt/bundled/core.h | 4170 ++++++++++++++
.../spdlog/fmt/bundled/fmt.license.rst | 27 +
.../include/spdlog/fmt/bundled/format-inl.h | 2974 ++++++++++
.../include/spdlog/fmt/bundled/format.h | 4972 +++++++++++++++++
.../include/spdlog/fmt/bundled/locale.h | 2 +
CAPI/spdlog/include/spdlog/fmt/bundled/os.h | 561 ++
.../include/spdlog/fmt/bundled/ostream.h | 263 +
.../include/spdlog/fmt/bundled/printf.h | 808 +++
.../include/spdlog/fmt/bundled/ranges.h | 850 +++
CAPI/spdlog/include/spdlog/fmt/bundled/std.h | 202 +
.../spdlog/include/spdlog/fmt/bundled/xchar.h | 243 +
CAPI/spdlog/include/spdlog/fmt/chrono.h | 22 +
CAPI/spdlog/include/spdlog/fmt/compile.h | 22 +
CAPI/spdlog/include/spdlog/fmt/fmt.h | 33 +
CAPI/spdlog/include/spdlog/fmt/ostr.h | 22 +
CAPI/spdlog/include/spdlog/fmt/ranges.h | 22 +
CAPI/spdlog/include/spdlog/fmt/std.h | 23 +
CAPI/spdlog/include/spdlog/fmt/xchar.h | 22 +
CAPI/spdlog/include/spdlog/formatter.h | 19 +
CAPI/spdlog/include/spdlog/fwd.h | 21 +
CAPI/spdlog/include/spdlog/logger-inl.h | 256 +
CAPI/spdlog/include/spdlog/logger.h | 434 ++
.../include/spdlog/pattern_formatter-inl.h | 1480 +++++
.../spdlog/include/spdlog/pattern_formatter.h | 131 +
.../include/spdlog/sinks/android_sink.h | 147 +
.../include/spdlog/sinks/ansicolor_sink-inl.h | 149 +
.../include/spdlog/sinks/ansicolor_sink.h | 120 +
.../include/spdlog/sinks/base_sink-inl.h | 65 +
CAPI/spdlog/include/spdlog/sinks/base_sink.h | 54 +
.../spdlog/sinks/basic_file_sink-inl.h | 46 +
.../include/spdlog/sinks/basic_file_sink.h | 64 +
.../include/spdlog/sinks/daily_file_sink.h | 295 +
CAPI/spdlog/include/spdlog/sinks/dist_sink.h | 100 +
.../include/spdlog/sinks/dup_filter_sink.h | 99 +
.../include/spdlog/sinks/hourly_file_sink.h | 204 +
CAPI/spdlog/include/spdlog/sinks/mongo_sink.h | 109 +
CAPI/spdlog/include/spdlog/sinks/msvc_sink.h | 62 +
CAPI/spdlog/include/spdlog/sinks/null_sink.h | 50 +
.../include/spdlog/sinks/ostream_sink.h | 53 +
CAPI/spdlog/include/spdlog/sinks/qt_sinks.h | 107 +
.../include/spdlog/sinks/ringbuffer_sink.h | 79 +
.../spdlog/sinks/rotating_file_sink-inl.h | 155 +
.../include/spdlog/sinks/rotating_file_sink.h | 82 +
CAPI/spdlog/include/spdlog/sinks/sink-inl.h | 25 +
CAPI/spdlog/include/spdlog/sinks/sink.h | 37 +
.../spdlog/sinks/stdout_color_sinks-inl.h | 39 +
.../include/spdlog/sinks/stdout_color_sinks.h | 47 +
.../include/spdlog/sinks/stdout_sinks-inl.h | 143 +
.../include/spdlog/sinks/stdout_sinks.h | 89 +
.../spdlog/include/spdlog/sinks/syslog_sink.h | 110 +
.../include/spdlog/sinks/systemd_sink.h | 125 +
CAPI/spdlog/include/spdlog/sinks/tcp_sink.h | 86 +
CAPI/spdlog/include/spdlog/sinks/udp_sink.h | 80 +
.../include/spdlog/sinks/win_eventlog_sink.h | 297 +
.../include/spdlog/sinks/wincolor_sink-inl.h | 178 +
.../include/spdlog/sinks/wincolor_sink.h | 87 +
CAPI/spdlog/include/spdlog/spdlog-inl.h | 121 +
CAPI/spdlog/include/spdlog/spdlog.h | 355 ++
CAPI/spdlog/include/spdlog/stopwatch.h | 70 +
CAPI/spdlog/include/spdlog/tweakme.h | 140 +
CAPI/spdlog/include/spdlog/version.h | 10 +
106 files changed, 30726 insertions(+), 28 deletions(-)
create mode 100644 CAPI/spdlog/include/spdlog/async.h
create mode 100644 CAPI/spdlog/include/spdlog/async_logger-inl.h
create mode 100644 CAPI/spdlog/include/spdlog/async_logger.h
create mode 100644 CAPI/spdlog/include/spdlog/cfg/argv.h
create mode 100644 CAPI/spdlog/include/spdlog/cfg/env.h
create mode 100644 CAPI/spdlog/include/spdlog/cfg/helpers-inl.h
create mode 100644 CAPI/spdlog/include/spdlog/cfg/helpers.h
create mode 100644 CAPI/spdlog/include/spdlog/common-inl.h
create mode 100644 CAPI/spdlog/include/spdlog/common.h
create mode 100644 CAPI/spdlog/include/spdlog/details/backtracer-inl.h
create mode 100644 CAPI/spdlog/include/spdlog/details/backtracer.h
create mode 100644 CAPI/spdlog/include/spdlog/details/circular_q.h
create mode 100644 CAPI/spdlog/include/spdlog/details/console_globals.h
create mode 100644 CAPI/spdlog/include/spdlog/details/file_helper-inl.h
create mode 100644 CAPI/spdlog/include/spdlog/details/file_helper.h
create mode 100644 CAPI/spdlog/include/spdlog/details/fmt_helper.h
create mode 100644 CAPI/spdlog/include/spdlog/details/log_msg-inl.h
create mode 100644 CAPI/spdlog/include/spdlog/details/log_msg.h
create mode 100644 CAPI/spdlog/include/spdlog/details/log_msg_buffer-inl.h
create mode 100644 CAPI/spdlog/include/spdlog/details/log_msg_buffer.h
create mode 100644 CAPI/spdlog/include/spdlog/details/mpmc_blocking_q.h
create mode 100644 CAPI/spdlog/include/spdlog/details/null_mutex.h
create mode 100644 CAPI/spdlog/include/spdlog/details/os-inl.h
create mode 100644 CAPI/spdlog/include/spdlog/details/os.h
create mode 100644 CAPI/spdlog/include/spdlog/details/periodic_worker-inl.h
create mode 100644 CAPI/spdlog/include/spdlog/details/periodic_worker.h
create mode 100644 CAPI/spdlog/include/spdlog/details/registry-inl.h
create mode 100644 CAPI/spdlog/include/spdlog/details/registry.h
create mode 100644 CAPI/spdlog/include/spdlog/details/synchronous_factory.h
create mode 100644 CAPI/spdlog/include/spdlog/details/tcp_client-windows.h
create mode 100644 CAPI/spdlog/include/spdlog/details/tcp_client.h
create mode 100644 CAPI/spdlog/include/spdlog/details/thread_pool-inl.h
create mode 100644 CAPI/spdlog/include/spdlog/details/thread_pool.h
create mode 100644 CAPI/spdlog/include/spdlog/details/udp_client-windows.h
create mode 100644 CAPI/spdlog/include/spdlog/details/udp_client.h
create mode 100644 CAPI/spdlog/include/spdlog/details/windows_include.h
create mode 100644 CAPI/spdlog/include/spdlog/fmt/bin_to_hex.h
create mode 100644 CAPI/spdlog/include/spdlog/fmt/bundled/args.h
create mode 100644 CAPI/spdlog/include/spdlog/fmt/bundled/chrono.h
create mode 100644 CAPI/spdlog/include/spdlog/fmt/bundled/color.h
create mode 100644 CAPI/spdlog/include/spdlog/fmt/bundled/compile.h
create mode 100644 CAPI/spdlog/include/spdlog/fmt/bundled/core.h
create mode 100644 CAPI/spdlog/include/spdlog/fmt/bundled/fmt.license.rst
create mode 100644 CAPI/spdlog/include/spdlog/fmt/bundled/format-inl.h
create mode 100644 CAPI/spdlog/include/spdlog/fmt/bundled/format.h
create mode 100644 CAPI/spdlog/include/spdlog/fmt/bundled/locale.h
create mode 100644 CAPI/spdlog/include/spdlog/fmt/bundled/os.h
create mode 100644 CAPI/spdlog/include/spdlog/fmt/bundled/ostream.h
create mode 100644 CAPI/spdlog/include/spdlog/fmt/bundled/printf.h
create mode 100644 CAPI/spdlog/include/spdlog/fmt/bundled/ranges.h
create mode 100644 CAPI/spdlog/include/spdlog/fmt/bundled/std.h
create mode 100644 CAPI/spdlog/include/spdlog/fmt/bundled/xchar.h
create mode 100644 CAPI/spdlog/include/spdlog/fmt/chrono.h
create mode 100644 CAPI/spdlog/include/spdlog/fmt/compile.h
create mode 100644 CAPI/spdlog/include/spdlog/fmt/fmt.h
create mode 100644 CAPI/spdlog/include/spdlog/fmt/ostr.h
create mode 100644 CAPI/spdlog/include/spdlog/fmt/ranges.h
create mode 100644 CAPI/spdlog/include/spdlog/fmt/std.h
create mode 100644 CAPI/spdlog/include/spdlog/fmt/xchar.h
create mode 100644 CAPI/spdlog/include/spdlog/formatter.h
create mode 100644 CAPI/spdlog/include/spdlog/fwd.h
create mode 100644 CAPI/spdlog/include/spdlog/logger-inl.h
create mode 100644 CAPI/spdlog/include/spdlog/logger.h
create mode 100644 CAPI/spdlog/include/spdlog/pattern_formatter-inl.h
create mode 100644 CAPI/spdlog/include/spdlog/pattern_formatter.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/android_sink.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/ansicolor_sink-inl.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/ansicolor_sink.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/base_sink-inl.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/base_sink.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/basic_file_sink-inl.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/basic_file_sink.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/daily_file_sink.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/dist_sink.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/dup_filter_sink.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/hourly_file_sink.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/mongo_sink.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/msvc_sink.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/null_sink.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/ostream_sink.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/qt_sinks.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/ringbuffer_sink.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/rotating_file_sink-inl.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/rotating_file_sink.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/sink-inl.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/sink.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/stdout_color_sinks-inl.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/stdout_color_sinks.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/stdout_sinks-inl.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/stdout_sinks.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/syslog_sink.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/systemd_sink.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/tcp_sink.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/udp_sink.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/win_eventlog_sink.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/wincolor_sink-inl.h
create mode 100644 CAPI/spdlog/include/spdlog/sinks/wincolor_sink.h
create mode 100644 CAPI/spdlog/include/spdlog/spdlog-inl.h
create mode 100644 CAPI/spdlog/include/spdlog/spdlog.h
create mode 100644 CAPI/spdlog/include/spdlog/stopwatch.h
create mode 100644 CAPI/spdlog/include/spdlog/tweakme.h
create mode 100644 CAPI/spdlog/include/spdlog/version.h
diff --git a/CAPI/API/include/logic.h b/CAPI/API/include/logic.h
index 610e8d0..ce6910c 100644
--- a/CAPI/API/include/logic.h
+++ b/CAPI/API/include/logic.h
@@ -15,6 +15,10 @@
#include
#include
+#include
+#include
+#include
+
#include "Message2Server.pb.h"
#include "Message2Clients.pb.h"
#include "MessageType.pb.h"
@@ -30,8 +34,12 @@
class Logic : public ILogic
{
private:
+ // 日志组件
+ std::shared_ptr logger;
+
// 通信组件
std::unique_ptr pComm;
+
// ID、阵营记录
int64_t playerID;
THUAI6::PlayerType playerType;
@@ -148,7 +156,7 @@ public:
}
// Main函数同上
- void Main(CreateAIFunc createAI, std::string IP, std::string port, bool level, std::string filename);
+ void Main(CreateAIFunc createAI, std::string IP, std::string port, bool debug, bool level);
};
#endif
diff --git a/CAPI/API/src/logic.cpp b/CAPI/API/src/logic.cpp
index e1b44ea..b12be1b 100644
--- a/CAPI/API/src/logic.cpp
+++ b/CAPI/API/src/logic.cpp
@@ -1,12 +1,14 @@
#include "logic.h"
#include "structures.h"
#include
+#include
+#include
+#include
#include
#include "utils.hpp"
#include "Communication.h"
extern const bool asynchronous;
-extern const THUAI6::PlayerType playerType;
Logic::Logic(THUAI6::PlayerType type, int64_t ID, THUAI6::ButcherType butcher, THUAI6::HumanType human) :
playerType(type),
@@ -23,6 +25,7 @@ std::vector> Logic::GetButchers() const
std::lock_guard lock(mtxBuffer);
std::vector> temp;
temp.assign(currentState->butchers.begin(), currentState->butchers.end());
+ logger->debug("Called GetButchers");
return temp;
}
@@ -31,6 +34,7 @@ std::vector> Logic::GetHumans() const
std::unique_lock lock(mtxBuffer);
std::vector> temp;
temp.assign(currentState->humans.begin(), currentState->humans.end());
+ logger->debug("Called GetHumans");
return temp;
}
@@ -39,110 +43,131 @@ std::vector> Logic::GetProps() const
std::unique_lock lock(mtxBuffer);
std::vector> temp;
temp.assign(currentState->props.begin(), currentState->props.end());
+ logger->debug("Called GetProps");
return temp;
}
std::shared_ptr Logic::HumanGetSelfInfo() const
{
std::unique_lock lock(mtxBuffer);
+ logger->debug("Called HumanGetSelfInfo");
return currentState->humanSelf;
}
std::shared_ptr Logic::ButcherGetSelfInfo() const
{
std::unique_lock lock(mtxBuffer);
+ logger->debug("Called ButcherGetSelfInfo");
return currentState->butcherSelf;
}
std::vector> Logic::GetFullMap() const
{
std::unique_lock lock(mtxBuffer);
+ logger->debug("Called GetFullMap");
return currentState->gamemap;
}
THUAI6::PlaceType Logic::GetPlaceType(int32_t CellX, int32_t CellY) const
{
std::unique_lock lock(mtxBuffer);
+ logger->debug("Called GetPlaceType");
return currentState->gamemap[CellX][CellY];
}
bool Logic::Move(int64_t time, double angle)
{
+ logger->debug("Called Move");
return pComm->Move(time, angle, playerID);
}
bool Logic::PickProp(THUAI6::PropType prop)
{
+ logger->debug("Called PickProp");
return pComm->PickProp(prop, playerID);
}
bool Logic::UseProp()
{
+ logger->debug("Called UseProp");
return pComm->UseProp(playerID);
}
bool Logic::UseSkill()
{
+ logger->debug("Called UseSkill");
return pComm->UseSkill(playerID);
}
bool Logic::SendMessage(int64_t toID, std::string message)
{
+ logger->debug("Called SendMessage");
return pComm->SendMessage(toID, message, playerID);
}
bool Logic::HaveMessage()
{
+ logger->debug("Called HaveMessage");
return pComm->HaveMessage();
}
std::optional> Logic::GetMessage()
{
+ logger->debug("Called GetMessage");
return pComm->GetMessage();
}
bool Logic::Escape()
{
+ logger->debug("Called Escape");
return pComm->Escape(playerID);
}
bool Logic::StartFixMachine()
{
+ logger->debug("Called StartFixMachine");
return pComm->StartFixMachine(playerID);
}
bool Logic::EndFixMachine()
{
+ logger->debug("Called EndFixMachine");
return pComm->EndFixMachine(playerID);
}
bool Logic::StartSaveHuman()
{
+ logger->debug("Called StartSaveHuman");
return pComm->StartSaveHuman(playerID);
}
bool Logic::EndSaveHuman()
{
+ logger->debug("Called EndSaveHuman");
return pComm->EndSaveHuman(playerID);
}
bool Logic::Attack(double angle)
{
+ logger->debug("Called Attack");
return pComm->Attack(angle, playerID);
}
bool Logic::CarryHuman()
{
+ logger->debug("Called CarryHuman");
return pComm->CarryHuman(playerID);
}
bool Logic::ReleaseHuman()
{
+ logger->debug("Called ReleaseHuman");
return pComm->ReleaseHuman(playerID);
}
bool Logic::HangHuman()
{
+ logger->debug("Called HangHuman");
return pComm->HangHuman(playerID);
}
@@ -156,19 +181,20 @@ void Logic::ProcessMessage()
{
auto messageThread = [&]()
{
- std::cout << "Join Player!" << std::endl;
+ logger->info("Message thread start!");
pComm->AddPlayer(playerID, playerType, humanType, butcherType);
+ logger->info("Join the player!");
while (gameState != THUAI6::GameState::GameEnd)
{
if (pComm->HaveMessage2Client())
{
- std::cout << "Get Message!" << std::endl;
+ logger->debug("Get message from server!");
auto clientMsg = pComm->GetMessage2Client();
gameState = Proto2THUAI6::gameStateDict[clientMsg.game_state()];
switch (gameState)
{
case THUAI6::GameState::GameStart:
- std::cout << "Game Start!" << std::endl;
+ logger->info("Game Start!");
// 重新读取玩家的guid,guid确保人类在前屠夫在后
playerGUIDs.clear();
@@ -205,10 +231,10 @@ void Logic::ProcessMessage()
counterBuffer = -1;
}
cvBuffer.notify_one();
- std::cout << "Game End!" << std::endl;
+ logger->info("Game End!");
break;
default:
- std::cerr << "Invalid GameState!" << std::endl;
+ logger->debug("Unknown GameState!");
}
}
}
@@ -227,7 +253,7 @@ void Logic::LoadBuffer(protobuf::MessageToClient& message)
bufferState->butchers.clear();
bufferState->props.clear();
- std::cout << "Buffer clear!" << std::endl;
+ logger->debug("Buffer cleared!");
// 读取新的信息
// 读取消息的选择待补充,之后需要另外判断;具体做法应该是先读到自己,然后按照自己的视野做处理。此处暂时全部读了进来
bufferState->gamemap = Proto2THUAI6::Protobuf2THUAI6Map(message.map_message());
@@ -271,7 +297,7 @@ void Logic::LoadBuffer(protobuf::MessageToClient& message)
if (barrier)
continue;
bufferState->butchers.push_back(Proto2THUAI6::Protobuf2THUAI6Butcher(item));
- std::cout << "Add Butcher!" << std::endl;
+ logger->debug("Add Butcher!");
}
}
}
@@ -315,17 +341,21 @@ void Logic::LoadBuffer(protobuf::MessageToClient& message)
if (barrier)
continue;
bufferState->humans.push_back(Proto2THUAI6::Protobuf2THUAI6Human(item));
- std::cout << "Add Human!" << std::endl;
+ logger->debug("Add Human!");
}
}
}
for (const auto& item : message.prop_message())
+ {
bufferState->props.push_back(Proto2THUAI6::Protobuf2THUAI6Prop(item));
+ logger->debug("Add Prop!");
+ }
if (asynchronous)
{
{
std::lock_guard lock(mtxState);
std::swap(currentState, bufferState);
+ logger->info("Update State!");
}
freshed = true;
}
@@ -350,6 +380,7 @@ void Logic::Update() noexcept
std::swap(currentState, bufferState);
bufferUpdated = false;
counterState = counterBuffer;
+ logger->info("Update State!");
}
}
@@ -395,13 +426,31 @@ const std::vector Logic::GetPlayerGUIDs() const
bool Logic::TryConnection()
{
- std::cout << "Trying to connect to server..." << std::endl;
+ logger->info("Try to connect to server...");
bool result = pComm->TryConnection(playerID);
return result;
}
-void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port, bool level, std::string filename)
+void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port, bool debug, bool level)
{
+ // 建立日志组件
+ if (debug)
+ {
+ auto file_logger = std::make_shared("logs/logic-log.txt", true);
+ auto stdout_logger = std::make_shared();
+ if (level)
+ stdout_logger->set_level(spdlog::level::warn);
+ else
+ stdout_logger->set_level(spdlog::level::info);
+ file_logger->set_level(spdlog::level::trace);
+ logger = std::make_shared("logicLogger", spdlog::sinks_init_list{file_logger, stdout_logger});
+ }
+ else
+ {
+ auto logger = std::make_shared("logs/logic-log.txt", true);
+ logger->set_level(spdlog::level::trace);
+ }
+
// 建立与服务器之间通信的组件
pComm = std::make_unique(IP, port);
@@ -445,10 +494,11 @@ void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port, bool l
// 连接服务器
if (TryConnection())
{
- std::cout << "Connect to the server successfully, AI thread will be start." << std::endl;
+ logger->info("Connect to the server successfully, AI thread will be start.");
if (tAI.joinable())
{
- std::cout << "Join the AI thread." << std::endl;
+ logger->info("Join the AI thread!");
+
// 首先开启处理消息的线程
ProcessMessage();
tAI.join();
@@ -456,7 +506,7 @@ void Logic::Main(CreateAIFunc createAI, std::string IP, std::string port, bool l
}
else
{
- std::cout << "Connection error!" << std::endl;
+ logger->error("Connect to the server failed, AI thread will not be start.");
return;
}
}
diff --git a/CAPI/API/src/main.cpp b/CAPI/API/src/main.cpp
index bdc01b7..d995537 100644
--- a/CAPI/API/src/main.cpp
+++ b/CAPI/API/src/main.cpp
@@ -12,7 +12,7 @@ int THUAI6Main(int argc, char** argv, CreateAIFunc AIBuilder)
int pID = 114514;
std::string sIP = "114.51.41.91";
std::string sPort = "9810";
- std::string filename = "";
+ bool print = false;
bool level = false;
extern const THUAI6::PlayerType playerType;
extern const THUAI6::ButcherType butcherType;
@@ -20,11 +20,11 @@ int THUAI6Main(int argc, char** argv, CreateAIFunc AIBuilder)
// 仅供早期调试使用
{
Logic logic(playerType, pID, butcherType, humanType);
- logic.Main(AIBuilder, sIP, sPort, level, filename);
+ logic.Main(AIBuilder, sIP, sPort, print, level);
return 0;
}
- // 使用cmdline的版本
+ // 使用cmdline的正式版本
try
{
TCLAP::CmdLine cmd("THUAI6 C++ interface commandline parameter introduction");
@@ -40,16 +40,13 @@ int THUAI6Main(int argc, char** argv, CreateAIFunc AIBuilder)
TCLAP::ValueArg playerID("p", "playerID", "Player ID 0,1,2,3 valid only", true, -1, &playerIdConstraint);
cmd.add(playerID);
- std::string DebugDesc = "Set this flag to use API for debugging.\n"
- "If \"-f\" is not set, the log will be printed on the screen.\n"
- "Or you could specify a file to store it.";
+ std::string DebugDesc = "Set this flag to print the debug log on the screen.\n"
+ "The log will always be saved to ./logs folder.\n";
TCLAP::SwitchArg debug("d", "debug", DebugDesc);
cmd.add(debug);
- TCLAP::ValueArg FileName("f", "filename", "Specify a file to store the log.", false, "", "string");
- cmd.add(FileName);
-
- TCLAP::SwitchArg warning("w", "warning", "Warn of some obviously invalid operations (only when \"-d\" is set).");
+ TCLAP::SwitchArg warning("w", "warning", "Set this flag to only print warning on the screen.\n"
+ "This flag will be ignored if the debug flag is not set\n");
cmd.add(warning);
cmd.parse(argc, argv);
@@ -61,9 +58,9 @@ int THUAI6Main(int argc, char** argv, CreateAIFunc AIBuilder)
bool w = warning.getValue();
if (d)
{
+ print = true;
level = w;
}
- filename = FileName.getValue();
}
catch (TCLAP::ArgException& e)
{
@@ -71,7 +68,7 @@ int THUAI6Main(int argc, char** argv, CreateAIFunc AIBuilder)
return 1;
}
Logic logic(playerType, pID, butcherType, humanType);
- logic.Main(AIBuilder, sIP, sPort, level, filename);
+ logic.Main(AIBuilder, sIP, sPort, print, level);
return 0;
}
diff --git a/CAPI/CMakeLists.txt b/CAPI/CMakeLists.txt
index b557d52..ed69b96 100644
--- a/CAPI/CMakeLists.txt
+++ b/CAPI/CMakeLists.txt
@@ -18,7 +18,7 @@ message(STATUS "Using gRPC ${gRPC_VERSION}")
add_executable(capi ${CPP_LIST} ${PROTO_CPP_LIST})
-target_include_directories(capi PUBLIC ${PROJECT_SOURCE_DIR}/proto ${PROJECT_SOURCE_DIR}/API/include ${PROJECT_SOURCE_DIR}/tclap/include)
+target_include_directories(capi PUBLIC ${PROJECT_SOURCE_DIR}/proto ${PROJECT_SOURCE_DIR}/API/include ${PROJECT_SOURCE_DIR}/tclap/include ${PROJECT_SOURCE_DIR}/spdlog/include)
target_link_libraries(capi
protobuf::libprotobuf
diff --git a/CAPI/spdlog/include/spdlog/async.h b/CAPI/spdlog/include/spdlog/async.h
new file mode 100644
index 0000000..b5bd21f
--- /dev/null
+++ b/CAPI/spdlog/include/spdlog/async.h
@@ -0,0 +1,103 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+//
+// Async logging using global thread pool
+// All loggers created here share same global thread pool.
+// Each log message is pushed to a queue along with a shared pointer to the
+// logger.
+// If a logger deleted while having pending messages in the queue, it's actual
+// destruction will defer
+// until all its messages are processed by the thread pool.
+// This is because each message in the queue holds a shared_ptr to the
+// originating logger.
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+namespace spdlog
+{
+
+ namespace details
+ {
+ static const size_t default_async_q_size = 8192;
+ }
+
+ // async logger factory - creates async loggers backed with thread pool.
+ // if a global thread pool doesn't already exist, create it with default queue
+ // size of 8192 items and single thread.
+ template
+ struct async_factory_impl
+ {
+ template
+ static std::shared_ptr create(std::string logger_name, SinkArgs&&... args)
+ {
+ auto& registry_inst = details::registry::instance();
+
+ // create global thread pool if not already exists..
+
+ auto& mutex = registry_inst.tp_mutex();
+ std::lock_guard tp_lock(mutex);
+ auto tp = registry_inst.get_tp();
+ if (tp == nullptr)
+ {
+ tp = std::make_shared(details::default_async_q_size, 1U);
+ registry_inst.set_tp(tp);
+ }
+
+ auto sink = std::make_shared(std::forward(args)...);
+ auto new_logger = std::make_shared(std::move(logger_name), std::move(sink), std::move(tp), OverflowPolicy);
+ registry_inst.initialize_logger(new_logger);
+ return new_logger;
+ }
+ };
+
+ using async_factory = async_factory_impl;
+ using async_factory_nonblock = async_factory_impl;
+
+ template
+ inline std::shared_ptr create_async(std::string logger_name, SinkArgs&&... sink_args)
+ {
+ return async_factory::create(std::move(logger_name), std::forward(sink_args)...);
+ }
+
+ template
+ inline std::shared_ptr create_async_nb(std::string logger_name, SinkArgs&&... sink_args)
+ {
+ return async_factory_nonblock::create(std::move(logger_name), std::forward(sink_args)...);
+ }
+
+ // set global thread pool.
+ inline void init_thread_pool(
+ size_t q_size, size_t thread_count, std::function on_thread_start, std::function on_thread_stop
+ )
+ {
+ auto tp = std::make_shared(q_size, thread_count, on_thread_start, on_thread_stop);
+ details::registry::instance().set_tp(std::move(tp));
+ }
+
+ inline void init_thread_pool(size_t q_size, size_t thread_count, std::function on_thread_start)
+ {
+ init_thread_pool(q_size, thread_count, on_thread_start, [] {});
+ }
+
+ inline void init_thread_pool(size_t q_size, size_t thread_count)
+ {
+ init_thread_pool(
+ q_size, thread_count, [] {}, [] {}
+ );
+ }
+
+ // get the global thread pool.
+ inline std::shared_ptr thread_pool()
+ {
+ return details::registry::instance().get_tp();
+ }
+} // namespace spdlog
diff --git a/CAPI/spdlog/include/spdlog/async_logger-inl.h b/CAPI/spdlog/include/spdlog/async_logger-inl.h
new file mode 100644
index 0000000..af9a185
--- /dev/null
+++ b/CAPI/spdlog/include/spdlog/async_logger-inl.h
@@ -0,0 +1,96 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#ifndef SPDLOG_HEADER_ONLY
+#include
+#endif
+
+#include
+#include
+
+#include
+#include
+
+SPDLOG_INLINE spdlog::async_logger::async_logger(
+ std::string logger_name, sinks_init_list sinks_list, std::weak_ptr tp, async_overflow_policy overflow_policy
+) :
+ async_logger(std::move(logger_name), sinks_list.begin(), sinks_list.end(), std::move(tp), overflow_policy)
+{
+}
+
+SPDLOG_INLINE spdlog::async_logger::async_logger(
+ std::string logger_name, sink_ptr single_sink, std::weak_ptr tp, async_overflow_policy overflow_policy
+) :
+ async_logger(std::move(logger_name), {std::move(single_sink)}, std::move(tp), overflow_policy)
+{
+}
+
+// send the log message to the thread pool
+SPDLOG_INLINE void spdlog::async_logger::sink_it_(const details::log_msg& msg)
+{
+ if (auto pool_ptr = thread_pool_.lock())
+ {
+ pool_ptr->post_log(shared_from_this(), msg, overflow_policy_);
+ }
+ else
+ {
+ throw_spdlog_ex("async log: thread pool doesn't exist anymore");
+ }
+}
+
+// send flush request to the thread pool
+SPDLOG_INLINE void spdlog::async_logger::flush_()
+{
+ if (auto pool_ptr = thread_pool_.lock())
+ {
+ pool_ptr->post_flush(shared_from_this(), overflow_policy_);
+ }
+ else
+ {
+ throw_spdlog_ex("async flush: thread pool doesn't exist anymore");
+ }
+}
+
+//
+// backend functions - called from the thread pool to do the actual job
+//
+SPDLOG_INLINE void spdlog::async_logger::backend_sink_it_(const details::log_msg& msg)
+{
+ for (auto& sink : sinks_)
+ {
+ if (sink->should_log(msg.level))
+ {
+ SPDLOG_TRY
+ {
+ sink->log(msg);
+ }
+ SPDLOG_LOGGER_CATCH(msg.source)
+ }
+ }
+
+ if (should_flush_(msg))
+ {
+ backend_flush_();
+ }
+}
+
+SPDLOG_INLINE void spdlog::async_logger::backend_flush_()
+{
+ for (auto& sink : sinks_)
+ {
+ SPDLOG_TRY
+ {
+ sink->flush();
+ }
+ SPDLOG_LOGGER_CATCH(source_loc())
+ }
+}
+
+SPDLOG_INLINE std::shared_ptr spdlog::async_logger::clone(std::string new_name)
+{
+ auto cloned = std::make_shared(*this);
+ cloned->name_ = std::move(new_name);
+ return cloned;
+}
diff --git a/CAPI/spdlog/include/spdlog/async_logger.h b/CAPI/spdlog/include/spdlog/async_logger.h
new file mode 100644
index 0000000..c453299
--- /dev/null
+++ b/CAPI/spdlog/include/spdlog/async_logger.h
@@ -0,0 +1,68 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+// Fast asynchronous logger.
+// Uses pre allocated queue.
+// Creates a single back thread to pop messages from the queue and log them.
+//
+// Upon each log write the logger:
+// 1. Checks if its log level is enough to log the message
+// 2. Push a new copy of the message to a queue (or block the caller until
+// space is available in the queue)
+// Upon destruction, logs all remaining messages in the queue before
+// destructing..
+
+#include
+
+namespace spdlog
+{
+
+ // Async overflow policy - block by default.
+ enum class async_overflow_policy
+ {
+ block, // Block until message can be enqueued
+ overrun_oldest // Discard oldest message in the queue if full when trying to
+ // add new item.
+ };
+
+ namespace details
+ {
+ class thread_pool;
+ }
+
+ class SPDLOG_API async_logger final : public std::enable_shared_from_this, public logger
+ {
+ friend class details::thread_pool;
+
+ public:
+ template
+ async_logger(std::string logger_name, It begin, It end, std::weak_ptr tp, async_overflow_policy overflow_policy = async_overflow_policy::block) :
+ logger(std::move(logger_name), begin, end),
+ thread_pool_(std::move(tp)),
+ overflow_policy_(overflow_policy)
+ {
+ }
+
+ async_logger(std::string logger_name, sinks_init_list sinks_list, std::weak_ptr tp, async_overflow_policy overflow_policy = async_overflow_policy::block);
+
+ async_logger(std::string logger_name, sink_ptr single_sink, std::weak_ptr tp, async_overflow_policy overflow_policy = async_overflow_policy::block);
+
+ std::shared_ptr clone(std::string new_name) override;
+
+ protected:
+ void sink_it_(const details::log_msg& msg) override;
+ void flush_() override;
+ void backend_sink_it_(const details::log_msg& incoming_log_msg);
+ void backend_flush_();
+
+ private:
+ std::weak_ptr thread_pool_;
+ async_overflow_policy overflow_policy_;
+ };
+} // namespace spdlog
+
+#ifdef SPDLOG_HEADER_ONLY
+#include "async_logger-inl.h"
+#endif
diff --git a/CAPI/spdlog/include/spdlog/cfg/argv.h b/CAPI/spdlog/include/spdlog/cfg/argv.h
new file mode 100644
index 0000000..e371280
--- /dev/null
+++ b/CAPI/spdlog/include/spdlog/cfg/argv.h
@@ -0,0 +1,46 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+#include
+#include
+
+//
+// Init log levels using each argv entry that starts with "SPDLOG_LEVEL="
+//
+// set all loggers to debug level:
+// example.exe "SPDLOG_LEVEL=debug"
+
+// set logger1 to trace level
+// example.exe "SPDLOG_LEVEL=logger1=trace"
+
+// turn off all logging except for logger1 and logger2:
+// example.exe "SPDLOG_LEVEL=off,logger1=debug,logger2=info"
+
+namespace spdlog
+{
+ namespace cfg
+ {
+
+ // search for SPDLOG_LEVEL= in the args and use it to init the levels
+ inline void load_argv_levels(int argc, const char** argv)
+ {
+ const std::string spdlog_level_prefix = "SPDLOG_LEVEL=";
+ for (int i = 1; i < argc; i++)
+ {
+ std::string arg = argv[i];
+ if (arg.find(spdlog_level_prefix) == 0)
+ {
+ auto levels_string = arg.substr(spdlog_level_prefix.size());
+ helpers::load_levels(levels_string);
+ }
+ }
+ }
+
+ inline void load_argv_levels(int argc, char** argv)
+ {
+ load_argv_levels(argc, const_cast(argv));
+ }
+
+ } // namespace cfg
+} // namespace spdlog
diff --git a/CAPI/spdlog/include/spdlog/cfg/env.h b/CAPI/spdlog/include/spdlog/cfg/env.h
new file mode 100644
index 0000000..2b95c13
--- /dev/null
+++ b/CAPI/spdlog/include/spdlog/cfg/env.h
@@ -0,0 +1,40 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+#include
+#include
+#include
+
+//
+// Init levels and patterns from env variables SPDLOG_LEVEL
+// Inspired from Rust's "env_logger" crate (https://crates.io/crates/env_logger).
+// Note - fallback to "info" level on unrecognized levels
+//
+// Examples:
+//
+// set global level to debug:
+// export SPDLOG_LEVEL=debug
+//
+// turn off all logging except for logger1:
+// export SPDLOG_LEVEL="*=off,logger1=debug"
+//
+
+// turn off all logging except for logger1 and logger2:
+// export SPDLOG_LEVEL="off,logger1=debug,logger2=info"
+
+namespace spdlog
+{
+ namespace cfg
+ {
+ inline void load_env_levels()
+ {
+ auto env_val = details::os::getenv("SPDLOG_LEVEL");
+ if (!env_val.empty())
+ {
+ helpers::load_levels(env_val);
+ }
+ }
+
+ } // namespace cfg
+} // namespace spdlog
diff --git a/CAPI/spdlog/include/spdlog/cfg/helpers-inl.h b/CAPI/spdlog/include/spdlog/cfg/helpers-inl.h
new file mode 100644
index 0000000..23e404d
--- /dev/null
+++ b/CAPI/spdlog/include/spdlog/cfg/helpers-inl.h
@@ -0,0 +1,125 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#ifndef SPDLOG_HEADER_ONLY
+#include
+#endif
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+namespace spdlog
+{
+ namespace cfg
+ {
+ namespace helpers
+ {
+
+ // inplace convert to lowercase
+ inline std::string& to_lower_(std::string& str)
+ {
+ std::transform(
+ str.begin(), str.end(), str.begin(), [](char ch)
+ { return static_cast((ch >= 'A' && ch <= 'Z') ? ch + ('a' - 'A') : ch); }
+ );
+ return str;
+ }
+
+ // inplace trim spaces
+ inline std::string& trim_(std::string& str)
+ {
+ const char* spaces = " \n\r\t";
+ str.erase(str.find_last_not_of(spaces) + 1);
+ str.erase(0, str.find_first_not_of(spaces));
+ return str;
+ }
+
+ // return (name,value) trimmed pair from given "name=value" string.
+ // return empty string on missing parts
+ // "key=val" => ("key", "val")
+ // " key = val " => ("key", "val")
+ // "key=" => ("key", "")
+ // "val" => ("", "val")
+
+ inline std::pair extract_kv_(char sep, const std::string& str)
+ {
+ auto n = str.find(sep);
+ std::string k, v;
+ if (n == std::string::npos)
+ {
+ v = str;
+ }
+ else
+ {
+ k = str.substr(0, n);
+ v = str.substr(n + 1);
+ }
+ return std::make_pair(trim_(k), trim_(v));
+ }
+
+ // return vector of key/value pairs from sequence of "K1=V1,K2=V2,.."
+ // "a=AAA,b=BBB,c=CCC,.." => {("a","AAA"),("b","BBB"),("c", "CCC"),...}
+ inline std::unordered_map extract_key_vals_(const std::string& str)
+ {
+ std::string token;
+ std::istringstream token_stream(str);
+ std::unordered_map rv{};
+ while (std::getline(token_stream, token, ','))
+ {
+ if (token.empty())
+ {
+ continue;
+ }
+ auto kv = extract_kv_('=', token);
+ rv[kv.first] = kv.second;
+ }
+ return rv;
+ }
+
+ SPDLOG_INLINE void load_levels(const std::string& input)
+ {
+ if (input.empty() || input.size() > 512)
+ {
+ return;
+ }
+
+ auto key_vals = extract_key_vals_(input);
+ std::unordered_map levels;
+ level::level_enum global_level = level::info;
+ bool global_level_found = false;
+
+ for (auto& name_level : key_vals)
+ {
+ auto& logger_name = name_level.first;
+ auto level_name = to_lower_(name_level.second);
+ auto level = level::from_str(level_name);
+ // ignore unrecognized level names
+ if (level == level::off && level_name != "off")
+ {
+ continue;
+ }
+ if (logger_name.empty()) // no logger name indicate global level
+ {
+ global_level_found = true;
+ global_level = level;
+ }
+ else
+ {
+ levels[logger_name] = level;
+ }
+ }
+
+ details::registry::instance().set_levels(std::move(levels), global_level_found ? &global_level : nullptr);
+ }
+
+ } // namespace helpers
+ } // namespace cfg
+} // namespace spdlog
diff --git a/CAPI/spdlog/include/spdlog/cfg/helpers.h b/CAPI/spdlog/include/spdlog/cfg/helpers.h
new file mode 100644
index 0000000..0c9fc1d
--- /dev/null
+++ b/CAPI/spdlog/include/spdlog/cfg/helpers.h
@@ -0,0 +1,32 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#include
+#include
+
+namespace spdlog
+{
+ namespace cfg
+ {
+ namespace helpers
+ {
+ //
+ // Init levels from given string
+ //
+ // Examples:
+ //
+ // set global level to debug: "debug"
+ // turn off all logging except for logger1: "off,logger1=debug"
+ // turn off all logging except for logger1 and logger2: "off,logger1=debug,logger2=info"
+ //
+ SPDLOG_API void load_levels(const std::string& txt);
+ } // namespace helpers
+
+ } // namespace cfg
+} // namespace spdlog
+
+#ifdef SPDLOG_HEADER_ONLY
+#include "helpers-inl.h"
+#endif // SPDLOG_HEADER_ONLY
diff --git a/CAPI/spdlog/include/spdlog/common-inl.h b/CAPI/spdlog/include/spdlog/common-inl.h
new file mode 100644
index 0000000..a23f6d7
--- /dev/null
+++ b/CAPI/spdlog/include/spdlog/common-inl.h
@@ -0,0 +1,85 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#ifndef SPDLOG_HEADER_ONLY
+#include
+#endif
+
+#include
+#include
+
+namespace spdlog
+{
+ namespace level
+ {
+
+#if __cplusplus >= 201703L
+ constexpr
+#endif
+ static string_view_t level_string_views[] SPDLOG_LEVEL_NAMES;
+
+ static const char* short_level_names[] SPDLOG_SHORT_LEVEL_NAMES;
+
+ SPDLOG_INLINE const string_view_t& to_string_view(spdlog::level::level_enum l) SPDLOG_NOEXCEPT
+ {
+ return level_string_views[l];
+ }
+
+ SPDLOG_INLINE const char* to_short_c_str(spdlog::level::level_enum l) SPDLOG_NOEXCEPT
+ {
+ return short_level_names[l];
+ }
+
+ SPDLOG_INLINE spdlog::level::level_enum from_str(const std::string& name) SPDLOG_NOEXCEPT
+ {
+ auto it = std::find(std::begin(level_string_views), std::end(level_string_views), name);
+ if (it != std::end(level_string_views))
+ return static_cast(std::distance(std::begin(level_string_views), it));
+
+ // check also for "warn" and "err" before giving up..
+ if (name == "warn")
+ {
+ return level::warn;
+ }
+ if (name == "err")
+ {
+ return level::err;
+ }
+ return level::off;
+ }
+ } // namespace level
+
+ SPDLOG_INLINE spdlog_ex::spdlog_ex(std::string msg) :
+ msg_(std::move(msg))
+ {
+ }
+
+ SPDLOG_INLINE spdlog_ex::spdlog_ex(const std::string& msg, int last_errno)
+ {
+#ifdef SPDLOG_USE_STD_FORMAT
+ msg_ = std::system_error(std::error_code(last_errno, std::generic_category()), msg).what();
+#else
+ memory_buf_t outbuf;
+ fmt::format_system_error(outbuf, last_errno, msg.c_str());
+ msg_ = fmt::to_string(outbuf);
+#endif
+ }
+
+ SPDLOG_INLINE const char* spdlog_ex::what() const SPDLOG_NOEXCEPT
+ {
+ return msg_.c_str();
+ }
+
+ SPDLOG_INLINE void throw_spdlog_ex(const std::string& msg, int last_errno)
+ {
+ SPDLOG_THROW(spdlog_ex(msg, last_errno));
+ }
+
+ SPDLOG_INLINE void throw_spdlog_ex(std::string msg)
+ {
+ SPDLOG_THROW(spdlog_ex(std::move(msg)));
+ }
+
+} // namespace spdlog
diff --git a/CAPI/spdlog/include/spdlog/common.h b/CAPI/spdlog/include/spdlog/common.h
new file mode 100644
index 0000000..98d8544
--- /dev/null
+++ b/CAPI/spdlog/include/spdlog/common.h
@@ -0,0 +1,420 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef SPDLOG_USE_STD_FORMAT
+#include
+#if __cpp_lib_format >= 202207L
+#include
+#else
+#include
+#endif
+#endif
+
+#ifdef SPDLOG_COMPILED_LIB
+#undef SPDLOG_HEADER_ONLY
+#if defined(SPDLOG_SHARED_LIB)
+#if defined(_WIN32)
+#ifdef spdlog_EXPORTS
+#define SPDLOG_API __declspec(dllexport)
+#else // !spdlog_EXPORTS
+#define SPDLOG_API __declspec(dllimport)
+#endif
+#else // !defined(_WIN32)
+#define SPDLOG_API __attribute__((visibility("default")))
+#endif
+#else // !defined(SPDLOG_SHARED_LIB)
+#define SPDLOG_API
+#endif
+#define SPDLOG_INLINE
+#else // !defined(SPDLOG_COMPILED_LIB)
+#define SPDLOG_API
+#define SPDLOG_HEADER_ONLY
+#define SPDLOG_INLINE inline
+#endif // #ifdef SPDLOG_COMPILED_LIB
+
+#include
+
+#if !defined(SPDLOG_USE_STD_FORMAT) && FMT_VERSION >= 80000 // backward compatibility with fmt versions older than 8
+#define SPDLOG_FMT_RUNTIME(format_string) fmt::runtime(format_string)
+#define SPDLOG_FMT_STRING(format_string) FMT_STRING(format_string)
+#if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT)
+#include
+#endif
+#else
+#define SPDLOG_FMT_RUNTIME(format_string) format_string
+#define SPDLOG_FMT_STRING(format_string) format_string
+#endif
+
+// visual studio up to 2013 does not support noexcept nor constexpr
+#if defined(_MSC_VER) && (_MSC_VER < 1900)
+#define SPDLOG_NOEXCEPT _NOEXCEPT
+#define SPDLOG_CONSTEXPR
+#define SPDLOG_CONSTEXPR_FUNC inline
+#else
+#define SPDLOG_NOEXCEPT noexcept
+#define SPDLOG_CONSTEXPR constexpr
+#if __cplusplus >= 201402L
+#define SPDLOG_CONSTEXPR_FUNC constexpr
+#else
+#define SPDLOG_CONSTEXPR_FUNC inline
+#endif
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define SPDLOG_DEPRECATED __attribute__((deprecated))
+#elif defined(_MSC_VER)
+#define SPDLOG_DEPRECATED __declspec(deprecated)
+#else
+#define SPDLOG_DEPRECATED
+#endif
+
+// disable thread local on msvc 2013
+#ifndef SPDLOG_NO_TLS
+#if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__cplusplus_winrt)
+#define SPDLOG_NO_TLS 1
+#endif
+#endif
+
+#ifndef SPDLOG_FUNCTION
+#define SPDLOG_FUNCTION static_cast(__FUNCTION__)
+#endif
+
+#ifdef SPDLOG_NO_EXCEPTIONS
+#define SPDLOG_TRY
+#define SPDLOG_THROW(ex) \
+ do \
+ { \
+ printf("spdlog fatal error: %s\n", ex.what()); \
+ std::abort(); \
+ } while (0)
+#define SPDLOG_CATCH_STD
+#else
+#define SPDLOG_TRY try
+#define SPDLOG_THROW(ex) throw(ex)
+#define SPDLOG_CATCH_STD \
+ catch (const std::exception&) \
+ { \
+ }
+#endif
+
+namespace spdlog
+{
+
+ class formatter;
+
+ namespace sinks
+ {
+ class sink;
+ }
+
+#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
+ using filename_t = std::wstring;
+// allow macro expansion to occur in SPDLOG_FILENAME_T
+#define SPDLOG_FILENAME_T_INNER(s) L##s
+#define SPDLOG_FILENAME_T(s) SPDLOG_FILENAME_T_INNER(s)
+#else
+ using filename_t = std::string;
+#define SPDLOG_FILENAME_T(s) s
+#endif
+
+ using log_clock = std::chrono::system_clock;
+ using sink_ptr = std::shared_ptr;
+ using sinks_init_list = std::initializer_list;
+ using err_handler = std::function;
+#ifdef SPDLOG_USE_STD_FORMAT
+ namespace fmt_lib = std;
+
+ using string_view_t = std::string_view;
+ using memory_buf_t = std::string;
+
+ template
+#if __cpp_lib_format >= 202207L
+ using format_string_t = std::format_string;
+#else
+ using format_string_t = std::string_view;
+#endif
+
+ template
+ struct is_convertible_to_basic_format_string : std::integral_constant>::value>
+ {
+ };
+
+#if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT)
+ using wstring_view_t = std::wstring_view;
+ using wmemory_buf_t = std::wstring;
+
+ template
+#if __cpp_lib_format >= 202207L
+ using wformat_string_t = std::wformat_string;
+#else
+ using wformat_string_t = std::wstring_view;
+#endif
+#endif
+#define SPDLOG_BUF_TO_STRING(x) x
+#else // use fmt lib instead of std::format
+ namespace fmt_lib = fmt;
+
+ using string_view_t = fmt::basic_string_view;
+ using memory_buf_t = fmt::basic_memory_buffer;
+
+ template
+ using format_string_t = fmt::format_string;
+
+ template
+ using remove_cvref_t = typename std::remove_cv::type>::type;
+
+ // clang doesn't like SFINAE disabled constructor in std::is_convertible<> so have to repeat the condition from basic_format_string here,
+ // in addition, fmt::basic_runtime is only convertible to basic_format_string but not basic_string_view
+ template
+ struct is_convertible_to_basic_format_string : std::integral_constant>::value || std::is_same, fmt::basic_runtime>::value>
+ {
+ };
+
+#if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT)
+ using wstring_view_t = fmt::basic_string_view;
+ using wmemory_buf_t = fmt::basic_memory_buffer;
+
+ template
+ using wformat_string_t = fmt::wformat_string;
+#endif
+#define SPDLOG_BUF_TO_STRING(x) fmt::to_string(x)
+#endif
+
+#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
+#ifndef _WIN32
+#error SPDLOG_WCHAR_TO_UTF8_SUPPORT only supported on windows
+#endif // _WIN32
+#endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT
+
+ template
+ struct is_convertible_to_any_format_string : std::integral_constant::value || is_convertible_to_basic_format_string::value>
+ {
+ };
+
+#if defined(SPDLOG_NO_ATOMIC_LEVELS)
+ using level_t = details::null_atomic_int;
+#else
+ using level_t = std::atomic;
+#endif
+
+#define SPDLOG_LEVEL_TRACE 0
+#define SPDLOG_LEVEL_DEBUG 1
+#define SPDLOG_LEVEL_INFO 2
+#define SPDLOG_LEVEL_WARN 3
+#define SPDLOG_LEVEL_ERROR 4
+#define SPDLOG_LEVEL_CRITICAL 5
+#define SPDLOG_LEVEL_OFF 6
+
+#if !defined(SPDLOG_ACTIVE_LEVEL)
+#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_INFO
+#endif
+
+ // Log level enum
+ namespace level
+ {
+ enum level_enum : int
+ {
+ trace = SPDLOG_LEVEL_TRACE,
+ debug = SPDLOG_LEVEL_DEBUG,
+ info = SPDLOG_LEVEL_INFO,
+ warn = SPDLOG_LEVEL_WARN,
+ err = SPDLOG_LEVEL_ERROR,
+ critical = SPDLOG_LEVEL_CRITICAL,
+ off = SPDLOG_LEVEL_OFF,
+ n_levels
+ };
+
+#define SPDLOG_LEVEL_NAME_TRACE spdlog::string_view_t("trace", 5)
+#define SPDLOG_LEVEL_NAME_DEBUG spdlog::string_view_t("debug", 5)
+#define SPDLOG_LEVEL_NAME_INFO spdlog::string_view_t("info", 4)
+#define SPDLOG_LEVEL_NAME_WARNING spdlog::string_view_t("warning", 7)
+#define SPDLOG_LEVEL_NAME_ERROR spdlog::string_view_t("error", 5)
+#define SPDLOG_LEVEL_NAME_CRITICAL spdlog::string_view_t("critical", 8)
+#define SPDLOG_LEVEL_NAME_OFF spdlog::string_view_t("off", 3)
+
+#if !defined(SPDLOG_LEVEL_NAMES)
+#define SPDLOG_LEVEL_NAMES \
+ { \
+ SPDLOG_LEVEL_NAME_TRACE, SPDLOG_LEVEL_NAME_DEBUG, SPDLOG_LEVEL_NAME_INFO, SPDLOG_LEVEL_NAME_WARNING, SPDLOG_LEVEL_NAME_ERROR, \
+ SPDLOG_LEVEL_NAME_CRITICAL, SPDLOG_LEVEL_NAME_OFF \
+ }
+#endif
+
+#if !defined(SPDLOG_SHORT_LEVEL_NAMES)
+
+#define SPDLOG_SHORT_LEVEL_NAMES \
+ { \
+ "T", "D", "I", "W", "E", "C", "O" \
+ }
+#endif
+
+ SPDLOG_API const string_view_t& to_string_view(spdlog::level::level_enum l) SPDLOG_NOEXCEPT;
+ SPDLOG_API const char* to_short_c_str(spdlog::level::level_enum l) SPDLOG_NOEXCEPT;
+ SPDLOG_API spdlog::level::level_enum from_str(const std::string& name) SPDLOG_NOEXCEPT;
+
+ } // namespace level
+
+ //
+ // Color mode used by sinks with color support.
+ //
+ enum class color_mode
+ {
+ always,
+ automatic,
+ never
+ };
+
+ //
+ // Pattern time - specific time getting to use for pattern_formatter.
+ // local time by default
+ //
+ enum class pattern_time_type
+ {
+ local, // log localtime
+ utc // log utc
+ };
+
+ //
+ // Log exception
+ //
+ class SPDLOG_API spdlog_ex : public std::exception
+ {
+ public:
+ explicit spdlog_ex(std::string msg);
+ spdlog_ex(const std::string& msg, int last_errno);
+ const char* what() const SPDLOG_NOEXCEPT override;
+
+ private:
+ std::string msg_;
+ };
+
+ [[noreturn]] SPDLOG_API void throw_spdlog_ex(const std::string& msg, int last_errno);
+ [[noreturn]] SPDLOG_API void throw_spdlog_ex(std::string msg);
+
+ struct source_loc
+ {
+ SPDLOG_CONSTEXPR source_loc() = default;
+ SPDLOG_CONSTEXPR source_loc(const char* filename_in, int line_in, const char* funcname_in) :
+ filename{filename_in},
+ line{line_in},
+ funcname{funcname_in}
+ {
+ }
+
+ SPDLOG_CONSTEXPR bool empty() const SPDLOG_NOEXCEPT
+ {
+ return line == 0;
+ }
+ const char* filename{nullptr};
+ int line{0};
+ const char* funcname{nullptr};
+ };
+
+ struct file_event_handlers
+ {
+ file_event_handlers() :
+ before_open(nullptr),
+ after_open(nullptr),
+ before_close(nullptr),
+ after_close(nullptr)
+ {
+ }
+
+ std::function before_open;
+ std::function after_open;
+ std::function before_close;
+ std::function after_close;
+ };
+
+ namespace details
+ {
+
+ // to_string_view
+
+ SPDLOG_CONSTEXPR_FUNC spdlog::string_view_t to_string_view(const memory_buf_t& buf) SPDLOG_NOEXCEPT
+ {
+ return spdlog::string_view_t{buf.data(), buf.size()};
+ }
+
+ SPDLOG_CONSTEXPR_FUNC spdlog::string_view_t to_string_view(spdlog::string_view_t str) SPDLOG_NOEXCEPT
+ {
+ return str;
+ }
+
+#if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT)
+ SPDLOG_CONSTEXPR_FUNC spdlog::wstring_view_t to_string_view(const wmemory_buf_t& buf) SPDLOG_NOEXCEPT
+ {
+ return spdlog::wstring_view_t{buf.data(), buf.size()};
+ }
+
+ SPDLOG_CONSTEXPR_FUNC spdlog::wstring_view_t to_string_view(spdlog::wstring_view_t str) SPDLOG_NOEXCEPT
+ {
+ return str;
+ }
+#endif
+
+#ifndef SPDLOG_USE_STD_FORMAT
+ template
+ inline fmt::basic_string_view to_string_view(fmt::basic_format_string fmt)
+ {
+ return fmt;
+ }
+#elif __cpp_lib_format >= 202207L
+ template
+ SPDLOG_CONSTEXPR_FUNC std::basic_string_view to_string_view(std::basic_format_string fmt) SPDLOG_NOEXCEPT
+ {
+ return fmt.get();
+ }
+#endif
+
+ // make_unique support for pre c++14
+
+#if __cplusplus >= 201402L // C++14 and beyond
+ using std::enable_if_t;
+ using std::make_unique;
+#else
+ template
+ using enable_if_t = typename std::enable_if::type;
+
+ template
+ std::unique_ptr make_unique(Args&&... args)
+ {
+ static_assert(!std::is_array::value, "arrays not supported");
+ return std::unique_ptr(new T(std::forward(args)...));
+ }
+#endif
+
+ // to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
+ template::value, int> = 0>
+ constexpr T conditional_static_cast(U value)
+ {
+ return static_cast(value);
+ }
+
+ template::value, int> = 0>
+ constexpr T conditional_static_cast(U value)
+ {
+ return value;
+ }
+
+ } // namespace details
+} // namespace spdlog
+
+#ifdef SPDLOG_HEADER_ONLY
+#include "common-inl.h"
+#endif
diff --git a/CAPI/spdlog/include/spdlog/details/backtracer-inl.h b/CAPI/spdlog/include/spdlog/details/backtracer-inl.h
new file mode 100644
index 0000000..819cad0
--- /dev/null
+++ b/CAPI/spdlog/include/spdlog/details/backtracer-inl.h
@@ -0,0 +1,77 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#ifndef SPDLOG_HEADER_ONLY
+#include
+#endif
+namespace spdlog
+{
+ namespace details
+ {
+ SPDLOG_INLINE backtracer::backtracer(const backtracer& other)
+ {
+ std::lock_guard lock(other.mutex_);
+ enabled_ = other.enabled();
+ messages_ = other.messages_;
+ }
+
+ SPDLOG_INLINE backtracer::backtracer(backtracer&& other) SPDLOG_NOEXCEPT
+ {
+ std::lock_guard lock(other.mutex_);
+ enabled_ = other.enabled();
+ messages_ = std::move(other.messages_);
+ }
+
+ SPDLOG_INLINE backtracer& backtracer::operator=(backtracer other)
+ {
+ std::lock_guard lock(mutex_);
+ enabled_ = other.enabled();
+ messages_ = std::move(other.messages_);
+ return *this;
+ }
+
+ SPDLOG_INLINE void backtracer::enable(size_t size)
+ {
+ std::lock_guard lock{mutex_};
+ enabled_.store(true, std::memory_order_relaxed);
+ messages_ = circular_q{size};
+ }
+
+ SPDLOG_INLINE void backtracer::disable()
+ {
+ std::lock_guard lock{mutex_};
+ enabled_.store(false, std::memory_order_relaxed);
+ }
+
+ SPDLOG_INLINE bool backtracer::enabled() const
+ {
+ return enabled_.load(std::memory_order_relaxed);
+ }
+
+ SPDLOG_INLINE void backtracer::push_back(const log_msg& msg)
+ {
+ std::lock_guard lock{mutex_};
+ messages_.push_back(log_msg_buffer{msg});
+ }
+
+ SPDLOG_INLINE bool backtracer::empty() const
+ {
+ std::lock_guard lock{mutex_};
+ return messages_.empty();
+ }
+
+ // pop all items in the q and apply the given fun on each of them.
+ SPDLOG_INLINE void backtracer::foreach_pop(std::function fun)
+ {
+ std::lock_guard lock{mutex_};
+ while (!messages_.empty())
+ {
+ auto& front_msg = messages_.front();
+ fun(front_msg);
+ messages_.pop_front();
+ }
+ }
+ } // namespace details
+} // namespace spdlog
diff --git a/CAPI/spdlog/include/spdlog/details/backtracer.h b/CAPI/spdlog/include/spdlog/details/backtracer.h
new file mode 100644
index 0000000..a9bccb5
--- /dev/null
+++ b/CAPI/spdlog/include/spdlog/details/backtracer.h
@@ -0,0 +1,48 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#include
+#include
+
+#include
+#include
+#include
+
+// Store log messages in circular buffer.
+// Useful for storing debug data in case of error/warning happens.
+
+namespace spdlog
+{
+ namespace details
+ {
+ class SPDLOG_API backtracer
+ {
+ mutable std::mutex mutex_;
+ std::atomic enabled_{false};
+ circular_q messages_;
+
+ public:
+ backtracer() = default;
+ backtracer(const backtracer& other);
+
+ backtracer(backtracer&& other) SPDLOG_NOEXCEPT;
+ backtracer& operator=(backtracer other);
+
+ void enable(size_t size);
+ void disable();
+ bool enabled() const;
+ void push_back(const log_msg& msg);
+ bool empty() const;
+
+ // pop all items in the q and apply the given fun on each of them.
+ void foreach_pop(std::function fun);
+ };
+
+ } // namespace details
+} // namespace spdlog
+
+#ifdef SPDLOG_HEADER_ONLY
+#include "backtracer-inl.h"
+#endif
diff --git a/CAPI/spdlog/include/spdlog/details/circular_q.h b/CAPI/spdlog/include/spdlog/details/circular_q.h
new file mode 100644
index 0000000..67f1186
--- /dev/null
+++ b/CAPI/spdlog/include/spdlog/details/circular_q.h
@@ -0,0 +1,150 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+// circular q view of std::vector.
+#pragma once
+
+#include
+#include
+
+namespace spdlog
+{
+ namespace details
+ {
+ template
+ class circular_q
+ {
+ size_t max_items_ = 0;
+ typename std::vector::size_type head_ = 0;
+ typename std::vector::size_type tail_ = 0;
+ size_t overrun_counter_ = 0;
+ std::vector v_;
+
+ public:
+ using value_type = T;
+
+ // empty ctor - create a disabled queue with no elements allocated at all
+ circular_q() = default;
+
+ explicit circular_q(size_t max_items) :
+ max_items_(max_items + 1) // one item is reserved as marker for full q
+ ,
+ v_(max_items_)
+ {
+ }
+
+ circular_q(const circular_q&) = default;
+ circular_q& operator=(const circular_q&) = default;
+
+ // move cannot be default,
+ // since we need to reset head_, tail_, etc to zero in the moved object
+ circular_q(circular_q&& other) SPDLOG_NOEXCEPT
+ {
+ copy_moveable(std::move(other));
+ }
+
+ circular_q& operator=(circular_q&& other) SPDLOG_NOEXCEPT
+ {
+ copy_moveable(std::move(other));
+ return *this;
+ }
+
+ // push back, overrun (oldest) item if no room left
+ void push_back(T&& item)
+ {
+ if (max_items_ > 0)
+ {
+ v_[tail_] = std::move(item);
+ tail_ = (tail_ + 1) % max_items_;
+
+ if (tail_ == head_) // overrun last item if full
+ {
+ head_ = (head_ + 1) % max_items_;
+ ++overrun_counter_;
+ }
+ }
+ }
+
+ // Return reference to the front item.
+ // If there are no elements in the container, the behavior is undefined.
+ const T& front() const
+ {
+ return v_[head_];
+ }
+
+ T& front()
+ {
+ return v_[head_];
+ }
+
+ // Return number of elements actually stored
+ size_t size() const
+ {
+ if (tail_ >= head_)
+ {
+ return tail_ - head_;
+ }
+ else
+ {
+ return max_items_ - (head_ - tail_);
+ }
+ }
+
+ // Return const reference to item by index.
+ // If index is out of range 0…size()-1, the behavior is undefined.
+ const T& at(size_t i) const
+ {
+ assert(i < size());
+ return v_[(head_ + i) % max_items_];
+ }
+
+ // Pop item from front.
+ // If there are no elements in the container, the behavior is undefined.
+ void pop_front()
+ {
+ head_ = (head_ + 1) % max_items_;
+ }
+
+ bool empty() const
+ {
+ return tail_ == head_;
+ }
+
+ bool full() const
+ {
+ // head is ahead of the tail by 1
+ if (max_items_ > 0)
+ {
+ return ((tail_ + 1) % max_items_) == head_;
+ }
+ return false;
+ }
+
+ size_t overrun_counter() const
+ {
+ return overrun_counter_;
+ }
+
+ void reset_overrun_counter()
+ {
+ overrun_counter_ = 0;
+ }
+
+ private:
+ // copy from other&& and reset it to disabled state
+ void copy_moveable(circular_q&& other) SPDLOG_NOEXCEPT
+ {
+ max_items_ = other.max_items_;
+ head_ = other.head_;
+ tail_ = other.tail_;
+ overrun_counter_ = other.overrun_counter_;
+ v_ = std::move(other.v_);
+
+ // put &&other in disabled, but valid state
+ other.max_items_ = 0;
+ other.head_ = other.tail_ = 0;
+ other.overrun_counter_ = 0;
+ }
+ };
+ } // namespace details
+} // namespace spdlog
diff --git a/CAPI/spdlog/include/spdlog/details/console_globals.h b/CAPI/spdlog/include/spdlog/details/console_globals.h
new file mode 100644
index 0000000..c071e42
--- /dev/null
+++ b/CAPI/spdlog/include/spdlog/details/console_globals.h
@@ -0,0 +1,34 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#include
+#include
+
+namespace spdlog
+{
+ namespace details
+ {
+
+ struct console_mutex
+ {
+ using mutex_t = std::mutex;
+ static mutex_t& mutex()
+ {
+ static mutex_t s_mutex;
+ return s_mutex;
+ }
+ };
+
+ struct console_nullmutex
+ {
+ using mutex_t = null_mutex;
+ static mutex_t& mutex()
+ {
+ static mutex_t s_mutex;
+ return s_mutex;
+ }
+ };
+ } // namespace details
+} // namespace spdlog
diff --git a/CAPI/spdlog/include/spdlog/details/file_helper-inl.h b/CAPI/spdlog/include/spdlog/details/file_helper-inl.h
new file mode 100644
index 0000000..c940635
--- /dev/null
+++ b/CAPI/spdlog/include/spdlog/details/file_helper-inl.h
@@ -0,0 +1,175 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#ifndef SPDLOG_HEADER_ONLY
+#include
+#endif
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace spdlog
+{
+ namespace details
+ {
+
+ SPDLOG_INLINE file_helper::file_helper(const file_event_handlers& event_handlers) :
+ event_handlers_(event_handlers)
+ {
+ }
+
+ SPDLOG_INLINE file_helper::~file_helper()
+ {
+ close();
+ }
+
+ SPDLOG_INLINE void file_helper::open(const filename_t& fname, bool truncate)
+ {
+ close();
+ filename_ = fname;
+
+ auto* mode = SPDLOG_FILENAME_T("ab");
+ auto* trunc_mode = SPDLOG_FILENAME_T("wb");
+
+ if (event_handlers_.before_open)
+ {
+ event_handlers_.before_open(filename_);
+ }
+ for (int tries = 0; tries < open_tries_; ++tries)
+ {
+ // create containing folder if not exists already.
+ os::create_dir(os::dir_name(fname));
+ if (truncate)
+ {
+ // Truncate by opening-and-closing a tmp file in "wb" mode, always
+ // opening the actual log-we-write-to in "ab" mode, since that
+ // interacts more politely with eternal processes that might
+ // rotate/truncate the file underneath us.
+ std::FILE* tmp;
+ if (os::fopen_s(&tmp, fname, trunc_mode))
+ {
+ continue;
+ }
+ std::fclose(tmp);
+ }
+ if (!os::fopen_s(&fd_, fname, mode))
+ {
+ if (event_handlers_.after_open)
+ {
+ event_handlers_.after_open(filename_, fd_);
+ }
+ return;
+ }
+
+ details::os::sleep_for_millis(open_interval_);
+ }
+
+ throw_spdlog_ex("Failed opening file " + os::filename_to_str(filename_) + " for writing", errno);
+ }
+
+ SPDLOG_INLINE void file_helper::reopen(bool truncate)
+ {
+ if (filename_.empty())
+ {
+ throw_spdlog_ex("Failed re opening file - was not opened before");
+ }
+ this->open(filename_, truncate);
+ }
+
+ SPDLOG_INLINE void file_helper::flush()
+ {
+ if (std::fflush(fd_) != 0)
+ {
+ throw_spdlog_ex("Failed flush to file " + os::filename_to_str(filename_), errno);
+ }
+ }
+
+ SPDLOG_INLINE void file_helper::close()
+ {
+ if (fd_ != nullptr)
+ {
+ if (event_handlers_.before_close)
+ {
+ event_handlers_.before_close(filename_, fd_);
+ }
+
+ std::fclose(fd_);
+ fd_ = nullptr;
+
+ if (event_handlers_.after_close)
+ {
+ event_handlers_.after_close(filename_);
+ }
+ }
+ }
+
+ SPDLOG_INLINE void file_helper::write(const memory_buf_t& buf)
+ {
+ size_t msg_size = buf.size();
+ auto data = buf.data();
+ if (std::fwrite(data, 1, msg_size, fd_) != msg_size)
+ {
+ throw_spdlog_ex("Failed writing to file " + os::filename_to_str(filename_), errno);
+ }
+ }
+
+ SPDLOG_INLINE size_t file_helper::size() const
+ {
+ if (fd_ == nullptr)
+ {
+ throw_spdlog_ex("Cannot use size() on closed file " + os::filename_to_str(filename_));
+ }
+ return os::filesize(fd_);
+ }
+
+ SPDLOG_INLINE const filename_t& file_helper::filename() const
+ {
+ return filename_;
+ }
+
+ //
+ // return file path and its extension:
+ //
+ // "mylog.txt" => ("mylog", ".txt")
+ // "mylog" => ("mylog", "")
+ // "mylog." => ("mylog.", "")
+ // "/dir1/dir2/mylog.txt" => ("/dir1/dir2/mylog", ".txt")
+ //
+ // the starting dot in filenames is ignored (hidden files):
+ //
+ // ".mylog" => (".mylog". "")
+ // "my_folder/.mylog" => ("my_folder/.mylog", "")
+ // "my_folder/.mylog.txt" => ("my_folder/.mylog", ".txt")
+ SPDLOG_INLINE std::tuple file_helper::split_by_extension(const filename_t& fname)
+ {
+ auto ext_index = fname.rfind('.');
+
+ // no valid extension found - return whole path and empty string as
+ // extension
+ if (ext_index == filename_t::npos || ext_index == 0 || ext_index == fname.size() - 1)
+ {
+ return std::make_tuple(fname, filename_t());
+ }
+
+ // treat cases like "/etc/rc.d/somelogfile or "/abc/.hiddenfile"
+ auto folder_index = fname.find_last_of(details::os::folder_seps_filename);
+ if (folder_index != filename_t::npos && folder_index >= ext_index - 1)
+ {
+ return std::make_tuple(fname, filename_t());
+ }
+
+ // finally - return a valid base and extension tuple
+ return std::make_tuple(fname.substr(0, ext_index), fname.substr(ext_index));
+ }
+
+ } // namespace details
+} // namespace spdlog
diff --git a/CAPI/spdlog/include/spdlog/details/file_helper.h b/CAPI/spdlog/include/spdlog/details/file_helper.h
new file mode 100644
index 0000000..04896c1
--- /dev/null
+++ b/CAPI/spdlog/include/spdlog/details/file_helper.h
@@ -0,0 +1,63 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#include
+#include
+
+namespace spdlog
+{
+ namespace details
+ {
+
+ // Helper class for file sinks.
+ // When failing to open a file, retry several times(5) with a delay interval(10 ms).
+ // Throw spdlog_ex exception on errors.
+
+ class SPDLOG_API file_helper
+ {
+ public:
+ file_helper() = default;
+ explicit file_helper(const file_event_handlers& event_handlers);
+
+ file_helper(const file_helper&) = delete;
+ file_helper& operator=(const file_helper&) = delete;
+ ~file_helper();
+
+ void open(const filename_t& fname, bool truncate = false);
+ void reopen(bool truncate);
+ void flush();
+ void close();
+ void write(const memory_buf_t& buf);
+ size_t size() const;
+ const filename_t& filename() const;
+
+ //
+ // return file path and its extension:
+ //
+ // "mylog.txt" => ("mylog", ".txt")
+ // "mylog" => ("mylog", "")
+ // "mylog." => ("mylog.", "")
+ // "/dir1/dir2/mylog.txt" => ("/dir1/dir2/mylog", ".txt")
+ //
+ // the starting dot in filenames is ignored (hidden files):
+ //
+ // ".mylog" => (".mylog". "")
+ // "my_folder/.mylog" => ("my_folder/.mylog", "")
+ // "my_folder/.mylog.txt" => ("my_folder/.mylog", ".txt")
+ static std::tuple split_by_extension(const filename_t& fname);
+
+ private:
+ const int open_tries_ = 5;
+ const unsigned int open_interval_ = 10;
+ std::FILE* fd_{nullptr};
+ filename_t filename_;
+ file_event_handlers event_handlers_;
+ };
+ } // namespace details
+} // namespace spdlog
+
+#ifdef SPDLOG_HEADER_ONLY
+#include "file_helper-inl.h"
+#endif
diff --git a/CAPI/spdlog/include/spdlog/details/fmt_helper.h b/CAPI/spdlog/include/spdlog/details/fmt_helper.h
new file mode 100644
index 0000000..c782b81
--- /dev/null
+++ b/CAPI/spdlog/include/spdlog/details/fmt_helper.h
@@ -0,0 +1,167 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+
+#ifdef SPDLOG_USE_STD_FORMAT
+#include
+#include
+#endif
+
+// Some fmt helpers to efficiently format and pad ints and strings
+namespace spdlog
+{
+ namespace details
+ {
+ namespace fmt_helper
+ {
+
+ inline void append_string_view(spdlog::string_view_t view, memory_buf_t& dest)
+ {
+ auto* buf_ptr = view.data();
+ dest.append(buf_ptr, buf_ptr + view.size());
+ }
+
+#ifdef SPDLOG_USE_STD_FORMAT
+ template
+ inline void append_int(T n, memory_buf_t& dest)
+ {
+ // Buffer should be large enough to hold all digits (digits10 + 1) and a sign
+ SPDLOG_CONSTEXPR const auto BUF_SIZE = std::numeric_limits::digits10 + 2;
+ char buf[BUF_SIZE];
+
+ auto [ptr, ec] = std::to_chars(buf, buf + BUF_SIZE, n, 10);
+ if (ec == std::errc())
+ {
+ dest.append(buf, ptr);
+ }
+ else
+ {
+ throw_spdlog_ex("Failed to format int", static_cast(ec));
+ }
+ }
+#else
+ template
+ inline void append_int(T n, memory_buf_t& dest)
+ {
+ fmt::format_int i(n);
+ dest.append(i.data(), i.data() + i.size());
+ }
+#endif
+
+ template
+ SPDLOG_CONSTEXPR_FUNC unsigned int count_digits_fallback(T n)
+ {
+ // taken from fmt: https://github.com/fmtlib/fmt/blob/8.0.1/include/fmt/format.h#L899-L912
+ unsigned int count = 1;
+ for (;;)
+ {
+ // Integer division is slow so do it for a group of four digits instead
+ // of for every digit. The idea comes from the talk by Alexandrescu
+ // "Three Optimization Tips for C++". See speed-test for a comparison.
+ if (n < 10)
+ return count;
+ if (n < 100)
+ return count + 1;
+ if (n < 1000)
+ return count + 2;
+ if (n < 10000)
+ return count + 3;
+ n /= 10000u;
+ count += 4;
+ }
+ }
+
+ template
+ inline unsigned int count_digits(T n)
+ {
+ using count_type = typename std::conditional<(sizeof(T) > sizeof(uint32_t)), uint64_t, uint32_t>::type;
+#ifdef SPDLOG_USE_STD_FORMAT
+ return count_digits_fallback(static_cast(n));
+#else
+ return static_cast(fmt::
+// fmt 7.0.0 renamed the internal namespace to detail.
+// See: https://github.com/fmtlib/fmt/issues/1538
+#if FMT_VERSION < 70000
+ internal
+#else
+ detail
+#endif
+ ::count_digits(static_cast(n)));
+#endif
+ }
+
+ inline void pad2(int n, memory_buf_t& dest)
+ {
+ if (n >= 0 && n < 100) // 0-99
+ {
+ dest.push_back(static_cast('0' + n / 10));
+ dest.push_back(static_cast('0' + n % 10));
+ }
+ else // unlikely, but just in case, let fmt deal with it
+ {
+ fmt_lib::format_to(std::back_inserter(dest), SPDLOG_FMT_STRING("{:02}"), n);
+ }
+ }
+
+ template
+ inline void pad_uint(T n, unsigned int width, memory_buf_t& dest)
+ {
+ static_assert(std::is_unsigned::value, "pad_uint must get unsigned T");
+ for (auto digits = count_digits(n); digits < width; digits++)
+ {
+ dest.push_back('0');
+ }
+ append_int(n, dest);
+ }
+
+ template
+ inline void pad3(T n, memory_buf_t& dest)
+ {
+ static_assert(std::is_unsigned::value, "pad3 must get unsigned T");
+ if (n < 1000)
+ {
+ dest.push_back(static_cast(n / 100 + '0'));
+ n = n % 100;
+ dest.push_back(static_cast((n / 10) + '0'));
+ dest.push_back(static_cast((n % 10) + '0'));
+ }
+ else
+ {
+ append_int(n, dest);
+ }
+ }
+
+ template
+ inline void pad6(T n, memory_buf_t& dest)
+ {
+ pad_uint(n, 6, dest);
+ }
+
+ template
+ inline void pad9(T n, memory_buf_t& dest)
+ {
+ pad_uint(n, 9, dest);
+ }
+
+ // return fraction of a second of the given time_point.
+ // e.g.
+ // fraction(tp) -> will return the millis part of the second
+ template
+ inline ToDuration time_fraction(log_clock::time_point tp)
+ {
+ using std::chrono::duration_cast;
+ using std::chrono::seconds;
+ auto duration = tp.time_since_epoch();
+ auto secs = duration_cast(duration);
+ return duration_cast(duration) - duration_cast(secs);
+ }
+
+ } // namespace fmt_helper
+ } // namespace details
+} // namespace spdlog
diff --git a/CAPI/spdlog/include/spdlog/details/log_msg-inl.h b/CAPI/spdlog/include/spdlog/details/log_msg-inl.h
new file mode 100644
index 0000000..68a72a1
--- /dev/null
+++ b/CAPI/spdlog/include/spdlog/details/log_msg-inl.h
@@ -0,0 +1,44 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#ifndef SPDLOG_HEADER_ONLY
+#include
+#endif
+
+#include
+
+namespace spdlog
+{
+ namespace details
+ {
+
+ SPDLOG_INLINE log_msg::log_msg(spdlog::log_clock::time_point log_time, spdlog::source_loc loc, string_view_t a_logger_name, spdlog::level::level_enum lvl, spdlog::string_view_t msg) :
+ logger_name(a_logger_name),
+ level(lvl),
+ time(log_time)
+#ifndef SPDLOG_NO_THREAD_ID
+ ,
+ thread_id(os::thread_id())
+#endif
+ ,
+ source(loc),
+ payload(msg)
+ {
+ }
+
+ SPDLOG_INLINE log_msg::log_msg(
+ spdlog::source_loc loc, string_view_t a_logger_name, spdlog::level::level_enum lvl, spdlog::string_view_t msg
+ ) :
+ log_msg(os::now(), loc, a_logger_name, lvl, msg)
+ {
+ }
+
+ SPDLOG_INLINE log_msg::log_msg(string_view_t a_logger_name, spdlog::level::level_enum lvl, spdlog::string_view_t msg) :
+ log_msg(os::now(), source_loc{}, a_logger_name, lvl, msg)
+ {
+ }
+
+ } // namespace details
+} // namespace spdlog
diff --git a/CAPI/spdlog/include/spdlog/details/log_msg.h b/CAPI/spdlog/include/spdlog/details/log_msg.h
new file mode 100644
index 0000000..a38ad9c
--- /dev/null
+++ b/CAPI/spdlog/include/spdlog/details/log_msg.h
@@ -0,0 +1,39 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#include
+#include
+
+namespace spdlog
+{
+ namespace details
+ {
+ struct SPDLOG_API log_msg
+ {
+ log_msg() = default;
+ log_msg(log_clock::time_point log_time, source_loc loc, string_view_t logger_name, level::level_enum lvl, string_view_t msg);
+ log_msg(source_loc loc, string_view_t logger_name, level::level_enum lvl, string_view_t msg);
+ log_msg(string_view_t logger_name, level::level_enum lvl, string_view_t msg);
+ log_msg(const log_msg& other) = default;
+ log_msg& operator=(const log_msg& other) = default;
+
+ string_view_t logger_name;
+ level::level_enum level{level::off};
+ log_clock::time_point time;
+ size_t thread_id{0};
+
+ // wrapping the formatted text with color (updated by pattern_formatter).
+ mutable size_t color_range_start{0};
+ mutable size_t color_range_end{0};
+
+ source_loc source;
+ string_view_t payload;
+ };
+ } // namespace details
+} // namespace spdlog
+
+#ifdef SPDLOG_HEADER_ONLY
+#include "log_msg-inl.h"
+#endif
diff --git a/CAPI/spdlog/include/spdlog/details/log_msg_buffer-inl.h b/CAPI/spdlog/include/spdlog/details/log_msg_buffer-inl.h
new file mode 100644
index 0000000..8a935ea
--- /dev/null
+++ b/CAPI/spdlog/include/spdlog/details/log_msg_buffer-inl.h
@@ -0,0 +1,60 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#ifndef SPDLOG_HEADER_ONLY
+#include
+#endif
+
+namespace spdlog
+{
+ namespace details
+ {
+
+ SPDLOG_INLINE log_msg_buffer::log_msg_buffer(const log_msg& orig_msg) :
+ log_msg{orig_msg}
+ {
+ buffer.append(logger_name.begin(), logger_name.end());
+ buffer.append(payload.begin(), payload.end());
+ update_string_views();
+ }
+
+ SPDLOG_INLINE log_msg_buffer::log_msg_buffer(const log_msg_buffer& other) :
+ log_msg{other}
+ {
+ buffer.append(logger_name.begin(), logger_name.end());
+ buffer.append(payload.begin(), payload.end());
+ update_string_views();
+ }
+
+ SPDLOG_INLINE log_msg_buffer::log_msg_buffer(log_msg_buffer&& other) SPDLOG_NOEXCEPT : log_msg{other}, buffer{std::move(other.buffer)}
+ {
+ update_string_views();
+ }
+
+ SPDLOG_INLINE log_msg_buffer& log_msg_buffer::operator=(const log_msg_buffer& other)
+ {
+ log_msg::operator=(other);
+ buffer.clear();
+ buffer.append(other.buffer.data(), other.buffer.data() + other.buffer.size());
+ update_string_views();
+ return *this;
+ }
+
+ SPDLOG_INLINE log_msg_buffer& log_msg_buffer::operator=(log_msg_buffer&& other) SPDLOG_NOEXCEPT
+ {
+ log_msg::operator=(other);
+ buffer = std::move(other.buffer);
+ update_string_views();
+ return *this;
+ }
+
+ SPDLOG_INLINE void log_msg_buffer::update_string_views()
+ {
+ logger_name = string_view_t{buffer.data(), logger_name.size()};
+ payload = string_view_t{buffer.data() + logger_name.size(), payload.size()};
+ }
+
+ } // namespace details
+} // namespace spdlog
diff --git a/CAPI/spdlog/include/spdlog/details/log_msg_buffer.h b/CAPI/spdlog/include/spdlog/details/log_msg_buffer.h
new file mode 100644
index 0000000..2a15b21
--- /dev/null
+++ b/CAPI/spdlog/include/spdlog/details/log_msg_buffer.h
@@ -0,0 +1,35 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#include