UO-Dev Arama


Yazar: Bilinmiyor
Tarih: 26-08-2009 13:39


Paylaş : Paylaş

Kod:
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 );
}
}
}



Yorumlar

Henüz yorum yapılmamıştır.

Oylamalar

Oylama :
Üyelerin oylama ortalaması (10 dışında) : Henüz Oylanmamış   
Oylar: 0

Benzer Sayfalar

SayfalarYorumlarGönderenTarih
Distinct Extension0Amesron26-08-2009
Sort Compiler0Amesron26-08-2009
Conditional Compiler0Amesron26-08-2009


Keywords:

ultima online, RunUO, ultima online download, sphere scripting, role play, uo grafik, second age ultima, uo loop, macroman, pvp server, server kurulumu, sphere, multool, ml mulls, 56b 55r 55i, htmlgumps, client 4x, client edit, sphere release, osi, rp server, sunucular, ghost mouse, inside uo, kingdom reborn, stygian abyss, uo nasıl oynanır, mondain's legacy, age of shadows, world build, grandmaster, ultima online pvp, player dosyaları, ultima online indir, frp game, RunUO 1.0.0, razor, uo rice, hue editör, skill tools, ultima online patch, axis, world build, verdata, verdata patcher, map editör, gump editör, mul patcher, aos mulls, scriptler, anim edit, anim publish, hues mul, hosting vps, event dialog, account sistemi, skill gain, static yapımı,