Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 41 additions & 39 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -8,45 +8,47 @@
<WarningsAsErrors>true</WarningsAsErrors>
<NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>
<Choose>
<When Condition="$(MSBuildProjectName.EndsWith('Benchmarks'))">
<PropertyGroup>
<OutputType>Exe</OutputType>
<IsPackable>false</IsPackable>
<IsPublishable>false</IsPublishable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.15.8"/>
</ItemGroup>
</When>
<When Condition="$(MSBuildProjectName.EndsWith('Tests'))">
<PropertyGroup>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<IsPublishable>false</IsPublishable>
</PropertyGroup>
<!-- Для проектов Benchmarks -->

<PropertyGroup Condition="$(MSBuildProjectName.Contains('Benchmarks'))">
<IsPackable>false</IsPackable>
<IsPublishable>false</IsPublishable>
</PropertyGroup>

<ItemGroup Condition="$(MSBuildProjectName.Contains('Benchmarks'))">
<AssemblyAttribute Include="System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute"/>
</ItemGroup>

<ItemGroup Condition="$(MSBuildProjectName.EndsWith('Benchmarks'))">
<PackageReference Include="BenchmarkDotNet"/>
</ItemGroup>

<!-- Для проектов Tests -->
<PropertyGroup Condition="$(MSBuildProjectName.EndsWith('Tests'))">
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<IsPublishable>false</IsPublishable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AutoFixture.Xunit2" Version="4.18.1"/>
<PackageReference Include="FluentAssertions" Version="8.8.0"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1"/>
<PackageReference Include="Moq" Version="4.20.72"/>
<PackageReference Include="xunit" Version="2.9.3"/>
<PackageReference Include="JunitXml.TestLogger" Version="7.1.0"/>
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="coverlet.msbuild" Version="6.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="6.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</When>
</Choose>
<ItemGroup Condition="$(MSBuildProjectName.EndsWith('Tests'))">
<PackageReference Include="AutoFixture.Xunit2"/>
<PackageReference Include="FluentAssertions"/>
<PackageReference Include="Microsoft.NET.Test.Sdk"/>
<PackageReference Include="Moq"/>
<PackageReference Include="xunit"/>
<PackageReference Include="JunitXml.TestLogger"/>
<PackageReference Include="xunit.runner.visualstudio">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="coverlet.msbuild">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="coverlet.collector">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
31 changes: 31 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<CentralPackageVersionOverrideEnabled>true</CentralPackageVersionOverrideEnabled>
</PropertyGroup>

<ItemGroup>
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0"/>
</ItemGroup>

<ItemGroup>
<PackageVersion Include="MonoGame.Framework.DesktopGL" Version="3.8.4.1"/>
</ItemGroup>

<ItemGroup>
<PackageVersion Include="DefaultEcs" Version="0.17.2"/>
</ItemGroup>

