示例#1
0
 public void Evaluate(int spreadMax)
 {
     FOutput.SliceCount = spreadMax;
     for (int i = 0; i < spreadMax; i++)
     {
         var stream = FInput[i];
         var count  = FCountIn[i];
         if (count < 0)
         {
             FOutput[i] = new SkipStream(stream, Math.Max(stream.Length + count, 0));
         }
         else
         {
             FOutput[i] = new TakeStream(stream, count);
         }
     }
 }
示例#2
0
        public void Evaluate(int SpreadMax)
        {
            FOutOnData.SliceCount       = FOutElementCount.SliceCount = 1;
            FOutMemoryStream.SliceCount = FOutActiveChunkIndex.SliceCount = 0;

            if (FChunkManager.IsConnected && FChunkManager.SliceCount > 0 && FChunkManager[0] != null)
            {
                ChunkManager chunkManager = FChunkManager[0];

                // create chunkaccessdata list for all requested chunks
                if (FIndex.IsChanged || FDownsampling.IsChanged || FDownsamplingOffset.IsChanged)
                {
                    IEnumerable <int>      currentChunks    = FIndex;
                    List <int>             currentChunkList = FIndex.ToList();
                    List <ChunkAccessData> chunksToAdd      = new List <ChunkAccessData>();
                    for (int i = 0; i < FIndex.SliceCount; i++)
                    {
                        int    streamLimit              = FLimit[i];
                        int    streamDownsampling       = FDownsampling[i];
                        int    streamDownsamplingOffset = FDownsamplingOffset[i];
                        double streamLocktime           = FLockTime[i];
                        chunksToAdd.Add(new ChunkAccessData(FIndex[i], streamLimit, streamDownsampling, streamDownsamplingOffset, streamLocktime));
                    }

                    // now remove chunks that are already active (with the same LOD)
                    chunksToAdd.RemoveAll(chunkToAdd => ActiveChunks.Exists(activeChunk => chunkToAdd.chunkId == activeChunk.chunkId &&
                                                                            chunkToAdd.streamDownsampling == activeChunk.streamDownsampling &&
                                                                            chunkToAdd.streamDownsamplingOffset == activeChunk.streamDownsamplingOffset
                                                                            ));
                    // remove chunks that are locked
                    chunksToAdd.RemoveAll(chunkToAdd => LockedChunks.Exists(lockedChunk => chunkToAdd.chunkId == lockedChunk.chunkId));

                    // create list of chunks wo dont need anymore
                    var chunksToRemove = ActiveChunks.Select(activeChunk => activeChunk.chunkId).Except(currentChunks).ToList();

                    // update list of locked chunks
                    var chunksToLock = ActiveChunks.Where(activeChunk => chunksToRemove.Contains(activeChunk.chunkId) && activeChunk.streamFinished).ToList();
                    chunksToLock.ForEach(activeChunk => activeChunk.StartLock());
                    LockedChunks.AddRange(chunksToLock);
                    LockedChunks.RemoveAll(lockedChunk => lockedChunk.isLocked == false);

                    // finally add remaining chunkaccessdata items to active list ..
                    ActiveChunks.AddRange(chunksToAdd);
                    // and remove chunkaccessdata items we dont need anymore
                    ActiveChunks.RemoveAll(activeChunk => chunksToRemove.Contains(activeChunk.chunkId));

                    // start reading process for new chunks (if not already happened)
                    if (chunkManager.ChunkReader != null)
                    {
                        foreach (ChunkAccessData chunkAccessData in chunksToAdd)
                        {
                            Chunk chunk = chunkManager.GetChunk(chunkAccessData.chunkId);
                            chunkManager.ChunkReader.Read(chunk);
                        }
                    }
                }

                // add chunkdata streams to a list
                FOutElementCount[0] = 0;
                List <Stream> streams = new List <Stream>();
                foreach (ChunkAccessData activeChunk in ActiveChunks)
                {
                    Chunk chunk = chunkManager.GetChunk(activeChunk.chunkId);

                    if (!activeChunk.streamFinished && chunk.finishedLoading)
                    {
                        Stream stream = chunk.MemoryStream;

                        // logic for limited stream output
                        if (activeChunk.streamLimit > -1)
                        {
                            int bytesToRead = chunkManager.BytesPerElement * activeChunk.streamLimit;
                            stream = new SkipStream(stream, activeChunk.streamPosition);
                            stream = new TakeStream(stream, bytesToRead * activeChunk.streamDownsampling);
                        }

                        // logic for picking every nth element
                        if (activeChunk.streamDownsampling > 1)
                        {
                            stream = new ModuloStream(stream, chunkManager.BytesPerElement, activeChunk.streamDownsampling, activeChunk.streamDownsamplingOffset);
                        }

                        // calculate number of appended elements
                        int bytesRead = (int)stream.Length;
                        FOutElementCount[0] += (bytesRead / chunkManager.BytesPerElement);

                        // update streamposition and set flag if position is at end
                        activeChunk.streamPosition += bytesRead * activeChunk.streamDownsampling;
                        if (activeChunk.streamPosition >= chunk.MemoryStream.Length)
                        {
                            activeChunk.streamFinished = true;
                        }

                        // add stream to list
                        streams.Add(stream);
                    }
                }

                // aggregate streams if needed
                if (streams.Count > 1)
                {
                    FOutMemoryStream.Add(new AggregatedStream(streams));
                }
                else if (streams.Count == 1)
                {
                    FOutMemoryStream.Add(streams[0]);
                }

                // bang on data
                FOutOnData[0] = (FOutElementCount[0] > 0) ? true : false;

                // output active chunk ids
                FOutActiveChunkIndex.AddRange(ActiveChunks.Select(activeChunk => activeChunk.chunkId));
            }
            else
            {
                FOutMemoryStream.Add(new MemoryComStream(new byte[sizeof(Single)]));   // workaround to prevent DynamicBufer (raw) from throwing exceptions
            }
        }