Skip to content

Commit 204197b

Browse files
authored
Merge pull request #181 from Nfactor26/save-data-model-and-script-files-after-edit
Any change to proces data model file and initialization script are saved as change are done
2 parents 308f6b2 + 7a7e88a commit 204197b

File tree

25 files changed

+408
-138
lines changed

25 files changed

+408
-138
lines changed

src/Pixel.Automation.Designer.ViewModels/AutomationBuilder/AutomationEditorViewModel.cs

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,24 +100,47 @@ public override async Task EditDataModelAsync()
100100
{
101101
logger.Information($"Opening code editor for editing data model for project : {this.CurrentProject.Name}");
102102
var editorFactory = this.EntityManager.GetServiceOfType<ICodeEditorFactory>();
103+
var projectFileSystem = this.projectManager.GetProjectFileSystem();
103104
using (var editor = editorFactory.CreateMultiCodeEditorScreen())
104105
{
105-
foreach (var file in Directory.GetFiles(this.projectManager.GetProjectFileSystem().DataModelDirectory, "*.cs"))
106+
foreach (var file in Directory.GetFiles(projectFileSystem.DataModelDirectory, "*.cs"))
106107
{
107108
await editor.AddDocumentAsync(Path.GetFileName(file), this.CurrentProject.Name, File.ReadAllText(file), false);
108109
}
109110

110111
await editor.AddDocumentAsync($"{Constants.AutomationProcessDataModelName}.cs", this.CurrentProject.Name, string.Empty, false);
111-
await editor.OpenDocumentAsync($"{Constants.AutomationProcessDataModelName}.cs", this.CurrentProject.Name);
112-
112+
await editor.OpenDocumentAsync($"{Constants.AutomationProcessDataModelName}.cs", this.CurrentProject.Name);
113+
113114
bool? hasChanges = await this.windowManager.ShowDialogAsync(editor);
115+
var editorDocumentStates = editor.GetCurrentEditorState();
116+
114117
if (hasChanges.HasValue && !hasChanges.Value)
115118
{
119+
logger.Information("Discarding changes for data model files");
120+
foreach (var document in editorDocumentStates)
121+
{
122+
if(document.IsNewDocument)
123+
{
124+
File.Delete(Path.Combine(projectFileSystem.DataModelDirectory, document.TargetDocument));
125+
logger.Information("Delete file {@0} from data model files", document);
126+
}
127+
}
116128
return;
117129
}
118-
}
119-
logger.Information($"Editing data model completed for project : {this.CurrentProject.Name}");
120-
130+
131+
foreach (var document in editorDocumentStates)
132+
{
133+
if ((document.IsNewDocument || document.IsModified) && !document.IsDeleted)
134+
{
135+
await this.projectManager.AddOrUpdateDataFileAsync(Path.Combine(projectFileSystem.DataModelDirectory, document.TargetDocument));
136+
}
137+
if(document.IsDeleted && !document.IsNewDocument)
138+
{
139+
await this.projectManager.DeleteDataFileAsync(Path.Combine(projectFileSystem.DataModelDirectory, document.TargetDocument));
140+
}
141+
logger.Information("Updated state of data model file {@0}", document);
142+
}
143+
}
121144
await this.Reload();
122145
}
123146
catch (Exception ex)
@@ -155,6 +178,8 @@ public async Task EditScriptAsync()
155178
var scriptEngine = entityManager.GetScriptEngine();
156179
scriptEngine.ClearState();
157180
await scriptEngine.ExecuteFileAsync(scriptFile);
181+
await this.projectManager.AddOrUpdateDataFileAsync(scriptFile);
182+
logger.Information("Updated script file : {0}", scriptFile);
158183
}
159184
scriptEditorFactory.RemoveProject(this.CurrentProject.Name);
160185
}

src/Pixel.Automation.Designer.ViewModels/AutomationBuilder/AutomationProjectManager.cs

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -124,33 +124,25 @@ private void Initialize()
124124
if (!File.Exists(this.projectFileSystem.ProcessFile))
125125
{
126126
this.RootEntity = new ProcessRootEntity();
127+
this.RootEntity.AddComponent(new ApplicationPoolEntity());
128+
this.RootEntity.AddComponent(new OneTimeSetUpEntity() { Name = "Environment Setup" });
129+
this.RootEntity.AddComponent(new OneTimeTearDownEntity() { Name = "Environment Teardown" });
130+
this.serializer.Serialize<Entity>(this.projectFileSystem.ProcessFile, this.RootEntity);
127131
}
128132
else
129133
{
130134
this.RootEntity = DeserializeProject();
131135
}
132-
133-
AddDefaultEntities();
136+
RestoreParentChildRelation(this.RootEntity);
137+
134138
logger.Information($"Project file for {this.GetProjectName()} has been loaded ");
135139
}
136140

