servuo/Scripts/Commands/Generic/Extensions/DistinctExtension.cs

80 lines
2.3 KiB
C#
Raw Permalink Normal View History

2013-10-28 07:09:42 +00:00
using System;
using System.Collections;
using System.Collections.Generic;
namespace Server.Commands.Generic
{
public sealed class DistinctExtension : BaseExtension
{
public static ExtensionInfo ExtInfo = new ExtensionInfo(30, "Distinct", -1, delegate () { return new DistinctExtension(); });
2013-10-28 07:09:42 +00:00
private readonly List<Property> m_Properties;
private IComparer m_Comparer;
public DistinctExtension()
{
2020-04-16 21:29:55 -04:00
m_Properties = new List<Property>();
2013-10-28 07:09:42 +00:00
}
2020-04-16 20:21:33 -04:00
public override ExtensionInfo Info => ExtInfo;
2013-10-28 07:09:42 +00:00
public static void Initialize()
{
ExtensionInfo.Register(ExtInfo);
}
public override void Optimize(Mobile from, Type baseType, ref AssemblyEmitter assembly)
{
if (baseType == null)
throw new Exception("Distinct extension may only be used in combination with an object conditional.");
2020-04-16 21:29:55 -04:00
foreach (Property prop in m_Properties)
2013-10-28 07:09:42 +00:00
{
prop.BindTo(baseType, PropertyAccess.Read);
prop.CheckAccess(from);
}
if (assembly == null)
assembly = new AssemblyEmitter("__dynamic", false);
2020-04-16 21:29:55 -04:00
m_Comparer = DistinctCompiler.Compile(assembly, baseType, m_Properties.ToArray());
2013-10-28 07:09:42 +00:00
}
public override void Parse(Mobile from, string[] arguments, int offset, int size)
{
if (size < 1)
throw new Exception("Invalid distinction syntax.");
int end = offset + size;
while (offset < end)
{
string binding = arguments[offset++];
2020-04-16 21:29:55 -04:00
m_Properties.Add(new Property(binding));
2013-10-28 07:09:42 +00:00
}
}
public override void Filter(ArrayList list)
{
2020-04-16 21:29:55 -04:00
if (m_Comparer == null)
2013-10-28 07:09:42 +00:00
throw new InvalidOperationException("The extension must first be optimized.");
ArrayList copy = new ArrayList(list);
2020-04-16 21:29:55 -04:00
copy.Sort(m_Comparer);
2013-10-28 07:09:42 +00:00
list.Clear();
object last = null;
for (int i = 0; i < copy.Count; ++i)
{
object obj = copy[i];
2020-04-16 21:29:55 -04:00
if (last == null || m_Comparer.Compare(obj, last) != 0)
2013-10-28 07:09:42 +00:00
{
list.Add(obj);
last = obj;
}
}
}
}
}