Skip to content

Commit 4c47f2d

Browse files
author
MrsSima
committed
Implement functionality for constraints plugin
1 parent 6b650fd commit 4c47f2d

31 files changed

+297
-180
lines changed

ConstraintsMatcher/ConstraintsMatcher.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@
3232
<WarningLevel>4</WarningLevel>
3333
</PropertyGroup>
3434
<ItemGroup>
35+
<Reference Include="QuickGraph">
36+
<HintPath>..\packages\QuickGraphPCL\lib\portable-win+net4+sl5+wp8+win8+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\QuickGraph.dll</HintPath>
37+
</Reference>
38+
<Reference Include="QuickGraph.Graphviz">
39+
<HintPath>..\packages\QuickGraphPCL\lib\portable-win+net4+sl5+wp8+win8+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\QuickGraph.Graphviz.dll</HintPath>
40+
</Reference>
3541
<Reference Include="System" />
3642
<Reference Include="System.Core" />
3743
<Reference Include="System.Xml.Linq" />

ConstraintsMatcher/Matcher.cs

Lines changed: 91 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ namespace ConstraintsMatcher
55
using System;
66
using System.Collections.Generic;
77
using System.Linq;
8+
using System.Text.RegularExpressions;
89

910
public class Matcher
1011
{
@@ -30,6 +31,7 @@ public Matcher(IModel model)
3031
public bool PreCheck(IModel constraintsModel)
3132
{
3233
var Nodes = new List<INode>();
34+
//Find the root
3335
foreach (var node in constraintsModel.Nodes)
3436
{
3537
var inEdges = constraintsModel.Edges.Where(x => x.To == node).ToList();
@@ -44,26 +46,68 @@ public bool PreCheck(IModel constraintsModel)
4446
return false;
4547
}
4648
this.root = Nodes.FirstOrDefault();
49+
// Check if root is correct
4750
if ((this.root.Class.Name == "NotNode") || (this.root.Class.Name == "OrNode") || (this.root.Class.Name == "NoNodes"))
4851
{
49-
this.ErrorMsg = "The root should be NodeType from modrl or AllNodes.";
52+
this.ErrorMsg = "The root should be NodeType from model or AllNodes.";
5053
return false;
5154
}
55+
// Check ther there is only one outcoming edge from notNode
5256
var notNodes = constraintsModel.Nodes.Where(x => x.Class.Name == "NotNode");
5357
foreach(var notNode in notNodes)
5458
{
5559
if (constraintsModel.Edges.Where(x => x.From == notNode).ToList().Count() > 1)
5660
{
61+
this.ErrorMsg = "There should be only one outgoing edge from Not Node.";
5762
return false;
5863
}
5964
}
60-
//TODO check if tree
65+
//Check if there is no outgoing edges from noNodes
66+
var noNodes = constraintsModel.Nodes.Where(x => x.Class.Name == "NoNodes");
67+
foreach (var noNode in noNodes)
68+
{
69+
if (constraintsModel.Edges.Where(x => x.From == noNode).ToList().Count() > 0)
70+
{
71+
this.ErrorMsg = "There shouldn't be outgoing edges from NoNodes";
72+
return false;
73+
}
74+
}
75+
// Check if this constraint is a tree
76+
var visited = new HashSet<int>();
77+
if (!this.CheckIfTree(constraintsModel, this.root, visited))
78+
{
79+
this.ErrorMsg = "Constraints graph should have a tree structure.";
80+
return false;
81+
}
82+
6183
return true;
6284
}
6385

86+
public bool CheckIfTree(IModel constraintsModel, INode root, HashSet<int> visited)
87+
{
88+
visited.Add(root.GetHashCode());
89+
var outgoingEdges = constraintsModel.Edges.Where(x => x.From == root);
90+
foreach(var edge in outgoingEdges)
91+
{
92+
if (visited.Any(x => x == edge.To.GetHashCode()))
93+
{
94+
return false;
95+
}
96+
if (!CheckIfTree(constraintsModel, (INode)edge.To, visited))
97+
{
98+
return false;
99+
}
100+
}
101+
return true;
102+
}
64103
public bool Check(INode originRoot, INode constraintsRoot, IModel constraintsModel)
65104
{
66-
return this.InnerCheck(originRoot, constraintsRoot, constraintsModel);
105+
return this.InnerCheck(originRoot, constraintsRoot, constraintsModel);
106+
}
107+
108+
public bool AttrCheck(INode originRoot, INode constraintsRoot)
109+
{
110+
return this.AttributesAreIdentic(originRoot, constraintsRoot);
67111
}
68112

69113
private bool InnerCheck(INode targetRoot, INode constraintsRoot, IModel constraintsModel)
@@ -73,7 +117,7 @@ private bool InnerCheck(INode targetRoot, INode constraintsRoot, IModel constrai
73117
var areIdentic = ElementsAreIdentic(targetRoot, constraintsRoot);
74118
if (constraintsRoot.Class.Name == "AllNodes")
75119
{
76-
areIdentic = true;
120+
areIdentic = this.AttributesAreIdentic(targetRoot, constraintsRoot);
77121
}
78122
if (constraintsRoot.Class.Name == "AnyNodes")
79123
{
@@ -104,7 +148,7 @@ private bool InnerCheck(INode targetRoot, INode constraintsRoot, IModel constrai
104148
var constraintsToRoot = (INode)outConstraintsEdges.FirstOrDefault().To;
105149
var targetParentRoot = (INode)this.targetModel.Edges.Where(x => x.To == targetRoot).FirstOrDefault().From;
106150
var outParentTargetEdges = this.targetModel.Edges.Where(x => x.From == targetParentRoot);
107-
var innerCheck = outParentTargetEdges.Any(x => ElementsAreIdentic(constraintParentEdge, x) && this.InnerCheck((INode)x.To, constraintsToRoot, constraintsModel));
151+
var innerCheck = outParentTargetEdges.Any(x => ElementsAreIdentic(x, constraintParentEdge) && this.InnerCheck((INode)x.To, constraintsToRoot, constraintsModel));
108152
return !innerCheck;
109153
}
110154
if ((outConstraintsEdges.Count() > 0)&&(outConstraintsEdges.FirstOrDefault().To.Class.Name == "NoNodes"))
@@ -146,17 +190,54 @@ private bool FindEdge(IEnumerable<IEdge> outTargetEdges, IEdge edge)
146190
return false;
147191
}
148192

149-
public bool ElementsAreIdentic(IElement firstElement, IElement secondElement)
193+
public bool ElementsAreIdentic(IElement targetElement, IElement constraintsElement)
150194
{
151-
if (firstElement.Class.Name != secondElement.Class.Name)
195+
if ((targetElement.Class.Name != constraintsElement.Class.Name)||!AttributesAreIdentic(targetElement, constraintsElement))
152196
{
153197
return false;
154198
}
155-
foreach(var attr in firstElement.Attributes)
199+
return true;
200+
}
201+
202+
public bool AttributesAreIdentic(IElement targetElement, IElement constraintsElement)
203+
{
204+
foreach (var targetAttr in targetElement.Attributes)
156205
{
157-
if (secondElement.Attributes.Where(x => x.Name == attr.Name).FirstOrDefault().StringValue != attr.StringValue)
206+
if (targetAttr.StringValue != "Link")
158207
{
159-
return false;
208+
var constraintsAttr = constraintsElement.Attributes.Where(x => x.Name == targetAttr.Name).FirstOrDefault();
209+
210+
if (constraintsAttr.StringValue == "*")
211+
return true;
212+
213+
if ((constraintsAttr.StringValue.Length > 3) && (constraintsAttr.StringValue.Substring(0, 2) == "<="))
214+
{
215+
var value = constraintsAttr.StringValue.Substring(2);
216+
return (Convert.ToInt32(targetAttr.StringValue) <= Convert.ToInt32(value));
217+
}
218+
else if ((constraintsAttr.StringValue.Length > 3) && (constraintsAttr.StringValue.Substring(0, 2) == ">="))
219+
{
220+
var value = constraintsAttr.StringValue.Substring(2);
221+
return (Convert.ToInt32(targetAttr.StringValue) >= Convert.ToInt32(value));
222+
}
223+
else if ((constraintsAttr.StringValue.Length > 2) && (constraintsAttr.StringValue[0] == '<'))
224+
{
225+
var value = constraintsAttr.StringValue.Substring(1);
226+
return (Convert.ToInt32(targetAttr.StringValue) < Convert.ToInt32(value));
227+
}
228+
else if ((constraintsAttr.StringValue.Length > 2) && (constraintsAttr.StringValue[0] == '>'))
229+
{
230+
var value = constraintsAttr.StringValue.Substring(1);
231+
return (Convert.ToInt32(targetAttr.StringValue) > Convert.ToInt32(value));
232+
}
233+
else
234+
{
235+
Regex regEx = new Regex(constraintsAttr.StringValue);
236+
if (!regEx.IsMatch(targetAttr.StringValue))
237+
{
238+
return false;
239+
}
240+
}
160241
}
161242
}
162243
return true;

REAL.NET.sln

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Microsoft Visual Studio Solution File, Format Version 12.00
2-
# Visual Studio Version 16
3-
VisualStudioVersion = 16.0.28721.148
2+
# Visual Studio 15
3+
VisualStudioVersion = 15.0.28307.168
44
MinimumVisualStudioVersion = 10.0.40219.1
55
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{63297B98-5CED-492C-A5B7-A5B4F73CF142}"
66
ProjectSection(SolutionItems) = preProject
@@ -40,6 +40,9 @@ EndProject
4040
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Repo", "src\Repo\Repo.fsproj", "{9E7065A4-BA5E-4752-84BF-54D5C00DB60C}"
4141
EndProject
4242
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "plugins", "plugins", "{F12CD406-E1CD-43B7-B4BC-E2991723C56E}"
43+
ProjectSection(SolutionItems) = preProject
44+
src\plugins\ConstraintsPlugin\ConstraintsPlugin.csproj = src\plugins\ConstraintsPlugin\ConstraintsPlugin.csproj
45+
EndProjectSection
4346
EndProject
4447
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginManager", "src\PluginManager\PluginManager.csproj", "{8B9C8D76-65B3-4A01-9D6F-B6192A823642}"
4548
EndProject
@@ -52,15 +55,13 @@ EndProject
5255
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfEditor", "src\WpfEditor\WpfEditor.csproj", "{734861E8-17D4-43C4-BCFE-2B0C9434AD83}"
5356
ProjectSection(ProjectDependencies) = postProject
5457
{C57410A1-A86F-418B-9AC7-38249450C497} = {C57410A1-A86F-418B-9AC7-38249450C497}
55-
{F2CB1E30-1AED-49A9-91C5-BEE8E2922FBD} = {F2CB1E30-1AED-49A9-91C5-BEE8E2922FBD}
5658
EndProjectSection
5759
EndProject
5860
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AirSim", "src\AirSim\AirSim.csproj", "{757A3BAF-F8E1-4B54-96E7-B4D57B23251B}"
5961
EndProject
6062
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfControlsLib.Tests", "tests\WpfControlsLib.Tests\WpfControlsLib.Tests.csproj", "{8EDF4429-251A-416D-BB68-93F227191BCF}"
6163
EndProject
6264
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Repo.CSharp.Tests", "tests\Repo.CSharp.Tests\Repo.CSharp.Tests.csproj", "{604E3254-B3F7-4A16-872A-B0EACC7846DC}"
63-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConstraintsPlugin", "src\plugins\ConstraintsPlugin\ConstraintsPlugin.csproj", "{F2CB1E30-1AED-49A9-91C5-BEE8E2922FBD}"
6465
EndProject
6566
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConstraintsMatcher", "ConstraintsMatcher\ConstraintsMatcher.csproj", "{10456FBA-B53A-486A-811A-96A5E962B026}"
6667
EndProject
@@ -214,18 +215,6 @@ Global
214215
{604E3254-B3F7-4A16-872A-B0EACC7846DC}.Release|Any CPU.Build.0 = Release|Any CPU
215216
{604E3254-B3F7-4A16-872A-B0EACC7846DC}.Release|x64.ActiveCfg = Release|Any CPU
216217
{604E3254-B3F7-4A16-872A-B0EACC7846DC}.Release|x64.Build.0 = Release|Any CPU
217-
{F2CB1E30-1AED-49A9-91C5-BEE8E2922FBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
218-
{F2CB1E30-1AED-49A9-91C5-BEE8E2922FBD}.Debug|Any CPU.Build.0 = Debug|Any CPU
219-
{F2CB1E30-1AED-49A9-91C5-BEE8E2922FBD}.Debug|x64.ActiveCfg = Debug|Any CPU
220-
{F2CB1E30-1AED-49A9-91C5-BEE8E2922FBD}.Debug|x64.Build.0 = Debug|Any CPU
221-
{F2CB1E30-1AED-49A9-91C5-BEE8E2922FBD}.MonoRelease|Any CPU.ActiveCfg = MonoRelease|Any CPU
222-
{F2CB1E30-1AED-49A9-91C5-BEE8E2922FBD}.MonoRelease|Any CPU.Build.0 = MonoRelease|Any CPU
223-
{F2CB1E30-1AED-49A9-91C5-BEE8E2922FBD}.MonoRelease|x64.ActiveCfg = MonoRelease|Any CPU
224-
{F2CB1E30-1AED-49A9-91C5-BEE8E2922FBD}.MonoRelease|x64.Build.0 = MonoRelease|Any CPU
225-
{F2CB1E30-1AED-49A9-91C5-BEE8E2922FBD}.Release|Any CPU.ActiveCfg = Release|Any CPU
226-
{F2CB1E30-1AED-49A9-91C5-BEE8E2922FBD}.Release|Any CPU.Build.0 = Release|Any CPU
227-
{F2CB1E30-1AED-49A9-91C5-BEE8E2922FBD}.Release|x64.ActiveCfg = Release|Any CPU
228-
{F2CB1E30-1AED-49A9-91C5-BEE8E2922FBD}.Release|x64.Build.0 = Release|Any CPU
229218
{10456FBA-B53A-486A-811A-96A5E962B026}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
230219
{10456FBA-B53A-486A-811A-96A5E962B026}.Debug|Any CPU.Build.0 = Debug|Any CPU
231220
{10456FBA-B53A-486A-811A-96A5E962B026}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -250,7 +239,6 @@ Global
250239
{C57410A1-A86F-418B-9AC7-38249450C497} = {F12CD406-E1CD-43B7-B4BC-E2991723C56E}
251240
{8EDF4429-251A-416D-BB68-93F227191BCF} = {ED8079DD-2B06-4030-9F0F-DC548F98E1C4}
252241
{604E3254-B3F7-4A16-872A-B0EACC7846DC} = {ED8079DD-2B06-4030-9F0F-DC548F98E1C4}
253-
{F2CB1E30-1AED-49A9-91C5-BEE8E2922FBD} = {F12CD406-E1CD-43B7-B4BC-E2991723C56E}
254242
{10456FBA-B53A-486A-811A-96A5E962B026} = {F12CD406-E1CD-43B7-B4BC-E2991723C56E}
255243
EndGlobalSection
256244
GlobalSection(ExtensibilityGlobals) = postSolution

src/AirSim/View/MainWindow.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ private void InitAndLaunchPlugins()
7777
var libs = new PluginLauncher<PluginConfig>();
7878
const string folder = "../../../plugins/SamplePlugin/bin";
7979
var dirs = new List<string>(System.IO.Directory.GetDirectories(folder));
80-
var config = new PluginConfig(this.model, null, null, this.Console, null, null);
80+
var config = new PluginConfig(this.model, null, null, this.Console, null);
8181
foreach (var dir in dirs)
8282
{
8383
libs.LaunchPlugins(dir, config);

src/EditorPluginInterfaces/PluginConfig.cs

Lines changed: 9 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ public class PluginConfig
3838
/// </summary>
3939
public IToolbar Toolbar { get; }
4040

41+
/// <summary>
42+
/// Left panel grid
43+
/// </summary>
44+
public Grid LeftPanelGrid { get; }
4145
/// <summary>
4246
/// Console's reference that should be given to plugin
4347
/// </summary>
@@ -48,35 +52,14 @@ public class PluginConfig
4852
/// </summary>
4953
public IElementProvider ElementProvider { get; }
5054

51-
/// <summary>
52-
///
53-
/// </summary>
54-
public Grid ConstraintsGrid { get; set; }
55-
56-
/// <summary>
57-
/// RightPanel
58-
/// </summary>
59-
public Grid RightPanel { get; set; }
60-
61-
/// <summary>
62-
/// SceneGrid
63-
/// </summary>
64-
public Grid SceneGrid { get; set; }
65-
66-
/// <summary>
67-
/// SceneGrid
68-
/// </summary>
69-
public Grid PaletteGrid { get; set; }
70-
7155
public delegate void Func(string modelName);
7256
public Func FuncCreateConstraintsModel;
73-
public Func OnMainModelChangedFunction;
7457

75-
public delegate void Func1(bool modelName);
76-
public Func1 FuncChangeSelectorVisibility;
58+
public delegate void VisibilityFunc(bool isVisible);
59+
public VisibilityFunc FuncChangeSelectorVisibility;
7760

61+
public Action<String> OnMainModelChangedFunction;
7862

79-
public Action<String> OnMainModelChanged;
8063
/// <summary>
8164
/// Initializes a new instance of <see cref="PluginConfig"/>
8265
/// </summary>
@@ -86,22 +69,14 @@ public class PluginConfig
8669
/// <param name="toolbar">Toolbar</param>
8770
/// <param name="console">Console</param>
8871
/// <param name="elementProvider">Element provider</param>
89-
public PluginConfig(IModel model, IScene scene, IToolbar toolbar, IConsole console, IElementProvider elementProvider, Grid constraintsGrid)
72+
public PluginConfig(IModel model, IScene scene, IToolbar toolbar, IConsole console, IElementProvider elementProvider, Grid leftPanelGrid)
9073
{
9174
this.Model = model;
9275
this.Scene = scene;
9376
this.Toolbar = toolbar;
9477
this.Console = console;
9578
this.ElementProvider = elementProvider;
96-
this.ConstraintsGrid = constraintsGrid;
79+
this.LeftPanelGrid = leftPanelGrid;
9780
}
98-
99-
//public void AddGrids(Grid rightPanel, Grid sceneGrid, Grid paletteGrid)
100-
//{
101-
//
102-
// this.RightPanel = rightPanel;
103-
// this.SceneGrid = sceneGrid;
104-
// this.PaletteGrid = paletteGrid;
105-
//}
10681
}
10782
}

src/Repo/FacadeLayer/Model.fs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,6 @@ and Model
5151
member this.UnderlyingModel = model
5252

5353
interface IModel with
54-
member this.Visible
55-
with get (): bool =
56-
isVisible
57-
and set (v: bool): unit =
58-
isVisible <- v
5954

6055
member this.CreateElement (``type``: IElement) =
6156
let unwrappedType = (``type`` :?> Element).UnderlyingElement

src/Repo/ModelBuilders/ConstraintsMetamodelBuilder.fs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ type ConstraintsMetamodelBuilder() =
5151
let edgeTargetNameAssociation = findAssociation metamodelAssociation "targetName"
5252

5353
let model = repo.CreateModel("ConstraintsMetamodel", metamodel)
54+
model.Properties <- model.Properties.Add ("IsVisible", false.ToString())
5455

5556
let (~+) (name, shape, isAbstract) =
5657
let node = infrastructure.Instantiate model metamodelNode :?> INode
@@ -78,6 +79,7 @@ type ConstraintsMetamodelBuilder() =
7879
edge
7980

8081
let abstractNode = +("AbstractNode", "", true)
82+
let initialNode = +("InitialNode", "View/Pictures/initialBlock.png", false)
8183
let finalNode = +("FinalNode", "View/Pictures/finalBlock.png", false)
8284

8385
let abstractMotorsBlock = +("AbstractMotorsBlock", "", true)
@@ -92,11 +94,10 @@ type ConstraintsMetamodelBuilder() =
9294
let timer = +("Timer", "View/Pictures/timerBlock.png", false)
9395

9496
let allNodes = +("AllNodes", "View/Pictures/allNodes.png", false)
95-
let anyNodes = +("AnyNodes", "View/Pictures/timerBlock.png", false)
96-
let noNodes = +("NoNodes", "View/Pictures/timerBlock.png", false)
97-
let andNode = +("AndNode", "View/Pictures/timerBlock.png", false)
98-
let orNode = +("OrNode", "View/Pictures/timerBlock.png", false)
99-
let notNode = +("NotNode", "View/Pictures/timerBlock.png", false)
97+
//let anyNodes = +("AnyNodes", "View/Pictures/timerBlock.png", false)
98+
let noNodes = +("NoNodes", "View/Pictures/noNodes.png", false)
99+
let orNode = +("OrNode", "View/Pictures/orNode.png", false)
100+
let notNode = +("NotNode", "View/Pictures/notNode.png", false)
100101

101102
let link = abstractNode ---> (abstractNode, "target", "Link")
102103
infrastructure.Element.AddAttribute link "guard" "AttributeKind.String" ""
@@ -111,9 +112,9 @@ type ConstraintsMetamodelBuilder() =
111112
abstractMotorsBlock --|> abstractNode
112113
timer --|> abstractNode
113114
allNodes --|> abstractNode
114-
anyNodes --|> abstractNode
115+
//anyNodes --|> abstractNode
115116
noNodes --|> abstractNode
116-
andNode --|> abstractNode
117+
//andNode --|> abstractNode
117118
orNode --|> abstractNode
118119
notNode --|> abstractNode
119120

0 commit comments

Comments
 (0)