public void SetupOnce() { ObjectFactory.Initialize((cfg) => cfg.AddRegistry(new ProcessorRegistry())); var eventLogger = Substitute.For<IEventLogger>(); processor = new PipelineProcessor(ObjectFactory.Container, eventLogger); }
List <PipelineStepContainer> _pipelineSteps = new List <PipelineStepContainer>(); // Reference to all steps public Pipeline <TPipelineIn, TPipelineOut> AddStepAndStart <TIn, TOut>(IPipelineProcessor <TIn, TOut> processor) { var step = new PipelineStep <TIn, TOut>(processor); int stepIndex = _pipelineSteps.Count; // Alternatively, I can store a list of the Task.Run() handlers here and then run them at a later point // Start the step Task.Run(() => { // Cached next step IBufferable <TOut> nextBuffer = null; foreach (Item <TIn> input in step.Buffer.GetConsumingEnumerable()) { // Give us the most up-to-date status on our current position in the pipeline bool isLastStep = stepIndex == _pipelineSteps.Count - 1; TOut outputValue; // Attempt to process value try { outputValue = processor.Process(input.Value); } catch (Exception e) { input.TaskCompletionSource.SetException(e); continue; } // Move to next step if (isLastStep) { input.TaskCompletionSource.SetResult((TPipelineOut)(object)outputValue); } else { nextBuffer = nextBuffer ?? _pipelineSteps[stepIndex + 1].Value as IBufferable <TOut>; try // In the case of the pipeline closing prematurely, catch the error and throw an exception to the task { nextBuffer.Buffer.Add(new Item <TOut> { Value = outputValue, TaskCompletionSource = input.TaskCompletionSource }); } catch (InvalidOperationException e) { input.TaskCompletionSource.SetException(e); } } } }); _pipelineSteps.Add(new PipelineStepContainer { Value = step, }); return(this); }
public void SetupOnce() { ObjectFactory.Initialize((cfg) => cfg.AddRegistry(new ProcessorRegistry())); var eventLogger = Substitute.For <IEventLogger>(); processor = new PipelineProcessor(ObjectFactory.Container, eventLogger); }
public static PipelineResult ProcessActionForEvent(this IPipelineProcessor processor, IEvent @event) { var payloadType = typeof(Payload <>).MakeGenericType(@event.GetType()); var payloadInstance = Activator.CreateInstance(payloadType, @event); var processMethod = typeof(IPipelineProcessor).GetMethod("Process"); var genProcessMethod = processMethod.MakeGenericMethod(@event.GetType()); return((PipelineResult)genProcessMethod.Invoke(processor, new [] { payloadInstance })); }
// Token: 0x060008FC RID: 2300 RVA: 0x0001E60C File Offset: 0x0001C80C private void OnSessionClosed(object sender, EventArgs e) { this.m_Connected = false; this.m_LocalEndPoint = null; IPipelineProcessor pipeLineProcessor = this.PipeLineProcessor; if (pipeLineProcessor != null) { pipeLineProcessor.Reset(); } EventHandler closed = this.Closed; if (closed != null) { closed(this, EventArgs.Empty); } this.m_ConnectEvent.Set(); }
/// <summary> /// Construct the PVM task accumulator for the PVM rendering task to contain the values to be rendered /// We manage this here because the accumulator context relates to the query spatial bounds, not the rendered tile bounds /// The accumulator is instructed to created a context covering the OverrideSpatialExtents context from the processor (which /// will represent the bounding extent of data required due to any tile rotation), and covered by a matching (possibly larger) grid /// of cells to the map view grid of pixels /// </summary> private void ConstructPVMTaskAccumulator(IPipelineProcessor processor) { // Construct the PVM task accumulator for the PVM rendering task to contain the values to be rendered // We manage this here because the accumulator context relates to the query spatial bounds, not the rendered tile bounds // The accumulator is instructed to created a context covering the OverrideSpatialExtents context from the processor (which // will represent the bounding extent of data required due to any tile rotation), and covered by a matching (possibly larger) grid // of cells to the map view grid of pixels var smoother = (Displayer as IProductionPVMConsistentDisplayer)?.DataSmoother; var view = Displayer.MapView; var valueStoreCellSizeX = view.XPixelSize > processor.SiteModel.CellSize ? view.XPixelSize : processor.SiteModel.CellSize; var valueStoreCellSizeY = view.YPixelSize > processor.SiteModel.CellSize ? view.YPixelSize : processor.SiteModel.CellSize; // Compute the origin of the cell in the value store that encloses the origin of the map view. // In the case of tile rendering, OverrideSpatialExtents represents the enclosing rotated bounding box for the tile and // is the bounding extent of the data should be requested var valueStoreOriginX = Math.Truncate(processor.OverrideSpatialExtents.MinX / valueStoreCellSizeX) * valueStoreCellSizeX; var valueStoreOriginY = Math.Truncate(processor.OverrideSpatialExtents.MinY / valueStoreCellSizeY) * valueStoreCellSizeY; // Compute the limit of the cell in the value store that encloses the limit of the map view. // In the case of tile rendering, OverrideSpatialExtents represents the enclosing rotated bounding box for the tile and // is the bounding extent of the data should be requested var valueStoreLimitX = Math.Truncate((processor.OverrideSpatialExtents.MaxX + valueStoreCellSizeX) / valueStoreCellSizeX) * valueStoreCellSizeX; var valueStoreLimitY = Math.Truncate((processor.OverrideSpatialExtents.MaxY + valueStoreCellSizeY) / valueStoreCellSizeY) * valueStoreCellSizeY; var valueStoreCellsX = (int)Math.Round((valueStoreLimitX - valueStoreOriginX) / valueStoreCellSizeX); var valueStoreCellsY = (int)Math.Round((valueStoreLimitY - valueStoreOriginY) / valueStoreCellSizeY); var borderAdjustmentCells = 2 * smoother?.AdditionalBorderSize ?? 0; var extentAdjustmentSizeX = smoother?.AdditionalBorderSize * valueStoreCellSizeX ?? 0; var extentAdjustmentSizeY = smoother?.AdditionalBorderSize * valueStoreCellSizeY ?? 0; ((IPVMRenderingTask)processor.Task).Accumulator = ((IProductionPVMConsistentDisplayer)Displayer).GetPVMTaskAccumulator( valueStoreCellSizeX, valueStoreCellSizeY, valueStoreCellsX + borderAdjustmentCells, valueStoreCellsY + borderAdjustmentCells, valueStoreOriginX - extentAdjustmentSizeX, valueStoreOriginY - extentAdjustmentSizeY, (valueStoreLimitX - valueStoreOriginX) + 2 * extentAdjustmentSizeX, (valueStoreLimitY - valueStoreOriginY) + 2 * extentAdjustmentSizeY, processor.SiteModel.CellSize ); }
private void RunSubPipelines(PipelineContext pipelineContext, Pipeline subPipeline) { ILogger logger = pipelineContext.PipelineBatchContext.Logger; pipelineContext.CurrentPipeline = subPipeline; IPipelineProcessor pipelineProcessor = subPipeline.PipelineProcessor; if (pipelineProcessor == null) { logger.Error("Pipeline will be skipped because it does not have a processor assigned. (pipeline step: {0}, sub-pipeline: {1})", "Iterate and Run Async", (object)subPipeline.Name); } else if (!pipelineProcessor.CanProcess(subPipeline, pipelineContext)) { logger.Error("Pipeline will be skipped because the processor cannot processes the sub-pipeline. (pipeline step: {0}, sub-pipeline: {1}, sub-pipeline processor: {2})", "Iterate and Run Async", (object)subPipeline.Name, (object)pipelineProcessor.GetType().FullName); } else { pipelineProcessor.Process(subPipeline, pipelineContext); if (pipelineContext.CriticalError) { logger.Error("Sub pipeline processing will not abort since it's done async"); } } }
protected virtual void OnChannelReady() { m_PipeLineProcessor = new DefaultPipelineProcessor <PipePackageInfo>(new PipeReceiveFilter(), 1024 * 64); StartReceive(); }
public virtual void Register(string pipelineName, IPipelineProcessor processorMock) { this.Pipelines[pipelineName] = processorMock; this.Expects(pipelineName, delegate { return true; }); }
public PipelinesController(IPipelineProcessor pipelineProcesor) { _pipelineProcessor = pipelineProcesor; }
public PipelineStep(IPipelineProcessor <TStepIn, TStepOut> processor) { Processor = processor; }
public static PipelineResult ProcessAction <TEvent>(this IPipelineProcessor processor, TEvent @event) where TEvent : IEvent { return(processor.Process(new Payload <TEvent>(@event))); }
/// <summary> /// Initializes a new instance of an immutable Pipeline that either uses given /// processor or the default UninterruptibleProcessor as its processor. /// </summary> /// <param name="processor">Processor.</param> public Pipeline(IPipelineProcessor <TPayload> processor = null) { _processor = processor ?? new UninterruptibleProcessor <TPayload>(); _stages = new List <IPipelineStage <TPayload> >(); }
public virtual void Register(string pipelineName, IPipelineProcessor processorMock) { this.Pipelines[pipelineName] = processorMock; this.Expects(pipelineName, delegate { return(true); }); }
/// <summary> /// Setup pipeline for tile request /// </summary> /// <param name="siteModelExtent">Site Model Extent</param> /// <param name="cellSize">Cell Size</param> /// <returns></returns> private async Task <bool> SetupPipelineTask(BoundingWorldExtent3D siteModelExtent, double cellSize) { var requestDescriptor = Guid.NewGuid(); if (DisplayMode == QMConstants.DisplayModeStandard) { // Note coords are always supplied lat long if (SiteModel.CSIB() == string.Empty) { ResultStatus = RequestErrorStatus.EmptyCoordinateSystem; _log.LogError($"Failed to obtain site model coordinate system CSIB file for Project:{DataModelUid}"); return(false); } } LLHCoords = new[] { new XYZ(MapUtils.Deg2Rad(TileBoundaryLL.West), MapUtils.Deg2Rad(TileBoundaryLL.South), 0), new XYZ(MapUtils.Deg2Rad(TileBoundaryLL.East), MapUtils.Deg2Rad(TileBoundaryLL.North), 0), new XYZ(MapUtils.Deg2Rad(TileBoundaryLL.West), MapUtils.Deg2Rad(TileBoundaryLL.North), 0), new XYZ(MapUtils.Deg2Rad(TileBoundaryLL.East), MapUtils.Deg2Rad(TileBoundaryLL.South), 0) }; // This will change in Part3 once development is complete var strCSIB = DisplayMode == QMConstants.DisplayModeStandard ? SiteModel.CSIB() : DIMENSIONS_2012_DC_CSIB; var NEECoords = DIContext.Obtain <ICoreXWrapper>().LLHToNEE(strCSIB, LLHCoords.ToCoreX_XYZ(), CoreX.Types.InputAs.Radians).ToTRex_XYZ(); GridIntervalX = (NEECoords[1].X - NEECoords[0].X) / (TileGridSize - 1); GridIntervalY = (NEECoords[1].Y - NEECoords[0].Y) / (TileGridSize - 1); _log.LogDebug($"#Tile#.({TileX},{TileY}) TileInfo: Zoom:{TileZ}, TileSizeXY:{Math.Round(NEECoords[1].X - NEECoords[0].X, 3)}m x {Math.Round(NEECoords[2].Y - NEECoords[0].Y, 3)}m, GridInterval(m) X:{Math.Round(GridIntervalX, 3)}, Y:{Math.Round(GridIntervalY, 3)}, GridSize:{TileGridSize}"); var WorldTileHeight = MathUtilities.Hypot(NEECoords[0].X - NEECoords[2].X, NEECoords[0].Y - NEECoords[2].Y); var WorldTileWidth = MathUtilities.Hypot(NEECoords[0].X - NEECoords[3].X, NEECoords[0].Y - NEECoords[3].Y); double dx = NEECoords[2].X - NEECoords[0].X; CenterX = NEECoords[2].X + dx / 2; double dy = NEECoords[2].Y - NEECoords[0].Y; CenterY = NEECoords[0].Y + dy / 2; // Calculate the tile rotation as the mathematical angle turned from 0 (due east) to the vector defined by dy/dx TileRotation = Math.Atan2(dy, dx); // Convert TileRotation to represent the angular deviation rather than a bearing TileRotation = (Math.PI / 2) - TileRotation; SetRotation(TileRotation); _log.LogDebug($"QMTile render executing across tile: [Rotation:{ MathUtilities.RadiansToDegrees(TileRotation)}] " + $" [BL:{NEECoords[0].X}, {NEECoords[0].Y}, TL:{NEECoords[2].X},{NEECoords[2].Y}, " + $"TR:{NEECoords[1].X}, {NEECoords[1].Y}, BR:{NEECoords[3].X}, {NEECoords[3].Y}] " + $"World Width, Height: {WorldTileWidth}, {WorldTileHeight}"); RotatedTileBoundingExtents.SetInverted(); foreach (var xyz in NEECoords) { RotatedTileBoundingExtents.Include(xyz.X, xyz.Y); } // Intersect the site model extents with the extents requested by the caller _log.LogDebug($"Tile.({TileX},{TileY}) Calculating intersection of bounding box and site model {DataModelUid}:{siteModelExtent}"); var dataSelectionExtent = new BoundingWorldExtent3D(RotatedTileBoundingExtents); dataSelectionExtent.Intersect(siteModelExtent); if (!dataSelectionExtent.IsValidPlanExtent) { ResultStatus = RequestErrorStatus.InvalidCoordinateRange; _log.LogInformation($"Tile.({TileX},{TileY}) Site model extents {siteModelExtent}, do not intersect RotatedTileBoundingExtents {RotatedTileBoundingExtents}"); return(false); } // Compute the override cell boundary to be used when processing cells in the sub grids // selected as a part of this pipeline // Increase cell boundary by one cell to allow for cells on the boundary that cross the boundary SubGridTree.CalculateIndexOfCellContainingPosition(dataSelectionExtent.MinX, dataSelectionExtent.MinY, cellSize, SubGridTreeConsts.DefaultIndexOriginOffset, out var CellExtents_MinX, out var CellExtents_MinY); SubGridTree.CalculateIndexOfCellContainingPosition(dataSelectionExtent.MaxX, dataSelectionExtent.MaxY, cellSize, SubGridTreeConsts.DefaultIndexOriginOffset, out var CellExtents_MaxX, out var CellExtents_MaxY); var CellExtents = new BoundingIntegerExtent2D(CellExtents_MinX, CellExtents_MinY, CellExtents_MaxX, CellExtents_MaxY); CellExtents.Expand(1); // Setup Task task = DIContext.Obtain <Func <PipelineProcessorTaskStyle, ITRexTask> >()(PipelineProcessorTaskStyle.QuantizedMesh) as QuantizedMeshTask; processor = DIContext.Obtain <IPipelineProcessorFactory>().NewInstanceNoBuild <SubGridsRequestArgument>(requestDescriptor: requestDescriptor, dataModelID: DataModelUid, gridDataType: GridDataType.Height, response: GriddedElevationsResponse, filters: Filters, cutFillDesign: new DesignOffset(), task: task, pipeline: DIContext.Obtain <Func <PipelineProcessorPipelineStyle, ISubGridPipelineBase> >()(PipelineProcessorPipelineStyle.DefaultProgressive), requestAnalyser: DIContext.Obtain <IRequestAnalyser>(), requireSurveyedSurfaceInformation: true, //Rendering.Utilities.DisplayModeRequireSurveyedSurfaceInformation(DisplayMode.Height) && Rendering.Utilities.FilterRequireSurveyedSurfaceInformation(Filters), requestRequiresAccessToDesignFileExistenceMap: false, overrideSpatialCellRestriction: CellExtents, liftParams: LiftParams ); // Set the grid TRexTask parameters for progressive processing processor.Task.RequestDescriptor = requestDescriptor; processor.Task.TRexNodeID = RequestingTRexNodeID; processor.Task.GridDataType = GridDataType.Height; // Set the spatial extents of the tile boundary rotated into the north reference frame of the cell coordinate system to act as // a final restriction of the spatial extent used to govern data requests processor.OverrideSpatialExtents.Assign(RotatedTileBoundingExtents); // Setup new grid array for results GriddedElevDataArray = new GriddedElevDataRow[TileGridSize, TileGridSize]; // build up a data sample grid from SW to NE for (int y = 0; y < TileGridSize; y++) { for (int x = 0; x < TileGridSize; x++) { var x1 = NEECoords[0].X + (GridIntervalX * x); var y1 = NEECoords[0].Y + (GridIntervalY * y); if (Rotating) { Rotate_point(x1, y1, out x1, out y1); } GriddedElevDataArray[x, y].Easting = x1; GriddedElevDataArray[x, y].Northing = y1; GriddedElevDataArray[x, y].Elevation = CellPassConsts.NullHeight; } } _log.LogDebug($"Tile.({TileX},{TileY}) Boundary grid coords:{string.Concat(NEECoords)}"); _log.LogDebug($"Tile.({TileX},{TileY}) First Easting:{GriddedElevDataArray[0, 0].Easting} Northing:{GriddedElevDataArray[0, 0].Northing}"); _log.LogDebug($"Tile.({TileX},{TileY}) Last Easting:{GriddedElevDataArray[TileGridSize - 1, TileGridSize - 1].Easting} Northing:{GriddedElevDataArray[TileGridSize - 1, TileGridSize - 1].Northing}"); // point to container for results task.GriddedElevDataArray = GriddedElevDataArray; task.GridIntervalX = GridIntervalX; task.GridIntervalY = GridIntervalY; task.GridSize = TileGridSize; // Tile boundary task.TileMinX = NEECoords[0].X; task.TileMinY = NEECoords[0].Y; task.TileMaxX = NEECoords[1].X; task.TileMaxY = NEECoords[1].Y; task.LowestElevation = LowestElevation; Azimuth = 0; StartNorthing = NEECoords[0].Y; StartEasting = NEECoords[0].X; // Commented out for purposes of demo until relationship between TRex mediated skip/step selection and the quantised mesh tile vertex based selection are better understood // processor.Pipeline.AreaControlSet = // new AreaControlSet(false, GridIntervalX, GridIntervalY, StartEasting, StartNorthing, Azimuth); if (!processor.Build()) { _log.LogError($"Tile.({TileX},{TileY}) Failed to build pipeline processor for request to model {DataModelUid}"); return(false); } return(true); }
/// <summary> /// Perform rendering activities to produce a bitmap tile /// </summary> public RequestErrorStatus PerformRender(DisplayMode mode, IPipelineProcessor processor, IPlanViewPalette colourPalette, IFilterSet filters, ILiftParameters liftParams) { // Obtain the display responsible for rendering the thematic information for this mode Displayer = PVMDisplayerFactory.GetDisplayer(mode /*, FICOptions*/); if (Displayer == null) { processor.Response.ResultStatus = RequestErrorStatus.UnsupportedDisplayType; return(processor.Response.ResultStatus); } // Create and assign the colour palette logic for this mode to the displayer if (colourPalette == null) { if (mode == DisplayMode.CCA || mode == DisplayMode.CCASummary) { Displayer.SetPalette(Utilities.ComputeCCAPalette(processor.SiteModel, filters.Filters[0].AttributeFilter, mode)); if (Displayer.GetPalette() == null) { processor.Response.ResultStatus = RequestErrorStatus.FailedToGetCCAMinimumPassesValue; return(processor.Response.ResultStatus); } } else { Displayer.SetPalette(PVMPaletteFactory.GetPalette(processor.SiteModel, mode, processor.SpatialExtents)); } } else { Displayer.SetPalette(colourPalette); } // Create the world coordinate display surface the displayer will render onto Displayer.MapView = new MapSurface { SquareAspect = IsWhollyInTermsOfGridProjection }; var view = Displayer.MapView; // Set the world coordinate bounds of the display surface to be rendered on view.SetBounds(NPixelsX, NPixelsY); if (IsWhollyInTermsOfGridProjection) { view.FitAndSetWorldBounds(OriginX, OriginY, OriginX + Width, OriginY + Height, 0); } else { view.SetWorldBounds(OriginX, OriginY, OriginX + Width, OriginY + Height, 0); } // Provide data smoothing support to the displayer for the rendering operation being performed ((IProductionPVMConsistentDisplayer)Displayer).DataSmoother = DIContext.Obtain <Func <DisplayMode, IDataSmoother> >()(mode); // Set the rotation of the displayer rendering surface to match the tile rotation due to the project calibration rotation view.SetRotation(TileRotation); ConstructPVMTaskAccumulator(processor); // Displayer.ICOptions = ICOptions; // Set the skip-step area control cell selection parameters for this tile render. Note that the floating point // skip step algorithm is requested, and a user origin is configured that offsets the sampling grid by half a pixel // size to matching the skip-stepping the PVM accumulator will use when transcribing cell data from sub grids into // the accumulator. Note that the area control set is not configured with a rotation - this is taken into account // through the mapview rotation configured above processor.Pipeline.AreaControlSet = new AreaControlSet(false, view.XPixelSize, view.YPixelSize, view.XPixelSize / 2.0, view.YPixelSize / 2.0, 0.0); processor.Pipeline.LiftParams = liftParams; // todo PipeLine.NoChangeVolumeTolerance = FICOptions.NoChangeVolumeTolerance; // Perform the sub grid query and processing to render the tile var pipelineProcessorStopWatch = Stopwatch.StartNew(); processor.Process(); _log.LogInformation($"Pipeline processor completed in {pipelineProcessorStopWatch.Elapsed}"); if (processor.Response.ResultStatus == RequestErrorStatus.OK) { // Render the collection of data in the aggregator var consistentRenderStopWatch = Stopwatch.StartNew(); (Displayer as IProductionPVMConsistentDisplayer)?.PerformConsistentRender(); _log.LogInformation($"Consistent render complated in {consistentRenderStopWatch.Elapsed}"); PerformAnyRequiredDebugLevelDisplay(); if (DebugDrawDiagonalCrossOnRenderedTilesDefault) { // Draw diagonal cross and top left corner indicators view.DrawLine(view.OriginX, view.OriginY, view.LimitX, view.LimitY, Color.Red); view.DrawLine(view.OriginX, view.LimitY, view.LimitX, view.OriginY, Color.Red); // Draw the horizontal line a little below the world coordinate 'top' of the tile to encourage the line // drawing algorithm not to clip it view.DrawLine(view.OriginX, view.LimitY, view.OriginX, view.CenterY, Color.Red); view.DrawLine(view.OriginX, view.LimitY - 0.01, view.CenterX, view.LimitY - 0.01, Color.Red); } } return(processor.Response.ResultStatus); }