diff --git a/GlitchyEngine/src/Application.bf b/GlitchyEngine/src/Application.bf index 16585d0..7067c60 100644 --- a/GlitchyEngine/src/Application.bf +++ b/GlitchyEngine/src/Application.bf @@ -1,96 +1,99 @@ -using System; -using GlitchyEngine.Events; -using GlitchyEngine.ImGui; -using GlitchyEngine.Renderer; - -namespace GlitchyEngine -{ - public class Application - { - static Application s_Instance = null; - - private Window _window ~ delete _; - private RendererAPI _rendererApi ~ delete _; - private bool _running = true; - - private LayerStack _layerStack = new LayerStack() ~ delete _; - - private ImGuiLayer _imGuiLayer; - - private GameTime _gameTime = new GameTime(true) ~ delete _; - - public bool IsRunning => _running; - public Window Window => _window; - - [Inline] - public static Application Get() => s_Instance; - - public this() - { - Log.EngineLogger.Assert(s_Instance == null, "Tried to create a second application."); - s_Instance = this; - - _window = new Window(.Default); - _window.EventCallback = new => OnEvent; - - _rendererApi = new RendererAPI(); - _rendererApi.Context = _window.Context; - - SamplerStateManager.Init(_window.Context); - - RenderCommand.RendererAPI = _rendererApi; - - Renderer.Init(_window.Context); - - _imGuiLayer = new ImGuiLayer(); - PushOverlay(_imGuiLayer); - } - - public ~this() - { - SamplerStateManager.Uninit(); - } - - public void OnEvent(Event e) - { - EventDispatcher dispatcher = scope .(e); - dispatcher.Dispatch(scope => OnWindowClose); - - for(Layer layer in _layerStack) - { - layer.OnEvent(e); - if(e.Handled) - break; - } - } - - public void Run() - { - while(_running) - { - _gameTime.NewFrame(); - - Input.NewFrame(); - - for(Layer layer in _layerStack) - layer.Update(_gameTime); - - _window.Update(); - - _imGuiLayer.ImGuiRender(); - - _window.Context.SwapChain.Present(); - } - } - - public void PushLayer(Layer ownLayer) => _layerStack.PushLayer(ownLayer); - - public void PushOverlay(Layer ownOverlay) => _layerStack.PushOverlay(ownOverlay); - - public bool OnWindowClose(WindowCloseEvent e) - { - _running = false; - return true; - } - } -} +using System; +using GlitchyEngine.Events; +using GlitchyEngine.ImGui; +using GlitchyEngine.Renderer; + +namespace GlitchyEngine +{ + public class Application + { + static Application s_Instance = null; + + private Window _window ~ delete _; + private RendererAPI _rendererApi ~ delete _; + private bool _running = true; + + private LayerStack _layerStack = new LayerStack() ~ delete _; + + private ImGuiLayer _imGuiLayer; + + private GameTime _gameTime = new GameTime(true) ~ delete _; + + public bool IsRunning => _running; + public Window Window => _window; + + [Inline] + public static Application Get() => s_Instance; + + public this() + { + Log.EngineLogger.Assert(s_Instance == null, "Tried to create a second application."); + s_Instance = this; + + _window = new Window(.Default); + _window.EventCallback = new => OnEvent; + + _rendererApi = new RendererAPI(); + _rendererApi.Context = _window.Context; + + SamplerStateManager.Init(_window.Context); + + RenderCommand.RendererAPI = _rendererApi; + + Renderer.Init(_window.Context); + + _imGuiLayer = new ImGuiLayer(); + PushOverlay(_imGuiLayer); + } + + public ~this() + { + SamplerStateManager.Uninit(); + } + + public void OnEvent(Event e) + { + if(!_running) + return; + + EventDispatcher dispatcher = scope .(e); + dispatcher.Dispatch(scope => OnWindowClose); + + for(Layer layer in _layerStack) + { + layer.OnEvent(e); + if(e.Handled) + break; + } + } + + public void Run() + { + while(_running) + { + _gameTime.NewFrame(); + + Input.NewFrame(); + + for(Layer layer in _layerStack) + layer.Update(_gameTime); + + _window.Update(); + + _imGuiLayer.ImGuiRender(); + + _window.Context.SwapChain.Present(); + } + } + + public void PushLayer(Layer ownLayer) => _layerStack.PushLayer(ownLayer); + + public void PushOverlay(Layer ownOverlay) => _layerStack.PushOverlay(ownOverlay); + + public bool OnWindowClose(WindowCloseEvent e) + { + _running = false; + return true; + } + } +} diff --git a/GlitchyEngine/src/Events/ApplicationEvent.bf b/GlitchyEngine/src/Events/ApplicationEvent.bf index b6a49aa..d1ed7bb 100644 --- a/GlitchyEngine/src/Events/ApplicationEvent.bf +++ b/GlitchyEngine/src/Events/ApplicationEvent.bf @@ -89,4 +89,44 @@ namespace GlitchyEngine.Events strBuffer.AppendF("WindowMovedEvent: {}, {} (is moving: {})", _x, _y, _isMoving); } } + + public class WindowActivateEvent : Event, IEvent + { + public override EventType EventType => .WindowMoved; + + public override StringView Name => "WindowActivated"; + + public override EventCategory Category => .Application; + + public static EventType StaticType => .WindowActivated; + + public this() + { + } + + public override void ToString(String strBuffer) + { + strBuffer.AppendF("WindowActivatedEvent"); + } + } + + public class WindowDeactivateEvent : Event, IEvent + { + public override EventType EventType => .WindowMoved; + + public override StringView Name => "WindowDeactivated"; + + public override EventCategory Category => .Application; + + public static EventType StaticType => .WindowDeactivated; + + public this() + { + } + + public override void ToString(String strBuffer) + { + strBuffer.AppendF("WindowDeactivatedEvent"); + } + } } diff --git a/GlitchyEngine/src/Events/Event.bf b/GlitchyEngine/src/Events/Event.bf index c60a1fa..0aa61ee 100644 --- a/GlitchyEngine/src/Events/Event.bf +++ b/GlitchyEngine/src/Events/Event.bf @@ -4,7 +4,7 @@ namespace GlitchyEngine.Events public enum EventType { None = 0, - WindowClose, WindowResize, WindowFocus, WindowLostFocus, WindowMoved, + WindowClose, WindowResize, WindowFocus, WindowLostFocus, WindowMoved, WindowActivated, WindowDeactivated, AppTick, AppUpdate, AppRender, KeyPressed, KeyReleased, KeyTyped, MouseButtonPressed, MouseButtonReleased, MouseMoved, MouseScrolled diff --git a/GlitchyEngine/src/Platform/Windows/WindowsInput.bf b/GlitchyEngine/src/Platform/Windows/WindowsInput.bf index afde72b..711b92a 100644 --- a/GlitchyEngine/src/Platform/Windows/WindowsInput.bf +++ b/GlitchyEngine/src/Platform/Windows/WindowsInput.bf @@ -20,8 +20,10 @@ namespace GlitchyEngine public Point CursorPositionDifference; } - static WindowsInputState* CurrentState = new WindowsInputState() ~ delete _; - static WindowsInputState* LastState = new WindowsInputState() ~ delete _; + static WindowsInputState[2] IputStates; + + static WindowsInputState* CurrentState = &IputStates[0]; + static WindowsInputState* LastState = &IputStates[1]; // // Current Keyboard state @@ -162,11 +164,8 @@ namespace GlitchyEngine public override static void NewFrame() { - // Switch last and current states - var buffer = LastState; - LastState = CurrentState; - CurrentState = buffer; - + Swap!(CurrentState, LastState); + // Get current keyboard state if(DirectX.Windows.Winuser.GetKeyboardState((uint8*)&CurrentState.KeyStates) == 0) { diff --git a/GlitchyEngine/src/Platform/Windows/WindowsWindow.bf b/GlitchyEngine/src/Platform/Windows/WindowsWindow.bf index a9c5ca2..50f73f3 100644 --- a/GlitchyEngine/src/Platform/Windows/WindowsWindow.bf +++ b/GlitchyEngine/src/Platform/Windows/WindowsWindow.bf @@ -31,6 +31,8 @@ namespace GlitchyEngine private bool _isVSync = true; + private bool _isActive; + private GraphicsContext _graphicsContext ~ _?.ReleaseRef(); public override GraphicsContext Context => _graphicsContext; @@ -149,6 +151,8 @@ namespace GlitchyEngine set => _isVSync = value; } + public override bool IsActive => _isActive; + public override void* NativeWindow => (void*)(int)_windowHandle; public override this(WindowDescription desc) @@ -176,6 +180,9 @@ namespace GlitchyEngine UnregisterClass(WindowClassName.ToScopedNativeWChar!(), _instanceHandle); } + [LinkName(.C)] + static extern HWnd GetActiveWindow(); + private void Init(WindowDescription desc) { Log.EngineLogger.Trace($"Creating window \"{desc.Title}\" ({desc.Width}, {desc.Height})..."); @@ -215,6 +222,9 @@ namespace GlitchyEngine LoadWindowRectangle(); Log.EngineLogger.Trace($"Created window \"{Title}\" ({Width}, {Height})"); + + // Determine whether or not the window is currently active + _isActive = GetActiveWindow() == _windowHandle; } private bool _isResizingOrMoving; @@ -304,7 +314,26 @@ namespace GlitchyEngine var moveEvent = scope WindowMoveEvent(window._clientRect.X, window._clientRect.Y, false); window._eventCallback(moveEvent); } + + case 0x0006: //WM_ACTIVATE + { + SplitHighAndLowOrder!((int64)wParam, let lowWParam, let highWParam); + bool isActivate = lowWParam > 0; + + //HWnd windowHandle = (.)lParam; + + if(window._isActive != isActivate) + { + window._isActive = isActivate; + + if(window._isActive) + window._eventCallback(scope WindowActivateEvent()); + else + window._eventCallback(scope WindowDeactivateEvent()); + + } + } //// //// Keyboard input //// diff --git a/GlitchyEngine/src/Window.bf b/GlitchyEngine/src/Window.bf index b8b24de..c64c978 100644 --- a/GlitchyEngine/src/Window.bf +++ b/GlitchyEngine/src/Window.bf @@ -98,6 +98,11 @@ namespace GlitchyEngine */ public extern void* NativeWindow {get;} + /** + * Gets whether or not the window is active. + */ + public extern bool IsActive {get;} + public EventCallback EventCallback { get => _eventCallback; diff --git a/Sandbox/src/SandboxApp.bf b/Sandbox/src/SandboxApp.bf index efac599..722ebf1 100644 --- a/Sandbox/src/SandboxApp.bf +++ b/Sandbox/src/SandboxApp.bf @@ -193,32 +193,35 @@ namespace Sandbox public override void Update(GameTime gameTime) { - Vector2 movement = .(); - - if(Input.IsKeyPressed(Key.W)) + if(Application.Get().Window.IsActive) { - movement.Y += 1; - } - if(Input.IsKeyPressed(Key.S)) - { - movement.Y -= 1; - } - - if(Input.IsKeyPressed(Key.A)) - { - movement.X -= 1; - } - if(Input.IsKeyPressed(Key.D)) - { - movement.X += 1; - } + Vector2 movement = .(); - if(movement != .Zero) - movement.Normalize(); + if(Input.IsKeyPressed(Key.W)) + { + movement.Y += 1; + } + if(Input.IsKeyPressed(Key.S)) + { + movement.Y -= 1; + } - movement *= (float)(gameTime.FrameTime.TotalSeconds); + if(Input.IsKeyPressed(Key.A)) + { + movement.X -= 1; + } + if(Input.IsKeyPressed(Key.D)) + { + movement.X += 1; + } - _camera.Position += .(movement, 0); + if(movement != .Zero) + movement.Normalize(); + + movement *= (float)(gameTime.FrameTime.TotalSeconds); + + _camera.Position += .(movement, 0); + } _camera.Width = _context.SwapChain.BackbufferViewport.Width / 256; _camera.Height = _context.SwapChain.BackbufferViewport.Height / 256;