Skip to content

Commit

Permalink
Merge pull request #481 from BlueDotBrigade/Features/375-Regions
Browse files Browse the repository at this point in the history
Merge `Features/375 regions` branch to `main` for: adding a new `@Regions` moniker
  • Loading branch information
Pressacco authored Feb 1, 2025
2 parents e40ff30 + 3024e8e commit a0a7b85
Show file tree
Hide file tree
Showing 12 changed files with 81 additions and 53 deletions.
2 changes: 1 addition & 1 deletion Src/BlueDotBrigade.Weevil.Common/IRegionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public interface IRegionManager
{
ImmutableArray<Region> Regions { get; }

void CreateFromSelection();
void CreateFromSelection(int[] selectedLineNumbers);

void Clear();

Expand Down
7 changes: 4 additions & 3 deletions Src/BlueDotBrigade.Weevil.Core/CoreEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,15 @@ private CoreEngine(
var filterAliases = _coreExtension.GetFilterAliases(_context);
var filterAliasExpander = new FilterAliasExpander(filterAliases);

_regionManager = new RegionManager(regions);

_filterManager = new FilterManager(
_coreExtension,
_context,
filterAliasExpander,
_allRecords,
GetRecordCounters());
GetRecordCounters(),
_regionManager);

_filterManager.Apply(FilterType.PlainText, FilterCriteria.None);
_filterManager.ResultsChanged += OnResultsChanged;
Expand All @@ -151,8 +154,6 @@ private CoreEngine(
_sourceFileEncoding,
new Action(() => { _filterManager.ReApply(); }));

_regionManager = new RegionManager(_selectionManager, regions);

recordAndMetadataLoadingStopwatch.Stop();

_logFileMetrics = new LogFileMetrics(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ public bool TryGetExpression(string serializedExpression, out IExpression result
return SurrogateExpression.IsReal(result);
}

public static ExpressionBuilder Create(ICoreExtension coreExtension, ContextDictionary context, FilterType filterType, IFilterCriteria criteria)
public static ExpressionBuilder Create(ICoreExtension coreExtension, ContextDictionary context, FilterType filterType, IFilterCriteria criteria, IRegionManager regionManager)
{
var factories = new List<IExpressionFactory>();

var builtInMonikers = new Monikers.ExpressionFactory();
var builtInMonikers = new Monikers.ExpressionFactory(regionManager);

factories.Add(builtInMonikers);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public ExpressionFactory(IList<MonikerActivator> monikerActivators)
_creators = monikerActivators;
}

public ExpressionFactory()
public ExpressionFactory(IRegionManager regionManager)
{
_creators = new List<MonikerActivator>
{
Expand All @@ -24,6 +24,7 @@ public ExpressionFactory()
new MonikerActivator(UserCommentExpression.Moniker, (e) => new UserCommentExpression(e)),
new MonikerActivator(ContentLengthExpression.Moniker, (e) => new ContentLengthExpression(e)),
new MonikerActivator(ElapsedGreaterThanExpression.Moniker, (e) => new ElapsedGreaterThanExpression(e)),
new MonikerActivator(RegionExpression.Moniker, (e) => new RegionExpression(e, regionManager)),
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace BlueDotBrigade.Weevil.Filter.Expressions.Monikers
{
using BlueDotBrigade.Weevil.Filter.Expressions;
using Data;

internal class RegionExpression : IExpression
{
public static readonly Moniker Moniker = new Moniker("@Region");

private readonly IRegionManager _regionManager;

public RegionExpression(string serializedExpression, IRegionManager regionManager)
{
_regionManager = regionManager;
}

public bool IsMatch(IRecord record)
{
return
_regionManager.TryStartsWith(record.LineNumber, out var region) ||
_regionManager.TryEndsWith(record.LineNumber, out region);
}
}
}
9 changes: 7 additions & 2 deletions Src/BlueDotBrigade.Weevil.Core/Filter/FilterManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ internal class FilterManager : IClonableInternally<FilterManager>, IFilter
private FilterStrategy _latestFilterStrategy;
private ImmutableArray<IRecord> _latestFilterResults;

private IRegionManager _regionManager;

private Filter _currentFilter;

private readonly IList<string> _includeHistory;
Expand All @@ -42,13 +44,16 @@ public FilterManager(
ContextDictionary context,
IFilterAliasExpander filterAliasExpander,
ImmutableArray<IRecord> allRecords,
ImmutableArray<IMetricCollector> metricCollectors)
ImmutableArray<IMetricCollector> metricCollectors,
IRegionManager regionManager)
{
_coreExtension = coreExtension;
_context = context;
_filterAliasExpander = filterAliasExpander;
_allRecords = allRecords;

_regionManager = regionManager;

_metricCollectors = metricCollectors;

_latestFilterStrategy = FilterStrategy.KeepAllRecords;
Expand Down Expand Up @@ -285,7 +290,7 @@ public IFilter Apply(FilterType filterType, IFilterCriteria criteria)
});

_latestFilterStrategy =
new FilterStrategy(_coreExtension, _context, _filterAliasExpander, filterType, criteria);
new FilterStrategy(_coreExtension, _context, _filterAliasExpander, filterType, criteria, _regionManager);

_filterExecutionTime = TimeSpan.Zero;
var exectionTimeStopwatch = Stopwatch.StartNew();
Expand Down
6 changes: 4 additions & 2 deletions Src/BlueDotBrigade.Weevil.Core/Filter/FilterStrategy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,14 @@ public FilterStrategy(
ContextDictionary context,
IFilterAliasExpander filterAliasExpander,
FilterType filterType,
IFilterCriteria filterCriteria)
IFilterCriteria filterCriteria,
IRegionManager regionManager)
{
_filterType = filterType;
_filterCriteria = filterCriteria;

var expressionFactory = ExpressionBuilder.Create(coreExtension, context, filterType, filterCriteria);

var expressionFactory = ExpressionBuilder.Create(coreExtension, context, filterType, filterCriteria, regionManager);

List<IExpression> inclusiveExpressions = ConvertCriteriaIntoExpressions(filterAliasExpander, expressionFactory, filterCriteria, true);
List<IExpression> exclusiveExpressions = ConvertCriteriaIntoExpressions(filterAliasExpander, expressionFactory, filterCriteria, false);
Expand Down
47 changes: 20 additions & 27 deletions Src/BlueDotBrigade.Weevil.Core/RegionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,18 @@ namespace BlueDotBrigade.Weevil
[DebuggerDisplay("Count={_regions.Count}")]
internal class RegionManager : IRegionManager
{
private readonly ISelect _selectionManager;

private readonly List<Region> _regions;
private readonly object _regionsPadlock;

private int? _startLineNumber;

internal RegionManager(ISelect selectionManager) : this(selectionManager, ImmutableArray<Region>.Empty)
internal RegionManager() : this(ImmutableArray<Region>.Empty)
{
// nothing to do
}

internal RegionManager(ISelect selectionManager, ImmutableArray<Region> regions)
internal RegionManager(ImmutableArray<Region> regions)
{
_selectionManager = selectionManager ?? throw new ArgumentNullException(nameof(selectionManager));

_regions = new List<Region>(regions);
_regionsPadlock = new object();

Expand Down Expand Up @@ -52,33 +48,30 @@ public ImmutableArray<Region> Regions
}
}

public void CreateFromSelection()
public void CreateFromSelection(int[] selectedLineNumbers)
{
if (_selectionManager.HasSelectionPeriod)
var sortedLineNumbers = selectedLineNumbers.OrderBy(k => k).ToArray();
var minLineNumber = sortedLineNumbers.Min();
var maxLineNumber = sortedLineNumbers.Max();

lock (_regionsPadlock)
{
var sortedLineNumbers = _selectionManager.Selected.Keys.OrderBy(k => k).ToArray();
var minLineNumber = sortedLineNumbers.Min();
var maxLineNumber = sortedLineNumbers.Max();
var regionName = ConvertNumberToLetter(_regions.Count + 1);
var region = new Region(regionName, minLineNumber, maxLineNumber);

lock (_regionsPadlock)
// Prevent creating the same region twice
if (_regions.Any(r => r.Minimum.LineNumber == region.Minimum.LineNumber && r.Maximum.LineNumber == region.Maximum.LineNumber))
{
var regionName = ConvertNumberToLetter(_regions.Count + 1);
var region = new Region(regionName, minLineNumber, maxLineNumber);

// Prevent creating the same region twice
if (_regions.Any(r => r.Minimum.LineNumber == region.Minimum.LineNumber && r.Maximum.LineNumber == region.Maximum.LineNumber))
{
throw new InvalidOperationException("Unable to create region because this region has already been defined.");
}

// Check for overlap with existing regions
if (_regions.Any(r => r.OverlapsWith(region)))
{
throw new InvalidOperationException("Unable to create region because it overlaps with an existing region.");
}
throw new InvalidOperationException("Unable to create region because this region has already been defined.");
}

_regions.Add(region);
// Check for overlap with existing regions
if (_regions.Any(r => r.OverlapsWith(region)))
{
throw new InvalidOperationException("Unable to create region because it overlaps with an existing region.");
}

_regions.Add(region);
}
}

Expand Down
4 changes: 2 additions & 2 deletions Src/BlueDotBrigade.Weevil.Gui/Converters/RegionConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ public object Convert(object[] values, Type targetType, object parameter, Cultur
// - or "in region" otherwise
if (viewModel.RegionStartsWith(record, out var regionName1))
{
return $"↧↧{regionName1}↧↧";
return $"🡇 {regionName1} ";
}
else if (viewModel.RegionEndsWith(record, out var regionName2))
{
return $"↥↥{regionName2}↥↥";
return $"🡅 {regionName2} ";
}
else
{
Expand Down
6 changes: 5 additions & 1 deletion Src/BlueDotBrigade.Weevil.Gui/Filter/FilterView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,11 @@
<TextBlock>
<TextBlock TextWrapping="WrapWithOverflow" HorizontalAlignment="Right"
Text="{Binding Mode=OneWay, Converter={StaticResource ContentConverter}}"/>
<TextBlock Margin="0,0,0,0" FontWeight="Bold" FontSize="17" Foreground="Red">
<TextBlock
Margin="0,0,0,0" Padding="0,0,0,0"
FontWeight="ExtraBlack" FontSize="17"
Background="WhiteSmoke" Foreground="Black"
ToolTip="Region Of Interest">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource RegionStringConverter}">
<!-- 1) The current item (record) -->
Expand Down
9 changes: 6 additions & 3 deletions Src/BlueDotBrigade.Weevil.Gui/Filter/FilterViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1462,9 +1462,12 @@ private void AddRegion()
{
try
{
_engine.Regions.CreateFromSelection();
RaiseResultsChanged();

if (_engine.Selector.HasSelectionPeriod)
{
var selectedLineNumbers = _engine.Selector.Selected.Keys.ToArray();
_engine.Regions.CreateFromSelection(selectedLineNumbers);
RaiseResultsChanged();
}
}
catch (Exception e)
{
Expand Down
13 changes: 4 additions & 9 deletions Tst/BlueDotBrigade.Weevil.Core-UnitTests/RegionManagerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,12 @@ namespace BlueDotBrigade.Weevil.Core.UnitTests
[TestClass]
public class RegionManagerTests
{
private ISelect _selectionManager;
private RegionManager _regionManager;

[TestInitialize]
public void Setup()
{
_selectionManager = Substitute.For<ISelect>();
_regionManager = new RegionManager(_selectionManager);
_regionManager = new RegionManager();
}

[TestMethod]
Expand Down Expand Up @@ -116,15 +114,12 @@ public void Clear_LineNumberIsOutsideOfRegion_ReturnsFalseAndKeepsRegions()
public void CreateFromSelection_LineNumberIsOutsideOfBookend_ReturnsFalseAndKeepsBookend()
{
// Arrange
var selectedRecords = Enumerable
var selectedLineNumbers = Enumerable
.Range(start: 16, count: 17)
.ToDictionary(lineNumber => lineNumber, lineNumber => R.WithLineNumber(lineNumber));

_selectionManager.Selected.Returns(selectedRecords);
_selectionManager.HasSelectionPeriod.Returns(true);
.ToArray();

// Act
_regionManager.CreateFromSelection();
_regionManager.CreateFromSelection(selectedLineNumbers);

// Assert
_regionManager.Regions.Length.Should().Be(1);
Expand Down

0 comments on commit a0a7b85

Please sign in to comment.