312 lines
11 KiB
C#
312 lines
11 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Reflection;
|
|
using System.Reflection.Emit;
|
|
using System.ComponentModel;
|
|
using System.Globalization;
|
|
|
|
namespace ActorAnimPlayer
|
|
{
|
|
class ActorsManager
|
|
{
|
|
private List<ActorType> m_types;
|
|
private AssemblyName m_assemblyName;
|
|
private AssemblyBuilder m_assemblyBuilder;
|
|
private ModuleBuilder m_module;
|
|
|
|
public ActorsManager(string _moduleName)
|
|
{
|
|
m_types = new List<ActorType>();
|
|
|
|
m_assemblyName = new AssemblyName();
|
|
m_assemblyName.Name = "tmpAssembly";
|
|
m_assemblyBuilder = System.Threading.Thread.GetDomain().DefineDynamicAssembly(m_assemblyName, AssemblyBuilderAccess.Run);
|
|
m_module = m_assemblyBuilder.DefineDynamicModule(_moduleName);
|
|
}
|
|
|
|
public ActorType buildNewType( string _name )
|
|
{
|
|
ActorType newType = new ActorType(_name,m_module);
|
|
|
|
m_types.Add(newType);
|
|
|
|
return newType;
|
|
}
|
|
|
|
public ActorType findActorType(string _name)
|
|
{
|
|
for ( int i = 0; i < m_types.Count; i++ )
|
|
{
|
|
ActorType type = m_types[i];
|
|
|
|
if (type.Name == _name)
|
|
{
|
|
return type;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public class ActorType
|
|
{
|
|
private string m_name;
|
|
private TypeBuilder m_builder;
|
|
private Type m_type;
|
|
|
|
public ActorType(string _name, ModuleBuilder _module)
|
|
{
|
|
m_name = _name;
|
|
|
|
m_builder = _module.DefineType(_name, TypeAttributes.Public | TypeAttributes.Class);
|
|
|
|
ConstructorInfo ctor = typeof(DisplayNameAttribute).GetConstructor(new Type[] { typeof(string) });
|
|
object[] ctorArgs = new object[] { _name };
|
|
m_builder.SetCustomAttribute(new CustomAttributeBuilder(ctor, ctorArgs));
|
|
|
|
ctor = typeof(TypeConverterAttribute).GetConstructor(new Type[] { typeof(System.Type) });
|
|
ctorArgs = new object[] { typeof(ExpandableObjectConverter) };
|
|
m_builder.SetCustomAttribute(new CustomAttributeBuilder(ctor, ctorArgs));
|
|
}
|
|
|
|
public void addProperty(string _name, Type _propertyType, Type _objectTypeConverter)
|
|
{
|
|
FieldBuilder field = m_builder.DefineField("_" + _name, _propertyType, FieldAttributes.Private);
|
|
// Generate a public property
|
|
PropertyBuilder property = m_builder.DefineProperty(_name,
|
|
System.Reflection.PropertyAttributes.None,
|
|
_propertyType,
|
|
new Type[] { _propertyType });
|
|
|
|
// The property set and property get methods require a special set of attributes:
|
|
MethodAttributes GetSetAttr = MethodAttributes.Public | MethodAttributes.HideBySig;
|
|
|
|
// Define the "get" accessor method for current private field.
|
|
MethodBuilder currGetPropMthdBldr = m_builder.DefineMethod("get_value",
|
|
GetSetAttr,
|
|
_propertyType,
|
|
Type.EmptyTypes);
|
|
|
|
// Intermediate Language stuff...
|
|
ILGenerator currGetIL = currGetPropMthdBldr.GetILGenerator();
|
|
currGetIL.Emit(OpCodes.Ldarg_0);
|
|
currGetIL.Emit(OpCodes.Ldfld, field);
|
|
currGetIL.Emit(OpCodes.Ret);
|
|
|
|
// Define the "set" accessor method for current private field.
|
|
MethodBuilder currSetPropMthdBldr = m_builder.DefineMethod("set_value",
|
|
GetSetAttr,
|
|
null,
|
|
new Type[] { _propertyType });
|
|
|
|
// Again some Intermediate Language stuff...
|
|
ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator();
|
|
currSetIL.Emit(OpCodes.Ldarg_0);
|
|
currSetIL.Emit(OpCodes.Ldarg_1);
|
|
currSetIL.Emit(OpCodes.Stfld, field);
|
|
currSetIL.Emit(OpCodes.Ret);
|
|
|
|
// Last, we must map the two methods created above to our PropertyBuilder to
|
|
// their corresponding behaviors, "get" and "set" respectively.
|
|
property.SetGetMethod(currGetPropMthdBldr);
|
|
property.SetSetMethod(currSetPropMthdBldr);
|
|
|
|
ConstructorInfo ctor = null;
|
|
object[] ctorArgs = null;
|
|
|
|
if (_objectTypeConverter != null)
|
|
{
|
|
ctor = typeof(TypeConverterAttribute).GetConstructor(new Type[] { typeof(System.Type) });
|
|
ctorArgs = new object[] { _objectTypeConverter };
|
|
property.SetCustomAttribute(new CustomAttributeBuilder(ctor, ctorArgs));
|
|
}
|
|
|
|
ctor = typeof(DisplayNameAttribute).GetConstructor(new Type[] { typeof(string) });
|
|
ctorArgs = new object[] { _name };
|
|
property.SetCustomAttribute(new CustomAttributeBuilder(ctor, ctorArgs));
|
|
}
|
|
|
|
public object createType()
|
|
{
|
|
if (m_type == null)
|
|
{
|
|
m_type = m_builder.CreateType();
|
|
}
|
|
|
|
return Activator.CreateInstance(m_type);
|
|
}
|
|
|
|
public void setAttributeValue( object _object, string _name, Type _type, object _value )
|
|
{
|
|
PropertyInfo[] properties = m_type.GetProperties();
|
|
int numProperties = properties.Count();
|
|
|
|
for (int i = 0; i < numProperties; i++)
|
|
{
|
|
PropertyInfo propInfo = properties[i];
|
|
|
|
if (_name == propInfo.Name)
|
|
{
|
|
object[] custom_attributes = propInfo.GetCustomAttributes(false);
|
|
bool set = false;
|
|
|
|
for (int j = 0; j < custom_attributes.Count(); j++)
|
|
{
|
|
if (custom_attributes[j] is TypeConverterAttribute)
|
|
{
|
|
TypeConverterAttribute converter = (TypeConverterAttribute)custom_attributes[j];
|
|
Type converterType = Type.GetType(converter.ConverterTypeName);
|
|
TypeConverter converterObject = (TypeConverter)Activator.CreateInstance(converterType);
|
|
propInfo.SetValue(_object, converterObject.ConvertFrom(_value), null);
|
|
set = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!set)
|
|
{
|
|
propInfo.SetValue(_object, _value, null);
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public string Name
|
|
{
|
|
get
|
|
{
|
|
return m_name;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#region UInt32Converter
|
|
public class UInt32VarConverter : StringConverter
|
|
{
|
|
public override bool CanConvertTo(ITypeDescriptorContext context,
|
|
System.Type destinationType)
|
|
{
|
|
if (destinationType == typeof(string))
|
|
return true;
|
|
|
|
return base.CanConvertTo(context, destinationType);
|
|
}
|
|
|
|
public override object ConvertTo(ITypeDescriptorContext context,
|
|
CultureInfo culture,
|
|
object value,
|
|
System.Type destinationType)
|
|
{
|
|
if (destinationType == typeof(System.String) && value is UInt32)
|
|
{
|
|
|
|
UInt32 so = (UInt32)value;
|
|
return so.ToString();
|
|
}
|
|
|
|
return base.ConvertTo(context, culture, value, destinationType);
|
|
}
|
|
|
|
public override bool CanConvertFrom(ITypeDescriptorContext context,
|
|
System.Type sourceType)
|
|
{
|
|
if (sourceType == typeof(string))
|
|
return true;
|
|
|
|
return base.CanConvertFrom(context, sourceType);
|
|
}
|
|
|
|
public override object ConvertFrom(ITypeDescriptorContext context,
|
|
CultureInfo culture, object value)
|
|
{
|
|
if (value is string)
|
|
{
|
|
string val = (string)value;
|
|
UInt32 ret;
|
|
|
|
if (val != null)
|
|
{
|
|
ret = UInt32.Parse(val);
|
|
}
|
|
else
|
|
{
|
|
ret = 0;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
return base.ConvertFrom(context, culture, value);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region DecimalValConverter
|
|
public class DecimalVarConverter : StringConverter
|
|
{
|
|
public override bool CanConvertTo(ITypeDescriptorContext context,
|
|
System.Type destinationType)
|
|
{
|
|
if (destinationType == typeof(string))
|
|
return true;
|
|
|
|
return base.CanConvertTo(context, destinationType);
|
|
}
|
|
|
|
public override object ConvertTo(ITypeDescriptorContext context,
|
|
CultureInfo culture,
|
|
object value,
|
|
System.Type destinationType)
|
|
{
|
|
if (destinationType == typeof(System.String) && value is Decimal)
|
|
{
|
|
|
|
Decimal so = (Decimal)value;
|
|
return so.ToString();
|
|
}
|
|
|
|
return base.ConvertTo(context, culture, value, destinationType);
|
|
}
|
|
|
|
public override bool CanConvertFrom(ITypeDescriptorContext context,
|
|
System.Type sourceType)
|
|
{
|
|
if (sourceType == typeof(string))
|
|
return true;
|
|
|
|
return base.CanConvertFrom(context, sourceType);
|
|
}
|
|
|
|
public override object ConvertFrom(ITypeDescriptorContext context,
|
|
CultureInfo culture, object value)
|
|
{
|
|
if (value is string)
|
|
{
|
|
string val = (string)value;
|
|
Decimal ret;
|
|
|
|
if (val != null)
|
|
{
|
|
CultureInfo ci = new CultureInfo(CultureInfo.CurrentCulture.Name, false);
|
|
NumberFormatInfo formatInfo = ci.NumberFormat;
|
|
formatInfo.NumberDecimalSeparator = ".";
|
|
formatInfo.NumberGroupSeparator = ",";
|
|
|
|
ret = Decimal.Parse(val, formatInfo);
|
|
}
|
|
else
|
|
{
|
|
ret = 0;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
return base.ConvertFrom(context, culture, value);
|
|
}
|
|
}
|
|
#endregion
|
|
}
|