Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MonoGame support #105

Merged
merged 5 commits into from
Feb 16, 2024
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
13 changes: 13 additions & 0 deletions R3.sln
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MauiApp1", "sandbox\MauiApp
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "R3.Maui", "src\R3.Maui\R3.Maui.csproj", "{F1D6609C-AA33-4099-8932-BADBCB935FBD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoGameApplication1", "sandbox\MonoGameApplication1\MonoGameApplication1.csproj", "{BEF76A77-E2F9-4113-8DC2-DB825964D6EF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "R3.MonoGame", "src\R3.MonoGame\R3.MonoGame.csproj", "{D754069D-C912-4D71-97CB-9B2DDD2380B4}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "R3.WinUI3", "src\R3.WinUI3\R3.WinUI3.csproj", "{87F12DBB-E32B-49B8-B5F1-5B53B711989B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinUI3App1", "sandbox\WinUI3App1\WinUI3App1.csproj", "{CDC17599-81AD-44B9-B4E5-38241147CDA2}"
Expand Down Expand Up @@ -319,6 +322,14 @@ Global
{F1D6609C-AA33-4099-8932-BADBCB935FBD}.Debug|x86.Build.0 = Debug|Any CPU
{F1D6609C-AA33-4099-8932-BADBCB935FBD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F1D6609C-AA33-4099-8932-BADBCB935FBD}.Release|Any CPU.Build.0 = Release|Any CPU
{BEF76A77-E2F9-4113-8DC2-DB825964D6EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BEF76A77-E2F9-4113-8DC2-DB825964D6EF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BEF76A77-E2F9-4113-8DC2-DB825964D6EF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BEF76A77-E2F9-4113-8DC2-DB825964D6EF}.Release|Any CPU.Build.0 = Release|Any CPU
{D754069D-C912-4D71-97CB-9B2DDD2380B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D754069D-C912-4D71-97CB-9B2DDD2380B4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D754069D-C912-4D71-97CB-9B2DDD2380B4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D754069D-C912-4D71-97CB-9B2DDD2380B4}.Release|Any CPU.Build.0 = Release|Any CPU
{F1D6609C-AA33-4099-8932-BADBCB935FBD}.Release|ARM64.ActiveCfg = Release|Any CPU
{F1D6609C-AA33-4099-8932-BADBCB935FBD}.Release|ARM64.Build.0 = Release|Any CPU
{F1D6609C-AA33-4099-8932-BADBCB935FBD}.Release|x64.ActiveCfg = Release|Any CPU
Expand Down Expand Up @@ -386,6 +397,8 @@ Global
{B95D732A-7538-4795-AC42-6F595ECB8DB8} = {9FA6D327-728B-4436-AE3A-9E46D8FEF591}
{2CD257D7-DF21-4D60-AC05-747D83236E5A} = {FAB2137C-1DBA-4F2F-8E22-DF3521C9B365}
{F1D6609C-AA33-4099-8932-BADBCB935FBD} = {9FA6D327-728B-4436-AE3A-9E46D8FEF591}
{BEF76A77-E2F9-4113-8DC2-DB825964D6EF} = {FAB2137C-1DBA-4F2F-8E22-DF3521C9B365}
{D754069D-C912-4D71-97CB-9B2DDD2380B4} = {9FA6D327-728B-4436-AE3A-9E46D8FEF591}
{87F12DBB-E32B-49B8-B5F1-5B53B711989B} = {9FA6D327-728B-4436-AE3A-9E46D8FEF591}
{CDC17599-81AD-44B9-B4E5-38241147CDA2} = {FAB2137C-1DBA-4F2F-8E22-DF3521C9B365}
EndGlobalSection
Expand Down
829 changes: 438 additions & 391 deletions README.md

Large diffs are not rendered by default.

36 changes: 36 additions & 0 deletions sandbox/MonoGameApplication1/.config/dotnet-tools.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-mgcb": {
"version": "3.8.1.303",
"commands": [
"mgcb"
]
},
"dotnet-mgcb-editor": {
"version": "3.8.1.303",
"commands": [
"mgcb-editor"
]
},
"dotnet-mgcb-editor-linux": {
"version": "3.8.1.303",
"commands": [
"mgcb-editor-linux"
]
},
"dotnet-mgcb-editor-windows": {
"version": "3.8.1.303",
"commands": [
"mgcb-editor-windows"
]
},
"dotnet-mgcb-editor-mac": {
"version": "3.8.1.303",
"commands": [
"mgcb-editor-mac"
]
}
}
}
15 changes: 15 additions & 0 deletions sandbox/MonoGameApplication1/Content/Content.mgcb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

#----------------------------- Global Properties ----------------------------#

