Exemple #1
0
        private void InitializeCore(
            BaseControlFlowGraph source,
            Func <ControlFlowBlock, bool> vertexFilter,
            Func <ControlFlowEdge, bool> edgeFilter,
            Action <ControlFlowEdge, ViewOfControlFlowGraph> onAlienEdge)
        {
            Source = source.AssertNotNull();
            HookUpVertexPostprocessors();

            _vertexFilter = vertexFilter.AssertNotNull();
            _edgeFilter   = edgeFilter.AssertNotNull();

            _cachedVertices = _hardcodedVertices != null ? null : source.Vertices.Where(_vertexFilter).ToList();
            (_cachedVertices ?? _hardcodedVertices.AsEnumerable()).ForEach(OnVertexAdded);

            ReadOnlyCollection <ControlFlowEdge> alienEdges = null;

            if (_hardcodedEdges != null)
            {
                var edgeVertices = _hardcodedEdges.SelectMany(e => new [] { e.Source, e.Target }).ToHashSet();
                edgeVertices.ExceptWith(_cachedVertices ?? _hardcodedVertices.AsEnumerable());
                edgeVertices.AssertEmpty();
            }
            else
            {
                _edgeFilter = e => edgeFilter(e) && _vertexFilter(e.Source) && _vertexFilter(e.Target);

                var relatedEdges = source.Edges(_vertexFilter, null).Concat(source.Edges(null, _vertexFilter)).Distinct();
                var parts        = relatedEdges.GroupBy(e => _edgeFilter(e)).ToDictionary(g => g.Key, g => g.AsEnumerable());
                _cachedEdges = (parts.GetOrDefault(true, Seq.Empty <ControlFlowEdge>)).ToList();
                alienEdges   = parts.GetOrDefault(false, Seq.Empty <ControlFlowEdge>).ToReadOnly();
            }
            (_cachedEdges ?? _hardcodedEdges.AsEnumerable()).ForEach(OnEdgeAdded);

            Action <ControlFlowBlock> cacheVertex = v => { if (_cachedVertices != null)
                                                           {
                                                               _cachedVertices.Add(v);
                                                           }
                                                           else
                                                           {
                                                               throw AssertionHelper.Fail();
                                                           } };
            Action <ControlFlowBlock> uncacheVertex = v => { if (_cachedVertices != null)
                                                             {
                                                                 _cachedVertices.Remove(v);
                                                             }
                                                             else
                                                             {
                                                                 _hardcodedVertices.Remove(v);
                                                             } };

            source.VertexAdded += v => { if (_vertexFilter(v))
                                         {
                                             cacheVertex(v); OnVertexAdded(v);
                                         }
            };
            source.VertexRemoved += v => { if (_vertexFilter(v))
                                           {
                                               uncacheVertex(v); OnVertexRemoved(v);
                                           }
            };

            Action <ControlFlowEdge> cacheEdge = e => { if (_cachedEdges != null)
                                                        {
                                                            _cachedEdges.Add(e);
                                                        }
                                                        else
                                                        {
                                                            throw AssertionHelper.Fail();
                                                        } };
            Action <ControlFlowEdge> uncacheEdge = e => { if (_cachedEdges != null)
                                                          {
                                                              _cachedEdges.Remove(e);
                                                          }
                                                          else
                                                          {
                                                              _hardcodedEdges.Remove(e);
                                                          } };

            source.EdgeAdded += e => { if (_edgeFilter(e))
                                       {
                                           cacheEdge(e); OnEdgeAdded(e);
                                       }
            };
            source.EdgeRemoved += e => { if (_edgeFilter(e))
                                         {
                                             uncacheEdge(e); OnEdgeRemoved(e);
                                         }
            };

            __vertices = new VirtualList <ControlFlowBlock>(
                () => (_hardcodedVertices ?? (IEnumerable <ControlFlowBlock>)_cachedVertices).Concat(_eigenVertices),
                (i, v) =>
            {
                if (_eigenVertices.Contains(v))
                {
                    // do nothing - the vertex has just been created by AddEigenVertex
                }
                else
                {
                    _vertexFilter(v).AssertTrue();
                    (_cachedVertices != null && i == _cachedVertices.Count()).AssertTrue();
                    Source.AddVertex(v);
                }
            },
                (i, v) => { _vertexFilter(v).AssertTrue(); throw AssertionHelper.Fail(); },
                i =>
            {
                if (i < _cachedEdges.Count())
                {
                    var v = _cachedVertices[i];
                    Source.RemoveVertex(v);
                }
                else
                {
                    throw AssertionHelper.Fail();
                }
            });

            __edges = new VirtualList <ControlFlowEdge>(
                () => (_hardcodedEdges ?? (IEnumerable <ControlFlowEdge>)_cachedEdges).Concat(_eigenEdges),
                (i, e) =>
            {
                if (_eigenEdges.Contains(e))
                {
                    // do nothing - the edge has just been created by AddEigenEdge
                }
                else
                {
                    _edgeFilter(e).AssertTrue();
                    (_cachedEdges != null && i == _cachedEdges.Count()).AssertTrue();
                    Source.AddEdge(e);
                }
            },
                (i, e) => { _edgeFilter(e).AssertTrue(); throw AssertionHelper.Fail(); },
                i =>
            {
                if (i < _cachedEdges.Count())
                {
                    var e = _cachedEdges[i];
                    Source.RemoveEdge(e);
                }
                else
                {
                    var e = _eigenEdges[i - _cachedEdges.Count()];
                    _eigenEdges.Remove(e);
                }
            });

            try { _allowAutoCreateStartAndFinish = true; alienEdges.ForEach(e => onAlienEdge(e, this)); }
            finally { _allowAutoCreateStartAndFinish = false; }
        }