// SyncContext.cs // // Author: // Lluis Sanchez Gual // // Copyright (c) 2005 Novell, Inc (http://www.novell.com) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // // using System; using System.Text; using System.Collections; using System.Reflection; using System.Reflection.Emit; using System.Runtime.Remoting.Contexts; using System.Runtime.Remoting.Messaging; using System.Runtime.Remoting.Activation; namespace MonoDevelop.Ide.Gui { public class SyncContext { [ThreadStatic] static SyncContext context; static Hashtable delegateFactories = new Hashtable (); static ModuleBuilder module; static AssemblyBuilder asmBuilder; static int typeCounter; public static void SetContext (SyncContext ctx) { context = ctx; } public static SyncContext GetContext () { return context; } public virtual void Dispatch (StatefulMessageHandler cb, object ob) { cb (ob); } public virtual void AsyncDispatch (StatefulMessageHandler cb, object ob) { cb.BeginInvoke (ob, null, null); } public Delegate CreateSynchronizedDelegate (Delegate del) { lock (delegateFactories.SyncRoot) { Type delType = del.GetType(); IDelegateFactory factory = delegateFactories [delType] as IDelegateFactory; if (factory == null) { Type t = GetDelegateFactoryType (delType); factory = Activator.CreateInstance (t) as IDelegateFactory; delegateFactories [delType] = factory; } return factory.Create (del, this); } } Type GetDelegateFactoryType (Type delegateType) { MethodInfo invoke = delegateType.GetMethod ("Invoke"); ModuleBuilder module = GetModuleBuilder (); // *** Data class StringBuilder typeNameBuilder = new StringBuilder (); typeNameBuilder.Append ("__"); typeNameBuilder.Append (delegateType.Name); Type[] generics = delegateType.GetGenericArguments (); if (generics != null) { foreach (Type t in generics) { typeNameBuilder.Append ("_"); typeNameBuilder.Append (t.Name); } } TypeBuilder dataTypeBuilder = module.DefineType (typeNameBuilder + "_DelegateData_" + (typeCounter++), TypeAttributes.Public, typeof(object), Type.EmptyTypes); // Parameters ParameterInfo[] pars = invoke.GetParameters (); FieldBuilder[] paramFields = new FieldBuilder [pars.Length]; Type[] paramTypes = new Type[pars.Length]; for (int n=0; n