/// <summary> /// Builds a preview for the parents of a function /// </summary> /// <param name="additionalFunction">Function</param> /// <param name="flexFieldObject">Flex field object to which the dialog belongs</param> /// <returns>Preview of the parents of the function</returns> protected async Task <string> BuildFunctionParentPreview(ExportDialogFunction additionalFunction, FlexFieldObject flexFieldObject) { if (additionalFunction.RootNode.Parents == null) { return(string.Empty); } HashSet <string> usedParents = new HashSet <string>(); List <string> previewLines = new List <string>(); foreach (ExportDialogData curParent in additionalFunction.RootNode.Parents) { if (usedParents.Contains(curParent.Id)) { continue; } usedParents.Add(curParent.Id); foreach (IExportDialogStepRenderer curRenderer in _stepRenderers) { string stepPreview = await curRenderer.BuildParentTextPreview(additionalFunction.RootNode, curParent, flexFieldObject, _errorCollection); if (stepPreview != null) { previewLines.Add(stepPreview); continue; } } } return(string.Join(", ", previewLines)); }
/// <summary> /// Extracts all additional dialog functions /// </summary> /// <param name="exportDialog">Dialog data</param> /// <returns>Additional dialog functions</returns> protected List <ExportDialogFunction> ExtractAdditionalFunctions(ExportDialogData exportDialog) { List <ExportDialogFunction> additionalDialogFunctions = new List <ExportDialogFunction>(); HashSet <ExportDialogData> usedNodesForFunctions = new HashSet <ExportDialogData>(); Queue <ExportDialogData> dataForFunctions = new Queue <ExportDialogData>(); foreach (ExportDialogDataChild curChild in exportDialog.Children) { dataForFunctions.Enqueue(curChild.Child); usedNodesForFunctions.Add(curChild.Child); } while (dataForFunctions.Any()) { ExportDialogData curDialogData = dataForFunctions.Dequeue(); if (!string.IsNullOrEmpty(curDialogData.DialogStepFunctionName)) { ExportDialogFunction curAdditionalDialogFunction = new ExportDialogFunction(curDialogData); AddNodesToFunction(curAdditionalDialogFunction, curDialogData); additionalDialogFunctions.Add(curAdditionalDialogFunction); } foreach (ExportDialogDataChild curChild in curDialogData.Children) { if (!usedNodesForFunctions.Contains(curChild.Child)) { dataForFunctions.Enqueue(curChild.Child); usedNodesForFunctions.Add(curChild.Child); } } } return(additionalDialogFunctions); }
/// <summary> /// Renders a node graph /// </summary> /// <param name="exportNodeGraph">Node graph snippet to parse</param> /// <param name="npc">Npc to which the dialog belongs</param> /// <returns>Result of parsing the node graph</returns> public async Task <ExportNodeGraphRenderResult> RenderNodeGraph(ExportDialogData exportNodeGraph, KortistoNpc npc) { _curProject = await _cachedDbAccess.GetDefaultProject(); _exportSettings = await _cachedDbAccess.GetExportSettings(_curProject.Id); SetupStepRenderes(); ExportNodeGraphRenderResult renderResult = new ExportNodeGraphRenderResult(); renderResult.StartStepCode = string.Empty; renderResult.AdditionalFunctionsCode = string.Empty; // Group to Functions ExportDialogFunction rootFunction = new ExportDialogFunction(exportNodeGraph); AddNodesToFunction(rootFunction, exportNodeGraph); List <ExportDialogFunction> additionalFunctions = ExtractAdditionalFunctions(exportNodeGraph); // Render functions string startStepCode = await RenderDialogStepList(rootFunction.FunctionSteps, npc); string additionalFunctionsCode = string.Empty; foreach (ExportDialogFunction curAdditionalFunction in additionalFunctions) { additionalFunctionsCode += await RenderDialogFunction(curAdditionalFunction, npc); } renderResult.StartStepCode = startStepCode; renderResult.AdditionalFunctionsCode = additionalFunctionsCode; return(renderResult); }
/// <summary> /// Renders a state machine event node graph /// </summary> /// <param name="functions">Functions array to fill</param> /// <param name="scriptNodeGraph">Node graph to render</param> /// <param name="flexFieldObject">Npc to which the events belong</param> /// <param name="rootStateMachineFunction">Root state machine function to fill</param> /// <returns>Task</returns> private async Task RenderStateMachineEventNodeGraph(List <StateFunction> functions, NodeGraphSnippet scriptNodeGraph, FlexFieldObject flexFieldObject, StateFunction rootStateMachineFunction) { _nodeGraphParser.SetErrorCollection(_errorCollection); ExportDialogData exportData = _nodeGraphParser.ParseNodeGraph(scriptNodeGraph); if (exportData == null) { return; } exportData = await _nodeGraphFunctionGenerator.GenerateFunctions(flexFieldObject.ProjectId, flexFieldObject.Id, exportData, _errorCollection); ExportDialogFunction rootFunction = new ExportDialogFunction(exportData); AddNodesToFunction(rootFunction, exportData); List <ExportDialogFunction> additionalFunctions = ExtractAdditionalFunctions(exportData); rootStateMachineFunction.Code = await RenderDialogStepList(rootFunction.FunctionSteps, flexFieldObject); foreach (ExportDialogFunction curAdditionalFunction in additionalFunctions) { StateFunction additionalFunction = new StateFunction(); additionalFunction.FunctionName = curAdditionalFunction.RootNode.DialogStepFunctionName; additionalFunction.ParentPreviewText = await BuildFunctionParentPreview(curAdditionalFunction, flexFieldObject); string functionContent = await RenderDialogStepList(curAdditionalFunction.FunctionSteps, flexFieldObject); additionalFunction.Code = functionContent; functions.Add(additionalFunction); } }
/// <summary> /// Builds the dialog function code /// </summary> /// <param name="additionalFunction">Function</param> /// <param name="additionalFunctionsCode">Additional Function Code to wrap</param> /// <param name="npc">Npc to which the dialog belongs</param> /// <returns>Function Code</returns> protected override async Task <string> BuildDialogFunctionCode(ExportDialogFunction additionalFunction, string additionalFunctionsCode, KortistoNpc npc) { string functionContentCode = (await _defaultTemplateProvider.GetDefaultTemplateByType(_curProject.Id, TemplateType.ObjectDailyRoutineFunction)).Code; functionContentCode = ExportUtil.BuildPlaceholderRegex(Placeholder_FunctionName).Replace(functionContentCode, additionalFunction.RootNode.DialogStepFunctionName); functionContentCode = ExportUtil.BuildPlaceholderRegex(Placeholder_Function_ParentPreview).Replace(functionContentCode, await BuildFunctionParentPreview(additionalFunction, npc)); functionContentCode = ExportUtil.BuildPlaceholderRegex(Placeholder_FunctionContent, ExportConstants.ListIndentPrefix).Replace(functionContentCode, m => { return(ExportUtil.TrimEmptyLines(ExportUtil.IndentListTemplate(additionalFunctionsCode, m.Groups[1].Value))); }); return(functionContentCode); }
/// <summary> /// Renders a daily routine event node graph /// </summary> /// <param name="snippetName">Snippet name</param> /// <param name="scriptNodeGraph">Node graph to render</param> /// <param name="flexFieldObject">Npc to which the events belong</param> /// <returns>Task</returns> private async Task <List <ExportSnippetFunction> > RenderExportSnippetNodeGraph(string snippetName, NodeGraphSnippet scriptNodeGraph, FlexFieldObject flexFieldObject) { _nodeGraphParser.SetErrorCollection(_errorCollection); _curProject = await _cachedDbAccess.GetUserProject(); _exportSettings = await _cachedDbAccess.GetExportSettings(_curProject.Id); SetupStepRenderes(); ExportDialogData exportData = _nodeGraphParser.ParseNodeGraph(scriptNodeGraph); if (exportData == null) { return(new List <ExportSnippetFunction>()); } exportData = await _nodeGraphFunctionGenerator.GenerateFunctions(flexFieldObject.ProjectId, flexFieldObject.Id, exportData, _errorCollection); ExportDialogFunction rootFunction = new ExportDialogFunction(exportData); AddNodesToFunction(rootFunction, exportData); List <ExportDialogFunction> additionalFunctions = ExtractAdditionalFunctions(exportData); List <ExportSnippetFunction> snippetFunctions = new List <ExportSnippetFunction>(); ExportSnippetFunction snippetRootFunction = new ExportSnippetFunction(); snippetRootFunction.FunctionName = snippetName; snippetRootFunction.Code = await RenderDialogStepList(rootFunction.FunctionSteps, flexFieldObject); snippetRootFunction.ParentPreviewText = ""; snippetFunctions.Add(snippetRootFunction); foreach (ExportDialogFunction curAdditionalFunction in additionalFunctions) { ExportSnippetFunction additionalFunction = new ExportSnippetFunction(); additionalFunction.FunctionName = curAdditionalFunction.RootNode.DialogStepFunctionName; additionalFunction.ParentPreviewText = await BuildFunctionParentPreview(curAdditionalFunction, flexFieldObject); string functionContent = await RenderDialogStepList(curAdditionalFunction.FunctionSteps, flexFieldObject); additionalFunction.Code = functionContent; snippetFunctions.Add(additionalFunction); } return(snippetFunctions); }
/// <summary> /// Adds all nodes that do not start a new function to a dialog function /// </summary> /// <param name="targetFunction">Target Function</param> /// <param name="exportDialog">Dialog step to check</param> protected void AddNodesToFunction(ExportDialogFunction targetFunction, ExportDialogData exportDialog) { if (targetFunction.FunctionSteps.Contains(exportDialog)) { return; } targetFunction.FunctionSteps.Add(exportDialog); foreach (ExportDialogDataChild curChild in exportDialog.Children) { if (string.IsNullOrEmpty(curChild.Child.DialogStepFunctionName)) { AddNodesToFunction(targetFunction, curChild.Child); } } }
/// <summary> /// Builds a preview for the parents of a function /// </summary> /// <param name="additionalFunction">Function</param> /// <param name="npc">Npc to which the dialog belongs</param> /// <returns>Preview of the parents of the function</returns> protected async Task <string> BuildFunctionParentPreview(ExportDialogFunction additionalFunction, KortistoNpc npc) { if (additionalFunction.RootNode.Parents == null) { return(string.Empty); } List <string> previewLines = new List <string>(); foreach (ExportDialogData curParent in additionalFunction.RootNode.Parents) { foreach (IExportDialogStepRenderer curRenderer in _stepRenderers) { string stepPreview = await curRenderer.BuildParentTextPreview(additionalFunction.RootNode, curParent, npc, _errorCollection); if (stepPreview != null) { previewLines.Add(stepPreview); continue; } } } return(string.Join(", ", previewLines)); }
/// <summary> /// Builds the dialog function code /// </summary> /// <param name="additionalFunction">Function</param> /// <param name="additionalFunctionsCode">Additional Function Code to wrap</param> /// <param name="flexFieldObject">Flex field object to which the dialog belongs</param> /// <returns>Function Code</returns> protected abstract Task <string> BuildDialogFunctionCode(ExportDialogFunction additionalFunction, string additionalFunctionsCode, FlexFieldObject flexFieldObject);
/// <summary> /// Renders a dialog function /// </summary> /// <param name="additionalFunction">additionalFunction</param> /// <param name="flexFieldObject">Flex field object to which the dialog belongs</param> /// <returns>Dialog function code</returns> protected async Task <string> RenderDialogFunction(ExportDialogFunction additionalFunction, FlexFieldObject flexFieldObject) { string functionCode = await RenderDialogStepList(additionalFunction.FunctionSteps, flexFieldObject); return(await BuildDialogFunctionCode(additionalFunction, functionCode, flexFieldObject)); }
/// <summary> /// Builds the dialog function code /// </summary> /// <param name="additionalFunction">Function</param> /// <param name="additionalFunctionsCode">Additional Function Code to wrap</param> /// <param name="npc">Npc to which the dialog belongs</param> /// <returns>Function Code</returns> protected abstract Task <string> BuildDialogFunctionCode(ExportDialogFunction additionalFunction, string additionalFunctionsCode, KortistoNpc npc);
/// <summary> /// Renders a dialog function /// </summary> /// <param name="additionalFunction">additionalFunction</param> /// <param name="npc">Npc to which the dialog belongs</param> /// <returns>Dialog function code</returns> protected async Task <string> RenderDialogFunction(ExportDialogFunction additionalFunction, KortistoNpc npc) { string functionCode = await RenderDialogStepList(additionalFunction.FunctionSteps, npc); return(await BuildDialogFunctionCode(additionalFunction, functionCode, npc)); }