<ItemGroup>
<PackageVersion Include="AutoFixture.Xunit2" Version="4.18.1"/>
<PackageVersion Include="BenchmarkDotNet" Version="0.15.8"/>
<PackageVersion Include="FluentAssertions" Version="8.8.0"/>
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.0.1"/>
<PackageVersion Include="Moq" Version="4.20.72"/>
<PackageVersion Include="xunit" Version="2.9.3"/>
<PackageVersion Include="JunitXml.TestLogger" Version="7.1.0"/>
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5"/>
<PackageVersion Include="coverlet.msbuild" Version="6.0.4"/>
<PackageVersion Include="coverlet.collector" Version="6.0.4"/>
</ItemGroup>
</Project>
23 changes: 18 additions & 5 deletions Hexecs.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hexecs.Tests", "src\Hexecs.
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hexecs.Benchmarks", "src\Hexecs.Benchmarks\Hexecs.Benchmarks.csproj", "{6B3B5C57-80EF-4CC7-A0CE-5533B7628FDB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hexecs.Benchmarks.MonoGame", "src\Hexecs.Benchmarks.MonoGame\Hexecs.Benchmarks.MonoGame.csproj", "{1F5BACA8-7AC3-48B4-9F28-532F7684C80B}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hexecs.Benchmarks.Noise", "src\Hexecs.Benchmarks.Noise\Hexecs.Benchmarks.Noise.csproj", "{0CA9A4D9-359D-4F10-8A45-DC3D1A3940AB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hexecs.Benchmarks.City", "src\Hexecs.Benchmarks.City\Hexecs.Benchmarks.City.csproj", "{B95D5C8E-90D4-4719-A6B4-81120C3BAD39}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Benchmarks", "Benchmarks", "{9BB142FC-044B-48F4-A183-5B2BA50E4658}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -25,9 +29,18 @@ Global
{6B3B5C57-80EF-4CC7-A0CE-5533B7628FDB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6B3B5C57-80EF-4CC7-A0CE-5533B7628FDB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6B3B5C57-80EF-4CC7-A0CE-5533B7628FDB}.Release|Any CPU.Build.0 = Release|Any CPU
{1F5BACA8-7AC3-48B4-9F28-532F7684C80B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1F5BACA8-7AC3-48B4-9F28-532F7684C80B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1F5BACA8-7AC3-48B4-9F28-532F7684C80B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1F5BACA8-7AC3-48B4-9F28-532F7684C80B}.Release|Any CPU.Build.0 = Release|Any CPU
{0CA9A4D9-359D-4F10-8A45-DC3D1A3940AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0CA9A4D9-359D-4F10-8A45-DC3D1A3940AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0CA9A4D9-359D-4F10-8A45-DC3D1A3940AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0CA9A4D9-359D-4F10-8A45-DC3D1A3940AB}.Release|Any CPU.Build.0 = Release|Any CPU
{B95D5C8E-90D4-4719-A6B4-81120C3BAD39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B95D5C8E-90D4-4719-A6B4-81120C3BAD39}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B95D5C8E-90D4-4719-A6B4-81120C3BAD39}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B95D5C8E-90D4-4719-A6B4-81120C3BAD39}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{6B3B5C57-80EF-4CC7-A0CE-5533B7628FDB} = {9BB142FC-044B-48F4-A183-5B2BA50E4658}
{B95D5C8E-90D4-4719-A6B4-81120C3BAD39} = {9BB142FC-044B-48F4-A183-5B2BA50E4658}
{0CA9A4D9-359D-4F10-8A45-DC3D1A3940AB} = {9BB142FC-044B-48F4-A183-5B2BA50E4658}
EndGlobalSection
EndGlobal
89 changes: 89 additions & 0 deletions src/Hexecs.Benchmarks.City/BenchmarkCounter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using System.Globalization;
using System.Text;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace Hexecs.Benchmarks.Map;

internal sealed class BenchmarkCounter
{
private readonly Func<int> _countResolver;
private readonly int[] _fpsHistory;

private double _frameTime;
private int _fps;
private int _frameCount;
private double _fpsTimer;

private int _historyIndex;
private bool _historyFull;
private double _avgFps;
private long _historySum;

private readonly SpriteFont _font;
private readonly SpriteBatch _spriteBatch;

// Используем StringBuilder как буфер
private readonly StringBuilder _stringBuilder = new(128);
private readonly Vector2 _textPos = new(10, 10);
private readonly Vector2 _shadowPos = new(11, 11);

public BenchmarkCounter(Func<int> countResolver, ContentManager contentManager, GraphicsDevice graphicsDevice)
{
_countResolver = countResolver;
_fpsHistory = new int[60];
_font = contentManager.Load<SpriteFont>("DebugFont");
_spriteBatch = new SpriteBatch(graphicsDevice);
}

public void Draw(GameTime gameTime)
{
_frameCount++;

_spriteBatch.Begin();

_spriteBatch.DrawString(_font, _stringBuilder, _shadowPos, Color.Black);
_spriteBatch.DrawString(_font, _stringBuilder, _textPos, Color.Yellow);

_spriteBatch.End();
}

public void Update(GameTime gameTime)
{
var elapsedSeconds = gameTime.ElapsedGameTime.TotalSeconds;
_frameTime = gameTime.ElapsedGameTime.TotalMilliseconds;
_fpsTimer += elapsedSeconds;

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code should not contain multiple blank lines in a row.

Suggested change

if (_fpsTimer >= 1.0)
{
_fps = _frameCount;

_historySum -= _fpsHistory[_historyIndex];
_fpsHistory[_historyIndex] = _fps;
_historySum += _fps;

_historyIndex = (_historyIndex + 1) % 60;
if (_historyIndex == 0) _historyFull = true;

var historyCount = _historyFull ? 60 : _historyIndex;
_avgFps = (double)_historySum / historyCount;

var alloc = GC.GetTotalMemory(false) / 1024.0 / 1024.0;
var count = _countResolver();

// Очищаем буфер и записываем новые данные без создания строк
var culture = CultureInfo.InvariantCulture;

_stringBuilder.Clear();
_stringBuilder
.Append($"{_fps} FPS")
.Append(culture, $" | Avg:{_avgFps:F1} fps")
.Append(culture, $" | Entities:{count:N0}")
.Append(culture, $" | Frame time:{_frameTime:F1}ms")
.Append(culture, $" | Alloc:{alloc:F3}mb");

_frameCount = 0;
_fpsTimer = 0;
}
}
}
102 changes: 102 additions & 0 deletions src/Hexecs.Benchmarks.City/CityGame.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
using Hexecs.Benchmarks.Map.Common;
using Hexecs.Benchmarks.Map.Common.Visibles;
using Hexecs.Benchmarks.Map.Terrains;
using Hexecs.Benchmarks.Map.Terrains.Commands.Generate;
using Hexecs.Benchmarks.Map.Utils;
using Hexecs.Worlds;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace Hexecs.Benchmarks.Map;

