perf: Migrates New Guild System gumps from legacy Gump. (#2422)
## Summary Migrates the eight concrete New Guild System gumps (CreateGuild, GuildInfo, GuildMemberInfo, GuildRoster, GuildDiplomacy, WarDeclaration, GuildAdvancedSearch, GuildInvitationRequest) and three abstract bases (BaseGuildGump, BaseGuildListGump, OtherGuildInfo) from the legacy `Gump` class to `DynamicGump`. Layout work moves from constructor-side `AddX(...)` calls into `BuildLayout(ref DynamicGumpBuilder builder)` — the abstract `BaseGuildGump` now provides a `BuildContent` callout for shared tab-strip chrome, and `BaseGuildListGump<T>` adds another `BuildListExtras` hook so subclasses can paint highlighted titles after the filter/sort/pagination chrome. The headline win is the **self-refresh pattern** on the list gumps and diplomacy advanced search. Previously each filter/sort/back/forward click allocated a brand new gump via `GetResentGump`. After migration, those handlers mutate `_filter`, `_startNumber`, `_comparer`, `_ascending`, or `_display` on the existing gump and call `from.SendGump(this)`, letting the singleton path in `NetStateGumps.Send` swap in the same instance with the new layout. The original list is preserved separately from the per-render filtered/sorted `_displayList`, so refreshes pick up the latest state without losing the source list. All guild gumps deal with per-instance dynamic strings (guild names, member names, war declarations, alliance names), which would defeat `StaticGump<T>` caching per the cliloc rule, so every concrete subclass migrates to `DynamicGump`. `AllianceRosterGump` (in `Misc/Guild.cs`) is a `GuildDiplomacyGump` subclass and inherits the new behavior; its unused override and stored alliance reference were dropped along with the now-obsolete `GetResentGump` abstract.
This commit is contained in:
parent
598c3c125c
commit
9c2ac2b8ea
12 changed files with 642 additions and 689 deletions
|
|
@ -9,137 +9,146 @@ namespace Server.Guilds
|
|||
public abstract class BaseGuildListGump<T> : BaseGuildGump
|
||||
{
|
||||
private const int itemsPerPage = 8;
|
||||
private readonly IComparer<T> m_Comparer;
|
||||
private readonly InfoField<T>[] m_Fields;
|
||||
private readonly string m_Filter;
|
||||
private bool m_Ascending;
|
||||
private List<T> m_List;
|
||||
private int m_StartNumber;
|
||||
|
||||
public BaseGuildListGump(
|
||||
private readonly InfoField<T>[] _fields;
|
||||
private readonly List<T> _originalList;
|
||||
private List<T> _displayList;
|
||||
private IComparer<T> _comparer;
|
||||
private bool _ascending;
|
||||
private string _filter;
|
||||
private int _startNumber;
|
||||
|
||||
protected BaseGuildListGump(
|
||||
PlayerMobile pm, Guild g, List<T> list, IComparer<T> currentComparer, bool ascending,
|
||||
string filter, int startNumber, InfoField<T>[] fields
|
||||
)
|
||||
: base(pm, g)
|
||||
) : base(pm, g)
|
||||
{
|
||||
m_Filter = filter.Trim();
|
||||
|
||||
m_Comparer = currentComparer;
|
||||
m_Fields = fields;
|
||||
m_Ascending = ascending;
|
||||
m_StartNumber = startNumber;
|
||||
m_List = list;
|
||||
_filter = filter.Trim();
|
||||
_comparer = currentComparer;
|
||||
_fields = fields;
|
||||
_ascending = ascending;
|
||||
_startNumber = startNumber;
|
||||
_originalList = list;
|
||||
}
|
||||
|
||||
public virtual bool WillFilter => m_Filter.Length > 0;
|
||||
public virtual bool WillFilter => _filter.Length > 0;
|
||||
|
||||
public override void PopulateGump()
|
||||
protected override void BuildContent(ref DynamicGumpBuilder builder)
|
||||
{
|
||||
base.PopulateGump();
|
||||
|
||||
var list = m_List;
|
||||
// Build the filtered/sorted display list per-render so refreshes pick up
|
||||
// the latest filter/sort/pagination state.
|
||||
if (WillFilter)
|
||||
{
|
||||
m_List = [];
|
||||
for (var i = 0; i < list.Count; i++)
|
||||
var filtered = new List<T>(_originalList.Count);
|
||||
for (var i = 0; i < _originalList.Count; i++)
|
||||
{
|
||||
if (!IsFiltered(list[i], m_Filter))
|
||||
if (!IsFiltered(_originalList[i], _filter))
|
||||
{
|
||||
m_List.Add(list[i]);
|
||||
filtered.Add(_originalList[i]);
|
||||
}
|
||||
}
|
||||
|
||||
_displayList = filtered;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_List = new List<T>(list);
|
||||
_displayList = new List<T>(_originalList);
|
||||
}
|
||||
|
||||
m_List.Sort(m_Comparer);
|
||||
m_StartNumber = Math.Max(Math.Min(m_StartNumber, m_List.Count - 1), 0);
|
||||
_displayList.Sort(_comparer);
|
||||
_startNumber = Math.Max(Math.Min(_startNumber, _displayList.Count - 1), 0);
|
||||
|
||||
AddBackground(130, 75, 385, 30, 0xBB8);
|
||||
AddTextEntry(135, 80, 375, 30, 0x481, 1, m_Filter);
|
||||
AddButton(520, 75, 0x867, 0x868, 5); // Filter Button
|
||||
builder.AddBackground(130, 75, 385, 30, 0xBB8);
|
||||
builder.AddTextEntry(135, 80, 375, 30, 0x481, 1, _filter);
|
||||
builder.AddButton(520, 75, 0x867, 0x868, 5); // Filter Button
|
||||
|
||||
var width = 0;
|
||||
for (var i = 0; i < m_Fields.Length; i++)
|
||||
for (var i = 0; i < _fields.Length; i++)
|
||||
{
|
||||
var f = m_Fields[i];
|
||||
var f = _fields[i];
|
||||
|
||||
AddImageTiled(65 + width, 110, f.Width + 10, 26, 0xA40);
|
||||
AddImageTiled(67 + width, 112, f.Width + 6, 22, 0xBBC);
|
||||
AddHtmlText(70 + width, 113, f.Width, 20, f.Name, false, false);
|
||||
builder.AddImageTiled(65 + width, 110, f.Width + 10, 26, 0xA40);
|
||||
builder.AddImageTiled(67 + width, 112, f.Width + 6, 22, 0xBBC);
|
||||
AddHtmlText(ref builder, 70 + width, 113, f.Width, 20, f.Name, false, false);
|
||||
|
||||
var isComparer = m_Fields[i].Comparer.GetType() == m_Comparer.GetType();
|
||||
var isComparer = _fields[i].Comparer.GetType() == _comparer.GetType();
|
||||
|
||||
var ButtonID = isComparer ? m_Ascending ? 0x983 : 0x985 : 0x2716;
|
||||
var buttonId = isComparer ? _ascending ? 0x983 : 0x985 : 0x2716;
|
||||
|
||||
AddButton(59 + width + f.Width, 117, ButtonID, ButtonID + (isComparer ? 1 : 0), 100 + i);
|
||||
builder.AddButton(59 + width + f.Width, 117, buttonId, buttonId + (isComparer ? 1 : 0), 100 + i);
|
||||
|
||||
width += f.Width + 12;
|
||||
}
|
||||
|
||||
if (m_StartNumber <= 0)
|
||||
if (_startNumber <= 0)
|
||||
{
|
||||
AddButton(65, 80, 0x15E3, 0x15E7, 0, GumpButtonType.Page);
|
||||
builder.AddButton(65, 80, 0x15E3, 0x15E7, 0, GumpButtonType.Page);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddButton(65, 80, 0x15E3, 0x15E7, 6); // Back
|
||||
builder.AddButton(65, 80, 0x15E3, 0x15E7, 6); // Back
|
||||
}
|
||||
|
||||
if (m_StartNumber + itemsPerPage > m_List.Count)
|
||||
if (_startNumber + itemsPerPage > _displayList.Count)
|
||||
{
|
||||
AddButton(95, 80, 0x15E1, 0x15E5, 0, GumpButtonType.Page);
|
||||
builder.AddButton(95, 80, 0x15E1, 0x15E5, 0, GumpButtonType.Page);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddButton(95, 80, 0x15E1, 0x15E5, 7); // Forward
|
||||
builder.AddButton(95, 80, 0x15E1, 0x15E5, 7); // Forward
|
||||
}
|
||||
|
||||
var itemNumber = 0;
|
||||
|
||||
if (m_Ascending)
|
||||
if (_ascending)
|
||||
{
|
||||
for (var i = m_StartNumber; i < m_StartNumber + itemsPerPage && i < m_List.Count; i++)
|
||||
for (var i = _startNumber; i < _startNumber + itemsPerPage && i < _displayList.Count; i++)
|
||||
{
|
||||
DrawEntry(m_List[i], i, itemNumber++);
|
||||
DrawEntry(ref builder, _displayList[i], i, itemNumber++);
|
||||
}
|
||||
}
|
||||
else // descending, go from bottom of list to the top
|
||||
{
|
||||
for (var i = m_List.Count - 1 - m_StartNumber;
|
||||
i >= 0 && i >= m_List.Count - itemsPerPage - m_StartNumber;
|
||||
for (var i = _displayList.Count - 1 - _startNumber;
|
||||
i >= 0 && i >= _displayList.Count - itemsPerPage - _startNumber;
|
||||
i--)
|
||||
{
|
||||
DrawEntry(m_List[i], i, itemNumber++);
|
||||
DrawEntry(ref builder, _displayList[i], i, itemNumber++);
|
||||
}
|
||||
}
|
||||
|
||||
DrawEndingEntry(itemNumber);
|
||||
DrawEndingEntry(ref builder, itemNumber);
|
||||
|
||||
BuildListExtras(ref builder);
|
||||
}
|
||||
|
||||
public virtual void DrawEndingEntry(int itemNumber)
|
||||
protected virtual void BuildListExtras(ref DynamicGumpBuilder builder)
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void DrawEndingEntry(ref DynamicGumpBuilder builder, int itemNumber)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual bool HasRelationship(T o) => false;
|
||||
|
||||
public virtual void DrawEntry(T o, int index, int itemNumber)
|
||||
protected virtual void DrawEntry(ref DynamicGumpBuilder builder, T o, int index, int itemNumber)
|
||||
{
|
||||
var width = 0;
|
||||
for (var j = 0; j < m_Fields.Length; j++)
|
||||
var values = GetValuesFor(o, _fields.Length);
|
||||
for (var j = 0; j < _fields.Length; j++)
|
||||
{
|
||||
var f = m_Fields[j];
|
||||
var f = _fields[j];
|
||||
|
||||
AddImageTiled(65 + width, 138 + itemNumber * 28, f.Width + 10, 26, 0xA40);
|
||||
AddImageTiled(67 + width, 140 + itemNumber * 28, f.Width + 6, 22, 0xBBC);
|
||||
builder.AddImageTiled(65 + width, 138 + itemNumber * 28, f.Width + 10, 26, 0xA40);
|
||||
builder.AddImageTiled(67 + width, 140 + itemNumber * 28, f.Width + 6, 22, 0xBBC);
|
||||
AddHtmlText(
|
||||
ref builder,
|
||||
70 + width,
|
||||
141 + itemNumber * 28,
|
||||
f.Width,
|
||||
20,
|
||||
GetValuesFor(o, m_Fields.Length)[j],
|
||||
values[j],
|
||||
false,
|
||||
false
|
||||
);
|
||||
|
|
@ -149,22 +158,23 @@ namespace Server.Guilds
|
|||
|
||||
if (HasRelationship(o))
|
||||
{
|
||||
AddButton(40, 143 + itemNumber * 28, 0x8AF, 0x8AF, 200 + index); // Info Button
|
||||
builder.AddButton(40, 143 + itemNumber * 28, 0x8AF, 0x8AF, 200 + index); // Info Button
|
||||
}
|
||||
else
|
||||
{
|
||||
AddButton(40, 143 + itemNumber * 28, 0x4B9, 0x4BA, 200 + index); // Info Button
|
||||
builder.AddButton(40, 143 + itemNumber * 28, 0x4B9, 0x4BA, 200 + index); // Info Button
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract TextDefinition[] GetValuesFor(T o, int aryLength);
|
||||
|
||||
protected abstract bool IsFiltered(T o, string filter);
|
||||
|
||||
public override void OnResponse(NetState sender, in RelayInfo info)
|
||||
{
|
||||
base.OnResponse(sender, info);
|
||||
|
||||
if (sender.Mobile is not PlayerMobile pm || !IsMember(pm, guild))
|
||||
if (sender.Mobile is not PlayerMobile pm || !IsMember(pm, Guild))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -176,52 +186,59 @@ namespace Server.Guilds
|
|||
case 5: // Filter
|
||||
{
|
||||
var t = info.GetTextEntry(1);
|
||||
pm.SendGump(GetResentGump(player, guild, m_Comparer, m_Ascending, t ?? "", 0));
|
||||
break;
|
||||
_filter = (t ?? "").Trim();
|
||||
_startNumber = 0;
|
||||
pm.SendGump(this);
|
||||
return;
|
||||
}
|
||||
case 6: // Back
|
||||
{
|
||||
pm.SendGump(
|
||||
GetResentGump(player, guild, m_Comparer, m_Ascending, m_Filter, m_StartNumber - itemsPerPage)
|
||||
);
|
||||
break;
|
||||
_startNumber -= itemsPerPage;
|
||||
pm.SendGump(this);
|
||||
return;
|
||||
}
|
||||
case 7: // Forward
|
||||
{
|
||||
pm.SendGump(
|
||||
GetResentGump(player, guild, m_Comparer, m_Ascending, m_Filter, m_StartNumber + itemsPerPage)
|
||||
);
|
||||
break;
|
||||
_startNumber += itemsPerPage;
|
||||
pm.SendGump(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (id >= 100 && id < 100 + m_Fields.Length)
|
||||
if (id >= 100 && id < 100 + _fields.Length)
|
||||
{
|
||||
var comparer = m_Fields[id - 100].Comparer;
|
||||
var comparer = _fields[id - 100].Comparer;
|
||||
|
||||
if (m_Comparer.GetType() == comparer.GetType())
|
||||
if (_comparer.GetType() == comparer.GetType())
|
||||
{
|
||||
m_Ascending = !m_Ascending;
|
||||
_ascending = !_ascending;
|
||||
}
|
||||
else
|
||||
{
|
||||
_comparer = comparer;
|
||||
}
|
||||
|
||||
pm.SendGump(GetResentGump(player, guild, comparer, m_Ascending, m_Filter, 0));
|
||||
_startNumber = 0;
|
||||
pm.SendGump(this);
|
||||
}
|
||||
else if (id >= 200 && id < 200 + m_List.Count)
|
||||
else if (id >= 200)
|
||||
{
|
||||
pm.SendGump(GetObjectInfoGump(player, guild, m_List[id - 200]));
|
||||
// The display list is rebuilt every render, so we use the most recent
|
||||
// build to resolve the clicked entry.
|
||||
var list = _displayList ?? _originalList;
|
||||
var idx = id - 200;
|
||||
if (idx < list.Count)
|
||||
{
|
||||
pm.SendGump(GetObjectInfoGump(Player, Guild, list[idx]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract Gump GetResentGump(
|
||||
PlayerMobile pm, Guild g, IComparer<T> comparer, bool ascending, string filter,
|
||||
int startNumber
|
||||
);
|
||||
|
||||
public abstract Gump GetObjectInfoGump(PlayerMobile pm, Guild g, T o);
|
||||
public abstract BaseGump GetObjectInfoGump(PlayerMobile pm, Guild g, T o);
|
||||
|
||||
public void ResendGump()
|
||||
{
|
||||
player.SendGump(GetResentGump(player, guild, m_Comparer, m_Ascending, m_Filter, m_StartNumber));
|
||||
Player.SendGump(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue