using System.Globalization;
using System.IO;
using System.Windows;
using System.Windows.Threading;
using Engine;
using Engine.Graphics;
using Engine.Graphics.Texture;
using Engine.Input;
using OpenTK.Mathematics;
using OpenTK.Windowing.Common;
using Serilog.Events;
namespace PresenterWpf;
///
/// Interaction logic for App.xaml
///
public partial class App : Application
{
// Hijack the default startup event to start the engine
protected override void OnStartup(StartupEventArgs parEventArgs)
{
var presenter = new PresenterWrapper();
var inputHandler = new InputHandlerWrapper();
var engine = new EngineBuilder()
.Headless()
.Presenter(_ => presenter)
.InputHandler(_ => inputHandler)
.LogToConsole()
.LogToFile(true, "log.txt")
.LogLevel(LogEventLevel.Debug)
.AssetFolder(Path.GetFullPath("./asset"))
.DataFolder(Path.GetFullPath("./data"))
.Build();
// Since engine claims current thread for rendering, we need to create a new thread to run WPF
var thread = new Thread(() =>
{
var window = new MainWindow();
presenter.Presenter = window;
inputHandler.InputHandler = new WpfInputHandler(window);
window.Show();
Dispatcher.Run();
});
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = true;
thread.Start();
DoomDeathmatch.DoomDeathmatch.Initialize(engine);
engine.Run();
// Shutdown WPF
Shutdown();
}
private class InputHandlerWrapper : IInputHandler
{
public IInputHandler? InputHandler { get; set; }
public CultureInfo CurrentInputLanguage => InputHandler?.CurrentInputLanguage ?? new CultureInfo(1033);
public Vector2 MousePosition => InputHandler?.MousePosition ?? Vector2.Zero;
public bool IsKeyPressed(KeyboardButtonCode parKeyboardButtonCode)
{
return InputHandler?.IsKeyPressed(parKeyboardButtonCode) ?? false;
}
public bool IsKeyJustPressed(KeyboardButtonCode parKeyboardButtonCode)
{
return InputHandler?.IsKeyJustPressed(parKeyboardButtonCode) ?? false;
}
public bool IsMouseButtonPressed(MouseButtonCode parButtonCode)
{
return InputHandler?.IsMouseButtonPressed(parButtonCode) ?? false;
}
public bool IsMouseButtonJustPressed(MouseButtonCode parButtonCode)
{
return InputHandler?.IsMouseButtonJustPressed(parButtonCode) ?? false;
}
public void Update(double parDeltaTime)
{
InputHandler?.Update(parDeltaTime);
}
}
private class PresenterWrapper : IPresenter
{
public event Action? OnResize;
public IPresenter? Presenter
{
get => _presenter;
set
{
if (_presenter != null)
{
_presenter.OnResize -= PresenterResize;
}
if (value != null)
{
value.OnResize += PresenterResize;
}
_presenter = value;
}
}
public int Width => Presenter?.Width ?? 0;
public int Height => Presenter?.Height ?? 0;
public bool IsExiting => Presenter?.IsExiting ?? false;
private IPresenter? _presenter;
public void Present(IConstTexture parTexture)
{
Presenter?.Present(parTexture);
}
public void Update(double parDeltaTime)
{
Presenter?.Update(parDeltaTime);
}
public void Render()
{
Presenter?.Render();
}
public void Exit()
{
Presenter?.Exit();
}
private void PresenterResize(ResizeEventArgs e)
{
OnResize?.Invoke(e);
}
}
}