137141
private Entity DeserializeProject()
138142
{
139143
var entity = this.Load<Entity>(this.projectFileSystem.ProcessFile);
140144
return entity;
141-
}
142-
143-
144-
private void AddDefaultEntities()
145-
{
146-
if (this.RootEntity.Components.Count() == 0)
147-
{
148-
this.RootEntity.AddComponent(new ApplicationPoolEntity());
149-
this.RootEntity.AddComponent(new OneTimeSetUpEntity() { Name = "Environment Setup" });
150-
this.RootEntity.AddComponent(new OneTimeTearDownEntity() { Name = "Environment Teardown" });
151-
}
152-
RestoreParentChildRelation(this.RootEntity);
153-
}
145+
}
154146

155147
#endregion Load Project
156148

@@ -194,6 +186,30 @@ public override async Task Reload()
194186

195187
#region overridden methods
196188

189+
///<inheritdoc/>
190+
public override async Task AddOrUpdateDataFileAsync(string targetFile)
191+
{
192+
await this.projectDataManager.AddOrUpdateDataFileAsync(this.activeProject, this.loadedVersion as ProjectVersion, targetFile, this.activeProject.ProjectId);
193+
}
194+
195+
///<inheritdoc/>
196+
public override async Task DeleteDataFileAsync(string fileToDelete)
197+
{
198+
await this.projectDataManager.DeleteDataFileAsync(this.activeProject, this.loadedVersion as ProjectVersion, fileToDelete);
199+
}
200+
201+
///<inheritdoc/>
202+
protected override string GetProjectName()
203+
{
204+
return this.activeProject.Name;
205+
}
206+
207+
///<inheritdoc/>
208+
protected override string GetProjectNamespace()
209+
{
210+
return this.activeProject.Namespace;
211+
}
212+
197213
/// <summary>
198214
/// Save automation project and process
199215
/// </summary>
@@ -221,16 +237,6 @@ public override async Task Save()
221237
await this.projectDataManager.SaveProjectDataAsync(this.activeProject, this.loadedVersion as ProjectVersion);
222238
}
223239

224-
protected override string GetProjectName()
225-
{
226-
return this.activeProject.Name;
227-
}
228-
229-
protected override string GetProjectNamespace()
230-
{
231-
return this.activeProject.Namespace;
232-
}
233-
234240
#endregion overridden methods
235241
}
236242
}

src/Pixel.Automation.Designer.ViewModels/AutomationBuilder/EditorViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public async Task DeleteComponent(ComponentViewModel componentViewModel)
9494
scripts = this.scriptExtractor.ExtractScripts(componentViewModel.Model).ToList();
9595
}
9696

