Changed to custom logging solution.

This commit is contained in:
Harrison Deng 2020-07-04 18:41:06 -05:00
parent 30d7221a85
commit b744ae653c
13 changed files with 226 additions and 133 deletions

View File

@ -2,11 +2,10 @@ using System;
using System.Runtime.InteropServices;
using System.Threading;
using SDL2;
using Serilog;
using Serilog.Core;
using SlatedGameToolkit.Framework.Exceptions;
using SlatedGameToolkit.Framework.Graphics.Window;
using SlatedGameToolkit.Framework.Input.Devices;
using SlatedGameToolkit.Framework.Logging;
using SlatedGameToolkit.Framework.StateSystem;
using SlatedGameToolkit.Framework.StateSystem.States;
@ -17,7 +16,6 @@ namespace SlatedGameToolkit.Framework {
public static class GameEngine {
private const int GL_MAJOR_VER = 3, GL_MINOR_VER = 3;
public static bool Debugging { get; set; }
public static Logger Logger { get; private set; }
private static readonly object ignitionLock = new object();
private static readonly object deltaUpdateLock = new object();
private static Thread thread;
@ -78,120 +76,113 @@ namespace SlatedGameToolkit.Framework {
private static void Loop(Object o) {
if (!(o is IState)) throw new InternalFrameworkException(String.Format("Expected initial state object for asynchronous loop. Got {0}", o));
StateManager manager = new StateManager();
try {
IState initialState = (IState) o;
manager.Initialize(initialState);
DateTime previousTime = DateTime.Now;
TimeSpan timePassedFromLastUpdate = TimeSpan.Zero;
TimeSpan timePassedFromLastRender = TimeSpan.Zero;
TimeSpan updateDeltaTime = GameEngine.updateDeltaTime;
TimeSpan frameDeltaTime = GameEngine.frameDeltaTime;
deltaChanged = true;
stopped = false;
Logger.Information("Game engine initiated.");
while (!exit) {
//Pull latest deltas.
if (deltaChanged) {
lock (deltaUpdateLock) {
updateDeltaTime = GameEngine.updateDeltaTime;
frameDeltaTime = GameEngine.frameDeltaTime;
Logger.Information(String.Format("Deltas were set. Update Delta: {0}, Render target Delta: {1}", updateDeltaTime.TotalSeconds, frameDeltaTime.TotalSeconds));
}
deltaChanged = false;
IState initialState = (IState) o;
manager.Initialize(initialState);
DateTime previousTime = DateTime.Now;
TimeSpan timePassedFromLastUpdate = TimeSpan.Zero;
TimeSpan timePassedFromLastRender = TimeSpan.Zero;
TimeSpan updateDeltaTime = GameEngine.updateDeltaTime;
TimeSpan frameDeltaTime = GameEngine.frameDeltaTime;
deltaChanged = true;
stopped = false;
Logger.Log("Game engine initiated.");
while (!exit) {
//Pull latest deltas.
if (deltaChanged) {
lock (deltaUpdateLock) {
updateDeltaTime = GameEngine.updateDeltaTime;
frameDeltaTime = GameEngine.frameDeltaTime;
Logger.Log(String.Format("Deltas were set. Update Delta: {0}, Render target Delta: {1}", updateDeltaTime.TotalSeconds, frameDeltaTime.TotalSeconds));
}
#region EventHandling
//Events
SDL.SDL_Event SDL_Event;
while (SDL.SDL_PollEvent(out SDL_Event) != 0) {
switch (SDL_Event.type) {
case SDL.SDL_EventType.SDL_MOUSEMOTION:
Mouse.OnMouseMoved(SDL_Event.motion.x, SDL_Event.motion.y);
break;
case SDL.SDL_EventType.SDL_MOUSEWHEEL:
Mouse.OnScroll(SDL_Event.wheel.x, SDL_Event.wheel.y);
break;
case SDL.SDL_EventType.SDL_MOUSEBUTTONDOWN:
if (SDL.SDL_BUTTON_LEFT == SDL_Event.button.button) {
Mouse.OnLeftChange(true);
} else if (SDL.SDL_BUTTON_RIGHT == SDL_Event.button.button) {
Mouse.OnRightChange(true);
} else if (SDL.SDL_BUTTON_MIDDLE == SDL_Event.button.button) {
Mouse.OnMiddleChange(true);
}
break;
case SDL.SDL_EventType.SDL_MOUSEBUTTONUP:
if (SDL.SDL_BUTTON_LEFT == SDL_Event.button.button) {
Mouse.OnLeftChange(false);
} else if (SDL.SDL_BUTTON_RIGHT == SDL_Event.button.button) {
Mouse.OnRightChange(false);
} else if (SDL.SDL_BUTTON_MIDDLE == SDL_Event.button.button) {
Mouse.OnMiddleChange(false);
}
break;
case SDL.SDL_EventType.SDL_KEYDOWN:
Keyboard.OnKeyPressed(SDL_Event.key.keysym.sym);
break;
case SDL.SDL_EventType.SDL_KEYUP:
Keyboard.OnKeyReleased(SDL_Event.key.keysym.sym);
break;
case SDL.SDL_EventType.SDL_WINDOWEVENT:
WindowContext handle = WindowContextsManager.ContextFromWindowID(SDL_Event.window.windowID);
switch (SDL_Event.window.windowEvent)
{
case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_SIZE_CHANGED:
handle.OnResize(SDL_Event.window.data1, SDL_Event.window.data2);
break;
case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_FOCUS_LOST:
handle.OnFocusLost();
break;
case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_FOCUS_GAINED:
handle.OnFocusGained();
break;
}
deltaChanged = false;
}
#region EventHandling
//Events
SDL.SDL_Event SDL_Event;
while (SDL.SDL_PollEvent(out SDL_Event) != 0) {
switch (SDL_Event.type) {
case SDL.SDL_EventType.SDL_MOUSEMOTION:
Mouse.OnMouseMoved(SDL_Event.motion.x, SDL_Event.motion.y);
break;
case SDL.SDL_EventType.SDL_MOUSEWHEEL:
Mouse.OnScroll(SDL_Event.wheel.x, SDL_Event.wheel.y);
break;
case SDL.SDL_EventType.SDL_MOUSEBUTTONDOWN:
if (SDL.SDL_BUTTON_LEFT == SDL_Event.button.button) {
Mouse.OnLeftChange(true);
} else if (SDL.SDL_BUTTON_RIGHT == SDL_Event.button.button) {
Mouse.OnRightChange(true);
} else if (SDL.SDL_BUTTON_MIDDLE == SDL_Event.button.button) {
Mouse.OnMiddleChange(true);
}
break;
case SDL.SDL_EventType.SDL_MOUSEBUTTONUP:
if (SDL.SDL_BUTTON_LEFT == SDL_Event.button.button) {
Mouse.OnLeftChange(false);
} else if (SDL.SDL_BUTTON_RIGHT == SDL_Event.button.button) {
Mouse.OnRightChange(false);
} else if (SDL.SDL_BUTTON_MIDDLE == SDL_Event.button.button) {
Mouse.OnMiddleChange(false);
}
break;
case SDL.SDL_EventType.SDL_KEYDOWN:
Keyboard.OnKeyPressed(SDL_Event.key.keysym.sym);
break;
case SDL.SDL_EventType.SDL_KEYUP:
Keyboard.OnKeyReleased(SDL_Event.key.keysym.sym);
break;
case SDL.SDL_EventType.SDL_WINDOWEVENT:
WindowContext handle = WindowContextsManager.ContextFromWindowID(SDL_Event.window.windowID);
switch (SDL_Event.window.windowEvent)
{
case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_SIZE_CHANGED:
handle.OnResize(SDL_Event.window.data1, SDL_Event.window.data2);
break;
case SDL.SDL_EventType.SDL_QUIT:
Stop();
case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_FOCUS_LOST:
handle.OnFocusLost();
break;
case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_FOCUS_GAINED:
handle.OnFocusGained();
break;
}
break;
}
}
#endregion
DateTime frameStart = DateTime.Now;
TimeSpan difference = frameStart - previousTime;
previousTime = frameStart;
timePassedFromLastUpdate += difference;
while (timePassedFromLastUpdate > updateDeltaTime) {
//Updates.
manager.update(updateDeltaTime.TotalSeconds <= 0 ? timePassedFromLastUpdate.TotalSeconds : updateDeltaTime.TotalSeconds);
timePassedFromLastUpdate -= updateDeltaTime;
if (updateDeltaTime.TotalSeconds <= 0) {
timePassedFromLastUpdate = TimeSpan.Zero;
break;
}
}
timePassedFromLastRender += difference;
if (timePassedFromLastRender > frameDeltaTime) {
//Draw calls.
manager.render(updateDeltaTime.TotalSeconds <= 0 ? updateDeltaTime.TotalSeconds : (timePassedFromLastUpdate / updateDeltaTime));
timePassedFromLastRender = TimeSpan.Zero;
} else {
Thread.Yield();
case SDL.SDL_EventType.SDL_QUIT:
Stop();
break;
}
}
} catch (Exception e) {
Logger.Fatal(e.ToString());
throw e;
} finally {
stopped = true;
manager.Dispose();
SDL.SDL_Quit();
Logger.Information("Game engine has stopped.");
Logger.Dispose();
WindowContextsManager.DisposeAllWindowContexts();
Logger = null;
#endregion
DateTime frameStart = DateTime.Now;
TimeSpan difference = frameStart - previousTime;
previousTime = frameStart;
timePassedFromLastUpdate += difference;
while (timePassedFromLastUpdate > updateDeltaTime) {
//Updates.
manager.update(updateDeltaTime.TotalSeconds <= 0 ? timePassedFromLastUpdate.TotalSeconds : updateDeltaTime.TotalSeconds);
timePassedFromLastUpdate -= updateDeltaTime;
if (updateDeltaTime.TotalSeconds <= 0) {
timePassedFromLastUpdate = TimeSpan.Zero;
break;
}
}
timePassedFromLastRender += difference;
if (timePassedFromLastRender > frameDeltaTime) {
//Draw calls.
manager.render(updateDeltaTime.TotalSeconds <= 0 ? updateDeltaTime.TotalSeconds : (timePassedFromLastUpdate / updateDeltaTime));
timePassedFromLastRender = TimeSpan.Zero;
} else {
Thread.Yield();
}
}
stopped = true;
manager.Dispose();
SDL.SDL_Quit();
WindowContextsManager.DisposeAllWindowContexts();
Logger.Log("Game engine has gracefully stopped.");
Logger.FlushListeners();
}
/// <summary>
@ -216,21 +207,18 @@ namespace SlatedGameToolkit.Framework {
lock (ignitionLock) {
if (initialState == null) throw new ArgumentNullException("initialState");
if (!stopped) {
Logger.Warning("Engine is already running.");
Logger.Log("Engine is already running.", LogLevel.WARNING);
return false;
}
GameEngine.Logger = new LoggerConfiguration().MinimumLevel.Debug().
WriteTo.File("SlatedGameToolKit.log", fileSizeLimitBytes: 1048576, rollOnFileSizeLimit: true).
CreateLogger();
SDL.SDL_version SDLVersion;
SDL.SDL_version SDLBuiltVersion;
SDL.SDL_GetVersion(out SDLVersion);
SDL.SDL_VERSION(out SDLBuiltVersion);
Logger.Information(String.Format("Attempting to initiate game engine with SDL version: {0}.{1}.{2}", SDLVersion.major, SDLVersion.minor, SDLVersion.patch));
Logger.Log(String.Format("Attempting to initiate game engine with SDL version: {0}.{1}.{2}", SDLVersion.major, SDLVersion.minor, SDLVersion.patch));
if (!SDL.SDL_VERSION_ATLEAST(SDLBuiltVersion.major, SDLBuiltVersion.minor, SDLBuiltVersion.patch)) {
Logger.Warning(String.Format("Engine was designed with SDL version {0}.{1}.{2}, currently running on {3}.{4}.{5}", SDLBuiltVersion.major, SDLBuiltVersion.minor, SDLBuiltVersion.patch, SDLVersion.major, SDLVersion.minor, SDLVersion.patch));
Logger.Log(String.Format("Engine was designed with SDL version {0}.{1}.{2}, currently running on {3}.{4}.{5}", SDLBuiltVersion.major, SDLBuiltVersion.minor, SDLBuiltVersion.patch, SDLVersion.major, SDLVersion.minor, SDLVersion.patch), LogLevel.WARNING);
if (SDLVersion.major < 2) {
Logger.Error("This engine was designed to work with SDL2. The version you're currently running is severely outdated.");
Logger.Log("This engine was designed to work with SDL2. The version you're currently running is severely outdated.", LogLevel.FATAL);
throw new FrameworkUsageException("Outdated SDL binaries.");
}
}

View File

@ -6,6 +6,7 @@ using SDL2;
using SlatedGameToolkit.Framework.Exceptions;
using SlatedGameToolkit.Framework.Graphics;
using SlatedGameToolkit.Framework.Graphics.OpenGL;
using SlatedGameToolkit.Framework.Logging;
namespace SlatedGameToolkit.Framework.Graphics.Window
{
@ -256,7 +257,7 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
/// Instantiates a window with the given OpenGL context, or a new context.
/// </summary>
public WindowContext(string title, int x = -1, int y = -1, int width = 640, int height = 480, bool specialRegions = false, SDL.SDL_WindowFlags options = default(SDL.SDL_WindowFlags)) {
GameEngine.Logger.Information(String.Format("Starting openGL window with title \"{0}\"", title));
Logger.Log(String.Format("Starting openGL window with title \"{0}\"", title));
windowHandle = SDL.SDL_CreateWindow(title, x < 0 ? SDL.SDL_WINDOWPOS_CENTERED : x, y < 0 ? SDL.SDL_WINDOWPOS_CENTERED : y, width, height, SDL.SDL_WindowFlags.SDL_WINDOW_INPUT_FOCUS | SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL | SDL.SDL_WindowFlags.SDL_WINDOW_MOUSE_FOCUS | options);
if (windowHandle == null) {
throw new FrameworkSDLException();

View File

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using SlatedGameToolkit.Framework.Graphics.OpenGL;
using SlatedGameToolkit.Framework.Logging;
namespace SlatedGameToolkit.Framework.Graphics.Window
{
@ -44,12 +45,12 @@ namespace SlatedGameToolkit.Framework.Graphics.Window
}
internal static void RegisterWindow(WindowContext windowHandle) {
GameEngine.Logger.Debug("Registering window: " + windowHandle.WindowID);
Logger.Log("Registering window: " + windowHandle.WindowID, LogLevel.DEBUG);
existingWindows.Add(windowHandle.WindowID, windowHandle);
}
internal static void DeregisterWindow(WindowContext windowHandle) {
GameEngine.Logger.Debug("Deregistering window: " + windowHandle.WindowID);
Logger.Log("Deregistering window: " + windowHandle.WindowID, LogLevel.DEBUG);
existingWindows.Remove(windowHandle.WindowID);
}

View File

@ -0,0 +1,17 @@
using System;
namespace SlatedGameToolkit.Framework.Logging
{
public interface ILogListener
{
LogLevel Level { get; }
/// <summary>
/// Logs the message.
/// </summary>
/// <param name="message">The message to be logged.</param>
/// <param name="time">The time at which this message was requested to be logged.</param>
/// <param name="level">The severity of this message.</param>
void LogMesesage(string message, DateTime time, LogLevel level);
}
}

View File

@ -0,0 +1,10 @@
namespace SlatedGameToolkit.Framework.Logging
{
public enum LogLevel
{
FATAL,
INFO,
DEBUG,
WARNING,
}
}

View File

@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
namespace SlatedGameToolkit.Framework.Logging
{
public static class Logger {
private static HashSet<ILogListener> listeners = new HashSet<ILogListener>();
/// <summary>
/// Logs the message to listeners that are listening to the set severity of the message or greater.
/// </summary>
/// <param name="message">The message to log.</param>
/// <param name="level">The level of severity, by defeault, info.</param>
public static void Log(string message, LogLevel level = LogLevel.INFO) {
foreach (ILogListener listener in listeners)
{
if (level <= listener.Level) {
listener.LogMesesage(message, DateTime.Now, level);
}
}
}
/// <summary>
/// Adds a log listener.
/// </summary>
/// <param name="listener">The listener to add.</param>
public static void AddLogListener(ILogListener listener) {
listeners.Add(listener);
}
/// <summary>
/// Removes a log listener.
/// </summary>
/// <param name="listener">The listener to remove.</param>
public static void RemoveLogListener(ILogListener listener) {
listeners.Remove(listener);
}
/// <summary>
/// Called when all listeners should perform any flushing they need.
/// </summary>
public static void FlushListeners() {
}
}
}

View File

@ -7,8 +7,6 @@
<ItemGroup>
<PackageReference Include="StbTrueTypeSharp" Version="1.24.6" />
<PackageReference Include="Serilog" Version="2.9.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
</ItemGroup>
<ItemGroup>

View File

@ -7,6 +7,7 @@ using SlatedGameToolkit.Framework.StateSystem.States;
using SlatedGameToolkit.Framework.Utilities;
using SlatedGameToolkit.Framework.Graphics;
using SlatedGameToolkit.Framework.Graphics.OpenGL;
using SlatedGameToolkit.Framework.Logging;
namespace SlatedGameToolkit.Framework.StateSystem
{
@ -92,7 +93,7 @@ namespace SlatedGameToolkit.Framework.StateSystem
public bool addState(IState state) {
if (thread != Thread.CurrentThread) throw new ThreadStateException("Cannot add a state from a different thread.");
try {
GameEngine.Logger.Debug("Adding state: " + state.getName());
Logger.Log("Adding state: " + state.getName(), LogLevel.WARNING);
this.states.Add(state.getName(), state);
} catch (ArgumentException) {
return false;
@ -112,12 +113,12 @@ namespace SlatedGameToolkit.Framework.StateSystem
if (thread != Thread.CurrentThread) throw new ThreadStateException("Cannot remove a state from a different thread.");
if (states[name] == currentState) return false;
IState state = states[name];
GameEngine.Logger.Debug("Removing state: " + name);
Logger.Log("Removing state: " + name, LogLevel.DEBUG);
try {
state.Deinitialize();
} catch (Exception e) {
GameEngine.Logger.Error(e.ToString());
GameEngine.Logger.Error("Failed to deinitialize state: " + state.getName());
Logger.Log(e.ToString(), LogLevel.WARNING);
Logger.Log("Failed to deinitialize state: " + state.getName(), LogLevel.WARNING);
}
return states.Remove(name);
}
@ -127,12 +128,12 @@ namespace SlatedGameToolkit.Framework.StateSystem
/// Disposes of the removed states.
/// </summary>
public void removeAllStates() {
GameEngine.Logger.Debug("Beginning to remove all states...");
Logger.Log("Beginning to remove all states...", LogLevel.DEBUG);
foreach (String state in this.states.Keys)
{
removeState(state);
}
GameEngine.Logger.Debug("Completed removing all states...");
Logger.Log("Completed removing all states...", LogLevel.DEBUG);
}
public void Dispose()

View File

@ -1,28 +1,47 @@
using System;
using SlatedGameToolkit.Framework.Logging;
namespace SlatedGameToolkit.Tools.CommandSystem.Interaction
{
public class ConsoleInteraction : IInteractable
public class ConsoleInteraction : IInteractable, ILogListener
{
private volatile bool listening;
string prefix;
public bool Debug { get; set; }
public LogLevel Level => Debug ? LogLevel.DEBUG : LogLevel.INFO;
public ConsoleInteraction(string prefix) {
this.prefix = prefix;
}
public void Separate()
{
listening = false;
Console.WriteLine();
}
public string Listen()
{
listening = true;
Console.Write(prefix + "> ");
return Console.ReadLine();
}
public void Tell(string message)
{
listening = false;
Console.SetCursorPosition(0, Console.CursorTop);
Console.WriteLine(message);
}
public void LogMesesage(string message, DateTime time, LogLevel level)
{
Console.SetCursorPosition(0, Console.CursorTop);
Console.WriteLine(string.Format("Playground [{0}] [{1}]: {2}", level, time.ToString("H:mm:ss"), message));
if (listening) {
Console.SetCursorPosition(0, Console.CursorTop);
Console.Write(prefix + "> ");
}
}
}
}

View File

@ -1,6 +1,8 @@
using SlatedGameToolkit.Framework.Logging;
namespace SlatedGameToolkit.Tools.CommandSystem.Interaction
{
public interface IInteractable
public interface IInteractable : ILogListener
{
void Tell(string message);
void Separate();

View File

@ -1,4 +1,5 @@
using System;
using SlatedGameToolkit.Framework.Logging;
using SlatedGameToolkit.Tools.CommandSystem.Exceptions;
namespace SlatedGameToolkit.Tools.CommandSystem.Interaction
@ -10,6 +11,9 @@ namespace SlatedGameToolkit.Tools.CommandSystem.Interaction
public SingleConsoleInteraction(string oneTime) {
this.oneTime = oneTime;
}
public LogLevel Level => LogLevel.DEBUG;
public string Listen()
{
if (interacted) throw new FatalUsageException("Command attempted to request for more information. This generally occurs if the command being ran requires more user input.");
@ -17,6 +21,12 @@ namespace SlatedGameToolkit.Tools.CommandSystem.Interaction
return oneTime;
}
public void LogMesesage(string message, DateTime time, LogLevel level)
{
Console.SetCursorPosition(0, Console.CursorTop);
Console.WriteLine(string.Format("Game Engine [{0}] [{1}]: \n{2}", level, time.ToString(), message));
}
public void Separate()
{
Console.WriteLine();

View File

@ -1,4 +1,5 @@
using SlatedGameToolkit.Framework;
using SlatedGameToolkit.Framework.Logging;
using SlatedGameToolkit.Framework.StateSystem;
using SlatedGameToolkit.Tools.CommandSystem;
using SlatedGameToolkit.Tools.CommandSystem.Interaction;
@ -19,7 +20,7 @@ namespace SlatedGameToolkit.Tools.Commands
interactable.Tell("Engine is already running!");
return true;
}
Logger.AddLogListener(interactable);
GameEngine.Ignite(new MainState());
return true;
} else if (args[0].Equals("stop")) {

View File

@ -28,7 +28,6 @@ namespace SlatedGameToolkit.Tools
interactable.Tell("Welcome to SlatedGameToolkit.Tools! These tools are meant for the developers using the SlatedGameToolkit. Type \"help\" for a list of things this tool can currently do.");
live = true;
while (live) {
interactable.Separate();
processor.Process(interactable);
}
}