From c9d9828221aaa571651ded4a01e21a10adcafb5e Mon Sep 17 00:00:00 2001 From: jpbruyere Date: Wed, 16 Sep 2015 15:16:45 +0200 Subject: [PATCH] * Interface.cs: * GraphicObject.cs: * TemplatedControl.cs: * CompilerServices.cs: Free references queue for dynamic bindings prevent adding reference to spurious object creation during serializer init which cause alien ref impossible to clear * testPopper.goml: f --- Tests/Interfaces/testPopper.goml | 8 +++- src/CompilerServices/CompilerServices.cs | 9 +--- src/GraphicObjects/GraphicObject.cs | 54 +++++++++++++----------- src/GraphicObjects/TemplatedControl.cs | 5 ++- src/Interface.cs | 38 +++++++++++++++-- 5 files changed, 75 insertions(+), 39 deletions(-) diff --git a/Tests/Interfaces/testPopper.goml b/Tests/Interfaces/testPopper.goml index 8f66d751..114f471a 100755 --- a/Tests/Interfaces/testPopper.goml +++ b/Tests/Interfaces/testPopper.goml @@ -1,6 +1,12 @@  - + + + + + + + diff --git a/src/CompilerServices/CompilerServices.cs b/src/CompilerServices/CompilerServices.cs index 3d4ebc5a..1f5df063 100644 --- a/src/CompilerServices/CompilerServices.cs +++ b/src/CompilerServices/CompilerServices.cs @@ -254,14 +254,7 @@ namespace go dynHandleCpt++; //register target object reference - int dstIdx = Interface.References.IndexOf(binding.Source); - - if (dstIdx < 0) { - dstIdx = Interface.References.Count; - Interface.References.Add (binding.Source); - } - - + int dstIdx = Interface.Reference(binding.Source); #region IL generation ILGenerator il = dm.GetILGenerator(256); diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs index 41720ed9..a068a0d5 100644 --- a/src/GraphicObjects/GraphicObject.cs +++ b/src/GraphicObjects/GraphicObject.cs @@ -749,7 +749,10 @@ namespace go public override string ToString () { - return Name == "unamed" ? this.GetType ().ToString() : Name; + string tmp =""; + if (Parent != null) + tmp = Parent.ToString () + tmp; + return Name == "unamed" ? tmp + "." + this.GetType ().Name : tmp + "." + Name; } #region IXmlSerializable @@ -771,11 +774,13 @@ namespace go continue; } if (mi.MemberType == MemberTypes.Event) { - Interface.GOMLResolver.Add (new DynAttribute { - Source = this, - Value = attValue, - MemberName = attName - }); + if (!Interface.DontResoveGOML) { + Interface.GOMLResolver.Add (new DynAttribute { + Source = this, + Value = attValue, + MemberName = attName + }); + } } else if (mi.MemberType == MemberTypes.Property) { PropertyInfo pi = mi as PropertyInfo; @@ -817,6 +822,8 @@ namespace go } else { if (attValue.StartsWith("{")) { + if (Interface.DontResoveGOML) + continue; //binding if (!attValue.EndsWith("}")) throw new Exception (string.Format("GOML:Malformed binding: {0}", attValue)); @@ -944,27 +951,26 @@ namespace go /// public virtual void ClearBinding(){ object ds = this.DataSource; - if (ds == null) - return; - - Type dataSourceType = ds.GetType (); - EventInfo evtInfo = dataSourceType.GetEvent ("ValueChanged"); - if (evtInfo != null) { - FieldInfo evtFi = CompilerServices.GetEventHandlerField (dataSourceType, "ValueChanged"); - MulticastDelegate multicastDelegate = evtFi.GetValue (ds) as MulticastDelegate; - if (multicastDelegate != null) { - foreach (Delegate d in multicastDelegate.GetInvocationList()) { - string dn = d.Method.Name; - if (!dn.StartsWith ("dynHandle_")) - continue; - int did = int.Parse (dn.Substring (10)); - if (this.DynamicMethodIds.Contains (did)) - evtInfo.RemoveEventHandler (ds, d); + if (ds != null) { + Type dataSourceType = ds.GetType (); + EventInfo evtInfo = dataSourceType.GetEvent ("ValueChanged"); + if (evtInfo != null) { + FieldInfo evtFi = CompilerServices.GetEventHandlerField (dataSourceType, "ValueChanged"); + MulticastDelegate multicastDelegate = evtFi.GetValue (ds) as MulticastDelegate; + if (multicastDelegate != null) { + foreach (Delegate d in multicastDelegate.GetInvocationList()) { + string dn = d.Method.Name; + if (!dn.StartsWith ("dynHandle_")) + continue; + int did = int.Parse (dn.Substring (10)); + if (this.DynamicMethodIds.Contains (did)) + evtInfo.RemoveEventHandler (ds, d); + } } } } - - Interface.References.Remove (this); + Interface.Unreference (this); + } } } diff --git a/src/GraphicObjects/TemplatedControl.cs b/src/GraphicObjects/TemplatedControl.cs index 87bbeb09..0599c6e3 100644 --- a/src/GraphicObjects/TemplatedControl.cs +++ b/src/GraphicObjects/TemplatedControl.cs @@ -104,7 +104,7 @@ namespace go { if (template == null) { DefaultTemplate dt = (DefaultTemplate)this.GetType ().GetCustomAttributes (typeof(DefaultTemplate), true).FirstOrDefault(); - this.SetChild (Interface.Load (dt.Path, this)); + this.SetChild (Interface.Load (dt.Path, this,!Interface.DontResoveGOML)); }else this.SetChild (template); } @@ -146,13 +146,14 @@ namespace go xr.Read ();//go close tag xr.Read ();//Template close tag + break; } else { xr.ReadInnerXml (); } } } } else - loadTemplate (Interface.Load (template, this)); + loadTemplate (Interface.Load (template, this, !Interface.DontResoveGOML)); //normal xml read diff --git a/src/Interface.cs b/src/Interface.cs index c3ddc8fa..723bdad7 100644 --- a/src/Interface.cs +++ b/src/Interface.cs @@ -36,6 +36,7 @@ namespace go public static bool ReplaceTabsWithSpace = false; /// Allow rendering of interface in development environment public static bool DesignerMode = false; + public static bool DontResoveGOML = false; /// Threshold to catch borders for sizing public static int BorderThreshold = 5; @@ -43,7 +44,32 @@ namespace go /// Graphic objects References use in dynamic delegates for binding /// public static List References = new List(); + public static Queue FreeRefIndices = new Queue(); + public static void Unreference(Object o) + { + int idxt = Interface.References.IndexOf (o); + if (idxt < 0) + return; + References[idxt] = null; + FreeRefIndices.Enqueue (idxt); + } + /// register target object reference in an array for binding CIL + public static int Reference(object o) + { + + int dstIdx = Interface.References.IndexOf(o); + if (dstIdx < 0) { + if (FreeRefIndices.Count == 0) { + dstIdx = Interface.References.Count; + Interface.References.Add (o); + } else { + dstIdx = FreeRefIndices.Dequeue (); + Interface.References [dstIdx] = o; + } + } + return dstIdx; + } public static LayoutingQueue LayoutingQueue = new LayoutingQueue(); #region Load/Save @@ -110,22 +136,26 @@ namespace go return t; } public static string CurrentGOMLPath; - public static GraphicObject Load(string path, object hostClass = null) + public static GraphicObject Load(string path, object hostClass = null, bool resolveGOML = true) { CurrentGOMLPath = path; using (Stream stream = GetStreamFromPath (path)) { - return Load(stream, GetTopContainerOfGOMLStream(stream), hostClass); + return Load(stream, GetTopContainerOfGOMLStream(stream), hostClass, resolveGOML); } CurrentGOMLPath = ""; } public static GraphicObject Load(Stream stream, Type type, object hostClass = null, bool resolve = true) { GraphicObject result; - GOMLResolutionStack.Push(new List()); + XmlSerializerNamespaces xn = new XmlSerializerNamespaces(); xn.Add("", ""); - XmlSerializer xs = new XmlSerializer(type); + //prevent unused ref in References created by xmlSerializer + Interface.DontResoveGOML = true; + XmlSerializer xs = new XmlSerializer(type); + Interface.DontResoveGOML = false; + GOMLResolutionStack.Push(new List()); result = (GraphicObject)xs.Deserialize(stream); result.DataSource = hostClass; -- 2.47.3