97-
var deleteScriptsViewModel = new DeleteComponentViewModel(componentViewModel, scripts ?? Enumerable.Empty<ScriptStatus>());
97+
var deleteScriptsViewModel = new DeleteComponentViewModel(componentViewModel, scripts ?? Enumerable.Empty<ScriptStatus>(), projectManager);
9898
var result = await this.windowManager.ShowDialogAsync(deleteScriptsViewModel);
9999
if (!result.GetValueOrDefault())
100100
{

src/Pixel.Automation.Designer.ViewModels/AutomationBuilder/PrefabEditorViewModel.cs

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using Pixel.Automation.Designer.ViewModels.AutomationBuilder;
77
using Pixel.Automation.Editor.Core.Interfaces;
88
using Pixel.Scripting.Editor.Core.Contracts;
9+
using Serilog;
910
using System.Diagnostics;
1011
using System.IO;
1112
using IDropTarget = GongSolutions.Wpf.DragDrop.IDropTarget;
@@ -14,6 +15,7 @@ namespace Pixel.Automation.Designer.ViewModels
1415
{
1516
public class PrefabEditorViewModel : EditorViewModel , IPrefabEditor
1617
{
18+
private readonly ILogger logger = Log.ForContext<PrefabEditorViewModel>();
1719
private readonly IServiceResolver serviceResolver;
1820
private readonly IPrefabProjectManager projectManager;
1921

@@ -60,20 +62,47 @@ public async Task DoLoad(PrefabProject prefabProject, VersionInfo versionToLoad
6062
public override async Task EditDataModelAsync()
6163
{
6264
var editorFactory = this.EntityManager.GetServiceOfType<ICodeEditorFactory>();
65+
var prefabFileSystem = this.projectManager.GetProjectFileSystem();
6366
using (var editor = editorFactory.CreateMultiCodeEditorScreen())
6467
{
6568
foreach (var file in Directory.GetFiles(this.projectManager.GetProjectFileSystem().DataModelDirectory, "*.cs"))
6669
{
6770
await editor.AddDocumentAsync(Path.GetFileName(file), this.PrefabProject.PrefabName, File.ReadAllText(file), false);
6871
}
6972
await editor.AddDocumentAsync($"{Constants.PrefabDataModelName}.cs", this.PrefabProject.PrefabName, string.Empty, false);
70-
await editor.OpenDocumentAsync($"{Constants.PrefabDataModelName}.cs", this.PrefabProject.PrefabName);
71-
72-
await this.windowManager.ShowDialogAsync(editor);
73+
await editor.OpenDocumentAsync($"{Constants.PrefabDataModelName}.cs", this.PrefabProject.PrefabName);
7374

74-
await this.Reload();
75-
}
76-
75+
bool? hasChanges = await this.windowManager.ShowDialogAsync(editor);
76+
var editorDocumentStates = editor.GetCurrentEditorState();
77+
78+
if (hasChanges.HasValue && !hasChanges.Value)
79+
{
80+
logger.Information("Discarding changes for data model files");
81+
foreach (var document in editorDocumentStates)
82+
{
83+
if (document.IsNewDocument)
84+
{
85+
File.Delete(Path.Combine(prefabFileSystem.DataModelDirectory, document.TargetDocument));
86+
logger.Information("Delete file {@0} from data model files", document);
87+
}
88+
}
89+
return;
90+
}
91+
92+
foreach (var document in editorDocumentStates)
93+
{
94+
if ((document.IsNewDocument || document.IsModified) && !document.IsDeleted)
95+
{
96+
await this.projectManager.AddOrUpdateDataFileAsync(Path.Combine(prefabFileSystem.DataModelDirectory, document.TargetDocument));
97+
}
98+
if (document.IsDeleted && !document.IsNewDocument)
99+
{
100+
await this.projectManager.DeleteDataFileAsync(Path.Combine(prefabFileSystem.DataModelDirectory, document.TargetDocument));
101+
}
102+
logger.Information("Updated state of data model file {@0}", document);
103+
}
104+
}
105+
await this.Reload();
77106
}
78107

79108
protected override async Task Reload()

src/Pixel.Automation.Designer.ViewModels/AutomationBuilder/PrefabProjectManager.cs

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,30 @@ public override async Task Reload()
211211

212212
#region overridden methods
213213

214+
///<inheritdoc/>
215+
public override async Task AddOrUpdateDataFileAsync(string targetFile)
216+
{
217+
await this.prefabDataManager.AddOrUpdateDataFileAsync(this.prefabProject, this.loadedVersion, targetFile, this.prefabProject.PrefabId);
218+
}
219+
220+
///<inheritdoc/>
221+
public override async Task DeleteDataFileAsync(string fileToDelete)
222+
{
223+
await this.prefabDataManager.DeleteDataFileAsync(this.prefabProject, this.loadedVersion, fileToDelete);
224+
}
225+
226+
/// <inheritdoc/>
227+
protected override string GetProjectName()
228+
{
229+
return this.prefabProject.PrefabName;
230+
}
231+
232+
/// <inheritdoc/>
233+
protected override string GetProjectNamespace()
234+
{
235+
return this.prefabProject.Namespace;
236+
}
237+
214238
/// <summary>
215239
/// Save prefab data
216240
/// </summary>
@@ -234,18 +258,7 @@ public override async Task Save()
234258
}
235259
}
236260

237-
/// <inheritdoc/>
238-
protected override string GetProjectName()
239-
{
240-
return this.prefabProject.PrefabName;
241-
}
242-
243-
/// <inheritdoc/>
244-
protected override string GetProjectNamespace()
245-
{
246-
return this.prefabProject.Namespace;
247-
}
248-
261+
249262
#endregion overridden methods
250263
}
251264
}

