diff options
| author | jpbruyere <jp.bruyere@hotmail.com> | 2015-09-29 10:07:13 +0200 |
|---|---|---|
| committer | jpbruyere <jp.bruyere@hotmail.com> | 2015-09-29 10:07:13 +0200 |
| commit | 8dcac53903c37878d54d59066eb7f80da1d62bc7 (patch) | |
| tree | 577390ded6146578e0c8b0efae5da549c99c5cec /src | |
| parent | bc12a8d14fd559918c1ed97ed8f2cc5c8c9043c7 (diff) | |
generate c# with codedom for GOML
MonoDevelop.GOLib addin
Diffstat (limited to 'src')
| -rw-r--r-- | src/CompilerServices/CompilerServices.cs | 142 | ||||
| -rw-r--r-- | src/GraphicObjects/GraphicObject.cs | 117 | ||||
| -rw-r--r-- | src/GraphicObjects/Group.cs | 2 | ||||
| -rw-r--r-- | src/GraphicObjects/PrivateContainer.cs | 2 | ||||
| -rw-r--r-- | src/GraphicObjects/Scroller.cs | 2 | ||||
| -rw-r--r-- | src/Interface.cs | 378 |
6 files changed, 534 insertions, 109 deletions
diff --git a/src/CompilerServices/CompilerServices.cs b/src/CompilerServices/CompilerServices.cs index 17d36f13..22585f95 100644 --- a/src/CompilerServices/CompilerServices.cs +++ b/src/CompilerServices/CompilerServices.cs @@ -10,9 +10,151 @@ using System.Runtime.CompilerServices; namespace go { + public enum BindingType + { + Handler, + DynamicHandler, + PropertyBinding + } + public class Binding{ + public BindingType BindingType; + public string MemberName; + public string BindingExpression; + } + + public static class CompilerServices2 + { + static int dynHandleCpt = 0; + /// <summary> + /// Compile events expression in GOML attributes + /// </summary> + /// <param name="es">Event binding details</param> + public static void ResolveBinding(DynAttribute es) + { + Type srcType = es.Source.GetType (); + + #region Retrieve EventHandler parameter type + EventInfo ei = srcType.GetEvent (es.MemberName); + MethodInfo invoke = ei.EventHandlerType.GetMethod ("Invoke"); + ParameterInfo[] pars = invoke.GetParameters (); + + Type handlerArgsType = pars [1].ParameterType; + #endregion + + Type[] args = {typeof(object), handlerArgsType}; + DynamicMethod dm = new DynamicMethod("dynHandle_" + dynHandleCpt, + typeof(void), + args, + srcType.Module); + + es.Source.DynamicMethodIds.Add (dynHandleCpt); + + dynHandleCpt++; + + #region IL generation + ILGenerator il = dm.GetILGenerator(256); + + string src = es.Value.Trim(); + + if (! (src.StartsWith("{") || src.EndsWith ("}"))) + throw new Exception (string.Format("GOML:Malformed {0} Event handler: {1}", es.MemberName, es.Value)); + + src = src.Substring (1, src.Length - 2); + string[] srcLines = src.Split (new char[] { ';' }); + + foreach (string srcLine in srcLines) { + string statement = srcLine.Trim (); + + string[] operandes = statement.Split (new char[] { '=' }); + if (operandes.Length < 2) //not an affectation + { + continue; + } + string lop = operandes [0].Trim (); + string rop = operandes [operandes.Length-1].Trim (); + + #region LEFT OPERANDES + GraphicObject lopObj = es.Source; //default left operand base object is + //the first arg (object sender) of the event handler + + string[] lopParts = lop.Split (new char[] { '.' }); + if (lopParts.Length == 2) {//should search also for member of es.Source + lopObj = es.Source.FindByName (lopParts [0]); + if (lopObj==null) + throw new Exception (string.Format("GOML:Unknown name: {0}", lopParts[0])); + //TODO: should create private member holding ref of lopObj, and emit + //a call to FindByName(lopObjName) during #ctor or in a onLoad func or evt handler + throw new Exception (string.Format("GOML:obj tree ref not yet implemented", lopParts[0])); + }else + il.Emit(OpCodes.Ldarg_0); //load sender ref onto the stack + + int i = lopParts.Length -1; + + MemberInfo lopMbi = lopObj.GetType().GetMember (lopParts[i])[0]; + OpCode lopSetOC; + dynamic lopSetMbi; + Type lopT = null; + switch (lopMbi.MemberType) { + case MemberTypes.Property: + PropertyInfo lopPi = srcType.GetProperty (lopParts[i]); + MethodInfo dstMi = lopPi.GetSetMethod (); + lopT = lopPi.PropertyType; + lopSetMbi = dstMi; + lopSetOC = OpCodes.Callvirt; + break; + case MemberTypes.Field: + FieldInfo dstFi = srcType.GetField(lopParts[i]); + lopT = dstFi.FieldType; + lopSetMbi = dstFi; + lopSetOC = OpCodes.Stfld; + break; + default: + throw new Exception (string.Format("GOML:member type not handle: {0}", lopParts[i])); + } + #endregion + + #region RIGHT OPERANDES + if (rop.StartsWith("\'")){ + if (!rop.EndsWith("\'")) + throw new Exception (string.Format + ("GOML:malformed string constant in handler: {0}", rop)); + string strcst = rop.Substring (1, rop.Length - 2); + + il.Emit(OpCodes.Ldstr,strcst); + + }else{ + //search for a static field in left operand type named 'rop name' + FieldInfo ropFi = lopT.GetField (rop, BindingFlags.Static|BindingFlags.Public); + if (ropFi != null) + { + il.Emit (OpCodes.Ldsfld, ropFi); + }else{ + //search if parsing methods are present + MethodInfo lopTryParseMi = lopT.GetMethod("TryParse"); + + } + } + + #endregion + + //emit left operand assignment + il.Emit(lopSetOC, lopSetMbi); + } + + il.Emit(OpCodes.Ret); + + #endregion + + Delegate del = dm.CreateDelegate(ei.EventHandlerType); + MethodInfo addHandler = ei.GetAddMethod (); + addHandler.Invoke(es.Source, new object[] {del}); + } + + } public static class CompilerServices { static int dynHandleCpt = 0; + /// <summary> /// Compile events expression in GOML attributes /// </summary> diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs index 443fa653..63d10122 100644 --- a/src/GraphicObjects/GraphicObject.cs +++ b/src/GraphicObjects/GraphicObject.cs @@ -18,7 +18,7 @@ using System.IO; using System.Xml;
namespace go
-{
+{
public class GraphicObject : IXmlSerializable, ILayoutable, IValueChange
{
internal List<int> DynamicMethodIds = new List<int> ();
@@ -47,19 +47,19 @@ namespace go #region private fields
ILayoutable _parent;
- string _name;
- Color _background;
- Color _foreground;
- Font _font;
- double _cornerRadius;
- int _margin;
+ string _name = "unamed";
+ Color _background = Color.Transparent;
+ Color _foreground = Color.White;
+ Font _font = "droid, 10";
+ double _cornerRadius = 0;
+ int _margin = 0;
bool _focusable = false;
bool _hasFocus = false;
protected bool _isVisible = true;
- VerticalAlignment _verticalAlignment;
- HorizontalAlignment _horizontalAlignment;
- Size _maximumSize;
- Size _minimumSize;
+ VerticalAlignment _verticalAlignment = VerticalAlignment.Center;
+ HorizontalAlignment _horizontalAlignment = HorizontalAlignment.Center;
+ Size _maximumSize = "0;0";
+ Size _minimumSize = "0;0";
Picture _backgroundImage;
string _backgroundImagePath;
@@ -709,7 +709,7 @@ namespace go {
return Visible ? ScreenCoordinates(Slot).ContainsOrIsEqual (m) : false;
}
- internal virtual void checkHoverWidget(MouseMoveEventArgs e)
+ public virtual void checkHoverWidget(MouseMoveEventArgs e)
{
IGOLibHost glh = TopContainer;
if (glh.hoverWidget != this) {
@@ -788,6 +788,10 @@ namespace go while (reader.MoveToNextAttribute ()) {
string attName = reader.Name;
string attValue = reader.Value;
+
+ if (string.IsNullOrEmpty (attValue))
+ continue;
+
MemberInfo mi = thisType.GetMember (attName).FirstOrDefault();
if (mi == null) {
Debug.WriteLine (Interface.CurrentGOMLPath + "=>GOML: Unknown attribute in " + thisType.ToString() + " : " + attName);
@@ -812,69 +816,68 @@ namespace go bool isAttribute = false;
object defaultValue = null;
- foreach (object o in pi.GetCustomAttributes ()) {
- XmlAttributeAttribute xaa = o as XmlAttributeAttribute;
+ foreach (object attrib in pi.GetCustomAttributes ()) {
+ XmlAttributeAttribute xaa = attrib as XmlAttributeAttribute;
if (xaa != null) {
isAttribute = true;
if (!string.IsNullOrEmpty (xaa.AttributeName))
attName = xaa.AttributeName;
continue;
}
- if (o is XmlIgnoreAttribute)
+ if (attrib is XmlIgnoreAttribute)
break;
- DefaultValueAttribute dv = o as DefaultValueAttribute;
+ DefaultValueAttribute dv = attrib as DefaultValueAttribute;
if (dv != null)
defaultValue = dv.Value;
}
if (!isAttribute)
continue;
-
- if (string.IsNullOrEmpty (attValue)) {
- //avoid system types automaticaly converted by parser
- if (defaultValue != null && !pi.PropertyType.Namespace.StartsWith("System")) {
- if (pi.PropertyType != defaultValue.GetType()) {
- MethodInfo miParse = pi.PropertyType.GetMethod ("Parse", BindingFlags.Static | BindingFlags.Public);
- if (miParse != null) {
- pi.SetValue (this, miParse.Invoke (null, new object[]{ defaultValue }), null);
- continue;
- }
- }
- }
- pi.SetValue (this, defaultValue, null);
- } else {
+// {
+// //avoid system types automaticaly converted by parser
+// if (defaultValue != null && !pi.PropertyType.Namespace.StartsWith("System")) {
+// if (pi.PropertyType != defaultValue.GetType()) {
+// MethodInfo miParse = pi.PropertyType.GetMethod ("Parse", BindingFlags.Static | BindingFlags.Public);
+// if (miParse != null) {
+// pi.SetValue (this, miParse.Invoke (null, new object[]{ defaultValue }), null);
+// continue;
+// }
+// }
+// }
+// pi.SetValue (this, defaultValue, null);
+// } else {
- if (attValue.StartsWith("{")) {
- if (Interface.DontResoveGOML)
- continue;
- //binding
- if (!attValue.EndsWith("}"))
- throw new Exception (string.Format("GOML:Malformed binding: {0}", attValue));
-
- string strBinding = attValue.Substring (1, attValue.Length - 2);
- Interface.GOMLResolver.Add (new DynAttribute () {
- Source = this,
- MemberName = attName,
- Value = strBinding
- });
+ if (attValue.StartsWith("{")) {
+ if (Interface.DontResoveGOML)
continue;
- }
+ //binding
+ if (!attValue.EndsWith("}"))
+ throw new Exception (string.Format("GOML:Malformed binding: {0}", attValue));
- if (pi.PropertyType == typeof(string)) {
- pi.SetValue (this, attValue, null);
- continue;
- }
+ string strBinding = attValue.Substring (1, attValue.Length - 2);
+ Interface.GOMLResolver.Add (new DynAttribute () {
+ Source = this,
+ MemberName = attName,
+ Value = strBinding
+ });
+ continue;
+ }
- object o = null;
+ if (pi.PropertyType == typeof(string)) {
+ pi.SetValue (this, attValue, null);
+ continue;
+ }
- if (pi.PropertyType.IsEnum) {
- o = Enum.Parse (pi.PropertyType, attValue);
- } else {
- MethodInfo me = pi.PropertyType.GetMethod ("Parse", new Type[] { typeof(string) });
- o = me.Invoke (null, new string[] { attValue });
- }
+ object o = null;
+
+ if (pi.PropertyType.IsEnum) {
+ pi.SetValue (this, Enum.Parse (pi.PropertyType, attValue), null);
+ } else {
+ MethodInfo me = pi.PropertyType.GetMethod ("Parse", new Type[] { typeof(string) });
+ pi.SetValue (this, me.Invoke (null, new string[] { attValue }), null);
+ }
+
+
- pi.SetValue (this, o, null);
- }
}
}
reader.MoveToElement();
diff --git a/src/GraphicObjects/Group.cs b/src/GraphicObjects/Group.cs index 179c4116..f711bb88 100644 --- a/src/GraphicObjects/Group.cs +++ b/src/GraphicObjects/Group.cs @@ -222,7 +222,7 @@ namespace go #region Mouse handling
- internal override void checkHoverWidget (OpenTK.Input.MouseMoveEventArgs e)
+ public override void checkHoverWidget (OpenTK.Input.MouseMoveEventArgs e)
{
if (TopContainer.hoverWidget != this) {
TopContainer.hoverWidget = this;
diff --git a/src/GraphicObjects/PrivateContainer.cs b/src/GraphicObjects/PrivateContainer.cs index 010fca71..3d29177d 100644 --- a/src/GraphicObjects/PrivateContainer.cs +++ b/src/GraphicObjects/PrivateContainer.cs @@ -138,7 +138,7 @@ namespace go #endregion #region Mouse handling - internal override void checkHoverWidget (MouseMoveEventArgs e) + public override void checkHoverWidget (MouseMoveEventArgs e) { base.checkHoverWidget (e); if (child != null) diff --git a/src/GraphicObjects/Scroller.cs b/src/GraphicObjects/Scroller.cs index 1ee4e1bb..b0fdc120 100644 --- a/src/GraphicObjects/Scroller.cs +++ b/src/GraphicObjects/Scroller.cs @@ -128,7 +128,7 @@ namespace go {
return Visible ? base.ScreenCoordinates(Slot).ContainsOrIsEqual (m) : false;
}
- internal override void checkHoverWidget (MouseMoveEventArgs e)
+ public override void checkHoverWidget (MouseMoveEventArgs e)
{
Point m = e.Position - new Point ((int)ScrollX, (int)ScrollY);
base.checkHoverWidget (new MouseMoveEventArgs(m.X,m.Y,e.XDelta,e.YDelta));
diff --git a/src/Interface.cs b/src/Interface.cs index f988a17a..7712b577 100644 --- a/src/Interface.cs +++ b/src/Interface.cs @@ -26,6 +26,10 @@ using System.Diagnostics; using System.Collections.Generic; using System.Xml; using System.Linq; +using System.Reflection.Emit; +using System.CodeDom; +using Microsoft.CSharp; +using System.CodeDom.Compiler; namespace go { @@ -43,25 +47,27 @@ namespace go /// <summary> /// Graphic objects References use in dynamic delegates for binding /// </summary> - public static List<object> References = new List<object>(); - public static Queue<int> FreeRefIndices = new Queue<int>(); - public static void Unreference(Object o) + public static List<object> References = new List<object> (); + public static Queue<int> FreeRefIndices = new Queue<int> (); + + public static void Unreference (Object o) { int idxt = Interface.References.IndexOf (o); if (idxt < 0) return; - References[idxt] = null; + References [idxt] = null; FreeRefIndices.Enqueue (idxt); } + /// <summary> register target object reference in an array for binding CIL </summary> - public static int Reference(object o) + public static int Reference (object o) { - int dstIdx = Interface.References.IndexOf(o); + int dstIdx = Interface.References.IndexOf (o); if (dstIdx < 0) { if (FreeRefIndices.Count == 0) { - dstIdx = Interface.References.Count(); + dstIdx = Interface.References.Count (); Interface.References.Add (o); } else { dstIdx = FreeRefIndices.Dequeue (); @@ -70,40 +76,40 @@ namespace go } return dstIdx; } - public static LayoutingQueue LayoutingQueue = new LayoutingQueue(); + + public static LayoutingQueue LayoutingQueue = new LayoutingQueue (); #region Load/Save - internal static Stack<List<DynAttribute>> GOMLResolutionStack = new Stack<List<DynAttribute>>(); - internal static List<DynAttribute> GOMLResolver - { - get { return GOMLResolutionStack.Peek ();} + internal static Stack<List<DynAttribute>> GOMLResolutionStack = new Stack<List<DynAttribute>> (); + + internal static List<DynAttribute> GOMLResolver { + get { return GOMLResolutionStack.Peek (); } } //internal static List<DynAttribute> Bindings; - public static void Save<T>(string file, T graphicObject) + public static void Save<T> (string file, T graphicObject) { - XmlSerializerNamespaces xn = new XmlSerializerNamespaces(); - xn.Add("", ""); - XmlSerializer xs = new XmlSerializer(typeof(T)); + XmlSerializerNamespaces xn = new XmlSerializerNamespaces (); + xn.Add ("", ""); + XmlSerializer xs = new XmlSerializer (typeof(T)); - xs = new XmlSerializer(typeof(T)); - using (Stream s = new FileStream(file, FileMode.Create)) - { - xs.Serialize(s, graphicObject, xn); + xs = new XmlSerializer (typeof(T)); + using (Stream s = new FileStream (file, FileMode.Create)) { + xs.Serialize (s, graphicObject, xn); } } - public static Stream GetStreamFromPath(string path) + public static Stream GetStreamFromPath (string path) { Stream stream = null; if (path.StartsWith ("#")) { string resId = path.Substring (1); - stream = System.Reflection.Assembly.GetEntryAssembly().GetManifestResourceStream(resId); + stream = System.Reflection.Assembly.GetEntryAssembly ().GetManifestResourceStream (resId); if (stream == null)//try to find ressource in golib assembly - stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resId); + stream = System.Reflection.Assembly.GetExecutingAssembly ().GetManifestResourceStream (resId); if (stream == null) throw new Exception ("Resource not found: " + path); } else { @@ -113,38 +119,312 @@ namespace go } return stream; } + /// <summary> /// Pre-read first node to set GraphicObject class for loading /// and reset stream position to 0 /// </summary> - public static Type GetTopContainerOfGOMLStream(Stream stream){ + public static Type GetTopContainerOfGOMLStream (Stream stream) + { string root = "Object"; - stream.Seek(0,SeekOrigin.Begin); + string ClassName = ""; + stream.Seek (0, SeekOrigin.Begin); using (XmlReader reader = XmlReader.Create (stream)) { - while (reader.Read()) { + while (reader.Read ()) { // first element is the root element if (reader.NodeType == XmlNodeType.Element) { root = reader.Name; + ClassName = reader.GetAttribute ("Class"); + if (!string.IsNullOrEmpty (ClassName)) + break; + if (CurrentGOMLPath.StartsWith ("#")) + ClassName = Path.GetFileNameWithoutExtension (CurrentGOMLPath.Substring (1)); + else + ClassName = Path.GetFileNameWithoutExtension (CurrentGOMLPath); break; } } } - Type t = Type.GetType("go." + root); - //var go = Activator.CreateInstance(t); - stream.Seek(0,SeekOrigin.Begin); + Type t = Type.GetType ("go." + root); + + //t = CreateDynamicType (ClassName, t); + + stream.Seek (0, SeekOrigin.Begin); return t; } + + + + + static AssemblyBuilder assemblyBuilder; + static ModuleBuilder moduleBuilder; + + public static void InitDynamicAssembly () + { + AssemblyName an = new AssemblyName ("DynamicGraphicObjects"); + assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly (an, AssemblyBuilderAccess.RunAndSave); + moduleBuilder = assemblyBuilder.DefineDynamicModule ("MainModule"); + } + + public static void TerminateDynamicAssembly () + { + } + + public static CodeCompileUnit CompileUnit; + public static CodeTypeDeclaration GOTypeDecl; + + public static CodeTypeDeclaration GenCodeType (string newTypeName, Type baseType) + { + CompileUnit = new CodeCompileUnit (); + CodeNamespace cns = null; + + int idxLastDot = newTypeName.LastIndexOf ('.'); + string typeName = newTypeName; + if (idxLastDot < 0) + cns = new CodeNamespace ("go"); + else { + typeName = newTypeName.Substring (idxLastDot + 1); + cns = new CodeNamespace (newTypeName.Substring (0, idxLastDot)); + } + CompileUnit.Namespaces.Add (new CodeNamespace ()); + CompileUnit.Namespaces.Add (cns); + CompileUnit.Namespaces [0].Imports.Add (new CodeNamespaceImport ("System")); + CodeTypeDeclaration GOTypeDecl = new CodeTypeDeclaration (typeName); + GOTypeDecl.IsClass = true; + GOTypeDecl.IsPartial = true; + GOTypeDecl.TypeAttributes |= TypeAttributes.Public; + GOTypeDecl.BaseTypes.Add (baseType.Name); + cns.Types.Add (GOTypeDecl); + return GOTypeDecl; + } + + static void GenNewClassFromGOML (string path) + { + string root = null; + string newClassName = ""; + + using (Stream stream = GetStreamFromPath (path)) { + using (XmlReader reader = XmlReader.Create (stream)) { + CodeTypeDeclaration GOTypeDecl = null; + CodeConstructor constructor = null; + + CodeExpression curRef = null; + Type curType = null; + Stack<CodeExpression> curRefStack = new Stack<CodeExpression> (); + Stack<Type> curTypeStack = new Stack<Type> (); + + int arrayIndex = -1; + int localVarCpt = 0; + + while (reader.Read ()) { + switch (reader.NodeType) { + case XmlNodeType.Element: + if (string.IsNullOrEmpty (root)) { + //create the new base class + // first element is the root element + root = reader.Name; + newClassName = reader.GetAttribute ("Class"); + if (string.IsNullOrEmpty (newClassName)) { + if (path.StartsWith ("#")) + newClassName = Path.GetFileNameWithoutExtension (path.Substring (1)); + else + newClassName = Path.GetFileNameWithoutExtension (path); + } + curType = Type.GetType ("go." + root); + + GOTypeDecl = GenCodeType (newClassName, curType); + // Declares a constructor. + constructor = new CodeConstructor (); + constructor.Attributes = MemberAttributes.Public; + GOTypeDecl.Members.Add (constructor); + + curRef = new CodeThisReferenceExpression (); + } else if (reader.Name == "Template") { + }else{ + Type childType = Type.GetType ("go." + reader.Name); + localVarCpt++; + string localVarName = childType.Name + localVarCpt; + constructor.Statements.Add ( + new CodeVariableDeclarationStatement ( + childType, + localVarName, + new CodeObjectCreateExpression (childType) + ) + ); + if (curType == typeof(go.Container) || curType.IsSubclassOf (typeof(go.Container))) { + constructor.Statements.Add ( + new CodeMethodInvokeExpression ( + curRef, + "SetChild", + new CodeVariableReferenceExpression (localVarName) + ) + ); + } else if (curType == typeof(go.Group) || curType.IsSubclassOf (typeof(go.Group))) { + constructor.Statements.Add ( + new CodeMethodInvokeExpression (curRef, "addChild", + new CodeVariableReferenceExpression (localVarName) + ) + ); + } + curTypeStack.Push (curType); + curRefStack.Push (curRef); + curRef = new CodeVariableReferenceExpression (localVarName); + curType = childType; + } + while (reader.MoveToNextAttribute ()) { + string attName = reader.Name; + string attValue = reader.Value; + + if (string.IsNullOrEmpty (attValue)) + continue; + + MemberInfo mi = curType.GetMember (attName).FirstOrDefault (); + if (mi == null) { + Debug.WriteLine (Interface.CurrentGOMLPath + "=>GOML: Unknown attribute in " + curType.ToString () + " : " + attName); + continue; + } + if (mi.MemberType == MemberTypes.Event) { + //TODO: handle events + continue; + } + if (mi.MemberType == MemberTypes.Property) { + PropertyInfo pi = mi as PropertyInfo; + + if (pi.GetSetMethod () == null) { + Debug.WriteLine (Interface.CurrentGOMLPath + "=>GOML: Read only property in " + curType.ToString () + " : " + attName); + continue; + } + + if (attValue.StartsWith("{")) { + if (Interface.DontResoveGOML) + continue; + //binding + if (!attValue.EndsWith("}")) + throw new Exception (string.Format("GOML:Malformed binding: {0}", attValue)); + + string strBinding = attValue.Substring (1, attValue.Length - 2); + + continue; + } + + CodeExpression val = null; + if (pi.PropertyType == typeof(string)) { + val = new CodePrimitiveExpression (attValue); + } else if (pi.PropertyType.IsPrimitive) { + MethodInfo me = pi.PropertyType.GetMethod ("Parse", new Type[] { typeof(string) }); + val = new CodePrimitiveExpression ( + me.Invoke (null, new string[] { attValue })); + } else if (pi.PropertyType.IsEnum || (pi.PropertyType == typeof(go.Color) && Char.IsLetter (attValue [0]))) { + val = new CodeFieldReferenceExpression (new CodeTypeReferenceExpression (pi.PropertyType), attValue); + }else if (pi.PropertyType == typeof(go.Color) || pi.PropertyType == typeof(go.Font)) { + val = new CodeCastExpression(pi.PropertyType, + new CodeMethodInvokeExpression ( + new CodeTypeReferenceExpression (pi.PropertyType), + "Parse", + new CodePrimitiveExpression (attValue) + ) + ); + } else { + val = new CodeMethodInvokeExpression (new CodeTypeReferenceExpression (pi.PropertyType), + "Parse", new CodePrimitiveExpression (attValue)); + + } + constructor.Statements.Add ( + new CodeAssignStatement ( + new CodePropertyReferenceExpression (curRef, attName), + val + ) + ); + } + } + reader.MoveToElement (); + if (reader.IsEmptyElement) { + curType = curTypeStack.Pop (); + curRef = curRefStack.Pop (); + } + break; + case XmlNodeType.EndElement: + if (curTypeStack.Count < 1)//GOML last closing tag + break; + curType = curTypeStack.Pop (); + curRef = curRefStack.Pop (); + if (curType.IsSubclassOf (typeof(go.Container))) + arrayIndex = -1; + break; + } + } + } + } + + + + + GenerateCSharpCode (CompileUnit, path + ".cs"); + } + + static void GenerateCSharpCode (CodeCompileUnit codeBase, string file) + { + CodeDomProvider codeDomProvider = new CSharpCodeProvider (); + //On définit les options de génération de code + CodeGeneratorOptions options = new CodeGeneratorOptions (); + //On demande a ce que le code généré soit dans le même ordre que le code inséré + options.VerbatimOrder = false; + //options.BracingStyle = "C"; + //options.BracingStyle = "C"; + options.ElseOnClosing = true; + options.BlankLinesBetweenMembers = false; + + using (IndentedTextWriter itw = new IndentedTextWriter (new StreamWriter (file, false), "\t")) { + //On demande la génération proprement dite + codeDomProvider.GenerateCodeFromCompileUnit (codeBase, itw, options); + itw.Flush (); + } + Console.WriteLine ("C# code generated: " + file); + } + + public static Type CreateDynamicType (string newTypeName, Type baseType) + { + if (moduleBuilder == null) + InitDynamicAssembly (); + TypeBuilder tb = moduleBuilder.DefineType (newTypeName + , TypeAttributes.Public | + TypeAttributes.Class | + TypeAttributes.AutoClass | + TypeAttributes.AnsiClass | + TypeAttributes.BeforeFieldInit | + TypeAttributes.AutoLayout + , baseType); + + ConstructorBuilder constructor = tb.DefineDefaultConstructor (MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName); + + ConstructorInfo cn = typeof(XmlRootAttribute).GetConstructor (new Type[] { typeof(string) }); + CustomAttributeBuilder cab = new CustomAttributeBuilder (cn, new object[] { baseType.Name }); + + tb.SetCustomAttribute (cab); + + + + + Type tmp = tb.CreateType (); + //assemblyBuilder.Save ("newAssembly.dll",PortableExecutableKinds.ILOnly,ImageFileMachine.I386); + return tmp; + } + public static string CurrentGOMLPath; - public static GraphicObject Load(string path, object hostClass = null, bool resolveGOML = true) - { + + public static GraphicObject Load (string path, object hostClass = null, bool resolveGOML = true) + { +// GenNewClassFromGOML (path); +// return null; CurrentGOMLPath = path; using (Stream stream = GetStreamFromPath (path)) { return Load(stream, GetTopContainerOfGOMLStream(stream), hostClass, resolveGOML); } CurrentGOMLPath = ""; } - public static GraphicObject Load(Stream stream, Type type, object hostClass = null, bool resolve = true) + + public static GraphicObject Load (Stream stream, Type type, object hostClass = null, bool resolve = true) { #if DEBUG_LOAD_TIME Stopwatch loadingTime = new Stopwatch (); @@ -154,16 +434,16 @@ namespace go GraphicObject result; - XmlSerializerNamespaces xn = new XmlSerializerNamespaces(); - xn.Add("", ""); + XmlSerializerNamespaces xn = new XmlSerializerNamespaces (); + xn.Add ("", ""); //prevent unused ref in References created by xmlSerializer Interface.DontResoveGOML = true; - XmlSerializer xs = new XmlSerializer(type); + XmlSerializer xs = new XmlSerializer (type); Interface.DontResoveGOML = false; - GOMLResolutionStack.Push(new List<DynAttribute>()); + GOMLResolutionStack.Push (new List<DynAttribute> ()); - result = (GraphicObject)xs.Deserialize(stream); - result.DataSource = hostClass; + result = (GraphicObject)xs.Deserialize (stream); + //result.DataSource = hostClass; if (hostClass == null) { GOMLResolutionStack.Pop (); @@ -175,24 +455,23 @@ namespace go #if DEBUG_LOAD_TIME loadingTime.Stop (); - Debug.WriteLine("GOML Loading ({2}): {0} ticks \t, {1} ms", - loadingTime.ElapsedTicks, - loadingTime.ElapsedMilliseconds, - CurrentGOMLPath); + Debug.WriteLine ("GOML Loading ({2}): {0} ticks \t, {1} ms", + loadingTime.ElapsedTicks, + loadingTime.ElapsedMilliseconds, + CurrentGOMLPath); #endif return result; } - public static void resolveGOML(object hostClass) + public static void resolveGOML (object hostClass) { - foreach (DynAttribute es in GOMLResolver) - { + foreach (DynAttribute es in GOMLResolver) { // if (string.IsNullOrEmpty(es.Value)) // continue; Type dstType = es.Source.GetType (); - MemberInfo miTarget = dstType.GetMember (es.MemberName).FirstOrDefault(); + MemberInfo miTarget = dstType.GetMember (es.MemberName).FirstOrDefault (); if (miTarget == null) { Debug.WriteLine ("'{0}' Member not found in '{1}' type.", es.MemberName, dstType.ToString ()); @@ -210,7 +489,7 @@ namespace go if (mi == null) { //TODO: hack to have it work, hostClass and dataSource should be clearly separated mi = OpenTKGameWindow.currentWindow.GetType ().GetMethod (es.Value, BindingFlags.NonPublic | BindingFlags.Public - | BindingFlags.Instance); + | BindingFlags.Instance); if (mi == null) { Debug.WriteLine ("Handler Method not found: " + es.Value); continue; @@ -223,15 +502,16 @@ namespace go Delegate del = Delegate.CreateDelegate (ei.EventHandlerType, effectiveHostClass, mi); - addHandler.Invoke(es.Source, new object[] {del}); + addHandler.Invoke (es.Source, new object[] { del }); } } else { CompilerServices.ResolveBinding (es, hostClass); } } - GOMLResolutionStack.Pop(); + GOMLResolutionStack.Pop (); } + #endregion } } |