/************************************************************************* * ModernUO * * Copyright 2019-2023 - ModernUO Development Team * * Email: hi@modernuo.com * * File: GumpSystem.cs * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * *************************************************************************/ using Server.Network; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Server.Gumps; public static partial class GumpSystem { private static readonly Dictionary> _gumps = []; public static unsafe void Configure() { IncomingPackets.Register(0xB1, 0, true, &DisplayGumpResponse); EventSink.Disconnected += EventSink_Disconnected; } private static void EventSink_Disconnected(Mobile m) { if (m.NetState != null && _gumps.Remove(m.NetState, out var gumps)) { gumps.Clear(); } } private static void Remove(NetState ns, BaseGump gump) { if (_gumps.TryGetValue(ns, out var gumps)) { for (int i = 0; i < gumps.Count; i++) { if (gumps[i] == gump) { gumps.RemoveAt(i); return; } } } } private static NetStateGumps Get(NetState ns) { if (ns == null) { return new NetStateGumps(null, null); } ref List list = ref CollectionsMarshal.GetValueRefOrAddDefault(_gumps, ns, out bool exists); if (!exists) { list = []; } return new NetStateGumps(list, ns); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool HasGump([DisallowNull] this Mobile m) where T : BaseGump { ArgumentNullException.ThrowIfNull(m); var state = m.NetState; return state != null && Get(state).Find() != null; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T FindGump([DisallowNull] this Mobile m) where T : BaseGump { ArgumentNullException.ThrowIfNull(m); var state = m.NetState; return state != null ? Get(state).Find() : null; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool CloseGump([DisallowNull] this Mobile m) where T : BaseGump { ArgumentNullException.ThrowIfNull(m); var state = m.NetState; return state != null && Get(state).Close(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void SendGump([DisallowNull] this Mobile m, BaseGump g, bool singleton = false) { ArgumentNullException.ThrowIfNull(m); var state = m.NetState; if (state != null) { Get(state).Send(g, singleton); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static NetStateGumps GetGumps([DisallowNull] this Mobile m) { ArgumentNullException.ThrowIfNull(m); return Get(m.NetState); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool HasGump([DisallowNull] this NetState ns) where T : BaseGump { ArgumentNullException.ThrowIfNull(ns); return Get(ns).Find() != null; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T FindGump([DisallowNull] this NetState ns) where T : BaseGump { ArgumentNullException.ThrowIfNull(ns); return Get(ns).Find(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool CloseGump([DisallowNull] this NetState ns) where T : BaseGump { ArgumentNullException.ThrowIfNull(ns); return Get(ns).Close(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void SendGump([DisallowNull] this NetState ns, BaseGump g, bool singleton = false) { ArgumentNullException.ThrowIfNull(ns); Get(ns).Send(g, singleton); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static NetStateGumps GetGumps([DisallowNull] this NetState ns) { ArgumentNullException.ThrowIfNull(ns); return Get(ns); } }