internal sealed class CityGame : Game
{
private BenchmarkCounter _benchmarkCounter = null!;
private Camera _camera = null!;
private readonly GraphicsDeviceManager _graphics;
private World _world = null!;

public CityGame()
{
_graphics = new GraphicsDeviceManager(this)
{
PreferredBackBufferWidth = 1280,
PreferredBackBufferHeight = 720,
GraphicsProfile = GraphicsProfile.HiDef,
PreferMultiSampling = true,
SynchronizeWithVerticalRetrace = true,
IsFullScreen = false,
HardwareModeSwitch = false
};

// Включаем поддержку сглаживания для устройства
_graphics.PreparingDeviceSettings += (_, e) =>
{
e.GraphicsDeviceInformation.PresentationParameters.MultiSampleCount = 8; // 8x MSAA
};

_graphics.ApplyChanges();

IsFixedTimeStep = false;
Content.RootDirectory = "Content";
}

protected override void Initialize()
{
GraphicsDevice.SamplerStates[0] = SamplerState.AnisotropicClamp;

_camera = new Camera(GraphicsDevice);
_world = new WorldBuilder()
.UseDefaultParallelWorker(Math.Min(6, Environment.ProcessorCount))
.UseSingleton(Content)
.UseSingleton(GraphicsDevice)
.UseSingleton(_camera)
.UseTerrain()
.UseDefaultActorContext(context => context
.Capacity(3_000_000)
.AddCommon()
.AddTerrain()
.AddVisible())
.Build();

_world.Actors.Execute(new GenerateTerrainCommand());

_benchmarkCounter = new BenchmarkCounter(() => _world.Actors.Length, Content, GraphicsDevice);

base.Initialize();
}

protected override void Dispose(bool disposing)
{
if (disposing)
{
_world.Dispose();
}

base.Dispose(disposing);
}

protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.White);

_world.Draw(gameTime.ElapsedGameTime, gameTime.TotalGameTime);
_benchmarkCounter.Draw(gameTime);

base.Draw(gameTime);
}

protected override void Update(GameTime gameTime)
{
var keyboard = Keyboard.GetState();
if (keyboard.IsKeyDown(Keys.Space))
{
}

_camera.Update(gameTime);
_benchmarkCounter.Update(gameTime);
_world.Update(gameTime.ElapsedGameTime, gameTime.TotalGameTime);

base.Update(gameTime);
}
}
13 changes: 13 additions & 0 deletions src/Hexecs.Benchmarks.City/Common/CommonInstaller.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Hexecs.Benchmarks.Map.Common.Positions;

namespace Hexecs.Benchmarks.Map.Common;

internal static class CommonInstaller
{
public static ActorContextBuilder AddCommon(this ActorContextBuilder builder)
{
builder.AddPositions();

return builder;
}
}
7 changes: 7 additions & 0 deletions src/Hexecs.Benchmarks.City/Common/Positions/Position.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Hexecs.Benchmarks.Map.Common.Positions;

public struct Position : IActorComponent
{
public Point Grid;
public Point World;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace Hexecs.Benchmarks.Map.Common.Positions;

public readonly struct PositionAbility: IAssetComponent;
Loading