using System; using System.Reflection; using System.Collections; using System.Collections.Generic; using System.Text; namespace Server.Commands.Generic { public sealed class SortExtension : BaseExtension { public static ExtensionInfo ExtInfo = new ExtensionInfo( 40, "Order", -1, delegate() { return new SortExtension(); } ); public static void Initialize() { ExtensionInfo.Register( ExtInfo ); } public override ExtensionInfo Info { get { return ExtInfo; } } private List m_Orders; private IComparer m_Comparer; public SortExtension() { m_Orders = new List(); } public override void Optimize( Mobile from, Type baseType, ref AssemblyEmitter assembly ) { if ( baseType == null ) throw new Exception( "The ordering extension may only be used in combination with an object conditional." ); foreach ( OrderInfo order in m_Orders ) { order.Property.BindTo( baseType, PropertyAccess.Read ); order.Property.CheckAccess( from ); } if ( assembly == null ) assembly = new AssemblyEmitter( "__dynamic", false ); m_Comparer = SortCompiler.Compile( assembly, baseType, m_Orders.ToArray() ); } public override void Parse( Mobile from, string[] arguments, int offset, int size ) { if ( size < 1 ) throw new Exception( "Invalid ordering syntax." ); if ( Insensitive.Equals( arguments[offset], "by" ) ) { ++offset; --size; if ( size < 1 ) throw new Exception( "Invalid ordering syntax." ); } int end = offset + size; while ( offset < end ) { string binding = arguments[offset++]; bool isAscending = true; if ( offset < end ) { string next = arguments[offset]; switch ( next.ToLower() ) { case "+": case "up": case "asc": case "ascending": isAscending = true; ++offset; break; case "-": case "down": case "desc": case "descending": isAscending = false; ++offset; break; } } Property property = new Property( binding ); m_Orders.Add( new OrderInfo( property, isAscending ) ); } } public override void Filter( ArrayList list ) { if ( m_Comparer == null ) throw new InvalidOperationException( "The extension must first be optimized." ); list.Sort( m_Comparer ); } } }