src/Pixel.Automation.Designer.ViewModels/AutomationBuilder/ProjectManager.cs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,27 +68,26 @@ public ProjectManager(ISerializer serializer, IEntityManager entityManager, IFil
6868
protected abstract string GetProjectNamespace();
6969

7070
///<inheritdoc/>
71-
public abstract Task Save();
71+
public abstract Task AddOrUpdateDataFileAsync(string targetFile);
7272

7373
///<inheritdoc/>
74-
public abstract Task Reload();
74+
public abstract Task DeleteDataFileAsync(string fileToDelete);
7575

76-
#endregion abstract methods
76+
///<inheritdoc/>
77+
public abstract Task Save();
7778

7879
///<inheritdoc/>
79-
public IProjectManager WithEntityManager(EntityManager entityManager)
80-
{
81-
this.entityManager = entityManager;
82-
this.entityManager.SetCurrentFileSystem(this.fileSystem);
83-
return this;
84-
}
80+
public abstract Task Reload();
8581

82+
#endregion abstract methods
83+
8684
///<inheritdoc/>
8785
public IFileSystem GetProjectFileSystem()
8886
{
8987
return this.fileSystem;
9088
}
9189

90+
///<inheritdoc/>
9291
public IReferenceManager GetReferenceManager()
9392
{
9493
return this.referenceManager;

src/Pixel.Automation.Designer.ViewModels/Screen/DeleteComponentViewModel.cs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Caliburn.Micro;
22
using Dawn;
3+
using Pixel.Automation.Editor.Core.Interfaces;
34
using Pixel.Automation.Editor.Core.ViewModels;
45
using Serilog;
56
using System.IO;
@@ -14,7 +15,8 @@ namespace Pixel.Automation.Designer.ViewModels
1415
public class DeleteComponentViewModel : Screen
1516
{
1617
private readonly ILogger logger = Log.ForContext<DeleteComponentViewModel>();
17-
18+
private readonly IProjectManager projectManager;
19+
1820
/// <summary>
1921
/// Component being deleted
2022
/// </summary>
@@ -25,6 +27,9 @@ public class DeleteComponentViewModel : Screen
2527
/// </summary>
2628
public BindableCollection<SelectableItem<string>> Scripts { get; private set; } = new ();
2729

30+
/// <summary>
31+
/// Indicates if there are any script files associated with the component to delete or it's descendants
32+
/// </summary>
2833
public bool HasScripts
2934
{
3035
get => this.Scripts.Any();
@@ -35,12 +40,13 @@ public bool HasScripts
3540
/// </summary>
3641
/// <param name="componentViewModel"></param>
3742
/// <param name="scripts"></param>
38-
public DeleteComponentViewModel(ComponentViewModel componentViewModel, IEnumerable<ScriptStatus> scripts)
43+
public DeleteComponentViewModel(ComponentViewModel componentViewModel, IEnumerable<ScriptStatus> scripts, IProjectManager projectManager)
3944
{
4045
this.DisplayName = "Delete Component";
41-
this.componentViewModel = Guard.Argument(componentViewModel).NotNull();
46+
this.componentViewModel = Guard.Argument(componentViewModel, nameof(componentViewModel)).NotNull();
4247
Guard.Argument(scripts).NotNull();
43-
this.Scripts.AddRange(scripts.Select(s => new SelectableItem<string>(s.ScriptName, true)));
48+
this.Scripts.AddRange(scripts.Select(s => new SelectableItem<string>(s.ScriptName, true)));
49+
this.projectManager = Guard.Argument(projectManager, nameof(projectManager)).NotNull().Value;
4450
}
4551

4652
/// <summary>
@@ -56,8 +62,9 @@ public async Task Delete()
5662
{
5763
if(script.IsSelected)
5864
{
59-
File.Delete(Path.Combine(fileSystem.WorkingDirectory, script.Item));
60-
logger.Information($"Deleted script file {script.Item}");
65+
await this.projectManager.DeleteDataFileAsync(Path.Combine(fileSystem.WorkingDirectory, script.Item));
66+
logger.Information("Script File '{0}' was deleted", script.Item);
67+
6168
}
6269
}
6370
catch (Exception ex)

0 commit comments

Comments
 (0)