public void MultiValueDictionary_Add_Set() { var mvd = MultiValueDictionary <int, int> .Create <HashSet <int> >(); mvd.Add(5, 42); mvd.Add(5, 42); mvd.Add(42, 42); Assert.AreEqual(2, mvd.Keys.Count); Assert.AreEqual(1, mvd[5].Count); }
public void MultiValueDictionary_Add_Set() { var mvd = MultiValueDictionary <int, int> .Create <HashSet <int> >(); mvd.Add(5, 42); mvd.Add(5, 42); mvd.Add(42, 42); mvd.Keys.Should().HaveCount(2); mvd[5].Should().HaveCount(1); }
public override void Initialize(AnalysisContext context) { context.RegisterCompilationStartAction( analysisContext => { var disposeMethod = DisposableNotDisposed.GetDisposeMethod(analysisContext.Compilation); if (disposeMethod == null) { return; } var disposeMethodsCalledFromDispose = MultiValueDictionary <INamedTypeSymbol, IMethodSymbol> .Create <HashSet <IMethodSymbol> >(); var implementingDisposeMethods = ImmutableHashSet <IMethodSymbol> .Empty; var allDisposeMethods = ImmutableHashSet <IMethodSymbol> .Empty; analysisContext.RegisterSymbolAction(c => CollectDisposeMethods(c, disposeMethod, ref allDisposeMethods, ref implementingDisposeMethods), SymbolKind.Method); analysisContext.RegisterCodeBlockStartAction <SyntaxKind>( cbc => { var methodDeclaration = cbc.CodeBlock as MethodDeclarationSyntax; if (methodDeclaration == null || methodDeclaration.Identifier.ValueText != DisposeMethodName) { return; } var declaredMethodSymbol = cbc.SemanticModel.GetDeclaredSymbol(methodDeclaration); if (declaredMethodSymbol == null || !MethodIsDisposeImplementation(declaredMethodSymbol, disposeMethod)) { return; } var disposableType = declaredMethodSymbol.ContainingType; cbc.RegisterSyntaxNodeAction( c => CollectDisposeMethodsCalledFromDispose((InvocationExpressionSyntax)c.Node, c.SemanticModel, disposableType, disposeMethodsCalledFromDispose), SyntaxKind.InvocationExpression); }); analysisContext.RegisterCompilationEndAction( c => ReportDisposeMethods(allDisposeMethods, implementingDisposeMethods, disposeMethodsCalledFromDispose, c)); }); }
protected override void Initialize(SonarAnalysisContext context) { context.RegisterCompilationStartAction(analysisContext => { if (analysisContext.Compilation.IsTest()) { return; } var fieldsByNamedType = MultiValueDictionary <INamedTypeSymbol, IFieldSymbol> .Create <HashSet <IFieldSymbol> >(); var fieldsAssigned = ImmutableHashSet <IFieldSymbol> .Empty; analysisContext.RegisterSymbolAction(c => { var namedTypeSymbol = (INamedTypeSymbol)c.Symbol; if (!namedTypeSymbol.IsClass() || namedTypeSymbol.Implements(KnownType.System_IDisposable)) { return; } var disposableFields = namedTypeSymbol.GetMembers() .OfType <IFieldSymbol>() .Where(IsNonStaticNonPublicDisposableField) .ToImmutableHashSet(); fieldsByNamedType.AddRangeWithKey(namedTypeSymbol, disposableFields); }, SymbolKind.NamedType); analysisContext.RegisterSyntaxNodeAction(c => { var assignment = (AssignmentExpressionSyntax)c.Node; var expression = assignment.Right; var fieldSymbol = c.SemanticModel.GetSymbolInfo(assignment.Left).Symbol as IFieldSymbol; fieldsAssigned = AddFieldIfNeeded(fieldSymbol, expression, fieldsAssigned); }, SyntaxKind.SimpleAssignmentExpression); analysisContext.RegisterSyntaxNodeAction(c => { var field = (FieldDeclarationSyntax)c.Node; foreach (var variableDeclaratorSyntax in field.Declaration.Variables .Where(declaratorSyntax => declaratorSyntax.Initializer != null)) { var fieldSymbol = c.SemanticModel.GetDeclaredSymbol(variableDeclaratorSyntax) as IFieldSymbol; fieldsAssigned = AddFieldIfNeeded(fieldSymbol, variableDeclaratorSyntax.Initializer.Value, fieldsAssigned); } }, SyntaxKind.FieldDeclaration); analysisContext.RegisterCompilationEndAction(c => { foreach (var kv in fieldsByNamedType) { foreach (var classSyntax in kv.Key.DeclaringSyntaxReferences .Select(declaringSyntaxReference => declaringSyntaxReference.GetSyntax()) .OfType <ClassDeclarationSyntax>()) { var assignedFields = kv.Value.Intersect(fieldsAssigned).ToList(); if (!assignedFields.Any()) { continue; } var variableNames = string.Join(", ", assignedFields.Select(symbol => $"\"{symbol.Name}\"").OrderBy(s => s)); c.ReportDiagnosticIfNonGenerated( Diagnostic.Create(Rule, classSyntax.Identifier.GetLocation(), variableNames), c.Compilation); } } }); }); }
public TerrainOverlayNetwork CompileTerrainOverlayNetwork(double agentRadius) { if (terrainOverlayNetworkCache.TryGetValue(agentRadius, out var existingTerrainOverlayNetwork)) { return(existingTerrainOverlayNetwork); } // Console.WriteLine($"Compiling Terrain Overlay Network for Agent Radius {agentRadius}."); //---------------------------------------------------------------------------------------- // Sector Node Description => Default Local Geometry View //---------------------------------------------------------------------------------------- var renderedLocalGeometryViewBySectorNodeDescription = localGeometryViewManagerBySectorNodeDescription.Map( (k, v) => v.GetErodedView(agentRadius * k.WorldToLocalScalingFactor)); var defaultLocalGeometryViewBySectorNodeDescription = renderedLocalGeometryViewBySectorNodeDescription.Map( (k, v) => true || v.IsPunchedLandEvaluated ? v : v.Preview); var landPolyNodesByDefaultLocalGeometryView = defaultLocalGeometryViewBySectorNodeDescription.Values.Distinct().ToDictionary( lgv => lgv, lgv => lgv.PunchedLand.GetLandNodes()); var terrainNodesBySectorNodeDescription = defaultLocalGeometryViewBySectorNodeDescription.Map( (k, v) => landPolyNodesByDefaultLocalGeometryView[v].Map(pn => new TerrainOverlayNetworkNode(k, v, pn))); var terrainNodesBySectorNodeDescriptionAndPolyNode = terrainNodesBySectorNodeDescription.Values.SelectMany(tns => tns).ToDictionary( tn => (tn.SectorNodeDescription, tn.LandPolyNode)); //---------------------------------------------------------------------------------------- // Edge Lookups //---------------------------------------------------------------------------------------- var edgesBySource = edgeDescriptions.ToLookup(ed => ed.Source); var edgesByDestination = edgeDescriptions.ToLookup(ed => ed.Destination); var edgesByEndpoints = MultiValueDictionary <SectorNodeDescription, SectorEdgeDescription> .Create(() => new HashSet <SectorEdgeDescription>()); foreach (var(k, edges) in edgesBySource) { foreach (var edge in edges) { edgesByEndpoints.Add(k, edge); } } foreach (var(k, edges) in edgesByDestination) { foreach (var edge in edges) { edgesByEndpoints.Add(k, edge); } } //---------------------------------------------------------------------------------------- // Build and Initialize Terrain Overlay Network //---------------------------------------------------------------------------------------- var terrainOverlayNetwork = new TerrainOverlayNetwork( agentRadius, defaultLocalGeometryViewBySectorNodeDescription, terrainNodesBySectorNodeDescription, landPolyNodesByDefaultLocalGeometryView, terrainNodesBySectorNodeDescriptionAndPolyNode, edgeDescriptions, edgesBySource, edgesByDestination, edgesByEndpoints); terrainOverlayNetwork.Initialize(); return(terrainOverlayNetworkCache[agentRadius] = terrainOverlayNetwork); }
private static MultiValueDictionary <TerrainOverlayNetworkNode, IntLineSegment2> FindVisibleCrossoverSegmentsByNeighborAndClearLocalAt( IDebugCanvas canvas, TerrainOverlayNetworkNode terrainNode, VisibilityPolygon visibilityPolygon, IntVector2 visibilityPolygonOrigin, HashSet <TerrainOverlayNetworkNode> visited = null) { var visibleCrossoverSegmentsByNeighbor = MultiValueDictionary <TerrainOverlayNetworkNode, IntLineSegment2> .Create(() => new HashSet <IntLineSegment2>()); foreach (var outboundEdgeGroup in terrainNode.OutboundEdgeGroups) { var otherTerrainNode = outboundEdgeGroup.Key; if (visited?.Contains(otherTerrainNode) ?? false) { continue; } foreach (var outboundEdge in outboundEdgeGroup.Value) { var ranges = visibilityPolygon.Get(); (IntLineSegment2, bool) FlipMaybeSorta(IntLineSegment2 x) => GeometryOperations.Clockness(visibilityPolygonOrigin, x.First, x.Second) == Clockness.CounterClockwise ? (new IntLineSegment2(x.Second, x.First), true) : (x, false); var(localCrossoverSegment, lcsFlipped) = FlipMaybeSorta(outboundEdge.EdgeJob.EdgeDescription.SourceSegment); var(remoteCrossoverSegment, rcsFlipped) = FlipMaybeSorta(outboundEdge.EdgeJob.EdgeDescription.DestinationSegment); // todo: clamp visibleStartT, visibleEndT to account for agent radius eroding crossover segmetmentnt var rangeIndexIntervals = visibilityPolygon.RangeStab(localCrossoverSegment); var locallyClearedSegments = new List <IntLineSegment2>(); foreach (var(startIndexInclusive, endIndexInclusive) in rangeIndexIntervals) { for (var i = startIndexInclusive; i <= endIndexInclusive; i++) { if (ranges[i].Id == VisibilityPolygon.RANGE_ID_INFINITELY_FAR || ranges[i].Id == VisibilityPolygon.RANGE_ID_INFINITESIMALLY_NEAR) { continue; } var seg = ranges[i].Segment; var rstart = DoubleVector2.FromRadiusAngle(100, ranges[i].ThetaStart) * 100; var rend = DoubleVector2.FromRadiusAngle(100, ranges[i].ThetaEnd) * 100; double visibleStartT, visibleEndT; if (!GeometryOperations.TryFindNonoverlappingLineLineIntersectionT(localCrossoverSegment.First.ToDoubleVector2(), localCrossoverSegment.Second.ToDoubleVector2(), visibilityPolygonOrigin.ToDoubleVector2(), visibilityPolygonOrigin.ToDoubleVector2() + rstart, out visibleStartT) || !GeometryOperations.TryFindNonoverlappingLineLineIntersectionT(localCrossoverSegment.First.ToDoubleVector2(), localCrossoverSegment.Second.ToDoubleVector2(), visibilityPolygonOrigin.ToDoubleVector2(), visibilityPolygonOrigin.ToDoubleVector2() + rend, out visibleEndT)) { // wtf? Console.WriteLine("???"); continue; } // Todo: I don't actually understand why visibleEndT > 1 is a thing? // t values are for parameterization of crossover line segment, so must be within [0, 1] if ((visibleStartT < 0 && visibleEndT < 0) || (visibleStartT > 1 && visibleEndT > 1)) { continue; } visibleStartT = Math.Min(1.0, Math.Max(0.0, visibleStartT)); visibleEndT = Math.Min(1.0, Math.Max(0.0, visibleEndT)); if (visibilityPolygon.SegmentComparer.Compare(localCrossoverSegment, seg) < 0) { var localVisibleStart = localCrossoverSegment.PointAt(visibleStartT).LossyToIntVector2(); var localVisibleEnd = localCrossoverSegment.PointAt(visibleEndT).LossyToIntVector2(); var remoteVisibleStart = remoteCrossoverSegment.PointAt(lcsFlipped == rcsFlipped ? visibleStartT : 1.0 - visibleStartT).LossyToIntVector2(); var remoteVisibleEnd = remoteCrossoverSegment.PointAt(lcsFlipped == rcsFlipped ? visibleEndT : 1.0 - visibleEndT).LossyToIntVector2(); if (localVisibleStart == localVisibleEnd) { continue; } if (remoteVisibleStart == remoteVisibleEnd) { continue; } var locallyClearedSegment = new IntLineSegment2(localVisibleStart, localVisibleEnd); locallyClearedSegments.Add(locallyClearedSegment); visibleCrossoverSegmentsByNeighbor.Add(otherTerrainNode, new IntLineSegment2(remoteVisibleStart, remoteVisibleEnd)); } } } foreach (var locallyClearedSegment in locallyClearedSegments) { visibilityPolygon.ClearBefore(locallyClearedSegment); } } } return(visibleCrossoverSegmentsByNeighbor); }