using System.Collections.Generic; using Engine.Core; using SDL3; namespace Engine.Integration.SDL3; public class Sdl3WindowManager : Behaviour, IUpdate, IEnterUniverse, IExitUniverse { private readonly BehaviourCollector windows = new(); private readonly BehaviourCollector eventProcessors = new(); private readonly Dictionary windowsDictionary = []; public Sdl3WindowManager() { windows.OnCollected.AddListener(OnWindowCollected); windows.OnRemoved.AddListener(OnWindowRemoved); } private void OnWindowCollected(IBehaviourCollector sender, IBehaviourCollector.BehaviourCollectedArguments args) => windowsDictionary.Add(args.BehaviourCollected.Window, args.BehaviourCollected); private void OnWindowRemoved(IBehaviourCollector sender, IBehaviourCollector.BehaviourRemovedArguments args) { windowsDictionary.Remove(args.BehaviourRemoved.Window); if (windowsDictionary.Count == 0) SDL.Quit(); } public void EnterUniverse(IUniverse universe) { windows.Assign(universe); eventProcessors.Assign(universe); } public void ExitUniverse(IUniverse universe) { windows.Unassign(); eventProcessors.Unassign(); } public void Update() { while (SDL.PollEvent(out SDL.Event e)) ProcessInternalEvents(e); } private void ProcessInternalEvents(SDL.Event sdlEvent) { if (!windowsDictionary.TryGetValue(SDL.GetWindowFromID(sdlEvent.Window.WindowID), out Sdl3Window? window)) return; for (int i = 0; i < eventProcessors.Count; i++) eventProcessors[i].Process(sdlEvent); SDL.EventType eventType = (SDL.EventType)sdlEvent.Type; switch (eventType) { case SDL.EventType.WindowRestored: window.ShowState = WindowShowState.Normal; break; case SDL.EventType.WindowMaximized: window.ShowState = WindowShowState.Maximized; break; case SDL.EventType.WindowMinimized: window.ShowState = WindowShowState.Minimized; break; case SDL.EventType.WindowFocusGained: window.FocusState = WindowFocusState.Focused; break; case SDL.EventType.WindowFocusLost: window.FocusState = WindowFocusState.Unfocused; break; case SDL.EventType.WindowCloseRequested: case SDL.EventType.Quit: Universe.Remove(window.UniverseObject); break; } } }