/outputDir:bin/$(Platform)
/intermediateDir:obj/$(Platform)
/platform:DesktopGL
/config:
/profile:Reach
/compress:False

#-------------------------------- References --------------------------------#


#---------------------------------- Content ---------------------------------#

80 changes: 80 additions & 0 deletions sandbox/MonoGameApplication1/Game1.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using R3;

namespace MonoGameApplication1;

class SampleComponent : GameComponent
{
public SampleComponent(Game game) : base(game)
{
}

public override void Initialize()
{
Observable.Interval(TimeSpan.FromMilliseconds(500))
.GameTime()
.Subscribe(x =>
{
Console.WriteLine($"ElapsedGameTime={x.ElapsedGameTime} TotalGameTime={x.TotalGameTime}");
});

Observable.IntervalFrame(10)
.Subscribe(x =>
{
Console.WriteLine($"Frame: {ObservableSystem.DefaultFrameProvider.GetFrameCount()}");
});
}
}

public class Game1 : Game
{
private GraphicsDeviceManager _graphics;
private SpriteBatch _spriteBatch;

public Game1()
{
_graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;

Components.Add(new ObservableSystemComponent(this));
Components.Add(new SampleComponent(this));
}

protected override void Initialize()
{
// TODO: Add your initialization logic here

base.Initialize();
}

protected override void LoadContent()
{
_spriteBatch = new SpriteBatch(GraphicsDevice);

// TODO: use this.Content to load your game content here
}

protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed ||
Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();

// TODO: Add your update logic here

base.Update(gameTime);
}

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

// TODO: Add your drawing code here

base.Draw(gameTime);
}
}
Binary file added sandbox/MonoGameApplication1/Icon.bmp
Binary file not shown.
Binary file added sandbox/MonoGameApplication1/Icon.ico
Binary file not shown.
32 changes: 32 additions & 0 deletions sandbox/MonoGameApplication1/MonoGameApplication1.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<RollForward>Major</RollForward>
<PublishReadyToRun>false</PublishReadyToRun>
<TieredCompilation>false</TieredCompilation>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
<ApplicationIcon>Icon.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<None Remove="Icon.ico"/>
<None Remove="Icon.bmp"/>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Icon.ico"/>
<EmbeddedResource Include="Icon.bmp"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.1.303"/>
<PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.1.303"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\R3.MonoGame\R3.MonoGame.csproj" />
</ItemGroup>
<Target Name="RestoreDotnetTools" BeforeTargets="Restore">
<Message Text="Restoring dotnet tools" Importance="High"/>
<Exec Command="dotnet tool restore"/>
</Target>
</Project>
2 changes: 2 additions & 0 deletions sandbox/MonoGameApplication1/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
using var game = new MonoGameApplication1.Game1();
game.Run();
43 changes: 43 additions & 0 deletions sandbox/MonoGameApplication1/app.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MonoGameApplication1"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>

<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- A list of the Windows versions that this application has been tested on and is
is designed to work with. Uncomment the appropriate elements and Windows will
automatically selected the most compatible environment. -->

<!-- Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />

<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />

<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />

<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />

<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />

</application>
</compatibility>

<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">permonitorv2,permonitor</dpiAwareness>
</windowsSettings>
</application>

</assembly>
90 changes: 90 additions & 0 deletions src/R3.MonoGame/MonoGameFrameProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using System;
using R3.Collections;

namespace R3;

public class MonoGameFrameProvider : FrameProvider
{
public static readonly MonoGameFrameProvider Update = new();

readonly object gate = new();
FreeListCore<IFrameRunnerWorkItem> list;
long frameCount;
bool disposed;

// frame loop is delayed until first register
bool running;

public MonoGameFrameProvider()
{
list = new FreeListCore<IFrameRunnerWorkItem>(gate);
}

public override long GetFrameCount()
{
ThrowIfDisposed();
return frameCount;
}

public override void Register(IFrameRunnerWorkItem callback)
{
ThrowIfDisposed();
lock (gate)
{
running = true;
list.Add(callback, out _);
}
}

public void Dispose()
{
lock (gate)
{
disposed = true;
list.Dispose();
}
}

public void Tick()
{
if (!running) return;

frameCount++;

var span = list.AsSpan();
for (int i = 0; i < span.Length; i++)
{
ref readonly var item = ref span[i];
if (item != null)
{
try
{
if (!item.MoveNext(frameCount))
{
list.Remove(i);
}
}
catch (Exception ex)
{
list.Remove(i);
try
{
ObservableSystem.GetUnhandledExceptionHandler().Invoke(ex);
}
catch
{
// ignored
}
}
}
}
}

void ThrowIfDisposed()
{
if (disposed)
{
throw new ObjectDisposedException(typeof(MonoGameFrameProvider).FullName);
}
}
}
Loading