#W# Initial Commit: Avatars Conquest
This commit is contained in:
commit
8eae46895e
7512 changed files with 416187 additions and 0 deletions
|
|
@ -0,0 +1,249 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using System.Text;
|
||||
using Server;
|
||||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
public static class DistinctCompiler
|
||||
{
|
||||
public static IComparer Compile( AssemblyEmitter assembly, Type objectType, Property[] props )
|
||||
{
|
||||
TypeBuilder typeBuilder = assembly.DefineType(
|
||||
"__distinct",
|
||||
TypeAttributes.Public,
|
||||
typeof( object )
|
||||
);
|
||||
|
||||
#region Constructor
|
||||
{
|
||||
ConstructorBuilder ctor = typeBuilder.DefineConstructor(
|
||||
MethodAttributes.Public,
|
||||
CallingConventions.Standard,
|
||||
Type.EmptyTypes
|
||||
);
|
||||
|
||||
ILGenerator il = ctor.GetILGenerator();
|
||||
|
||||
// : base()
|
||||
il.Emit( OpCodes.Ldarg_0 );
|
||||
il.Emit( OpCodes.Call, typeof( object ).GetConstructor( Type.EmptyTypes ) );
|
||||
|
||||
// return;
|
||||
il.Emit( OpCodes.Ret );
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IComparer
|
||||
typeBuilder.AddInterfaceImplementation( typeof( IComparer ) );
|
||||
|
||||
MethodBuilder compareMethod;
|
||||
|
||||
#region Compare
|
||||
{
|
||||
MethodEmitter emitter = new MethodEmitter( typeBuilder );
|
||||
|
||||
emitter.Define(
|
||||
/* name */ "Compare",
|
||||
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
|
||||
/* return */ typeof( int ),
|
||||
/* params */ new Type[] { typeof( object ), typeof( object ) } );
|
||||
|
||||
LocalBuilder a = emitter.CreateLocal( objectType );
|
||||
LocalBuilder b = emitter.CreateLocal( objectType );
|
||||
|
||||
LocalBuilder v = emitter.CreateLocal( typeof( int ) );
|
||||
|
||||
emitter.LoadArgument( 1 );
|
||||
emitter.CastAs( objectType );
|
||||
emitter.StoreLocal( a );
|
||||
|
||||
emitter.LoadArgument( 2 );
|
||||
emitter.CastAs( objectType );
|
||||
emitter.StoreLocal( b );
|
||||
|
||||
emitter.Load( 0 );
|
||||
emitter.StoreLocal( v );
|
||||
|
||||
Label end = emitter.CreateLabel();
|
||||
|
||||
for ( int i = 0; i < props.Length; ++i )
|
||||
{
|
||||
if ( i > 0 )
|
||||
{
|
||||
emitter.LoadLocal( v );
|
||||
emitter.BranchIfTrue( end ); // if ( v != 0 ) return v;
|
||||
}
|
||||
|
||||
Property prop = props[i];
|
||||
|
||||
emitter.LoadLocal( a );
|
||||
emitter.Chain( prop );
|
||||
|
||||
bool couldCompare =
|
||||
emitter.CompareTo( 1, delegate()
|
||||
{
|
||||
emitter.LoadLocal( b );
|
||||
emitter.Chain( prop );
|
||||
} );
|
||||
|
||||
if ( !couldCompare )
|
||||
throw new InvalidOperationException( "Property is not comparable." );
|
||||
|
||||
emitter.StoreLocal( v );
|
||||
}
|
||||
|
||||
emitter.MarkLabel( end );
|
||||
|
||||
emitter.LoadLocal( v );
|
||||
emitter.Return();
|
||||
|
||||
typeBuilder.DefineMethodOverride(
|
||||
emitter.Method,
|
||||
typeof( IComparer ).GetMethod(
|
||||
"Compare",
|
||||
new Type[]
|
||||
{
|
||||
typeof( object ),
|
||||
typeof( object )
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
compareMethod = emitter.Method;
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region IEqualityComparer
|
||||
typeBuilder.AddInterfaceImplementation( typeof( IEqualityComparer<object> ) );
|
||||
|
||||
#region Equals
|
||||
{
|
||||
MethodEmitter emitter = new MethodEmitter( typeBuilder );
|
||||
|
||||
emitter.Define(
|
||||
/* name */ "Equals",
|
||||
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
|
||||
/* return */ typeof( bool ),
|
||||
/* params */ new Type[] { typeof( object ), typeof( object ) } );
|
||||
|
||||
emitter.Generator.Emit( OpCodes.Ldarg_0 );
|
||||
emitter.Generator.Emit( OpCodes.Ldarg_1 );
|
||||
emitter.Generator.Emit( OpCodes.Ldarg_2 );
|
||||
|
||||
emitter.Generator.Emit( OpCodes.Call, compareMethod );
|
||||
|
||||
emitter.Generator.Emit( OpCodes.Ldc_I4_0 );
|
||||
|
||||
emitter.Generator.Emit( OpCodes.Ceq );
|
||||
|
||||
emitter.Generator.Emit( OpCodes.Ret );
|
||||
|
||||
typeBuilder.DefineMethodOverride(
|
||||
emitter.Method,
|
||||
typeof( IEqualityComparer<object> ).GetMethod(
|
||||
"Equals",
|
||||
new Type[]
|
||||
{
|
||||
typeof( object ),
|
||||
typeof( object )
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GetHashCode
|
||||
{
|
||||
MethodEmitter emitter = new MethodEmitter( typeBuilder );
|
||||
|
||||
emitter.Define(
|
||||
/* name */ "GetHashCode",
|
||||
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
|
||||
/* return */ typeof( int ),
|
||||
/* params */ new Type[] { typeof( object ) } );
|
||||
|
||||
LocalBuilder obj = emitter.CreateLocal( objectType );
|
||||
|
||||
emitter.LoadArgument( 1 );
|
||||
emitter.CastAs( objectType );
|
||||
emitter.StoreLocal( obj );
|
||||
|
||||
for ( int i = 0; i < props.Length; ++i )
|
||||
{
|
||||
Property prop = props[i];
|
||||
|
||||
emitter.LoadLocal( obj );
|
||||
emitter.Chain( prop );
|
||||
|
||||
Type active = emitter.Active;
|
||||
|
||||
MethodInfo getHashCode = active.GetMethod( "GetHashCode", Type.EmptyTypes );
|
||||
|
||||
if ( getHashCode == null )
|
||||
getHashCode = typeof( object ).GetMethod( "GetHashCode", Type.EmptyTypes );
|
||||
|
||||
if ( active != typeof( int ) )
|
||||
{
|
||||
if ( !active.IsValueType )
|
||||
{
|
||||
LocalBuilder value = emitter.AcquireTemp( active );
|
||||
|
||||
Label valueNotNull = emitter.CreateLabel();
|
||||
Label done = emitter.CreateLabel();
|
||||
|
||||
emitter.StoreLocal( value );
|
||||
emitter.LoadLocal( value );
|
||||
|
||||
emitter.BranchIfTrue( valueNotNull );
|
||||
|
||||
emitter.Load( 0 );
|
||||
emitter.Pop( typeof( int ) );
|
||||
|
||||
emitter.Branch( done );
|
||||
|
||||
emitter.MarkLabel( valueNotNull );
|
||||
|
||||
emitter.LoadLocal( value );
|
||||
emitter.Call( getHashCode );
|
||||
|
||||
emitter.ReleaseTemp( value );
|
||||
|
||||
emitter.MarkLabel( done );
|
||||
}
|
||||
else
|
||||
{
|
||||
emitter.Call( getHashCode );
|
||||
}
|
||||
}
|
||||
|
||||
if ( i > 0 )
|
||||
emitter.Xor();
|
||||
}
|
||||
|
||||
emitter.Return();
|
||||
|
||||
typeBuilder.DefineMethodOverride(
|
||||
emitter.Method,
|
||||
typeof( IEqualityComparer<object> ).GetMethod(
|
||||
"GetHashCode",
|
||||
new Type[]
|
||||
{
|
||||
typeof( object )
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
Type comparerType = typeBuilder.CreateType();
|
||||
|
||||
return (IComparer) Activator.CreateInstance( comparerType );
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue