Skip to content

Commit

Permalink
Add an auto reload feature (dsharlet#217)
Browse files Browse the repository at this point in the history
* Add auto-reload feature

* Fix Auto-Reload nonoptimal file reload and implement rename listener

* Remove redundant code

* Remove auto-reload on manual file rename and optimize code
  • Loading branch information
kostoskistefan authored Feb 1, 2024
1 parent 8e5086a commit 5dda7b7
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 14 deletions.
7 changes: 5 additions & 2 deletions LiveSPICEVst/EditorView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@
<TextBlock Margin="5,0,5,0">About</TextBlock>
</Button>
</UniformGrid>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" HorizontalAlignment="Center" Margin="5" UseLayoutRounding="True">
<DockPanel DockPanel.Dock="Top" HorizontalAlignment="Center" Margin="5">
<CheckBox x:Name="AutoReloadCheckBox" Content="Auto Reload" FlowDirection="RightToLeft" FontWeight="Bold" VerticalAlignment="Center" Click="AutoReloadCheckBox_Click"/>
</DockPanel>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" HorizontalAlignment="Center" Margin="5,0" UseLayoutRounding="True">
<StackPanel.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontWeight" Value="Bold" />
Expand All @@ -52,7 +55,7 @@
<ComboBoxItem>32</ComboBoxItem>
<ComboBoxItem>64</ComboBoxItem>
</ComboBox>
</StackPanel>
</StackPanel>
<local:SimulationInterface DataContext="{Binding SimulationProcessor}" />
</DockPanel>
</Grid>
Expand Down
78 changes: 66 additions & 12 deletions LiveSPICEVst/EditorView.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public partial class EditorView : UserControl

SchematicWindow schematicWindow = null;

FileSystemWatcher loadedCircuitFileWatcher = null;

public EditorView(LiveSPICEPlugin plugin)
{
this.Plugin = plugin;
Expand Down Expand Up @@ -85,9 +87,8 @@ private void LoadCircuitButton_Click(object sender, RoutedEventArgs e)

if (dialog.ShowDialog() == true)
{
Plugin.LoadSchematic(dialog.FileName);

UpdateSchematic();
ReloadCircuit(dialog.FileName);
AutoReloadSetup();
}
}

Expand All @@ -99,17 +100,9 @@ private void ShowAboutButton_Click(object sender, RoutedEventArgs e)

private void ReloadCircuitButton_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(Plugin.SchematicPath))
{
return;
}

Plugin.LoadSchematic(Plugin.SchematicPath);

UpdateSchematic();
ReloadCircuit(Plugin.SchematicPath);
}


private void ShowCircuitButton_Click(object sender, RoutedEventArgs e)
{
if (Plugin.SimulationProcessor.Schematic != null)
Expand All @@ -127,5 +120,66 @@ private void ShowCircuitButton_Click(object sender, RoutedEventArgs e)
schematicWindow.Activate();
}
}

private void ReloadCircuit(string path)
{
if (string.IsNullOrEmpty(path))
{
return;
}

Plugin.LoadSchematic(path);
UpdateSchematic();
}

private void OnCircuitFileUpdate(object sender, FileSystemEventArgs e)
{
if (e.FullPath != Plugin.SchematicPath)
{
return;
}

// The OnCircuitFileUpdate function is called a from a thread separate from the UI
// and it cannot directly access the plugin data.
// Therefore, the main UI thread should be notified to call the reload function.
Dispatcher.Invoke(() => ReloadCircuit(Plugin.SchematicPath));
}

private void AutoReloadCheckBox_Click(object sender, RoutedEventArgs e)
{
AutoReloadSetup();
}

private void AutoReloadSetup()
{
// Dispose of the resources used by the file watcher (if needed) when the checkbox is unchecked
if (AutoReloadCheckBox.IsChecked == false)
{
loadedCircuitFileWatcher?.Dispose();
return;
}

// If a schematic is not loaded, there is no file to be watched
if (string.IsNullOrEmpty(Plugin.SchematicPath))
{
return;
}

// Create a new File System Watcher to watch for write events on the loaded schematic file
loadedCircuitFileWatcher = new FileSystemWatcher
{
Filter = Path.GetFileName(Plugin.SchematicPath),
Path = Path.GetDirectoryName(Plugin.SchematicPath),
NotifyFilter = NotifyFilters.FileName,
// EnableRaisingEvents has to be set last, otherwise it throws an error because the path is still empty
EnableRaisingEvents = true,
};

// Link a callback function to the file watcher that executes
// each time a rename operation occurs on the loaded schematic file.
// A rename happens because whenever the schematic file is saved, it is firstly
// stored as a .temp file and after writing, the file is renamed to use the correct extension.
loadedCircuitFileWatcher.Renamed += OnCircuitFileUpdate;
}
}
}

0 comments on commit 5dda7b7

Please sign in to comment.