private IEnumerable <Usage> ConnectionDefinitionUsages(IConversationNodeData data) { Id <TConnectorDefinition> connector1 = Id <TConnectorDefinition> .FromGuid(data.Parameters.Where(p => p.Id == DomainIDs.ConnectionDefinitionConnector1).OfType <IEnumParameter>().Single().Value); Id <TConnectorDefinition> connector2 = Id <TConnectorDefinition> .FromGuid(data.Parameters.Where(p => p.Id == DomainIDs.ConnectionDefinitionConnector2).OfType <IEnumParameter>().Single().Value); var reference = UnorderedTuple.Make(connector1, connector2); foreach (var conversationFile in m_project.Conversations) { HashSet <UnorderedTuple2 <Output> > connections = new HashSet <UnorderedTuple2 <Output> >(); foreach (var node in conversationFile.Nodes) { foreach (var connector in node.Data.Connectors) { if (connector.Definition.Id == connector1 || connector.Definition.Id == connector2) { foreach (var connection in connector.Connections) { var c = UnorderedTuple.Make(connector.Definition.Id, connection.Definition.Id); if (c == reference) { connections.Add(UnorderedTuple.Make(connector, connection)); } yield return(new Usage(node, conversationFile, "Node connection using connector definition")); } } } } } }
private Either <GraphAndUI <TUIRawData>, LoadError> ReadEditable(XElement node, IDataSource datasource, object documentID) { Id <NodeTemp> id = Id <NodeTemp> .Parse(node.Attribute("Id").Value); Id <NodeTypeTemp> guid = ReadType(node); INodeDataGenerator editableGenerator = datasource.GetNode(guid); Either <GraphAndUI <TUIRawData>, LoadError> result; var parameterNodes = node.Elements("Parameter"); var parameterData = parameterNodes.Select(p => new NodeDataGeneratorParameterData(Id <Parameter> .Parse(p.Attribute("guid").Value), p.Attribute("value").Value)).ToList(); if (editableGenerator != null) { IConversationNodeData editable = editableGenerator.Generate(id, parameterData, documentID); result = new GraphAndUI <TUIRawData>(editable, m_nodeUIDeserializer.Read(node)); } else { var parameters = parameterData.Select(p => new UnknownParameter(p.Guid, p.Value)); UnknownEditable editable = new UnknownEditable(id, guid, parameters); result = new GraphAndUI <TUIRawData>(editable, m_nodeUIDeserializer.Read(node)); } return(result); }
public ConversationNode MakeNode(IConversationNodeData e, NodeUIData uiData) { PointF p = uiData.Area.Center(); var result = new ConversationNode <INodeGui>(e, n => MakeRenderer(n, n.Renderer == null ? p : n.Renderer.Area.Center()), n => MakeCorruptedRenderer(n, p)); return(result); }
public override NodeData.ParameterData ReadDomainNode(IConversationNodeData parameterNode) { var parameterNameParameter = parameterNode.Parameters.Single(p => p.Id == DomainIDs.ParameterName) as IStringParameter; var parameterName = parameterNameParameter.Value; return(new NodeData.ParameterData(parameterName, Id <Parameter> .ConvertFrom(parameterNode.NodeId), ParameterType, ReadConfig(parameterNode))); }
public Output(Id <TConnector> id, ConnectorDefinitionData definition, IConversationNodeData parent, IReadOnlyList <IParameter> parameters, IConnectionRules rules) { Definition = definition; Parent = parent; Parameters = parameters; Rules = rules; Id = id; }
public override NodeData.ParameterData ReadDomainNode(IConversationNodeData parameterNode) { var parameterNameParameter = parameterNode.Parameters.Single(p => p.Id == DomainIDs.ParameterName) as IStringParameter; var parameterName = parameterNameParameter.Value; var parameterTypeParameter = parameterNode.Parameters.Single(p => p.Id == DomainIDs.PARAMETER_TYPE) as IEnumParameter; var parameterType = parameterTypeParameter.Value; var parameterDefParameter = parameterNode.Parameters.Single(p => p.Id == DomainIDs.ParameterDefault) as IDecimalParameter; var parameterDef = parameterDefParameter.Value; return(new NodeData.ParameterData(parameterName, Id <Parameter> .ConvertFrom(parameterNode.NodeId), ParameterType.Basic.FromGuid(parameterType), ReadConfig(parameterNode), parameterDef.ToString(CultureInfo.InvariantCulture))); }
protected static ReadOnlyCollection <NodeData.ConfigData> ReadConfig(IConversationNodeData parameterNode) { List <NodeData.ConfigData> config = new List <NodeData.ConfigData>(); var configs = parameterNode.Connectors.Single(c => c.Definition.Id == DomainIDs.ParameterConfigConnectorDefinition.Id).Connections.Select(l => l.Parent); foreach (var configNode in configs) { config.Add(new NodeData.ConfigData(configNode.NodeTypeId, configNode.Parameters)); } return(config.AsReadOnly()); }
public override ConfigureResult2 Edit(IColorScheme scheme, IConversationNodeData node, AudioGenerationParameters audioContext, Func <ParameterType, ParameterEditorSetupData, IParameterEditor> config, ILocalizationEngine localizer, IAudioParameterEditorCallbacks audioProvider, AutoCompleteSuggestionsDelegate autoCompleteSuggestions) { if (node.Parameters.Any()) { return(NodeEditor.Edit(scheme, node, audioContext, config, localizer, audioProvider, autoCompleteSuggestions)); } else { return(ConfigureResult2.NotApplicable); } }
public override NodeData.ParameterData ReadDomainNode(IConversationNodeData parameterNode) { var parameterNameParameter = parameterNode.Parameters.Single(p => p.Id == DomainIDs.ParameterName) as IStringParameter; var parameterName = parameterNameParameter.Value; var parameterTypeParameter = parameterNode.Parameters.Single(p => p.Id == DomainIDs.PARAMETER_TYPE) as IEnumParameter; var parameterType = ParameterType.ValueSetType.FromGuid(parameterTypeParameter.Value); var parameterDefParameter = parameterNode.Parameters.Single(p => p.Id == DomainIDs.ParameterDefault) as SetDefaultParameter; var data = new NodeData.ParameterData(parameterName, Id <Parameter> .ConvertFrom(parameterNode.NodeId), parameterType, ReadConfig(parameterNode), parameterDefParameter.SerializedValue); return(data); }
private static IEnumerable <IConversationNodeData> Next(IConversationNodeData node) { var nextConnector = node.Connectors.Where(c => c.Id == DomainIDs.AutoComplete.next.Id).SingleOrDefault(); if (nextConnector == null) { return(Enumerable.Empty <IConversationNodeData>()); } else { return(nextConnector.Connections.Select(c => c.Parent)); } }
private string NodeToString(IConversationNodeData data) { StringBuilder builder = new StringBuilder(); foreach (var parameter in data.Parameters) { builder.Append(" │ "); builder.Append(parameter.Name); builder.Append(": "); builder.Append(parameter.DisplayValue(m_project.Localizer.Localize)); } return(builder.ToString()); }
public override NodeData.ParameterData ReadDomainNode(IConversationNodeData parameterNode) { var parameterNameParameter = parameterNode.Parameters.Single(p => p.Id == DomainIDs.ParameterName) as IStringParameter; var parameterName = parameterNameParameter.Value; var parameterTypeParameter = parameterNode.Parameters.Single(p => p.Id == DomainIDs.PARAMETER_TYPE) as IEnumParameter; var parameterType = ParameterType.Basic.FromGuid(parameterTypeParameter.Value); var parameterDefParameter = parameterNode.Parameters.Single(p => p.Id == DomainIDs.ParameterDefault) as EnumDefaultParameter; var parameterDef = parameterDefParameter.BetterValue; var data = parameterDef.Transformed(d => new NodeData.ParameterData(parameterName, Id <Parameter> .ConvertFrom(parameterNode.NodeId), parameterType, ReadConfig(parameterNode), d.ToString()), d => new NodeData.ParameterData(parameterName, Id <Parameter> .ConvertFrom(parameterNode.NodeId), parameterType, ReadConfig(parameterNode), d)); return(data); }
private static bool HasPrevious(IConversationNodeData node) { var previousConnector = node.Connectors.Where(c => c.Id == DomainIDs.AutoComplete.previous.Id).SingleOrDefault(); if (previousConnector == null) { return(false); } else { return(previousConnector.Connections.Any()); } }
public ConversationNode(IConversationNodeData data, Func <ConversationNode <TNodeUI>, TNodeUI> nodeUI, Func <ConversationNode <TNodeUI>, TNodeUI> corruptedUI) { Data = data; m_uncorruptedUI = nodeUI; m_corruptedUI = corruptedUI; if (data.Parameters.Any(p => p.Corrupted)) { m_currentRenderer = corruptedUI; } else { m_currentRenderer = nodeUI; } Renderer = m_currentRenderer(this); }
private ConfigureResult MyEdit(IConversationNodeData data) { return(Edit(data, new AudioGenerationParameters(CurrentFile.File.File, m_project.File.File))); }
public ConversationNode MakeNode(IConversationNodeData e, NodeUIData uiData) { throw new NotImplementedException(); }
public ConversationNode MakeNode(IConversationNodeData e, NodeUIData uiData) => throw new NotSupportedException();
public GraphAndUI(IConversationNodeData graphData, TUIRawData uiData) { m_graphData = graphData; m_uiData = uiData; }
public abstract NodeData.ParameterData ReadDomainNode(IConversationNodeData parameterNode);
public XmlGraphData <TUIRawData, TEditorData> Read(Stream stream) { object documentID = new object(); stream.Position = 0; var d = XDocument.Load(stream); var root = d.Element(Root); //TODO: Should possibly treat this as a missing file rather than crashing the editor string encounteredVersion = root.Attribute("xmlversion")?.Value ?? ""; if (!XmlVersionRead.Contains(encounteredVersion)) { throw new DeserializerVersionMismatchException(string.Join(", ", XmlVersionRead), encounteredVersion); } var nodeElements = root.Elements("Node"); var filteredNodes = m_filter != null?nodeElements.Where(n => m_filter(ReadType(n))) : nodeElements; IEnumerable <Either <GraphAndUI <TUIRawData>, LoadError> > editables = filteredNodes.Select(n => ReadEditable(n, m_datasource, documentID)).Evaluate(); var allnodes = new Dictionary <Id <NodeTemp>, GraphAndUI <TUIRawData> >(); var errors = new List <LoadError>(); foreach (var editable in editables) { editable.Do(e => { allnodes[e.GraphData.NodeId] = new GraphAndUI <TUIRawData>(e.GraphData, e.UIData); }, a => { errors.Add(a); }); } var links = ReadLinks(n => allnodes.ContainsKey(n), root); foreach (var link in links) { var id1 = link.Item1.Item2; var id2 = link.Item2.Item2; if (allnodes.ContainsKey(id1) && allnodes.ContainsKey(id2)) //If copy/pasting a piece of graph, linked nodes may not exist { IConversationNodeData node1 = allnodes[id1].GraphData; IConversationNodeData node2 = allnodes[id2].GraphData; var unknownNode1 = node1 as UnknownEditable; var unknownNode2 = node2 as UnknownEditable; if (unknownNode1 != null) { unknownNode1.AddConnector(link.Item1.Item1); } if (unknownNode2 != null) { unknownNode2.AddConnector(link.Item2.Item1); } Output connector1 = node1.Connectors.SingleOrDefault(c => c.Id == link.Item1.Item1); Output connector2 = node2.Connectors.SingleOrDefault(c => c.Id == link.Item2.Item1); if (unknownNode1 != null) { unknownNode1.AllowConnection(connector1, connector2); } if (unknownNode2 != null) { unknownNode2.AllowConnection(connector1, connector2); } if (connector1 == null || connector2 == null) { errors.Add(new LoadError("Connector does not exist")); } else { bool success = connector1.ConnectTo(connector2, false); if (!success) { success = connector1.ConnectTo(connector2, true); if (!success) { errors.Add(new LoadError("Tried to connect two connectors that could not be connected")); //TODO: Might be better to add the connection in violation of the rule to avoid modifying the file then have an error checker } } } } } foreach (var node in root.Elements("Node")) { Id <NodeTemp> nodeID = Id <NodeTemp> .Parse(node.Attribute("Id").Value); //ID<NodeTypeTemp> nodeType = ID<NodeTypeTemp>.Parse(node.Attribute("Guid").Value); int outputIndex = 0; //no idea where the output guids come from so just assume they're ordered //TODO: Remove support for legacy linking foreach (var output in node.Elements("Output")) { Id <TConnector> outputGuid = Id <TConnector> .Parse(output.Attribute("guid").Value); bool legacyNodeOutput = Id <TConnector> .Parse("1583e20c-c725-48c3-944d-1ba40c3ebdf4") == outputGuid; var outputConnectors = legacyNodeOutput ? allnodes[nodeID].GraphData.Connectors : allnodes[nodeID].GraphData.Connectors.ElementAt(outputIndex).Only(); var connectedNodes = output.Elements("Link").Select(l => Id <NodeTemp> .Parse(l.Attribute("To").Value)); foreach (var connectedID in connectedNodes) { var connectedNode = allnodes[connectedID].GraphData; var orderedConnectors = connectedNode.Connectors.OrderBy(o => o.Definition.Id != ConnectorDefinitionData.InputDefinitionId); //Put any inputs at the front of the list bool success = false; foreach (var connector in orderedConnectors) { if (success) { break; } foreach (var outputConnector in outputConnectors) { if (success) { break; } if (connector.ConnectTo(outputConnector, false)) { success = true; } else { connector.ConnectTo(outputConnector, true); } } } if (!success) { errors.Add(new LoadError("Could not link nodes")); } } outputIndex++; } } return(new XmlGraphData <TUIRawData, TEditorData>(allnodes.Values, m_editorDataDeserializer.Read(root), new ReadOnlyCollection <LoadError>(errors), documentID)); }
private static Either <Node, IError> Process(IConversationNodeData node, DomainDomain source, int depth) { if (node == null) { return(null); } depth++; if (depth > 100) { return(new OverRecursionError()); } var c = Children(node).Select(n => Process(n, source, depth)); var cc = Either.Split(c); var ne = Next(node).Select(n => Process(n, source, depth)); var nene = Either.Split(ne); if (cc.Item2.Any()) { return(new Either <Node, IError>(cc.Item2.First())); } else if (nene.Item2.Any()) { return(new Either <Node, IError>(nene.Item2.First())); } Node[] children = cc.Item1.ToArray(); Node[] nexts = nene.Item1.ToArray(); //Node child = (children.Length == 0) ? null : children.Length == 1 ? children[0] : new OneOf() { Next = null, Options = children }; //Node next = (nexts.Length == 0) ? null : nexts.Length == 1 ? nexts[0] : new OneOf() { Next = null, Options = nexts }; if (node.NodeTypeId == DomainIDs.AutoComplete.ExactlyOne) { return(new Count() { Min = 1, Max = 1, Subjects = children, Next = nexts }); } else if (node.NodeTypeId == DomainIDs.AutoComplete.OneOrMore) { return(new Count() { Min = 1, Max = int.MaxValue, Subjects = children, Next = nexts }); } else if (node.NodeTypeId == DomainIDs.AutoComplete.ZeroOrMore) { return(new Count() { Min = 0, Max = int.MaxValue, Subjects = children, Next = nexts }); } else if (node.NodeTypeId == DomainIDs.AutoComplete.ZeroOrOne) { return(new Count() { Min = 0, Max = 1, Subjects = children, Next = nexts }); } else if (node.NodeTypeId == DomainIDs.AutoComplete.String) { return(new String() { Next = nexts, Value = node.Parameters.Single(p => p.Id == DomainIDs.AutoComplete.StringParameter).ValueAsString() }); } else if (node.NodeTypeId == DomainIDs.AutoComplete.Character) { var result = Character.Make(node.Parameters.Single(p => p.Id == DomainIDs.AutoComplete.CharacterParameter).ValueAsString()); result.Next = nexts; return(result); } else if (node.NodeTypeId == DomainIDs.AutoComplete.EnumerationValue) { var result = EnumerationValue.Make(node.Parameters.Single() as IEnumParameter, source); result.Next = nexts; return(result); } else if (node.NodeTypeId == DomainIDs.AutoComplete.DynamicEnumerationValue) { return(new DynamicEnumerationValue(node.Parameters.Single() as IEnumParameter) { Next = nexts }); } else if (node.NodeTypeId == DomainIDs.AutoComplete.LocalDynamicEnumerationValue) { return(new DynamicEnumerationValue(node.Parameters.Single() as IEnumParameter) { Next = nexts }); } else { return(null);//TODO: Not sure what effect this would have } }
private static void CheckNode(Dictionary <Id <TConnectorDefinition>, ConnectorDefinitionData> connectorDefinitions, NodeData.ConnectorData[] connectors, NodeData.ParameterData[] parameters, IEnumerable <NodeDataGeneratorParameterData> parameterData, NodeDataGenerator g, Id <NodeTemp> nodeId1, IConversationNodeData node) { Assert.That(node.Config, Is.EqualTo(g.Config)); //Check the connectors are sorted alphabetically by name Assert.That(String.Compare(node.Connectors.ElementAt(0).GetName(), node.Connectors.ElementAt(1).GetName(), StringComparison.CurrentCultureIgnoreCase), Is.LessThanOrEqualTo(0)); Assert.That(node.Connectors, Is.EqualTo(connectors.Select(c => Tuple.Create(c, connectorDefinitions[c.TypeId]))).Using(new OutputComparer())); foreach (var output in node.Connectors) { Assert.That(output.Parent, Is.EqualTo(node)); Assert.That(output.Rules, Is.EqualTo(Rules.Instance)); } Assert.That(node.Name, Is.EqualTo(g.Name)); Assert.That(node.NodeId, Is.EqualTo(nodeId1)); Assert.That(node.NodeTypeId, Is.EqualTo(g.Guid)); var expectedIds = parameters.Select(p => p.Id).Union(parameterData.Select(d => d.Guid)); Assert.That(node.Parameters.Select(p => p.Id), Is.EquivalentTo(expectedIds)); foreach (var parameter in node.Parameters) { var x = parameters.Where(p => p.Id == parameter.Id); if (x.Any()) { var definition = x.Single(); Assert.That(parameter.Name, Is.EqualTo(definition.Name)); Assert.That(parameter.TypeId, Is.EqualTo(definition.Type)); if (!parameterData.Any(d => d.Guid == parameter.Id)) { Assert.That(parameter.ValueAsString(), Is.EqualTo(definition.Default)); } } var y = parameterData.Where(d => d.Guid == parameter.Id); if (y.Any()) { var data = y.Single(); Assert.That(parameter.ValueAsString(), Is.EqualTo(data.Value)); } } foreach (var data in parameterData) { var parameter = node.Parameters.Where(p => p.Id == data.Guid).Single(); if (!parameters.Any(x => x.Id == data.Guid)) { Assert.That(parameter is UnknownParameter); } Assert.That(parameter.ValueAsString(), Is.EqualTo(data.Value)); } }
public NodeEditor(IColorScheme scheme, IConversationNodeData data, AudioGenerationParameters audioContext, Func <ParameterType, ParameterEditorSetupData, IParameterEditor> config, ILocalizationEngine localizer, IAudioParameterEditorCallbacks audioProvider, AutoCompleteSuggestionsDelegate autoCompleteSuggestions) : this() { Scheme = scheme; m_data = data; this.SuspendLayout(); flowLayoutPanel1.SuspendLayout(); flowLayoutPanel2.SuspendLayout(); if (!string.IsNullOrEmpty(data.Description)) { int padding = 8; m_descriptionBox = new MyTextBox(panel1, () => new RectangleF(panel1.Location.Plus(padding, padding), new SizeF(panel1.Width - padding * 2, panel1.Height - padding * 2)), MyTextBox.InputFormEnum.None, null, x => new SimpleTextBoxBorderDrawer(x), 8, Fonts.Default); m_descriptionBox.Text = data.Description; MyTextBox.SetupCallbacks(panel1, m_descriptionBox); panel1.Size = m_descriptionBox.RequestedArea.ToSize(); panel1.SizeChanged += (object sender, EventArgs e) => { var requested = m_descriptionBox.RequestedArea.ToSize(); panel1.Size = new Size(requested.Width + padding * 2, requested.Height + padding * 2); }; } else { panel1.Height = 0; } //Make the panels really tall so they can visibly contain all the parameter editors. //Note the whole control won't be visible as we'll scroll them by shifting them in Y. flowLayoutPanel1.Height = 10000; flowLayoutPanel2.Height = 10000; Title = m_data.Name; foreach (Parameter p in m_data.Parameters.OrderByDescending(p => p.Name)) { var editorData = new ParameterEditorSetupData(p, localizer, audioProvider, audioContext, (s) => autoCompleteSuggestions(p, s)); if (p is UnknownParameter unknown) { UnknownParameterEditor ed = null; Label label = null; ed = UnknownParameterEditor.Make(Scheme, editorData, m_data.RemoveUnknownParameter(unknown), () => { flowLayoutPanel2.Controls.Remove(ed); flowLayoutPanel1.Controls.Remove(label); SetupScrollbar(); }); label = AddParameter(p, ed); } else { AddParameter(p, config(p.TypeId, editorData)); } } flowLayoutPanel1.ResumeLayout(); flowLayoutPanel2.ResumeLayout(); SetupScrollbar(); if (flowLayoutPanel1.Controls.Count > 0) { EventHandler SizeChanged = (a, b) => { NeedsResize.Execute(); DoResize(); }; flowLayoutPanel2.Controls[0].LocationChanged += SizeChanged; flowLayoutPanel2.Controls[0].SizeChanged += SizeChanged; panel1.SizeChanged += SizeChanged; } ; this.ResumeLayout(); this.splitContainer1.Panel2.SizeChanged += Panel2_SizeChanged; if (flowLayoutPanel2.Controls.Count > 0) { for (int i = flowLayoutPanel2.Controls.Count - 1; i >= 0; i--) { (flowLayoutPanel2.Controls[i] as Panel).TabStop = true; (flowLayoutPanel2.Controls[i] as Panel).TabIndex = flowLayoutPanel2.Controls.Count - i - 1; } } }
public abstract ConfigureResult2 Edit(IColorScheme scheme, IConversationNodeData node, AudioGenerationParameters audioContext, Func <ParameterType, ParameterEditorSetupData, IParameterEditor> config, ILocalizationEngine localizer, IAudioParameterEditorCallbacks audioProvider, AutoCompleteSuggestionsDelegate autoCompleteSuggestions);
public ConversationNode MakeNode(IConversationNodeData e, NodeUIData uiData) { return(m_nodeFactory.MakeNode(e, uiData)); }
public T ReverseLookup(IConversationNodeData data) { return(m_reverseLookup(data)); }
public static ConfigureResult2 Edit(IColorScheme scheme, IConversationNodeData data, AudioGenerationParameters audioContext, Func <ParameterType, ParameterEditorSetupData, IParameterEditor> config, ILocalizationEngine localizer, IAudioParameterEditorCallbacks audioProvider, AutoCompleteSuggestionsDelegate autoCompleteSuggestions) { using (Form f = new Form()) { NodeEditor editor = new NodeEditor(scheme, data, audioContext, config, localizer, audioProvider, autoCompleteSuggestions); f.Text = editor.Title; bool oked = false; editor.Ok += () => { var invalid = editor.m_parameterEditors.Select(e => new { Name = e.Item2.Name, Message = e.Item1.IsValid() }).Where(e => e.Message != null); if (!invalid.Any()) { oked = true; f.Close(); } else { string message = "Invalid values specified for the following parameters:"; foreach (var i in invalid) { message += "\n"; message += i.Name + ": "; message += i.Message; } MessageBox.Show(message); } }; editor.Cancel += () => { oked = false; f.Close(); }; editor.Dock = DockStyle.Fill; int maxHeight = editor.MaximumHeight + f.Height - f.ClientSize.Height; int minHeight = editor.MinimumHeight + f.Height - f.ClientSize.Height; f.MaximumSize = new Size(999999, maxHeight); f.MinimumSize = new Size(0, minHeight); editor.NeedsResize += () => { bool resize = false; if (f.Size.Height == f.MaximumSize.Height || f.Size.Height == f.MinimumSize.Height) { resize = true; } int max = editor.MaximumHeight + f.Height - f.ClientSize.Height; int min = editor.MinimumHeight + f.Height - f.ClientSize.Height; f.MaximumSize = new Size(999999, max); f.MinimumSize = new Size(0, min); if (resize) { f.Size = new Size(f.Size.Width, max); } }; f.Size = new Size(500, 478); f.Controls.Add(editor); f.ShowDialog(); if (oked) { var updates = editor.m_parameterEditors.Select(e => e.Item1.UpdateParameterAction()); return(new ConfigureResult2(updates.ToArray())); } else { return(ConfigureResult.Cancel); } } }