aboutsummaryrefslogtreecommitdiffstatsci
path: root/src
diff options
context:
space:
mode:
authorj-p <jp.bruyere@live.be>2016-08-11 04:20:36 +0200
committerGitHub <noreply@github.com>2016-08-11 04:20:36 +0200
commit81eb8c7a75ffbe8b6740b2a84a9ebff75da9b393 (patch)
tree3225277358a2bba61c4496923ba39353c942098b /src
parent4d4a9116ea5c68b27f0b7c43db9682ab57738ae7 (diff)
parent7560c0bb4a769210e289e2633ddf13d2617f8e6e (diff)
Merge pull request #18 from jpbruyere/BindingImprovement
Instantiator
Diffstat (limited to 'src')
-rw-r--r--src/CompilerServices/Bindings.cs27
-rw-r--r--src/CompilerServices/CompilerServices.cs124
-rw-r--r--src/GraphicObjects/Container.cs4
-rw-r--r--src/GraphicObjects/GraphicObject.cs191
-rw-r--r--src/GraphicObjects/Grid.cs5
-rw-r--r--src/GraphicObjects/Group.cs11
-rw-r--r--src/GraphicObjects/ListBox.cs14
-rw-r--r--src/GraphicObjects/PrivateContainer.cs4
-rw-r--r--src/GraphicObjects/ProgressBar.cs8
-rw-r--r--src/GraphicObjects/Scroller.cs4
-rw-r--r--src/GraphicObjects/TabView.cs4
-rw-r--r--src/GraphicObjects/TemplatedControl.cs19
-rw-r--r--src/GraphicObjects/TextBox.cs5
-rw-r--r--src/IMLReader.cs336
-rw-r--r--src/Instantiator.cs104
-rw-r--r--src/Interface.cs91
-rw-r--r--src/ItemTemplate.cs (renamed from src/IMLStream.cs)65
-rw-r--r--src/LayoutingQueueItem.cs4
18 files changed, 720 insertions, 300 deletions
diff --git a/src/CompilerServices/Bindings.cs b/src/CompilerServices/Bindings.cs
index 8ece856c..64f412f6 100644
--- a/src/CompilerServices/Bindings.cs
+++ b/src/CompilerServices/Bindings.cs
@@ -41,6 +41,11 @@ namespace Crow
public string DynMethodId {
get { return dynMethodId; }
}
+ public Type SourceType {
+ get { return Source == null ? null
+ : Source.Instance == null ? null
+ : Source.Instance.GetType();}
+ }
public bool Resolved {
get { return resolved; }
@@ -123,10 +128,12 @@ namespace Crow
//datasource binding
object dataSource = (Source.Instance as GraphicObject).DataSource;
if (dataSource == null) {
+ #if DEBUG_BINDING
Debug.WriteLine ("\tDataSource is null => " + this.ToString());
+ #endif
return false;
}
-
+
Target = new MemberReference (dataSource);
memberName = bindingExp [0];
} else {
@@ -148,7 +155,7 @@ namespace Crow
while (ptr < bindingExp.Length - 1) {
if (tmpTarget == null) {
#if DEBUG_BINDING
- Debug.WriteLine ("\tERROR: target not found => " + this.ToString());
+ Debug.WriteLine ("\tTarget not found => " + this.ToString());
#endif
return false;
}
@@ -164,14 +171,12 @@ namespace Crow
}
if (tmpTarget == null) {
-#if DEBUG_BINDING
- Debug.WriteLine ("\tERROR: Binding Target not found => " + this.ToString());
-#endif
+ #if DEBUG_BINDING
+ Debug.WriteLine ("\tBinding Target not found => " + this.ToString());
+ #endif
return false;
}
- Target = new MemberReference (tmpTarget);
-
string [] bindTrg = bindingExp [ptr].Split ('.');
if (bindTrg.Length == 1)
@@ -182,6 +187,14 @@ namespace Crow
} else
throw new Exception ("Syntax error in binding, expected 'go dot member'");
+ if (tmpTarget == null) {
+ #if DEBUG_BINDING
+ Debug.WriteLine ("\tBinding Target not found => " + this.ToString());
+ #endif
+ return false;
+ }
+
+ Target = new MemberReference (tmpTarget);
}
if (Target.TryFindMember (memberName)) {
diff --git a/src/CompilerServices/CompilerServices.cs b/src/CompilerServices/CompilerServices.cs
index 0b69f970..d06cd29b 100644
--- a/src/CompilerServices/CompilerServices.cs
+++ b/src/CompilerServices/CompilerServices.cs
@@ -5,12 +5,136 @@ using System.Diagnostics;
using System.Linq;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
+using System.Xml;
namespace Crow
{
public static class CompilerServices
{
+ static MethodInfo miAddBinding = typeof(GraphicObject).GetMethod ("BindMember");
+
+
+ public static void emitBindingCreation(ILGenerator il, string memberName, string expression){
+ il.Emit (OpCodes.Ldloc_0);
+ il.Emit (OpCodes.Ldstr, memberName);
+ il.Emit (OpCodes.Ldstr, expression);
+ il.Emit (OpCodes.Callvirt, miAddBinding);
+ }
+
+ public static void EmitSetValue(ILGenerator il, PropertyInfo pi, object val){
+ il.Emit (OpCodes.Ldloc_0);
+
+ if (val == null) {
+ il.Emit (OpCodes.Ldnull);
+ il.Emit (OpCodes.Callvirt, pi.GetSetMethod ());
+ return;
+ }
+ Type dvType = val.GetType ();
+
+ if (dvType.IsValueType) {
+ if (pi.PropertyType.IsValueType) {
+ if (pi.PropertyType.IsEnum) {
+ if (pi.PropertyType != dvType)
+ throw new Exception ("Enum mismatch in default values: " + pi.PropertyType.FullName);
+ il.Emit (OpCodes.Ldc_I4, Convert.ToInt32 (val));
+ } else {
+ switch (Type.GetTypeCode (dvType)) {
+ case TypeCode.Boolean:
+ if ((bool)val == true)
+ il.Emit (OpCodes.Ldc_I4_1);
+ else
+ il.Emit (OpCodes.Ldc_I4_0);
+ break;
+ // case TypeCode.Empty:
+ // break;
+ // case TypeCode.Object:
+ // break;
+ // case TypeCode.DBNull:
+ // break;
+ // case TypeCode.SByte:
+ // break;
+ // case TypeCode.Decimal:
+ // break;
+ // case TypeCode.DateTime:
+ // break;
+ case TypeCode.Char:
+ il.Emit (OpCodes.Ldc_I4, Convert.ToChar (val));
+ break;
+ case TypeCode.Byte:
+ case TypeCode.Int16:
+ case TypeCode.Int32:
+ il.Emit (OpCodes.Ldc_I4, Convert.ToInt32 (val));
+ break;
+ case TypeCode.UInt16:
+ case TypeCode.UInt32:
+ il.Emit (OpCodes.Ldc_I4, Convert.ToUInt32 (val));
+ break;
+ case TypeCode.Int64:
+ il.Emit (OpCodes.Ldc_I8, Convert.ToInt64 (val));
+ break;
+ case TypeCode.UInt64:
+ il.Emit (OpCodes.Ldc_I8, Convert.ToUInt64 (val));
+ break;
+ case TypeCode.Single:
+ il.Emit (OpCodes.Ldc_R4, Convert.ToSingle (val));
+ break;
+ case TypeCode.Double:
+ il.Emit (OpCodes.Ldc_R8, Convert.ToDouble (val));
+ break;
+ case TypeCode.String:
+ il.Emit (OpCodes.Ldstr, Convert.ToString (val));
+ break;
+ default:
+ il.Emit (OpCodes.Pop);
+ return;
+ }
+ }
+ } else
+ throw new Exception ("Expecting valuetype in default values for: " + pi.Name);
+ }else{
+ //surely a class or struct
+ if (dvType != typeof(string))
+ throw new Exception ("Expecting String in default values for: " + pi.Name);
+ if (pi.PropertyType == typeof(string))
+ il.Emit (OpCodes.Ldstr, Convert.ToString (val));
+ else if (pi.PropertyType.IsEnum) {
+ MethodInfo miParse = typeof(Enum).GetMethod
+ ("Parse", BindingFlags.Static | BindingFlags.Public,
+ Type.DefaultBinder, new Type [] {typeof (Type), typeof (string), typeof (bool)}, null);
+
+ if (miParse == null)
+ throw new Exception ("Enum Parse method not found");
+
+ //load type of enum
+ il.Emit(OpCodes.Ldtoken, pi.PropertyType);
+ il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle", new
+ Type[1]{typeof(RuntimeTypeHandle)}));
+ //load enum value name
+ il.Emit (OpCodes.Ldstr, Convert.ToString (val));//TODO:is this convert required?
+ //load false
+ il.Emit (OpCodes.Ldc_I4_0);
+ il.Emit (OpCodes.Callvirt, miParse);
+
+ if (miParse.ReturnType != pi.PropertyType)
+ il.Emit (OpCodes.Unbox_Any, pi.PropertyType);
+ } else {
+ MethodInfo miParse = pi.PropertyType.GetMethod
+ ("Parse", BindingFlags.Static | BindingFlags.Public,
+ Type.DefaultBinder, new Type [] {typeof (string)},null);
+ if (miParse == null)
+ throw new Exception ("no Parse method found for: " + pi.PropertyType.FullName);
+
+ il.Emit (OpCodes.Ldstr, Convert.ToString (val));//TODO:is this convert required?
+ il.Emit (OpCodes.Callvirt, miParse);
+
+ if (miParse.ReturnType != pi.PropertyType)
+ il.Emit (OpCodes.Unbox_Any, pi.PropertyType);
+ }
+ }
+ il.Emit (OpCodes.Callvirt, pi.GetSetMethod ());
+ }
+
public static void ResolveBindings (List<Binding> Bindings)
{
if (Bindings == null)
diff --git a/src/GraphicObjects/Container.cs b/src/GraphicObjects/Container.cs
index 69e3a3b4..fb4a7834 100644
--- a/src/GraphicObjects/Container.cs
+++ b/src/GraphicObjects/Container.cs
@@ -25,9 +25,9 @@ namespace Crow
get { return child; }
set { child = value; }
}
- public virtual T SetChild<T> (T _child)
+ public virtual void SetChild(GraphicObject _child)
{
- return base.SetChild (_child);
+ base.SetChild (_child);
}
#region IXmlSerializable
diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs
index 8966acf6..88166fe6 100644
--- a/src/GraphicObjects/GraphicObject.cs
+++ b/src/GraphicObjects/GraphicObject.cs
@@ -513,7 +513,7 @@ namespace Crow
#endregion
/// <summary> Loads the default values from XML attributes default </summary>
- protected virtual void loadDefaultValues()
+ public void loadDefaultValues()
{
#if DEBUG_LOAD
Debug.WriteLine ("LoadDefValues for " + this.ToString ());
@@ -581,151 +581,70 @@ namespace Crow
typeof(void),new Type[] {typeof(object)},thisType,true);
il = dm.GetILGenerator(256);
-
+ il.DeclareLocal(typeof(GraphicObject));
il.Emit(OpCodes.Nop);
+ //set local GraphicObject to root object passed as 1st argument
+ il.Emit (OpCodes.Ldarg_0);
+ il.Emit (OpCodes.Stloc_0);
- foreach (PropertyInfo pi in thisType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
- string name = "";
- object defaultValue = null;
-
- #region retrieve custom attributes
+ foreach (PropertyInfo pi in thisType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
if (pi.GetSetMethod () == null)
continue;
-
- XmlIgnoreAttribute xia = (XmlIgnoreAttribute)pi.GetCustomAttribute (typeof(XmlIgnoreAttribute));
- if (xia != null)
- continue;
- XmlAttributeAttribute xaa = (XmlAttributeAttribute)pi.GetCustomAttribute (typeof(XmlAttributeAttribute));
- if (xaa != null) {
- if (string.IsNullOrEmpty (xaa.AttributeName))
- name = pi.Name;
- else
- name = xaa.AttributeName;
- }
-
- int styleIndex = -1;
- if (styling.Count > 0){
- for (int i = 0; i < styling.Count; i++) {
- if (styling[i].ContainsKey (name)){
- styleIndex = i;
- break;
- }
- }
- }
- if (styleIndex >= 0){
- if (pi.PropertyType.IsEnum)//maybe should be in parser..
- defaultValue = Enum.Parse(pi.PropertyType, (string)styling[styleIndex] [name], true);
- else
- defaultValue = styling[styleIndex] [name];
- }else {
- DefaultValueAttribute dv = (DefaultValueAttribute)pi.GetCustomAttribute (typeof (DefaultValueAttribute));
- if (dv == null)
- continue;
- defaultValue = dv.Value;
- }
- #endregion
-
- il.Emit (OpCodes.Ldarg_0);
-
- if (defaultValue == null) {
- il.Emit (OpCodes.Ldnull);
- il.Emit (OpCodes.Callvirt, pi.GetSetMethod ());
+ object defaultValue;
+ if (!getDefaultValue (pi, styling, out defaultValue))
continue;
- }
- Type dvType = defaultValue.GetType ();
-
- if (dvType.IsValueType) {
- if (pi.PropertyType.IsValueType) {
- if (pi.PropertyType.IsEnum) {
- if (pi.PropertyType != dvType)
- throw new Exception ("Enum mismatch in default values: " + pi.PropertyType.FullName);
- il.Emit (OpCodes.Ldc_I4, Convert.ToInt32 (defaultValue));
- } else {
- switch (Type.GetTypeCode (dvType)) {
- case TypeCode.Boolean:
- if ((bool)defaultValue == true)
- il.Emit (OpCodes.Ldc_I4_1);
- else
- il.Emit (OpCodes.Ldc_I4_0);
- break;
-// case TypeCode.Empty:
-// break;
-// case TypeCode.Object:
-// break;
-// case TypeCode.DBNull:
-// break;
-// case TypeCode.SByte:
-// break;
-// case TypeCode.Decimal:
-// break;
-// case TypeCode.DateTime:
-// break;
- case TypeCode.Char:
- il.Emit (OpCodes.Ldc_I4, Convert.ToChar (defaultValue));
- break;
- case TypeCode.Byte:
- case TypeCode.Int16:
- case TypeCode.Int32:
- il.Emit (OpCodes.Ldc_I4, Convert.ToInt32 (defaultValue));
- break;
- case TypeCode.UInt16:
- case TypeCode.UInt32:
- il.Emit (OpCodes.Ldc_I4, Convert.ToUInt32 (defaultValue));
- break;
- case TypeCode.Int64:
- il.Emit (OpCodes.Ldc_I8, Convert.ToInt64 (defaultValue));
- break;
- case TypeCode.UInt64:
- il.Emit (OpCodes.Ldc_I8, Convert.ToUInt64 (defaultValue));
- break;
- case TypeCode.Single:
- il.Emit (OpCodes.Ldc_R4, Convert.ToSingle (defaultValue));
- break;
- case TypeCode.Double:
- il.Emit (OpCodes.Ldc_R8, Convert.ToDouble (defaultValue));
- break;
- case TypeCode.String:
- il.Emit (OpCodes.Ldstr, Convert.ToString (defaultValue));
- break;
- default:
- il.Emit (OpCodes.Pop);
- continue;
- }
- }
- } else
- throw new Exception ("Expecting valuetype in default values for: " + pi.Name);
- }else{
- //surely a class or struct
- if (dvType != typeof(string))
- throw new Exception ("Expecting String in default values for: " + pi.Name);
- if (pi.PropertyType == typeof (string))
- il.Emit (OpCodes.Ldstr, Convert.ToString (defaultValue));
- else {
- MethodInfo miParse = pi.PropertyType.GetMethod
- ("Parse", BindingFlags.Static | BindingFlags.Public,
- Type.DefaultBinder, new Type [] {typeof (string)},null);
- if (miParse == null)
- throw new Exception ("no Parse method found for: " + pi.PropertyType.FullName);
- il.Emit (OpCodes.Ldstr, Convert.ToString (defaultValue));
- il.Emit (OpCodes.Callvirt, miParse);
-
- if (miParse.ReturnType != pi.PropertyType)
- il.Emit (OpCodes.Unbox_Any, pi.PropertyType);
- }
- }
- il.Emit (OpCodes.Callvirt, pi.GetSetMethod ());
+ CompilerServices.EmitSetValue (il, pi, defaultValue);
}
il.Emit(OpCodes.Ret);
#endregion
try {
- Interface.DefaultValuesLoader[styleKey] = (Interface.loadDefaultInvoker)dm.CreateDelegate(typeof(Interface.loadDefaultInvoker));
+ Interface.DefaultValuesLoader[styleKey] = (Interface.LoaderInvoker)dm.CreateDelegate(typeof(Interface.LoaderInvoker));
Interface.DefaultValuesLoader[styleKey] (this);
} catch (Exception ex) {
throw new Exception ("Error applying style <" + styleKey + ">:", ex);
}
}
+ bool getDefaultValue(PropertyInfo pi, List<Dictionary<string, object>> styling,
+ out object defaultValue){
+ defaultValue = null;
+ string name = "";
+
+ XmlIgnoreAttribute xia = (XmlIgnoreAttribute)pi.GetCustomAttribute (typeof(XmlIgnoreAttribute));
+ if (xia != null)
+ return false;
+ XmlAttributeAttribute xaa = (XmlAttributeAttribute)pi.GetCustomAttribute (typeof(XmlAttributeAttribute));
+ if (xaa != null) {
+ if (string.IsNullOrEmpty (xaa.AttributeName))
+ name = pi.Name;
+ else
+ name = xaa.AttributeName;
+ }
+
+ int styleIndex = -1;
+ if (styling.Count > 0){
+ for (int i = 0; i < styling.Count; i++) {
+ if (styling[i].ContainsKey (name)){
+ styleIndex = i;
+ break;
+ }
+ }
+ }
+ if (styleIndex >= 0){
+ if (pi.PropertyType.IsEnum)//maybe should be in parser..
+ defaultValue = Enum.Parse(pi.PropertyType, (string)styling[styleIndex] [name], true);
+ else
+ defaultValue = styling[styleIndex] [name];
+ }else {
+ DefaultValueAttribute dv = (DefaultValueAttribute)pi.GetCustomAttribute (typeof (DefaultValueAttribute));
+ if (dv == null)
+ return false;
+ defaultValue = dv.Value;
+ }
+ return true;
+ }
+
public virtual GraphicObject FindByName(string nameToFind){
return string.Equals(nameToFind, _name, StringComparison.Ordinal) ? this : null;
@@ -757,6 +676,18 @@ namespace Crow
if (RegisteredLayoutings == LayoutingType.None)
Interface.CurrentInterface.EnqueueForRepaint (this);
}
+// public Interface CurrentInterface {
+// get {
+// ILayoutable tmp = this.Parent;
+// while (tmp != null) {
+// if (tmp is Interface)
+// return tmp as Interface;
+// tmp = tmp.Parent;
+// }
+// return null;
+// }
+// }
+
#region Layouting
#if DEBUG_LAYOUTING
diff --git a/src/GraphicObjects/Grid.cs b/src/GraphicObjects/Grid.cs
index 525827e0..ed0cd986 100644
--- a/src/GraphicObjects/Grid.cs
+++ b/src/GraphicObjects/Grid.cs
@@ -29,11 +29,10 @@ namespace Crow
int _rowCount;
#endregion
- public override T AddChild<T> (T child)
+ public override void AddChild (GraphicObject child)
{
- T tmp = base.AddChild (child);
+ base.AddChild (child);
this.RegisterForLayouting (LayoutingType.ArrangeChildren);
- return tmp;
}
public override void RemoveChild (GraphicObject child)
{
diff --git a/src/GraphicObjects/Group.cs b/src/GraphicObjects/Group.cs
index a6ca5758..4c8d0537 100644
--- a/src/GraphicObjects/Group.cs
+++ b/src/GraphicObjects/Group.cs
@@ -38,19 +38,14 @@ namespace Crow
get { return _multiSelect; }
set { _multiSelect = value; }
}
-
-
- public virtual T AddChild<T>(T child)
- {
- GraphicObject g = child as GraphicObject;
+ public virtual void AddChild(GraphicObject g){
Children.Add(g);
- g.Parent = this as GraphicObject;
+ g.Parent = this;
g.ResolveBindings ();
g.RegisteredLayoutings = LayoutingType.None;
g.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren);
g.LayoutChanged += OnChildLayoutChanges;
- return (T)child;
- }
+ }
public virtual void RemoveChild(GraphicObject child)
{
child.LayoutChanged -= OnChildLayoutChanges;
diff --git a/src/GraphicObjects/ListBox.cs b/src/GraphicObjects/ListBox.cs
index 58d41e0b..ab349ed4 100644
--- a/src/GraphicObjects/ListBox.cs
+++ b/src/GraphicObjects/ListBox.cs
@@ -119,7 +119,7 @@ namespace Crow
if (ItemTemplates == null)
ItemTemplates = new Dictionary<string, ItemTemplate> ();
if (!ItemTemplates.ContainsKey ("default"))
- ItemTemplates["default"] = new ItemTemplate (ItemTemplate);
+ ItemTemplates ["default"] = Interface.GetItemTemplate (ItemTemplate);
for (int i = 1; i <= (data.Count / itemPerPage) + 1; i++) {
if (cancelLoading)
@@ -164,16 +164,16 @@ namespace Crow
return;
GraphicObject g = null;
- ItemTemplate itemStream = null;
+ ItemTemplate iTemp = null;
Type dataType = data [i].GetType ();
if (ItemTemplates.ContainsKey (dataType.FullName))
- itemStream = ItemTemplates [dataType.FullName];
+ iTemp = ItemTemplates [dataType.FullName];
else
- itemStream = ItemTemplates ["default"];
+ iTemp = ItemTemplates ["default"];
lock (Interface.CurrentInterface.LayoutMutex) {
- g = itemStream.Instance;
+ g = iTemp.CreateInstance();
page.AddChild (g);
g.DataSource = data [i];
}
@@ -190,8 +190,8 @@ namespace Crow
}else
g.MouseClick += itemClick;
- if (itemStream.Expand != null && g is Expandable) {
- (g as Expandable).Expand += itemStream.Expand;
+ if (iTemp.Expand != null && g is Expandable) {
+ (g as Expandable).Expand += iTemp.Expand;
}
//g.LogicalParent = this;
}
diff --git a/src/GraphicObjects/PrivateContainer.cs b/src/GraphicObjects/PrivateContainer.cs
index 8793ba45..a6f52f29 100644
--- a/src/GraphicObjects/PrivateContainer.cs
+++ b/src/GraphicObjects/PrivateContainer.cs
@@ -47,7 +47,7 @@ namespace Crow
protected GraphicObject child;
- protected virtual T SetChild<T>(T _child)
+ internal virtual void SetChild(GraphicObject _child)
{
if (child != null) {
@@ -67,8 +67,6 @@ namespace Crow
child.RegisteredLayoutings = LayoutingType.None;
child.RegisterForLayouting (LayoutingType.Sizing);
}
-
- return (T)_child;
}
#region GraphicObject Overrides
diff --git a/src/GraphicObjects/ProgressBar.cs b/src/GraphicObjects/ProgressBar.cs
index e3f778bf..6e1ce404 100644
--- a/src/GraphicObjects/ProgressBar.cs
+++ b/src/GraphicObjects/ProgressBar.cs
@@ -9,7 +9,7 @@ using System.ComponentModel;
namespace Crow
{
- [Serializable]
+
public class ProgressBar : NumericControl
{
#region CTOR
@@ -22,12 +22,6 @@ namespace Crow
}
#region GraphicObject overrides
- [XmlAttributeAttribute()][DefaultValue("vgradient|0:BlueCrayola|0,5:SkyBlue|1:BlueCrayola")]
- public override Fill Foreground {
- get { return base.Foreground; }
- set { base.Foreground = value; }
- }
-
protected override void onDraw (Context gr)
{
base.onDraw (gr);
diff --git a/src/GraphicObjects/Scroller.cs b/src/GraphicObjects/Scroller.cs
index 3eaff5f4..c248595d 100644
--- a/src/GraphicObjects/Scroller.cs
+++ b/src/GraphicObjects/Scroller.cs
@@ -148,7 +148,7 @@ namespace Crow
ScrollY = 0;
ScrollX = 0;
}
- public override T SetChild<T> (T _child)
+ public override void SetChild (GraphicObject _child)
{
GraphicObject c = child as GraphicObject;
Group g = child as Group;
@@ -164,7 +164,7 @@ namespace Crow
if (g != null)
g.ChildrenCleared += onChildListCleared;
}
- return base.SetChild (_child);
+ base.SetChild (_child);
}
#endregion
diff --git a/src/GraphicObjects/TabView.cs b/src/GraphicObjects/TabView.cs
index d616ffc6..015f5f4f 100644
--- a/src/GraphicObjects/TabView.cs
+++ b/src/GraphicObjects/TabView.cs
@@ -100,7 +100,7 @@ namespace Crow
set { }
}
- public override T AddChild<T> (T child)
+ public override void AddChild (GraphicObject child)
{
TabItem ti = child as TabItem;
if (ti == null)
@@ -113,7 +113,7 @@ namespace Crow
SelectedTab = 0;
}
- return base.AddChild (child);
+ base.AddChild (child);
}
public override void RemoveChild (GraphicObject child)
{
diff --git a/src/GraphicObjects/TemplatedControl.cs b/src/GraphicObjects/TemplatedControl.cs
index b325a0d2..422a45ec 100644
--- a/src/GraphicObjects/TemplatedControl.cs
+++ b/src/GraphicObjects/TemplatedControl.cs
@@ -65,8 +65,8 @@ namespace Crow
string _template;
string _itemTemplate;
- public Dictionary<string, ItemTemplate> ItemTemplates;
-
+ public Dictionary<string, ItemTemplate> ItemTemplates = new Dictionary<string, Crow.ItemTemplate>();//TODO: dont instantiate if not used
+ //but then i should test if null in msil gen
[XmlAttributeAttribute][DefaultValue(null)]
public string Template {
get { return _template; }
@@ -84,7 +84,7 @@ namespace Crow
[XmlAttributeAttribute][DefaultValue("#Crow.Templates.ItemTemplate.goml")]
public string ItemTemplate {
get { return _itemTemplate; }
- set {
+ set {
if (value == _itemTemplate)
return;
@@ -146,7 +146,7 @@ namespace Crow
xr.Read (); //read first child
xr.Read (); //skip root node
- while (!xr.EOF) {
+ while (!xr.EOF) {
if (!xr.IsStartElement ()) {
xr.Read ();
continue;
@@ -164,10 +164,13 @@ namespace Crow
if (ItemTemplates == null)
ItemTemplates = new Dictionary<string, ItemTemplate> ();
- //TODO:check encoding
- ItemTemplates[dataType] = new ItemTemplate (Encoding.UTF8.GetBytes(itemTmp));
+
+ using (IMLReader iTmp = new IMLReader (null, itemTmp)) {
+ ItemTemplates [dataType] =
+ new ItemTemplate (iTmp.RootType, iTmp.GetLoader (), dataType, datas);
+ }
if (!string.IsNullOrEmpty (datas))
- ItemTemplates [dataType].CreateExpandDelegate(this, dataType, datas);
+ ItemTemplates [dataType].CreateExpandDelegate(this);
continue;
}
@@ -197,7 +200,7 @@ namespace Crow
//if no template found, load default one
if (this.child == null)
loadTemplate ();
-
+
//normal xml read
using (XmlReader xr = new XmlTextReader (tmp, XmlNodeType.Element, null)) {
xr.Read ();
diff --git a/src/GraphicObjects/TextBox.cs b/src/GraphicObjects/TextBox.cs
index 5c3772b7..81fce3e2 100644
--- a/src/GraphicObjects/TextBox.cs
+++ b/src/GraphicObjects/TextBox.cs
@@ -29,14 +29,13 @@ namespace Crow
public class TextBox : Label
{
#region CTOR
+ public TextBox()
+ { }
public TextBox(string _initialValue)
: base(_initialValue)
{
}
-
- public TextBox()
- { }
#endregion
#region GraphicObject overrides
diff --git a/src/IMLReader.cs b/src/IMLReader.cs
new file mode 100644
index 00000000..f8fd34ed
--- /dev/null
+++ b/src/IMLReader.cs
@@ -0,0 +1,336 @@
+//
+// IMLReader.cs
+//
+// Author:
+// Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2016 jp
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+using System;
+using System.Xml;
+using System.IO;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Linq;
+using System.Collections.Generic;
+
+namespace Crow
+{
+ public class IMLReader : XmlTextReader
+ {
+ Interface.LoaderInvoker loader = null;
+
+ string ImlPath;
+ Stream ImlStream;
+
+ DynamicMethod dm = null;
+
+ public ILGenerator il = null;
+ public Type RootType = null;
+
+ /// <summary>
+ /// Finalize instatiator MSIL and return LoaderInvoker delegate
+ /// </summary>
+ public Interface.LoaderInvoker GetLoader(){
+ if (loader != null)
+ return loader;
+
+ il.Emit(OpCodes.Ret);
+ loader = (Interface.LoaderInvoker)dm.CreateDelegate (typeof(Interface.LoaderInvoker));
+ return loader;
+ }
+
+ #region CTOR
+ public IMLReader (string path)
+ : this(Interface.GetStreamFromPath (path)){
+ ImlPath = path;
+ }
+ public IMLReader (Stream stream)
+ : base(stream)
+ {
+ ImlStream = stream;
+ createInstantiator ();
+ }
+ /// <summary>
+ /// Used to parse xmlFrament with same code generator linked
+ /// If ilGen=null, a new Code Generator will be created.
+ /// </summary>
+ public IMLReader (ILGenerator ilGen, string xmlFragment)
+ : base(xmlFragment, XmlNodeType.Element,null){
+ il = ilGen;
+
+ if (il != null)
+ return;
+
+ createInstantiator();
+ }
+ #endregion
+
+ void createInstantiator(){
+ readRootType();
+ InitEmitter();
+ emitLoader(RootType);
+ Read();//close tag
+ }
+ /// <summary>
+ /// Inits il generator, RootType must have been read first
+ /// </summary>
+ void InitEmitter(){
+
+ dm = new DynamicMethod("dyn_instantiator",
+ MethodAttributes.Family | MethodAttributes.FamANDAssem | MethodAttributes.NewSlot,
+ CallingConventions.Standard,
+ typeof(void),new Type[] {typeof(object)}, RootType, true);
+
+ il = dm.GetILGenerator(256);
+ il.DeclareLocal(typeof(GraphicObject));
+ il.Emit(OpCodes.Nop);
+ //set local GraphicObject to root object passed as 1st argument
+ il.Emit (OpCodes.Ldarg_0);
+ il.Emit (OpCodes.Stloc_0);
+ }
+ void emitLoader(Type crowType){
+ string tmpXml = ReadOuterXml ();
+
+ il.Emit (OpCodes.Ldloc_0);//save current go onto the stack if child has to be added
+
+ if (typeof(TemplatedControl).IsAssignableFrom (crowType)) {
+ //if its a template, first read template elements
+ using (IMLReader reader = new IMLReader (il, tmpXml)) {
+
+ string templatePath = reader.GetAttribute ("Template");
+ //string itemTemplatePath = reader.GetAttribute ("ItemTemplate");
+
+ List<string[]> itemTemplateIds = new List<string[]> ();
+ bool inlineTemplate = false;
+ reader.Read ();
+ int depth = reader.Depth + 1;
+ while (reader.Read ()) {
+ if (!reader.IsStartElement () || reader.Depth > depth)
+ continue;
+ if (reader.Name == "Template") {
+ inlineTemplate = true;
+ reader.Read ();
+
+ readChildren (reader, crowType,true);
+ } else if (reader.Name == "ItemTemplate") {
+ string dataType = "default", datas = "", path = "";
+ while (reader.MoveToNextAttribute ()) {
+ if (reader.Name == "DataType")
+ dataType = reader.Value;
+ else if (reader.Name == "Data")
+ datas = reader.Value;
+ else if (reader.Name == "Path")
+ path = reader.Value;
+ }
+ reader.MoveToElement ();
+ using (IMLReader iTmp = new IMLReader (null, reader.ReadInnerXml ())) {
+ string uid = Guid.NewGuid ().ToString ();
+ Interface.Instantiators [uid] =
+ new ItemTemplate (iTmp.RootType, iTmp.GetLoader (), dataType, datas);
+
+ itemTemplateIds.Add (new string[] { dataType, uid, datas });
+ }
+ }
+ }
+
+ if (!inlineTemplate) {
+ if (string.IsNullOrEmpty (templatePath)) {
+ DefaultTemplate dt = (DefaultTemplate)crowType.GetCustomAttributes (typeof(DefaultTemplate), true).FirstOrDefault ();
+ if (dt!=null)
+ templatePath = dt.Path;
+ }
+
+ if (!string.IsNullOrEmpty (templatePath)) {
+ reader.il.Emit (OpCodes.Ldloc_0);//Load this templateControl ref
+
+ reader.il.Emit (OpCodes.Ldstr, templatePath); //Load template path string
+ reader.il.Emit (OpCodes.Callvirt,//call Interface.Load(path)
+ typeof(Interface).GetMethod ("Load", BindingFlags.Static | BindingFlags.Public));
+ reader.il.Emit (OpCodes.Callvirt,//add child
+ crowType.GetMethod ("loadTemplate", BindingFlags.Instance | BindingFlags.NonPublic));
+ }
+ }
+ foreach (string[] iTempId in itemTemplateIds) {
+ reader.il.Emit (OpCodes.Ldloc_0);//load TempControl ref
+ reader.il.Emit (OpCodes.Ldfld,//load ItemTemplates dic field
+ typeof(TemplatedControl).GetField("ItemTemplates"));
+ reader.il.Emit (OpCodes.Ldstr, iTempId[0]);//load key
+ reader.il.Emit (OpCodes.Ldstr, iTempId[1]);//load value
+ reader.il.Emit (OpCodes.Callvirt,
+ typeof(Interface).GetMethod ("GetItemTemplate"));
+ reader.il.Emit (OpCodes.Callvirt,
+ typeof(Dictionary<string, ItemTemplate>).GetMethod ("set_Item",
+ new Type[] { typeof(string), typeof(ItemTemplate) }));
+
+ if (!string.IsNullOrEmpty (iTempId [2])) {
+ //expand delegate creation
+ reader.il.Emit (OpCodes.Ldloc_0);//load TempControl ref
+ reader.il.Emit (OpCodes.Ldfld,//load ItemTemplates dic field
+ typeof(TemplatedControl).GetField ("ItemTemplates"));
+ reader.il.Emit (OpCodes.Ldstr, iTempId [0]);//load key
+ reader.il.Emit (OpCodes.Callvirt,
+ typeof(Dictionary<string, ItemTemplate>).GetMethod ("get_Item",
+ new Type[] { typeof(string) }));
+ reader.il.Emit (OpCodes.Ldloc_0);//load root of treeView
+ reader.il.Emit (OpCodes.Callvirt,
+ typeof(ItemTemplate).GetMethod ("CreateExpandDelegate"));
+ }
+ }
+ }
+ }
+
+ using (IMLReader reader = new IMLReader(il,tmpXml)){
+ reader.Read ();
+
+ if (reader.HasAttributes) {
+ string style = reader.GetAttribute ("Style");
+ if (!string.IsNullOrEmpty (style)) {
+ PropertyInfo pi = crowType.GetProperty ("Style");
+ CompilerServices.EmitSetValue (reader.il, pi, style);
+ }
+ }
+ reader.il.Emit (OpCodes.Ldloc_0);
+ reader.il.Emit (OpCodes.Callvirt, typeof(GraphicObject).GetMethod ("loadDefaultValues"));
+
+ if (reader.HasAttributes) {
+
+ MethodInfo miAddBinding = typeof(GraphicObject).GetMethod ("BindMember");
+
+ while (reader.MoveToNextAttribute ()) {
+ if (reader.Name == "Style")
+ continue;
+
+ MemberInfo mi = crowType.GetMember (reader.Name).FirstOrDefault();
+ if (mi == null)
+ throw new Exception ("Member '" + reader.Name + "' not found in " + crowType.Name);
+ if (mi.MemberType == MemberTypes.Event) {
+ CompilerServices.emitBindingCreation (reader.il, reader.Name, reader.Value);
+ continue;
+ }
+ PropertyInfo pi = mi as PropertyInfo;
+ if (pi == null)
+ throw new Exception ("Member '" + reader.Name + "' not found in " + crowType.Name);
+
+ if (reader.Value.StartsWith ("{")) {
+ CompilerServices.emitBindingCreation (reader.il, reader.Name, reader.Value.Substring (1, reader.Value.Length - 2));
+ }else
+ CompilerServices.EmitSetValue (reader.il, pi, reader.Value);
+
+ }
+ reader.MoveToElement ();
+ }
+
+ if (reader.IsEmptyElement) {
+ reader.il.Emit (OpCodes.Pop);//pop saved ref to current object
+ return;
+ }
+
+ readChildren (reader, crowType);
+ }
+ il.Emit (OpCodes.Pop);//pop saved ref to current object
+ }
+ /// <summary>
+ /// Parse child node an generate corresponding msil
+ /// </summary>
+ void readChildren(IMLReader reader, Type crowType, bool templateLoading = false){
+ MethodInfo miAddChild = null;
+ bool endTagReached = false;
+ while (reader.Read()){
+ switch (reader.NodeType) {
+ case XmlNodeType.EndElement:
+ endTagReached = true;
+ break;
+ case XmlNodeType.Element:
+ //Templates
+ if (reader.Name == "Template" ||
+ reader.Name == "ItemTemplate") {
+ reader.Skip ();
+ continue;
+ }
+
+ if (miAddChild == null) {
+ if (typeof(Group).IsAssignableFrom (crowType))
+ miAddChild = typeof(Group).GetMethod ("AddChild");
+ else if (typeof(Container).IsAssignableFrom (crowType))
+ miAddChild = typeof(Container).GetMethod ("SetChild");
+ else if (typeof(TemplatedContainer).IsAssignableFrom (crowType)&&!templateLoading)
+ miAddChild = typeof(TemplatedContainer).GetProperty("Content").GetSetMethod();
+ else if (typeof(TemplatedControl).IsAssignableFrom (crowType))
+ miAddChild = typeof(TemplatedControl).GetMethod ("loadTemplate",
+ BindingFlags.Instance | BindingFlags.NonPublic);
+ else if (typeof(PrivateContainer).IsAssignableFrom (crowType))
+ miAddChild = typeof(PrivateContainer).GetMethod ("SetChild",
+ BindingFlags.Instance | BindingFlags.NonPublic);
+ }
+
+ //push current instance on stack for parenting
+ //loc_0 will be used for child
+ reader.il.Emit (OpCodes.Ldloc_0);
+
+ Type t = Type.GetType ("Crow." + reader.Name);
+ if (t == null) {
+ Assembly a = Assembly.GetEntryAssembly ();
+ foreach (Type expT in a.GetExportedTypes ()) {
+ if (expT.Name == reader.Name)
+ t = expT;
+ }
+ }
+ if (t == null)
+ throw new Exception (reader.Name + " type not found");
+
+ reader.il.Emit(OpCodes.Newobj, t.GetConstructors () [0]);//TODO:search parameterless ctor
+ reader.il.Emit (OpCodes.Stloc_0);//child is now loc_0
+
+ reader.emitLoader(t);
+
+ reader.il.Emit (OpCodes.Ldloc_0);//load child on stack for parenting
+ reader.il.Emit (OpCodes.Callvirt, miAddChild);
+ reader.il.Emit (OpCodes.Stloc_0); //reset local to current go
+ reader.il.Emit (OpCodes.Ldloc_0);//save current go onto the stack if child has to be added
+ break;
+ }
+ if (endTagReached)
+ break;
+ }
+ }
+ /// <summary>
+ /// read first node to set GraphicObject class for loading
+ /// and let reader position on that node
+ /// </summary>
+ Type readRootType ()
+ {
+ string root = "Object";
+ while (Read()) {
+ if (NodeType == XmlNodeType.Element) {
+ root = this.Name;
+ break;
+ }
+ }
+
+ Type t = Type.GetType ("Crow." + root);
+ if (t == null) {
+ Assembly a = Assembly.GetEntryAssembly ();
+ foreach (Type expT in a.GetExportedTypes ()) {
+ if (expT.Name == root)
+ t = expT;
+ }
+ }
+ RootType = t;
+ return t;
+ }
+ }
+}
+
diff --git a/src/Instantiator.cs b/src/Instantiator.cs
new file mode 100644
index 00000000..e79988fb
--- /dev/null
+++ b/src/Instantiator.cs
@@ -0,0 +1,104 @@
+//
+// Instantiator.cs
+//
+// Author:
+// Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2016 jp
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+using System;
+using System.Threading;
+using System.IO;
+using System.Text;
+
+namespace Crow
+{
+ public class Instantiator
+ {
+ public Type RootType;
+ Interface.LoaderInvoker loader;
+ string imlPath;
+
+
+ #region CTOR
+ public Instantiator (string path){
+ imlPath = path;
+
+ #if DEBUG_LOAD
+ Stopwatch loadingTime = new Stopwatch ();
+ loadingTime.Start ();
+ #endif
+ try {
+ using (IMLReader itr = new IMLReader (path)){
+ loader = itr.GetLoader ();
+ RootType = itr.RootType;
+ }
+ } catch (Exception ex) {
+ throw new Exception ("Error loading <" + path + ">:\n", ex);
+ }
+
+ #if DEBUG_LOAD
+ loadingTime.Stop ();
+ Debug.WriteLine ("IML Instantiator creation '{2}' : {0} ticks, {1} ms",
+ loadingTime.ElapsedTicks, loadingTime.ElapsedMilliseconds, path);
+ #endif
+ }
+ public static Instantiator CreateFromImlFragment(string fragment){
+ try {
+ using (Stream s = new MemoryStream(Encoding.UTF8.GetBytes(fragment))){
+ return new Instantiator(s);
+ }
+ } catch (Exception ex) {
+ throw new Exception ("Error loading fragment:\n" + fragment + "\n", ex);
+ }
+ }
+ public Instantiator (Stream stream){
+ #if DEBUG_LOAD
+ Stopwatch loadingTime = new Stopwatch ();
+ loadingTime.Start ();
+ #endif
+ using (IMLReader itr = new IMLReader (stream)){
+ loader = itr.GetLoader ();
+ RootType = itr.RootType;
+ }
+ #if DEBUG_LOAD
+ loadingTime.Stop ();
+ Debug.WriteLine ("IML Instantiator creation '{2}' : {0} ticks, {1} ms",
+ loadingTime.ElapsedTicks, loadingTime.ElapsedMilliseconds, path);
+ #endif
+ }
+ public Instantiator (Type _root, Interface.LoaderInvoker _loader)
+ {
+ RootType = _root;
+ loader = _loader;
+ }
+ #endregion
+
+ public GraphicObject CreateInstance(){
+ GraphicObject tmp = (GraphicObject)Activator.CreateInstance(RootType);
+ loader (tmp);
+ return tmp;
+ }
+ public string GetImlSourcesCode(){
+ try {
+ using (StreamReader sr = new StreamReader (imlPath))
+ return sr.ReadToEnd();
+ } catch (Exception ex) {
+ throw new Exception ("Error getting sources for <" + imlPath + ">:", ex);
+ }
+ }
+ }
+}
+
diff --git a/src/Interface.cs b/src/Interface.cs
index 7b324de7..ba9769b1 100644
--- a/src/Interface.cs
+++ b/src/Interface.cs
@@ -28,6 +28,7 @@ using System.Threading;
using System.Xml;
using System.Xml.Serialization;
using Cairo;
+using System.Globalization;
namespace Crow
{
@@ -55,6 +56,7 @@ namespace Crow
}
public Interface(){
Interface.CurrentInterface = this;
+ CultureInfo.DefaultThreadCurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
}
#endregion
@@ -82,7 +84,7 @@ namespace Crow
public static FontOptions FontRenderingOptions;
#endregion
- internal bool XmlLoading = false;
+ internal bool XmlLoading = true;
public Dictionary<string,object> Ressources = new Dictionary<string, object>();
public Queue<LayoutingQueueItem> LayoutingQueue = new Queue<LayoutingQueueItem> ();
@@ -107,14 +109,16 @@ namespace Crow
g.IsQueueForRedraw = true;
}
}
+ //fast compiled IML instantiators
+ public static Dictionary<String, Instantiator> Instantiators = new Dictionary<string, Instantiator>();
#region Default values and Style loading
/// Default values of properties from GraphicObjects are retrieve from XML Attributes.
/// The reflexion process used to retrieve those values being very slow, it is compiled in MSIL
/// and injected as a dynamic method referenced in the DefaultValuesLoader Dictionnary.
/// The compilation is done on the first object instancing, and is also done for custom widgets
- public delegate void loadDefaultInvoker(object instance);
- public static Dictionary<String, loadDefaultInvoker> DefaultValuesLoader = new Dictionary<string, loadDefaultInvoker>();
+ public delegate void LoaderInvoker(object instance);
+ public static Dictionary<String, LoaderInvoker> DefaultValuesLoader = new Dictionary<string, LoaderInvoker>();
public static Dictionary<string, Dictionary<string, object>> Styling;
/// <summary> parse all styling data's and build global Styling Dictionary </summary>
static void LoadStyling() {
@@ -176,36 +180,6 @@ namespace Crow
return stream;
}
- /// <summary>
- /// Pre-read first node to set GraphicObject class for loading
- /// and reset stream position to 0
- /// </summary>
- public static Type GetTopContainerOfXMLStream (Stream stream)
- {
- string root = "Object";
- stream.Seek (0, SeekOrigin.Begin);
- using (XmlReader reader = XmlReader.Create (stream)) {
- while (reader.Read ()) {
- // first element is the root element
- if (reader.NodeType == XmlNodeType.Element) {
- root = reader.Name;
- break;
- }
- }
- }
-
- Type t = Type.GetType ("Crow." + root);
- if (t == null) {
- Assembly a = Assembly.GetEntryAssembly ();
- foreach (Type expT in a.GetExportedTypes ()) {
- if (expT.Name == root)
- t = expT;
- }
- }
-
- stream.Seek (0, SeekOrigin.Begin);
- return t;
- }
public static void Save<T> (string file, T graphicObject)
{
@@ -223,52 +197,27 @@ namespace Crow
System.Globalization.CultureInfo savedCulture = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
- GraphicObject tmp = null;
try {
- using (Stream stream = GetStreamFromPath (path)) {
- tmp = Load(stream, GetTopContainerOfXMLStream(stream));
- }
+ return GetInstantiator (path).CreateInstance ();
} catch (Exception ex) {
throw new Exception ("Error loading <" + path + ">:", ex);
}
Thread.CurrentThread.CurrentCulture = savedCulture;
-
- return tmp;
}
- internal static GraphicObject Load (Stream stream, Type type)
- {
- #if DEBUG_LOAD
- Stopwatch loadingTime = new Stopwatch ();
- loadingTime.Start ();
- #endif
-
- GraphicObject result;
-
- CurrentInterface.XmlLoading = true;
-
- XmlSerializerNamespaces xn = new XmlSerializerNamespaces ();
- xn.Add ("", "");
-
- XmlSerializer xs = new XmlSerializer (type);
-
- result = (GraphicObject)xs.Deserialize (stream);
- CurrentInterface.XmlLoading = false;
-
- #if DEBUG_LOAD
- FileStream fs = stream as FileStream;
- if (fs!=null)
- CurrentGOMLPath = fs.Name;
- loadingTime.Stop ();
- Debug.WriteLine ("GOML Loading ({2}->{3}): {0} ticks, {1} ms",
- loadingTime.ElapsedTicks,
- loadingTime.ElapsedMilliseconds,
- CurrentGOMLPath, result.ToString());
- #endif
-
- return result;
+ /// <summary>
+ /// fetch it from cache or create it
+ /// </summary>
+ public static Instantiator GetInstantiator(string path){
+ if (!Instantiators.ContainsKey(path))
+ Instantiators [path] = new Instantiator(path);
+ return Instantiators [path];
+ }
+ public static ItemTemplate GetItemTemplate(string path){
+ if (!Instantiators.ContainsKey(path))
+ Instantiators [path] = new ItemTemplate(path);
+ return Instantiators [path] as ItemTemplate;
}
-
public GraphicObject LoadInterface (string path)
{
lock (UpdateMutex) {
diff --git a/src/IMLStream.cs b/src/ItemTemplate.cs
index 542797a1..1afefe2b 100644
--- a/src/IMLStream.cs
+++ b/src/ItemTemplate.cs
@@ -23,56 +23,31 @@ using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;
+using System.Xml.Serialization;
+using System.Xml;
+using System.Collections.Generic;
+using System.Diagnostics;
namespace Crow
{
- public class IMLStream : MemoryStream {
- public string Path;
- public Type RootType;
- public IMLStream(string path) : base (){
- Path = path;
- using (Stream stream = Interface.GetStreamFromPath (path))
- stream.CopyTo (this);
- RootType = Interface.GetTopContainerOfXMLStream (this);
- }
- public IMLStream(Byte[] b) : base (b){
- RootType = Interface.GetTopContainerOfXMLStream (this);
- }
- /// <summary>
- /// Create a graphicObject instance from the this XML stream.
- /// </summary>
- public GraphicObject Instance {
- get {
- System.Globalization.CultureInfo savedCulture = Thread.CurrentThread.CurrentCulture;
- Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
-
- Seek (0, SeekOrigin.Begin);
- GraphicObject tmp = Interface.Load (this, this.RootType);
+ public class ItemTemplate : Instantiator {
+ public EventHandler Expand;
+ string strDataType;
+ string fetchMethodName;
- Thread.CurrentThread.CurrentCulture = savedCulture;
- return tmp;
- }
+ #region CTOR
+ public ItemTemplate(string path)
+ : base(path) {
}
- /// <summary>
- /// Gets the xml source code as a string
- /// </summary>
- public string Source {
- get {
- Seek (0, SeekOrigin.Begin);
- using (StreamReader sr = new StreamReader(this))
- return sr.ReadToEnd();
- }
+ public ItemTemplate (Type _root, Interface.LoaderInvoker _loader,string _dataType, string _fetchDataMethod)
+ :base(_root, _loader)
+ {
+ strDataType = _dataType;
+ fetchMethodName = _fetchDataMethod;
}
- }
- public class ItemTemplate : IMLStream {
- public EventHandler Expand;
-
- public ItemTemplate(string path)
- : base(path){}
- public ItemTemplate(Byte[] b)
- : base(b){}
+ #endregion
- public void CreateExpandDelegate (TemplatedControl host, string strDataType, string method){
+ public void CreateExpandDelegate (TemplatedControl host){
Type dataType = Type.GetType(strDataType);
Type hostType = typeof(TemplatedControl);//not sure is the best place to put the dyn method
Type evtType = typeof(EventHandler);
@@ -83,7 +58,7 @@ namespace Crow
Type handlerArgsType = evtParams [1].ParameterType;
Type [] args = { typeof (object), typeof (object), handlerArgsType };
- DynamicMethod dm = new DynamicMethod ("dyn_expand_" + method,
+ DynamicMethod dm = new DynamicMethod ("dyn_expand_" + fetchMethodName,
typeof (void),
args,
hostType);
@@ -110,7 +85,7 @@ namespace Crow
il.Emit (OpCodes.Ldarg_1);
il.Emit (OpCodes.Callvirt, typeof(GraphicObject).GetProperty("DataSource").GetGetMethod ());
- MethodInfo miGetDatas = dataType.GetMethod (method, new Type[] {});
+ MethodInfo miGetDatas = dataType.GetMethod (fetchMethodName, new Type[] {});
il.Emit (OpCodes.Callvirt, miGetDatas);
il.Emit (OpCodes.Callvirt, listBoxType.GetProperty("Data").GetSetMethod ());
diff --git a/src/LayoutingQueueItem.cs b/src/LayoutingQueueItem.cs
index b2a5f3ca..a7909022 100644
--- a/src/LayoutingQueueItem.cs
+++ b/src/LayoutingQueueItem.cs
@@ -107,10 +107,10 @@ namespace Crow
Layoutable.RegisteredLayoutings |= LayoutType;
Interface.CurrentInterface.DiscardQueue.Enqueue (this);
}
- //#if DEBUG_LAYOUTING
+ #if DEBUG_LAYOUTING
else
Debug.WriteLine ("\tDELETED => " + this.ToString ());
- //#endif
+ #endif
}
#if DEBUG_LAYOUTING
currentLQI = null;