From: Jean-Philippe Bruyère Date: Mon, 17 Dec 2018 22:39:49 +0000 (+0100) Subject: search template and itemtemplate in 1)entry assembly 2)assembly where type is defined X-Git-Tag: v0.9.5-beta~142 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=4a8104cc5902a535390e5a3a0cab70102b35bf25;p=jp%2Fcrow.git search template and itemtemplate in 1)entry assembly 2)assembly where type is defined --- diff --git a/Crow/Crow.csproj b/Crow/Crow.csproj index 186019f8..dce02f07 100644 --- a/Crow/Crow.csproj +++ b/Crow/Crow.csproj @@ -65,7 +65,6 @@ - diff --git a/Crow/src/GraphicObjects/TemplatedControl.cs b/Crow/src/GraphicObjects/TemplatedControl.cs index 83a24c39..6ecdb496 100644 --- a/Crow/src/GraphicObjects/TemplatedControl.cs +++ b/Crow/src/GraphicObjects/TemplatedControl.cs @@ -25,14 +25,9 @@ // THE SOFTWARE. using System; -using System.Xml.Serialization; using System.ComponentModel; using System.IO; using System.Xml; -using System.Diagnostics; -using System.Linq; -using System.Collections.Generic; -using System.Text; using System.Reflection; using Cairo; @@ -45,7 +40,7 @@ namespace Crow { #if DESIGN_MODE public bool design_inlineTemplate = false; - public override void getIML (System.Xml.XmlDocument doc, System.Xml.XmlNode parentElem) + public override void getIML (XmlDocument doc, XmlNode parentElem) { if (this.design_isTGItem) return; @@ -57,6 +52,7 @@ namespace Crow parentElem.LastChild.AppendChild (xe); } #endif + #region CTOR protected TemplatedControl() : base(){} public TemplatedControl (Interface iface) : base(iface){} @@ -110,11 +106,8 @@ namespace Crow /// /// widget identified by name, or null if not found /// widget's name to find - public override GraphicObject FindByName (string nameToFind) - { - //prevent name searching in template - return nameToFind == this.Name ? this : null; - } + public override GraphicObject FindByName (string nameToFind) => nameToFind == this.Name ? this : null; + /// ///onDraw is overrided to prevent default drawing of background, template top container ///may have a binding to root background or a fixed one. @@ -138,7 +131,9 @@ namespace Crow #endregion /// - /// Loads the template. + /// Loads the template. Each TemplatedControl MUST provide a default template + /// It must be an embedded ressource with ID = fullTypeName.template + /// Entry assembly is search first, then the one where the type is defined /// /// Optional template instance protected virtual void loadTemplate(GraphicObject template = null) @@ -147,9 +142,18 @@ namespace Crow this.ClearTemplateBinding(); if (template == null) { - if (!IFace.DefaultTemplates.ContainsKey (this.GetType ().FullName)) - throw new Exception (string.Format ("No default template found for '{0}'", this.GetType ().FullName)); - this.SetChild (IFace.CreateInstance (IFace.DefaultTemplates[this.GetType ().FullName])); + int mdTok = this.GetType ().MetadataToken; + + if (!IFace.DefaultTemplates.ContainsKey (mdTok)) { + string defTmpId = this.GetType ().FullName + ".template"; + Stream s = Assembly.GetEntryAssembly ().GetManifestResourceStream (defTmpId); + if (s == null) + s = Assembly.GetAssembly (this.GetType ()).GetManifestResourceStream (defTmpId); + if (s == null) + throw new Exception (string.Format ("No default template found for '{0}'", this.GetType ().FullName)); + IFace.DefaultTemplates [mdTok] = new IML.Instantiator (IFace, s, defTmpId); + } + this.SetChild (IFace.DefaultTemplates[mdTok].CreateInstance()); }else this.SetChild (template); } diff --git a/Crow/src/GraphicObjects/TemplatedGroup.cs b/Crow/src/GraphicObjects/TemplatedGroup.cs index b8a7c084..3fcfd3c7 100644 --- a/Crow/src/GraphicObjects/TemplatedGroup.cs +++ b/Crow/src/GraphicObjects/TemplatedGroup.cs @@ -84,7 +84,7 @@ namespace Crow #region Templating //TODO: dont instantiate ItemTemplates if not used //but then i should test if null in msil gen - public Dictionary ItemTemplates = new Dictionary(); + public Dictionary ItemTemplates = new Dictionary(); /// /// Keep track of expanded subnodes and closed time to unload @@ -97,8 +97,7 @@ namespace Crow /// ItemTemplate file may contains either a single template without the /// ItemTemplate enclosing tag, or several item templates each enclosed /// in a separate tag. - /// - + /// public string ItemTemplate { get { return _itemTemplate; } set { diff --git a/Crow/src/Instantiator.cs b/Crow/src/Instantiator.cs index 8c5a4d46..be534d6c 100644 --- a/Crow/src/Instantiator.cs +++ b/Crow/src/Instantiator.cs @@ -25,7 +25,6 @@ // THE SOFTWARE. using System; -using System.Threading; using System.IO; using System.Text; using System.Diagnostics; @@ -34,7 +33,6 @@ using System.Reflection.Emit; using System.Reflection; using System.Collections.Generic; using System.Linq; -using Crow.IML; namespace Crow.IML { @@ -107,16 +105,16 @@ namespace Crow.IML using (XmlReader itr = XmlReader.Create (stream)) { parseIML (itr); } - stream.Dispose (); } catch (Exception ex) { throw new InstantiatorException(sourcePath, ex); } finally { - #if DEBUG_LOAD + stream?.Dispose (); +#if DEBUG_LOAD loadingTime.Stop (); using (StreamWriter sw = new StreamWriter ("loading.log", true)) { sw.WriteLine ($"ITOR;{sourcePath,-50};{loadingTime.ElapsedTicks,8};{loadingTime.ElapsedMilliseconds,8}"); } - #endif +#endif } } /// @@ -267,7 +265,7 @@ namespace Crow.IML /// the string triplet dataType, itemTmpID read as attribute of this tag /// current xml text reader /// file containing the templates if its a dedicated one - string[] parseItemTemplateTag (XmlReader reader, string itemTemplatePath = "") { + string[] parseItemTemplateTag (IMLContext ctx, XmlReader reader, string itemTemplatePath = "") { string dataType = "default", datas = "", path = "", dataTest = "TypeOf"; while (reader.MoveToNextAttribute ()) { if (reader.Name == "DataType") @@ -285,16 +283,16 @@ namespace Crow.IML if (string.IsNullOrEmpty (path)) { itemTmpID += Guid.NewGuid ().ToString (); - iface.Instantiators [itemTmpID] = + iface.ItemTemplates [itemTmpID] = new ItemTemplate (iface, new MemoryStream (Encoding.UTF8.GetBytes (reader.ReadInnerXml ())), dataTest, dataType, datas); } else { if (!reader.IsEmptyElement) throw new Exception ("ItemTemplate with Path attribute set may not include sub nodes"); itemTmpID += path+dataType+datas; - if (!iface.Instantiators.ContainsKey (itemTmpID)) - iface.Instantiators [itemTmpID] = - new ItemTemplate (iface, path, dataTest, dataType, datas); + if (!iface.ItemTemplates.ContainsKey (itemTmpID)) + iface.ItemTemplates [itemTmpID] = + new ItemTemplate (iface, path, ctx.CurrentNodeType, dataTest, dataType, datas); } return new string [] { dataType, itemTmpID, datas, dataTest }; } @@ -328,7 +326,7 @@ namespace Crow.IML reader.Read (); readChildren (reader, ctx, -1); } else if (reader.Name == "ItemTemplate") - itemTemplateIds.Add (parseItemTemplateTag (reader)); + itemTemplateIds.Add (parseItemTemplateTag (ctx, reader)); } if (!inlineTemplate) {//load from path or default template @@ -347,13 +345,11 @@ namespace Crow.IML //try to load ItemTemplate(s) from ItemTemplate attribute of TemplatedGroup if (!string.IsNullOrEmpty (itemTemplatePath)) { //check if it is already loaded in cache as a single itemTemplate instantiator - if (iface.Instantiators.ContainsKey (itemTemplatePath)) { + if (iface.ItemTemplates.ContainsKey (itemTemplatePath)) { itemTemplateIds.Add (new string [] { "default", itemTemplatePath, "" }); } else { using (Stream stream = iface.GetStreamFromPath (itemTemplatePath)) { //itemtemplate files may have multiple root nodes - if (stream == null) - Debugger.Break (); XmlReaderSettings itrSettings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment }; using (XmlReader itr = XmlReader.Create (stream, itrSettings)) { while (itr.Read ()) { @@ -362,12 +358,12 @@ namespace Crow.IML if (itr.NodeType == XmlNodeType.Element) { if (itr.Name != "ItemTemplate") { //the file contains a single template to use as default - iface.Instantiators [itemTemplatePath] = + iface.ItemTemplates [itemTemplatePath] = new ItemTemplate (iface, itr); itemTemplateIds.Add (new string [] { "default", itemTemplatePath, "", "TypeOf" }); break;//we should be at the end of the file } - itemTemplateIds.Add (parseItemTemplateTag (itr, itemTemplatePath)); + itemTemplateIds.Add (parseItemTemplateTag (ctx, itr, itemTemplatePath)); } } } @@ -390,6 +386,9 @@ namespace Crow.IML //load itemTemplate ctx.il.Emit (OpCodes.Ldarg_1);//load currentInterface ctx.il.Emit (OpCodes.Ldstr, iTempId [1]);//load path + //second arg is Type, to find assembly where to search if not in entry + ctx.il.Emit (OpCodes.Ldloc_0);//load TempControl ref + ctx.il.Emit (OpCodes.Call, CompilerServices.miGetType); ctx.il.Emit (OpCodes.Callvirt, CompilerServices.miGetITemp); ctx.il.Emit (OpCodes.Callvirt, CompilerServices.miAddITemp); @@ -1159,7 +1158,7 @@ namespace Crow.IML typeof (void), CompilerServices.argsBoundValueChange, true); - il = dm.GetILGenerator (256); + il = dm.GetILGenerator (32); System.Reflection.Emit.Label endMethod = il.DefineLabel (); @@ -1212,7 +1211,7 @@ namespace Crow.IML typeof (void), CompilerServices.argsBoundDSChange, true); - il = dm.GetILGenerator (256); + il = dm.GetILGenerator (64); il.DeclareLocal (typeof(object));//used for checking propery less bindings il.DeclareLocal (typeof(MemberInfo));//used for checking propery less bindings @@ -1230,23 +1229,9 @@ namespace Crow.IML emitRemoveOldDataSourceHandler (il, "ValueChanged", delName, true); if (!string.IsNullOrEmpty(bindingDef.TargetMember)){ - if (bindingDef.TwoWay){ -// System.Reflection.Emit.Label cancelRemove = il.DefineLabel (); -// //remove handler if not null -// il.Emit (OpCodes.Ldarg_2);//load old parent -// il.Emit (OpCodes.Ldfld, CompilerServices.fiDSCOldDS); -// il.Emit (OpCodes.Brfalse, cancelRemove);//old parent is null - - //remove handler + if (bindingDef.TwoWay)//remove handler emitRemoveOldDataSourceHandler(il, "ValueChanged", delName, false); -// il.Emit (OpCodes.Ldarg_1);//3d arg: instance bound to delegate (the source) -// il.Emit (OpCodes.Ldstr, "ValueChanged");//2nd arg event name -// il.Emit (OpCodes.Ldarg_2);//1st arg load old datasource -// il.Emit (OpCodes.Ldfld, CompilerServices.fiDSCOldDS); -// il.Emit (OpCodes.Call, CompilerServices.miRemEvtHdlByTarget); -// il.MarkLabel(cancelRemove); - } il.Emit (OpCodes.Ldloc_2); il.Emit (OpCodes.Brfalse, newDSIsNull);//new ds is null } @@ -1339,7 +1324,6 @@ namespace Crow.IML System.Reflection.Emit.Label endMethod = il.DefineLabel (); - il.DeclareLocal (typeof(object)); il.Emit (OpCodes.Nop); //load value changed member name onto the stack @@ -1358,7 +1342,8 @@ namespace Crow.IML il.Emit (OpCodes.Ldarg_2); il.Emit (OpCodes.Ldfld, CompilerServices.fiVCNewValue); - CompilerServices.emitConvert (il, piOrig.PropertyType, piDest.PropertyType); + //if (piOrig.PropertyType != piDest.PropertyType) + CompilerServices.emitConvert (il, piOrig.PropertyType, piDest.PropertyType); il.Emit (OpCodes.Callvirt, piDest.GetSetMethod ()); diff --git a/Crow/src/Interface.cs b/Crow/src/Interface.cs index f4743402..99e385c9 100644 --- a/Crow/src/Interface.cs +++ b/Crow/src/Interface.cs @@ -188,7 +188,7 @@ namespace Crow { while (running) { Update (); - Thread.Sleep (20); + Thread.Sleep (1); } } @@ -234,7 +234,6 @@ namespace Crow CurrentInterface = this; //loadCursors (); loadStyling (); - findAvailableTemplates (); #if MEASURE_TIME PerfMeasures.Add (updateMeasure); @@ -356,6 +355,15 @@ namespace Crow /// on the first instance creation of a IML item. /// public Dictionary Instantiators = new Dictionary(); + /// + /// default templates dic by metadata token + /// + public Dictionary DefaultTemplates = new Dictionary (); + /// + /// Item templates stored with their index + /// + public Dictionary ItemTemplates = new Dictionary (); + public List CrowThreads = new List();//used to monitor thread finished public DragDropEventArgs DragAndDropOperation = null; @@ -414,44 +422,6 @@ namespace Crow #endregion - #region Templates - /// Store one default templates resource ID per class. - /// Resource ID must be 'fullClassName.template' (not case sensitive) - /// Those found in application assembly have priority to the default Crow's one - /// - public Dictionary DefaultTemplates; - /// Finds available default templates at startup - void findAvailableTemplates(){ - DefaultTemplates = new Dictionary(); - searchTemplatesOnDisk ("./"); - string defTemplatePath = System.IO.Path.Combine (CrowConfigRoot, "defaultTemplates"); - searchTemplatesOnDisk (defTemplatePath); - searchTemplatesIn (Assembly.GetEntryAssembly ()); - searchTemplatesIn (Assembly.GetExecutingAssembly ()); - } - void searchTemplatesOnDisk (string templatePath){ - if (!Directory.Exists (templatePath)) - return; - foreach (string f in Directory.GetFiles(templatePath, "*.template",SearchOption.AllDirectories)) { - string clsName = System.IO.Path.GetFileNameWithoutExtension(f); - if (DefaultTemplates.ContainsKey (clsName)) - continue; - DefaultTemplates [clsName] = f; - } - } - void searchTemplatesIn(Assembly assembly){ - if (assembly == null) - return; - foreach (string resId in assembly - .GetManifestResourceNames () - .Where (r => r.EndsWith (".template", StringComparison.OrdinalIgnoreCase))) { - string clsName = resId.Substring (0, resId.Length - 9); - if (DefaultTemplates.ContainsKey (clsName)) - continue; - DefaultTemplates[clsName] = "#" + resId; - } - } - #endregion #region Load/Save /// Open file or find a resource from path string @@ -486,14 +456,12 @@ namespace Crow if (path.StartsWith ("#", StringComparison.Ordinal)) { string resId = path.Substring (1); //try/catch added to prevent nunit error - try { - stream = Assembly.GetEntryAssembly ().GetManifestResourceStream (resId); - } catch{} + stream = Assembly.GetEntryAssembly ().GetManifestResourceStream (resId); if (stream == null)//try to find ressource in Crow assembly stream = Assembly.GetExecutingAssembly ().GetManifestResourceStream (resId); if (stream == null) throw new Exception("Resource not found: " + path); - + Console.WriteLine(Assembly.GetEntryAssembly ().GetName ()); } else { if (!File.Exists (path)) throw new FileNotFoundException ("File not found: ", path); @@ -561,10 +529,10 @@ namespace Crow /// try to fetch the requested one in the cache or create it. /// They have additional properties for recursivity and /// custom display per item type - public virtual ItemTemplate GetItemTemplate(string path){ - if (!Instantiators.ContainsKey(path)) - Instantiators [path] = new ItemTemplate(this, path); - return Instantiators [path] as ItemTemplate; + public virtual ItemTemplate GetItemTemplate(string path, Type declaringType){ + if (!ItemTemplates.ContainsKey(path)) + ItemTemplates [path] = new ItemTemplate(this, path, declaringType); + return ItemTemplates [path] as ItemTemplate; } #endregion diff --git a/Crow/src/ItemTemplate.cs b/Crow/src/ItemTemplate.cs index a12823cc..a27ddeaf 100644 --- a/Crow/src/ItemTemplate.cs +++ b/Crow/src/ItemTemplate.cs @@ -96,6 +96,24 @@ namespace Crow string fetchMethodName; string dataTest; + static Stream getItemTemplateStream (string path, Type declaringType) + { + Stream s = null; + if (path.StartsWith ("#", StringComparison.Ordinal)) { + string resId = path.Substring (1); + s = Assembly.GetEntryAssembly ().GetManifestResourceStream (resId); + if (s == null) + s = Assembly.GetAssembly (declaringType).GetManifestResourceStream (resId); + if (s == null) + throw new Exception ($"Item Template not found '{path}'"); + } else { + if (!File.Exists (path)) + throw new FileNotFoundException ("Item Template not found: ", path); + s = new FileStream (path, FileMode.Open, FileAccess.Read); + } + return s; + } + #region CTOR /// /// Initializes a new instance of the class by parsing the file passed as argument. @@ -103,13 +121,14 @@ namespace Crow /// IML file to parse /// type this item will be choosen for, or member of the data item /// for hierarchical data, method to call for children fetching - public ItemTemplate(Interface _iface, string path, string _dataTest = "TypeOf", string _dataType = "default", string _fetchDataMethod = null) - : base(_iface, path) { + public ItemTemplate (Interface _iface, string path, Type declaringType, string _dataTest = "TypeOf", string _dataType = "default", string _fetchDataMethod = null) + : base(_iface, getItemTemplateStream(path, declaringType)) { strDataType = _dataType; fetchMethodName = _fetchDataMethod; dataTest = _dataTest; } + /// /// Initializes a new instance of the class by parsing the IML fragment passed as arg. /// diff --git a/Crow/src/backends/xcb/XCBBackend.cs b/Crow/src/backends/xcb/XCBBackend.cs index b4199968..93a9be63 100644 --- a/Crow/src/backends/xcb/XCBBackend.cs +++ b/Crow/src/backends/xcb/XCBBackend.cs @@ -50,6 +50,7 @@ namespace Crow.XCB { const byte XCB_COPY_FROM_PARENT = 0; + #region struct an enums enum xcb_window_class_t : ushort { COPY_FROM_PARENT = 0, @@ -319,11 +320,11 @@ namespace Crow.XCB public UInt16 sequence; /**< Sequence number */ public UInt32 length; /**< Length of the response */ } - + #endregion #region pinvoke XCB - [DllImportAttribute("xcb")] + [DllImportAttribute ("xcb")] static extern IntPtr xcb_connect(string displayName, IntPtr screenNum); [DllImportAttribute("xcb")] static extern IntPtr xcb_get_setup(IntPtr connection); @@ -416,7 +417,7 @@ namespace Crow.XCB IntPtr visual = findVisual (scr_it, scr.root_visual); - //loadCursors (); + loadCursors (); iFace.surf = new Cairo.XcbSurface (conn, win, visual, iFace.ClientRectangle.Width, iFace.ClientRectangle.Height); }