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); } } }
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 } }