using System; using System.IO; using System.Reflection; using System.Reflection.Emit; using System.Runtime.Serialization.Formatters.Binary; using System.Text.RegularExpressions; using System.Threading; using Emergent.Gamebryo.SceneDesigner.PluginAPI; using Emergent.Gamebryo.SceneDesigner.PluginAPI.StandardServices; namespace Emergent.Gamebryo.SceneDesigner.GUI.Utility { /// /// Summary description for OptionUtilities. /// internal class OptionUtilities { public OptionUtilities() { } /// /// Returns the name of the option without the category prefixes /// e.g., an input of "advanced.user.inputmode" returns /// "inputmode" /// /// /// public static string StripCategories(string option) { //finds word at end of line that follows zero or more dots. Regex regex = new Regex("(?<=[.])?[^.]+$"); return regex.Match(option).Value; } /// /// Similar to StripCategories /// except it returns the opposite portion of the option /// e.g., an input of "advanced.user.inputmode" returns /// "advanced.user" /// /// /// public static string StripOption(string option) { //return all charaters up until but not including the last //occuring dot. Regex regex = new Regex(".+(?=[.])"); return regex.Match(option).Value; } public static TypeBuilder GetTypeBuilder() { AppDomain myDomain = Thread.GetDomain(); AssemblyName myAsmName = new AssemblyName(); myAsmName.Name = "DynamicAssemblyName"; AssemblyBuilder asmBuilder = myDomain.DefineDynamicAssembly( myAsmName, AssemblyBuilderAccess.RunAndSave); ModuleBuilder moduleBuilder = asmBuilder.DefineDynamicModule("DynamicOptionsmodule"); return moduleBuilder.DefineType("OptionsObject", TypeAttributes.Public, typeof(OptionObjectDescriptor)); } public static void AddProperty(string propertyName, string displayName, Type propertyType, TypeBuilder typeBuilder) { PropertyBuilder propBuilder = typeBuilder.DefineProperty( propertyName, PropertyAttributes.None, propertyType, new Type[] {propertyType}); FieldBuilder fieldBuilder = typeBuilder.DefineField("custom" + propertyName, propertyType, FieldAttributes.Private); //Create Getter MethodBuilder getterBuilder = typeBuilder.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName, propertyType, new Type[] {}); ILGenerator ilGenerator = getterBuilder.GetILGenerator(); ilGenerator.DeclareLocal(propertyType); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldfld, fieldBuilder); ilGenerator.Emit(OpCodes.Stloc_0); ilGenerator.Emit(OpCodes.Ldloc_0); ilGenerator.Emit(OpCodes.Ret); propBuilder.SetGetMethod(getterBuilder); //Create Setter MethodBuilder setterBuilder = typeBuilder.DefineMethod("set_" + propertyName, MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName, null, new Type[]{propertyType}); ilGenerator = setterBuilder.GetILGenerator(); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldarg_1); ilGenerator.Emit(OpCodes.Stfld, fieldBuilder); ilGenerator.Emit(OpCodes.Ret); propBuilder.SetSetMethod(setterBuilder); } /// /// Guarantees full depth deep copy by using serialization /// /// /// public static object DeepCopy(object oldObject) { if (oldObject == null) return null; MemoryStream ms = new MemoryStream(); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(ms, oldObject); ms.Seek(0, SeekOrigin.Begin); object retVal = formatter.Deserialize(ms); return retVal; } public static void SetProperty(object obj, string option, object val) { Type objectType = obj.GetType(); PropertyInfo propInfo = objectType.GetProperty(option); if (propInfo != null) { propInfo.SetValue(obj, val, null); } else { IMessageService msgService = ServiceProvider.Instance.GetService( typeof(IMessageService)) as IMessageService; msgService.AddMessage(MessageChannelType.Errors, "Could not set property for option: " + option); } } public static object GetProperty(object obj, string option) { Type objectType = obj.GetType(); PropertyInfo propInfo = objectType.GetProperty(option); if (propInfo != null) { return propInfo.GetValue(obj, new object[] {}); } else { IMessageService msgService = ServiceProvider.Instance.GetService( typeof(IMessageService)) as IMessageService; msgService.AddMessage(MessageChannelType.Errors, "Could not get property for option: " + option); return null; } } } }