diff options
| -rw-r--r-- | Crow/Crow.csproj | 9 | ||||
| -rw-r--r-- | Crow/src/IML/IMLContext.cs | 50 | ||||
| -rw-r--r-- | Crow/src/IML/Instantiator.cs | 23 | ||||
| -rw-r--r-- | Crow/src/IML/Node.cs | 11 | ||||
| -rw-r--r-- | Crow/src/IML/NodeStack.cs | 50 | ||||
| -rw-r--r-- | Crow/src/Interface.cs | 4 | ||||
| -rw-r--r-- | Crow/src/Widgets/Container.cs | 2 | ||||
| -rw-r--r-- | Samples/HelloWorld/main.cs | 36 | ||||
| -rw-r--r-- | Samples/HelloWorld/ui/helloworld.crow | 33 |
9 files changed, 96 insertions, 122 deletions
diff --git a/Crow/Crow.csproj b/Crow/Crow.csproj index f9881ede..4ad5a6dd 100644 --- a/Crow/Crow.csproj +++ b/Crow/Crow.csproj @@ -23,21 +23,20 @@ </PackageReleaseNotes> <GeneratePackageOnBuild>True</GeneratePackageOnBuild> <GenerateDocumentationFile>true</GenerateDocumentationFile> - <NoWarn>$(NoWarn);1591;1587;1570;1572;1573;1574</NoWarn> - <DefineConstants>DESIGN_MODE</DefineConstants> - <DefineConstants>DESIGN_MODE</DefineConstants> + <NoWarn>$(NoWarn);1591;1587;1570;1572;1573;1574</NoWarn> + <DefineConstants>_DESIGN_MODE</DefineConstants> <EnableDefaultItems>false</EnableDefaultItems> <EnableDefaultCompileItems>false</EnableDefaultCompileItems> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugType>full</DebugType> - <DefineConstants>DEBUG;TRACE;MEASURE_TIME;_DEBUG_DISPOSE;_DEBUG_BINDING;DESIGN_MODE;_DEBUG_CLIP_RECTANGLE;_DEBUG_FOCUS;DEBUG_DRAGNDROP;_DEBUG_LOG</DefineConstants> + <DefineConstants>DEBUG;TRACE;MEASURE_TIME;_DEBUG_DISPOSE;_DEBUG_BINDING;_DESIGN_MODE;_DEBUG_CLIP_RECTANGLE;_DEBUG_FOCUS;DEBUG_DRAGNDROP;_DEBUG_LOG</DefineConstants> <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow> </PropertyGroup> <ItemGroup Condition="$(TargetFramework.StartsWith('netstandard'))"> <PackageReference Include="System.Reflection.Emit.ILGeneration" Version="4.6.0" /> <PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.6.0" /> - <PackageReference Include="glfw-sharp" Version="0.2.6" /> + <PackageReference Include="glfw-sharp" Version="0.2.6-beta" /> <PackageReference Include="FastEnum" Version="1.5.3" /> </ItemGroup> <PropertyGroup Condition=" '$(CrowStbSharp)' == 'true'"> diff --git a/Crow/src/IML/IMLContext.cs b/Crow/src/IML/IMLContext.cs index 3aab2158..385ec3bb 100644 --- a/Crow/src/IML/IMLContext.cs +++ b/Crow/src/IML/IMLContext.cs @@ -27,7 +27,7 @@ namespace Crow.IML public DynamicMethod dm = null; public ILGenerator il = null; //public SubNodeType curSubNodeType; - public NodeStack nodesStack = new NodeStack (); + public Stack<Node> nodesStack = new Stack<Node> (); /// <summary> store addresses of named node for name resolution at end of parsing </summary> public Dictionary<string, List<NodeAddress>> Names = new Dictionary<string, List<NodeAddress>>(); @@ -37,6 +37,8 @@ namespace Crow.IML /// <summary> Store binding with name in target, will be resolved at end of parsing </summary> public List<BindingDefinition> UnresolvedTargets = new List<BindingDefinition>(); + Type curDataSourceType = null; + public IMLContext (Type rootType) { @@ -44,28 +46,42 @@ namespace Crow.IML dm = new DynamicMethod ("dyn_instantiator", typeof (object), new Type [] { typeof (Instantiator), typeof (Interface) }, true); il = dm.GetILGenerator (256); - - il.DeclareLocal (typeof (Widget)); - il.Emit (OpCodes.Nop); + lb = il.DeclareLocal(typeof(Widget)); + } + LocalBuilder lb; + /// <summary> + /// Instantiate a new widget, save it at loc.0 and set current interface from arg2 of loader + /// + /// </summary> + /// <param name="widgetType"></param> + public void EmitCreateWidget (Type widgetType, int index = 0) { //set local GraphicObject to root object - ConstructorInfo ci = rootType.GetConstructor ( - BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, + ConstructorInfo ci = widgetType.GetConstructor ( + BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, Type.EmptyTypes, null); if (ci == null) - throw new Exception ("No default parameterless constructor found in " + rootType.Name); + throw new Exception ("No default parameterless constructor found in " + widgetType.Name); il.Emit (OpCodes.Newobj, ci); - il.Emit (OpCodes.Stloc_0); - CompilerServices.emitSetCurInterface (il); + /// Loc0 is now the current new widget and arg2 of loader is the current interface + //LocalBuilder lb = il.DeclareLocal (typeof(Widget)); + nodesStack.Push (new Node (widgetType, lb, index, curDataSourceType)); + il.Emit (OpCodes.Stloc, lb); + il.Emit (OpCodes.Ldloc, lb); + il.Emit (OpCodes.Ldarg_1); + il.Emit (OpCodes.Stfld, CompilerServices.miSetCurIface); } + public void Emit (OpCode opcode) => il.Emit (opcode); + public void EmitLdCurrentNode () + => il.Emit (OpCodes.Ldloc, nodesStack.Peek ().Locale); + public void ResetCurrentNodeIndex () { + Node n = nodesStack.Pop (); + nodesStack.Push (new Node (n.CrowType, n.Locale)); + } + public InstanciatorInvoker CreateDelegate (Instantiator inst) { + EmitLdCurrentNode (); + il.Emit (OpCodes.Ret); - Type curDataSourceType = null; - /// <summary> - /// Pushs new node and set datasourcetype to current ds type - /// </summary> - /// <param name="crowType">Crow type.</param> - /// <param name="_index">Index.</param> - public void PushNode (Type crowType, int _index = 0) { - nodesStack.Push (new Node (crowType, _index, curDataSourceType)); + return (InstanciatorInvoker)dm.CreateDelegate (typeof (InstanciatorInvoker), inst); } /// <summary> /// Pops node and set curDS type to previous one in node on top of the stack diff --git a/Crow/src/IML/Instantiator.cs b/Crow/src/IML/Instantiator.cs index 0aa49eb4..c1c1e5ee 100644 --- a/Crow/src/IML/Instantiator.cs +++ b/Crow/src/IML/Instantiator.cs @@ -126,6 +126,12 @@ namespace Crow.IML { return new Instantiator (_iface, s); } } +#if DEBUG + //ctor for debugging + public Instantiator (Interface iface) { + this.iface = iface; + } +#endif #endregion /// <summary> @@ -194,7 +200,7 @@ namespace Crow.IML { void parseIML (XmlReader reader) { IMLContext ctx = new IMLContext (findRootType (reader)); - ctx.PushNode (ctx.RootType); + ctx.EmitCreateWidget (ctx.RootType); emitLoader (reader, ctx); ctx.PopNode (); @@ -508,7 +514,7 @@ namespace Crow.IML { readChildren (reader, ctx); - ctx.nodesStack.ResetCurrentNodeIndex (); + ctx.ResetCurrentNodeIndex (); } } /// <summary> @@ -535,24 +541,17 @@ namespace Crow.IML { //loc_0 will be used for child ctx.il.Emit (OpCodes.Ldloc_0); ctx.il.Emit (OpCodes.Ldloc_0); + ctx.il.Emit (OpCodes.Castclass, ctx.nodesStack.Peek ().CrowType); Type t = tryGetGOType (reader.Name); if (t == null) throw new Exception (reader.Name + " type not found"); - ConstructorInfo ci = t.GetConstructor ( - BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, - null, Type.EmptyTypes, null); - if (ci == null) - throw new Exception ("No default parameterless constructor found in " + t.Name); - ctx.il.Emit (OpCodes.Newobj, ci); - ctx.il.Emit (OpCodes.Stloc_0);//child is now loc_0 - CompilerServices.emitSetCurInterface (ctx.il); - ctx.nodesStack.Push (new Node (t, nodeIdx)); + ctx.EmitCreateWidget (t, nodeIdx); emitLoader (reader, ctx); ctx.nodesStack.Pop (); - ctx.il.Emit (OpCodes.Ldloc_0);//load child on stack for parenting + ctx.il.Emit (OpCodes.Ldloc_0);//load child on stack for parenting ctx.il.Emit (OpCodes.Callvirt, ctx.nodesStack.Peek().GetAddMethod(nodeIdx)); ctx.il.Emit (OpCodes.Stloc_0); //reset local to current go diff --git a/Crow/src/IML/Node.cs b/Crow/src/IML/Node.cs index 5ba93968..76f9231c 100644 --- a/Crow/src/IML/Node.cs +++ b/Crow/src/IML/Node.cs @@ -37,10 +37,10 @@ namespace Crow.IML public struct Node { #region CTOR - public Node (Type crowType, int _index = 0, Type dsType = null) - { + public Node (Type crowType, LocalBuilder locale, int index = 0, Type dsType = null) { CrowType = crowType; - Index = _index; + Index = index; + Locale = locale; DataSourceType = dsType; } #endregion @@ -50,6 +50,11 @@ namespace Crow.IML /// <summary> Index in parent, -1 for template</summary> public readonly int Index; /// <summary> + /// locale during instantiator emit + /// </summary> + public readonly LocalBuilder Locale; + + /// <summary> /// DataSourceType attribute if set /// </summary> public Type DataSourceType; diff --git a/Crow/src/IML/NodeStack.cs b/Crow/src/IML/NodeStack.cs deleted file mode 100644 index 80e9156f..00000000 --- a/Crow/src/IML/NodeStack.cs +++ /dev/null @@ -1,50 +0,0 @@ -// -// NodeStack.cs -// -// Author: -// Jean-Philippe Bruyère <jp.bruyere@hotmail.com> -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; -using System.Collections.Generic; - -namespace Crow.IML -{ - public class NodeStack : Stack<Node> - { - public NodeStack () : base() - { - } - public void IncrementCurrentNodeIndex(){ - Node n = this.Pop(); - this.Push (new Node (n.CrowType, n.Index + 1)); - } - public void DecrementCurrentNodeIndex(){ - Node n = this.Pop(); - this.Push (new Node (n.CrowType, n.Index - 1)); - } - public void ResetCurrentNodeIndex(){ - this.Push (new Node (this.Pop().CrowType)); - } - } -} - diff --git a/Crow/src/Interface.cs b/Crow/src/Interface.cs index 7e783b09..e244ae21 100644 --- a/Crow/src/Interface.cs +++ b/Crow/src/Interface.cs @@ -226,8 +226,8 @@ namespace Crow /// </summary> public void Init () { loadStyling (); - initTooltip (); - initContextMenus (); + //initTooltip (); + //initContextMenus (); OnInitialized (); } /// <summary> diff --git a/Crow/src/Widgets/Container.cs b/Crow/src/Widgets/Container.cs index 07ccfa9b..dcb78fac 100644 --- a/Crow/src/Widgets/Container.cs +++ b/Crow/src/Widgets/Container.cs @@ -41,7 +41,7 @@ namespace Crow /// override this to handle specific steps in child addition in derived class, /// and don't forget to call the base.SetChild /// </summary> - public new virtual void SetChild(Widget _child) + public virtual void SetChild(Widget _child) { base.SetChild (_child); } diff --git a/Samples/HelloWorld/main.cs b/Samples/HelloWorld/main.cs index 44ec3fb8..3efd1096 100644 --- a/Samples/HelloWorld/main.cs +++ b/Samples/HelloWorld/main.cs @@ -1,14 +1,48 @@ using System; +using System.Reflection; +using System.Reflection.Emit; using Crow; +using Crow.IML; namespace HelloWorld { class Program { - static void Main (string[] args) { + /*static void Main (string[] args) { using (Interface app = new Interface ()) { app.Initialized += (sender, e) => (sender as Interface).Load ("#HelloWorld.helloworld.crow"); app.Run (); } + }*/ + public static void testMethod (Group w, Widget z) { + Console.WriteLine (w); + Console.WriteLine (z); } + static void Main (string[] args) { + using (Interface app = new Interface ()) { + Instantiator inst = new Instantiator (app); + IMLContext ctx = new IMLContext (typeof (Widget)); + + ctx.EmitCreateWidget (typeof (Group)); + MethodInfo mi = typeof (Program).GetMethod ("testMethod", BindingFlags.Static | BindingFlags.Public); + ctx.Emit (OpCodes.Ldloc_0);//load child on stack for parenting + ctx.il.Emit (OpCodes.Castclass, typeof (Group)); + + ctx.Emit (OpCodes.Dup); + ctx.EmitCreateWidget (typeof (Widget)); + ctx.Emit (OpCodes.Ldloc_0);//load child on stack for parenting + + ctx.il.Emit (OpCodes.Call, mi); + ctx.Emit (OpCodes.Stloc_0); + + //ctx.Emit (OpCodes.Pop); + //ctx.Emit (OpCodes.Pop); + + InstanciatorInvoker del = ctx.CreateDelegate (inst); + + Widget w = (Widget)del (app); + Console.WriteLine ("widget ok"); + } + } + } } diff --git a/Samples/HelloWorld/ui/helloworld.crow b/Samples/HelloWorld/ui/helloworld.crow index 5c0fbbaf..25f27c2f 100644 --- a/Samples/HelloWorld/ui/helloworld.crow +++ b/Samples/HelloWorld/ui/helloworld.crow @@ -1,35 +1,6 @@ <?xml version="1.0"?> -<VerticalStack Background="DimGrey"> - <ColorPicker Name="cp" Width="Stretched"/> - <HorizontalStack Fit="True" Margin="10" Background="Jet"> - <Widget Width="100" Height="60" Background="{../../cp.CurrentColor}"/> - <Widget Width="100" Height="60" Background="{../../cp.CurrentColor2}"/> - </HorizontalStack> - <HorizontalStack DataSource="{../cp.CurrentColor}" Fit="True" Margin="10" Background="Jet"> - <Label Width="100" Text="Red"/> - <Label Width="100" Text="{R}"/> - </HorizontalStack> - <HorizontalStack DataSource="{../cp.CurrentColor}" Fit="True" Margin="10" Background="Jet"> - <Label Width="100" Text="Blue"/> - <Label Width="100" Text="{B}"/> - </HorizontalStack> - <HorizontalStack DataSource="{../cp.CurrentColor}" Fit="True" Margin="10" Background="Jet"> - <Label Width="100" Text="Green"/> - <Label Width="100" Text="{G}"/> - </HorizontalStack> - <HorizontalStack DataSource="{../cp.CurrentColor}" Fit="True" Margin="10" Background="Jet"> - <Label Width="100" Text="Hue"/> - <Label Width="100" Text="{Hue}"/> - </HorizontalStack> - <HorizontalStack DataSource="{../cp.CurrentColor}" Fit="True" Margin="10" Background="Jet"> - <Label Width="100" Text="Saturation"/> - <Label Width="100" Text="{Saturation}"/> - </HorizontalStack> - <HorizontalStack DataSource="{../cp.CurrentColor}" Fit="True" Margin="10" Background="Jet"> - <Label Width="100" Text="Value"/> - <Label Width="100" Text="{Value}"/> - </HorizontalStack> -</VerticalStack> +<Image Path="#Crow.Icons.crow.svg" Background="Blue" Width="100" Height="100"/> + |