public void Enummerieren(Tuple<string, string> input) { const int BATCH_SIZE = 5000; var batcher = new Batcher<string>(BATCH_SIZE); Dateien_enummerieren(input.Item1, input.Item2, batcher); Dateien(batcher.GrabAsEndOfStream(input.Item1)); }
public Batch<Tuple<FileInfo, string>> Abfrage_beimischen(Batch<FileInfo> dateien) { var filteraufträge = new Batcher<Tuple<FileInfo, string>>(dateien.Elements.Length); dateien.ForEach(t => { var suchvorgang = _suchvorgänge[dateien.CorrelationId]; var filterauftrag = new Tuple<FileInfo, string>(t, suchvorgang.Abfrage); filteraufträge.Add(filterauftrag); }); if (dateien.GetType() == typeof(EndOfStreamBatch<FileInfo>)) return filteraufträge.GrabAsEndOfStream(dateien.CorrelationId); return filteraufträge.Grab(dateien.CorrelationId); }
internal void Dateien_enummerieren(string id, string pfad, Batcher<string> batcher) { var dir = new DirectoryInfo(pfad); try { foreach (var file in dir.GetFiles(_dateinamenschablone)) if (batcher.Add(file.FullName) == BatchStatus.Full) Dateien(batcher.Grab(id)); foreach (var subdir in dir.GetDirectories()) Dateien_enummerieren(id, subdir.FullName, batcher); } catch(UnauthorizedAccessException ex) {} }
public void Should_work_out_correct_number_of_batches() { const int batchBy = 10; const int numberOfItems = 28; const int expectedBatches = numberOfItems / batchBy; const int expectedRemainder = numberOfItems % batchBy; Given_a_solr_resolver_that_returns_a_stubbed_solr_instance(); Given_a_set_of_items_of_length(numberOfItems); var batchedIndexer = new Batcher<TestClass>(batchBy); batchedIndexer.PrepareBatch(_itemsToIndex.Count); Assert.That(batchedIndexer.NumberOfBatches, Is.EqualTo(expectedBatches)); Assert.That(batchedIndexer.Remainder, Is.EqualTo(expectedRemainder)); }
public void Laden(Batch<string> dateipfade) { var dateien = new Batcher<FileInfo>(dateipfade.Elements.Length/5); dateipfade.ForEach(t => { var fi = new FileInfo(t); if (dateien.Add(fi) == BatchStatus.Full) Geladen(dateien.Grab(dateipfade.CorrelationId)); }); if (dateipfade.GetType() == typeof(EndOfStreamBatch<string>)) Geladen(dateien.GrabAsEndOfStream(dateipfade.CorrelationId)); else Geladen(dateien.Grab(dateipfade.CorrelationId)); }
public void Enummerieren() { var sut = new Dateisystem("*.cs"); var results = new List<Batch<string>>(); var batcher = new Batcher<string>(100); sut.Dateien += _ => { }; sut.Dateien_enummerieren("x", @"..\..", batcher); results.Add(batcher.Grab("x")); Assert.IsTrue(results.Count > 0); Assert.AreEqual("x", results[0].CorrelationId); Assert.LessOrEqual(13, results[0].Elements.Length); results[0].ForEach(Console.WriteLine); }
public void TestBatcherSingleBatch() { doneSignal = new CountdownEvent(10); inboxCapacity = 10; processorDelay = 1000; var scheduler = new SingleTaskThreadpoolScheduler(); var batcher = new Batcher<string>(new TaskFactory(scheduler), inboxCapacity, processorDelay, TestBatcherSingleBatchProcessor); var objectsToQueue = new List<string>(); for (var i = 0; i < inboxCapacity * 10; i++) { objectsToQueue.Add(i.ToString()); } batcher.QueueObjects(objectsToQueue); var success = doneSignal.Wait(TimeSpan.FromSeconds(35)); Assert.IsTrue(success); }
void Start() { var mesh = this.GetComponent<MeshFilter>().mesh; _batcher = new Batcher(mesh, this.GetComponent<Camera>()); AtlasBuilder atlasBuilder = new AtlasBuilder(); var watch = new System.Diagnostics.Stopwatch(); watch.Start(); foreach(char c in "abcdefghijklmnopqrst") { atlasBuilder.AddTexture("Textures/" + c.ToString()); } TextureItem[] items = atlasBuilder.Pack(); watch.Stop(); Debug.Log("Time to pack: " + watch.ElapsedMilliseconds); _batcher.AddTextureItems(items); renderer.material.mainTexture = atlasBuilder.atlasTexture; _root = new Container(new Vector2(0, 0)); // Container upperLeft = new Container("Textures/b", new Vector2(0, 0)); // upperLeft.batcher = _batcher; // // Container lowerRight = new Container("Textures/b", new Vector2(Screen.width - 512f, Screen.height - 512f)); // lowerRight.batcher = _batcher; // // _root.AddChild(upperLeft); // _root.AddChild(lowerRight); for(int i = 0; i < 100; i++) { AddStuffToContainer(_root); } }
public override void draw(Batcher batcher, Vector2 position, float layerDepth, RectangleF cameraClipBounds) { // offset it by the entity position since the tilemap will always expect positions in its own coordinate space cameraClipBounds.location -= (position + offset); int minX, minY, maxX, maxY; if (tiledMap.requiresLargeTileCulling) { // we expand our cameraClipBounds by the excess tile width/height of the largest tiles to ensure we include tiles whose // origin might be outside of the cameraClipBounds minX = tiledMap.worldToTilePositionX(cameraClipBounds.left - (tiledMap.largestTileWidth - tiledMap.tileWidth)); minY = tiledMap.worldToTilePositionY(cameraClipBounds.top - (tiledMap.largestTileHeight - tiledMap.tileHeight)); maxX = tiledMap.worldToTilePositionX(cameraClipBounds.right + (tiledMap.largestTileWidth - tiledMap.tileWidth)); maxY = tiledMap.worldToTilePositionY(cameraClipBounds.bottom + (tiledMap.largestTileHeight - tiledMap.tileHeight)); } else { minX = tiledMap.worldToTilePositionX(cameraClipBounds.left); minY = tiledMap.worldToTilePositionY(cameraClipBounds.top); maxX = tiledMap.worldToTilePositionX(cameraClipBounds.right); maxY = tiledMap.worldToTilePositionY(cameraClipBounds.bottom); } // loop through and draw all the non-culled tiles for (var y = minY; y <= maxY; y++) { for (var x = minX; x <= maxX; x++) { var tile = getTile(x, y); if (tile == null) { continue; } var tileRegion = tile.textureRegion; // culling for arbitrary size tiles if necessary if (tiledMap.requiresLargeTileCulling) { // TODO: this only checks left and bottom. we should check top and right as well to deal with rotated, odd-sized tiles var tileworldpos = tiledMap.tileToWorldPosition(new Point(x, y)); if (tileworldpos.X + tileRegion.sourceRect.Width < cameraClipBounds.left || tileworldpos.Y - tileRegion.sourceRect.Height > cameraClipBounds.bottom) { continue; } } // for the y position, we need to take into account if the tile is larger than the tileHeight and shift. Tiled uses // a bottom-left coordinate system and MonoGame a top-left var tx = tile.x * tiledMap.tileWidth + (int)position.X; var ty = tile.y * tiledMap.tileHeight + (int)position.Y; var rotation = 0f; var spriteEffects = SpriteEffects.None; if (tile.flippedHorizonally) { spriteEffects |= SpriteEffects.FlipHorizontally; } if (tile.flippedVertically) { spriteEffects |= SpriteEffects.FlipVertically; } if (tile.flippedDiagonally) { if (tile.flippedHorizonally && tile.flippedVertically) { spriteEffects ^= SpriteEffects.FlipVertically; rotation = MathHelper.PiOver2; tx += tiledMap.tileHeight + (tileRegion.sourceRect.Height - tiledMap.tileHeight); ty -= (tileRegion.sourceRect.Width - tiledMap.tileWidth); } else if (tile.flippedHorizonally) { spriteEffects ^= SpriteEffects.FlipVertically; rotation = -MathHelper.PiOver2; ty += tiledMap.tileHeight; } else if (tile.flippedVertically) { spriteEffects ^= SpriteEffects.FlipHorizontally; rotation = MathHelper.PiOver2; tx += tiledMap.tileWidth + (tileRegion.sourceRect.Height - tiledMap.tileHeight); ty += (tiledMap.tileWidth - tileRegion.sourceRect.Width); } else { spriteEffects ^= SpriteEffects.FlipHorizontally; rotation = -MathHelper.PiOver2; ty += tiledMap.tileHeight; } } // if we had no rotations (diagonal flipping) shift our y-coord to account for any non-tileSized tiles to account for // Tiled being bottom-left origin if (rotation == 0) { ty += (tiledMap.tileHeight - tileRegion.sourceRect.Height); } batcher.draw(tileRegion, new Vector2(tx, ty) + offset, color, rotation, Vector2.Zero, 1 + _flickerFix, spriteEffects, layerDepth); } } }
/// <summary> /// Draws selection rectangle /// </summary> /// <param name="selection">Selection.</param> /// <param name="batch">Batch.</param> /// <param name="font">Font.</param> /// <param name="x">The x coordinate.</param> /// <param name="y">The y coordinate.</param> protected void DrawSelection(IDrawable selection, Batcher batcher, BitmapFont font, float x, float y) { selection.Draw(batcher, x + selectionX + renderOffset + fontOffset, y - font.Padding.Bottom / 2, selectionWidth, textHeight, Color.White); }
public override void draw( Batcher batcher, Vector2 position, float layerDepth, RectangleF cameraClipBounds ) { // offset it by the entity position since the tilemap will always expect positions in its own coordinate space cameraClipBounds.location -= position; int minX, minY, maxX, maxY; if( tiledMap.requiresLargeTileCulling ) { // we expand our cameraClipBounds by the excess tile width/height of the largest tiles to ensure we include tiles whose // origin might be outside of the cameraClipBounds minX = tiledMap.worldToTilePositionX( cameraClipBounds.left - ( tiledMap.largestTileWidth - tiledMap.tileWidth ) ); minY = tiledMap.worldToTilePositionY( cameraClipBounds.top - ( tiledMap.largestTileHeight - tiledMap.tileHeight ) ); maxX = tiledMap.worldToTilePositionX( cameraClipBounds.right + ( tiledMap.largestTileWidth - tiledMap.tileWidth ) ); maxY = tiledMap.worldToTilePositionY( cameraClipBounds.bottom + ( tiledMap.largestTileHeight - tiledMap.tileHeight ) ); } else { minX = tiledMap.worldToTilePositionX( cameraClipBounds.left ); minY = tiledMap.worldToTilePositionY( cameraClipBounds.top ); maxX = tiledMap.worldToTilePositionX( cameraClipBounds.right ); maxY = tiledMap.worldToTilePositionY( cameraClipBounds.bottom ); } // loop through and draw all the non-culled tiles for( var y = minY; y <= maxY; y++ ) { for( var x = minX; x <= maxX; x++ ) { var tile = getTile( x, y ); if( tile == null ) continue; var tileRegion = tile.textureRegion; // culling for arbitrary size tiles if necessary if( tiledMap.requiresLargeTileCulling ) { // TODO: this only checks left and bottom. we should check top and right as well to deal with rotated, odd-sized tiles var tileworldpos = tiledMap.tileToWorldPosition( new Point( x, y ) ); if( tileworldpos.X + tileRegion.sourceRect.Width < cameraClipBounds.left || tileworldpos.Y - tileRegion.sourceRect.Height > cameraClipBounds.bottom ) continue; } // for the y position, we need to take into account if the tile is larger than the tileHeight and shift. Tiled uses // a bottom-left coordinate system and MonoGame a top-left var tx = tile.x * tiledMap.tileWidth + (int)position.X; var ty = tile.y * tiledMap.tileHeight + (int)position.Y; var rotation = 0f; var spriteEffects = SpriteEffects.None; if( tile.flippedHorizonally ) spriteEffects |= SpriteEffects.FlipHorizontally; if( tile.flippedVertically ) spriteEffects |= SpriteEffects.FlipVertically; if( tile.flippedDiagonally ) { if( tile.flippedHorizonally && tile.flippedVertically ) { spriteEffects ^= SpriteEffects.FlipVertically; rotation = MathHelper.PiOver2; tx += tiledMap.tileHeight + ( tileRegion.sourceRect.Height - tiledMap.tileHeight ); ty -= ( tileRegion.sourceRect.Width - tiledMap.tileWidth ); } else if( tile.flippedHorizonally ) { spriteEffects ^= SpriteEffects.FlipVertically; rotation = -MathHelper.PiOver2; ty += tiledMap.tileHeight; } else if( tile.flippedVertically ) { spriteEffects ^= SpriteEffects.FlipHorizontally; rotation = MathHelper.PiOver2; tx += tiledMap.tileWidth + ( tileRegion.sourceRect.Height - tiledMap.tileHeight ); ty += ( tiledMap.tileWidth - tileRegion.sourceRect.Width ); } else { spriteEffects ^= SpriteEffects.FlipHorizontally; rotation = -MathHelper.PiOver2; ty += tiledMap.tileHeight; } } // if we had no rotations (diagonal flipping) shift our y-coord to account for any non-tileSized tiles to account for // Tiled being bottom-left origin if( rotation == 0 ) ty += ( tiledMap.tileHeight - tileRegion.sourceRect.Height ); batcher.draw( tileRegion.texture2D, new Vector2( tx, ty ), tileRegion.sourceRect, color, rotation, Vector2.Zero, 1, spriteEffects, layerDepth ); } } }
public void TestBatcherLatencyInitialBatch() { var doneEvent = new ManualResetEvent(false); inboxCapacity = 100; processorDelay = 500; var timeProcessed = default(DateTime); var scheduler = new SingleThreadTaskScheduler(); var batcher = new Batcher<string>( new TaskFactory(scheduler), inboxCapacity, processorDelay, itemsToProcess => { Log.V(Tag, "process called with: " + itemsToProcess); timeProcessed = DateTime.UtcNow; doneEvent.Set(); }); var objectsToQueue = new List<string>(); for (var i = 0; i < inboxCapacity + 1; i++) { objectsToQueue.Add(i.ToString()); } var timeQueued = DateTime.UtcNow; batcher.QueueObjects(objectsToQueue); var success = doneEvent.WaitOne(TimeSpan.FromSeconds(35)); Assert.IsTrue(success); var delta = (timeProcessed - timeQueued).TotalMilliseconds; Assert.IsTrue(delta >= 0); // we want the delta between the time it was queued until the // time it was processed to be as small as possible. since // there is some overhead, rather than using a hardcoded number // express it as a ratio of the processor delay, asserting // that the entire processor delay never kicked in. int acceptableDelta = processorDelay - 1; Log.V(Tag, string.Format("TestBatcherLatencyInitialBatch : delta: {0}", delta)); Assert.IsTrue(delta < acceptableDelta); }
internal override void Stopping() { _downloadsToInsert = null; base.Stopping(); }
public override void Render(Batcher batcher, Camera camera) { batcher.Draw(Sprite, Transform.Position, Sprite.SourceRect, Color, Transform.Rotation, Sprite.Center, Transform.Scale, SpriteEffects.None, _layerDepth); }
/// <summary> /// Calls clipBegin(Batcher, float, float, float, float) to clip this actor's bounds /// </summary> /// <returns>The begin.</returns> public bool clipBegin( Batcher batcher ) { return clipBegin( batcher, x, y, width, height ); }
/// <summary> /// Ends clipping begun by clipBegin(Batcher, float, float, float, float) /// </summary> /// <returns>The end.</returns> public void clipEnd( Batcher batcher ) { batcher.enableScissorTest( false ); ScissorStack.popScissors(); }
/// <summary> /// Clips the specified screen aligned rectangle, specified relative to the transform matrix of the stage's Batch. The /// transform matrix and the stage's camera must not have rotational components. Calling this method must be followed by a call /// to clipEnd() if true is returned. /// </summary> public bool clipBegin( Batcher batcher, float x, float y, float width, float height ) { if( width <= 0 || height <= 0 ) return false; var tableBounds = RectangleExt.fromFloats( x, y, width, height ); var scissorBounds = ScissorStack.calculateScissors( stage?.entity?.scene?.camera, batcher.transformMatrix, tableBounds ); if( ScissorStack.pushScissors( scissorBounds ) ) { batcher.enableScissorTest( true ); return true; } return false; }
public abstract void draw( Batcher batcher, Vector2 position, float layerDepth, RectangleF cameraClipBounds );
/// <summary>Private Constructor</summary> protected Replication(Database db, Uri remote, bool continuous, IHttpClientFactory clientFactory, TaskFactory workExecutor, CancellationTokenSource tokenSource = null) { LocalDatabase = db; Continuous = continuous; WorkExecutor = workExecutor; CancellationTokenSource = tokenSource ?? new CancellationTokenSource(); RemoteUrl = remote; Status = ReplicationStatus.Stopped; online = true; RequestHeaders = new Dictionary<String, Object>(); if (RemoteUrl.GetQuery() != null && !RemoteUrl.GetQuery().IsEmpty()) { var uri = new Uri(remote.ToString()); var personaAssertion = URIUtils.GetQueryParameter(uri, PersonaAuthorizer.QueryParameter); if (personaAssertion != null && !personaAssertion.IsEmpty()) { var email = PersonaAuthorizer.RegisterAssertion(personaAssertion); var authorizer = new PersonaAuthorizer(email); Authorizer = authorizer; } var facebookAccessToken = URIUtils.GetQueryParameter(uri, FacebookAuthorizer.QueryParameter); if (facebookAccessToken != null && !facebookAccessToken.IsEmpty()) { var email = URIUtils.GetQueryParameter(uri, FacebookAuthorizer.QueryParameterEmail); var authorizer = new FacebookAuthorizer(email); Uri remoteWithQueryRemoved = null; try { remoteWithQueryRemoved = new UriBuilder(remote.Scheme, remote.GetHost(), remote.Port, remote.AbsolutePath).Uri; } #if PORTABLE catch (FormatException e) #else catch (UriFormatException e) #endif { throw new ArgumentException("Invalid URI format.", "remote", e); } FacebookAuthorizer.RegisterAccessToken(facebookAccessToken, email, remoteWithQueryRemoved.ToString()); Authorizer = authorizer; } // we need to remove the query from the URL, since it will cause problems when // communicating with sync gw / couchdb try { RemoteUrl = new UriBuilder(remote.Scheme, remote.GetHost(), remote.Port, remote.AbsolutePath).Uri; } #if PORTABLE catch (FormatException e) #else catch (UriFormatException e) #endif { throw new ArgumentException("Invalid URI format.", "remote", e); } } Batcher = new Batcher<RevisionInternal>(workExecutor, InboxCapacity, ProcessorDelay, inbox => { Log.V (Database.Tag, "*** " + this + ": BEGIN processInbox (" + inbox.Count + " sequences)"); ProcessInbox (new RevisionList (inbox)); Log.V (Database.Tag, "*** " + this.ToString () + ": END processInbox (lastSequence=" + LastSequence); UpdateActive(); }, CancellationTokenSource); this.clientFactory = clientFactory ?? CouchbaseLiteHttpClientFactory.Instance; }
public override void draw( Batcher batcher, Vector2 parentPosition, float layerDepth, RectangleF cameraClipBounds ) { batcher.draw( texture, parentPosition + offset, null, Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, layerDepth ); }
internal void drawInto(Batcher batcher, ref CharacterSource text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effect, float depth) { var flipAdjustment = Vector2.Zero; var flippedVert = (effect & SpriteEffects.FlipVertically) == SpriteEffects.FlipVertically; var flippedHorz = (effect & SpriteEffects.FlipHorizontally) == SpriteEffects.FlipHorizontally; if (flippedVert || flippedHorz) { Vector2 size; measureString(ref text, out size); if (flippedHorz) { origin.X *= -1; flipAdjustment.X = -size.X; } if (flippedVert) { origin.Y *= -1; flipAdjustment.Y = lineHeight - size.Y; } } var requiresTransformation = flippedHorz || flippedVert || rotation != 0f || scale != Vector2.One; if (requiresTransformation) { Matrix temp; Matrix.CreateTranslation(-origin.X, -origin.Y, 0f, out _transformationMatrix); Matrix.CreateScale((flippedHorz ? -scale.X : scale.X), (flippedVert ? -scale.Y : scale.Y), 1f, out temp); Matrix.Multiply(ref _transformationMatrix, ref temp, out _transformationMatrix); Matrix.CreateTranslation(flipAdjustment.X, flipAdjustment.Y, 0, out temp); Matrix.Multiply(ref temp, ref _transformationMatrix, out _transformationMatrix); Matrix.CreateRotationZ(rotation, out temp); Matrix.Multiply(ref _transformationMatrix, ref temp, out _transformationMatrix); Matrix.CreateTranslation(position.X, position.Y, 0f, out temp); Matrix.Multiply(ref _transformationMatrix, ref temp, out _transformationMatrix); } BitmapFontRegion currentFontRegion = null; var offset = requiresTransformation ? Vector2.Zero : position - origin; for (var i = 0; i < text.Length; ++i) { var c = text[i]; if (c == '\r') { continue; } if (c == '\n') { offset.X = requiresTransformation ? 0f : position.X - origin.X; offset.Y += lineHeight; currentFontRegion = null; continue; } if (currentFontRegion != null) { offset.X += spacing + currentFontRegion.xAdvance; } if (!_characterMap.TryGetValue(c, out currentFontRegion)) { currentFontRegion = defaultCharacterRegion; } var p = offset; if (flippedHorz) { p.X += currentFontRegion.width; } p.X += currentFontRegion.xOffset; if (flippedVert) { p.Y += currentFontRegion.height - lineHeight; } p.Y += currentFontRegion.yOffset; // transform our point if we need to if (requiresTransformation) { Vector2.Transform(ref p, ref _transformationMatrix, out p); } var destRect = RectangleExt.fromFloats ( p.X, p.Y, currentFontRegion.width * scale.X, currentFontRegion.height * scale.Y ); batcher.draw(currentFontRegion.subtexture, destRect, currentFontRegion.subtexture.sourceRect, color, rotation, Vector2.Zero, effect, depth); } }
public void TestBatcherCancel() { var mre = new ManualResetEventSlim(); var scheduler = new SingleTaskThreadpoolScheduler(); var batcher = new Batcher<int>(new TaskFactory(scheduler), 5, 500, (inbox) => { mre.Set(); }); batcher.QueueObject(0); Assert.IsTrue(mre.Wait(1000), "Batcher didn't initially run"); mre.Reset(); batcher.QueueObject(0); batcher.Clear(); Assert.False(mre.Wait(TimeSpan.FromSeconds(1)), "Batcher ran after being cancelled"); }
/// <summary> /// Default constructor /// </summary> /// <param name="db">The local database to replicate to/from</param> /// <param name="remote">The remote Uri to sync with</param> /// <param name="continuous">If set to <c>true</c> continuous.</param> /// <param name="clientFactory">The client factory for instantiating the HttpClient used to create web requests</param> /// <param name="workExecutor">The TaskFactory to execute work on</param> internal Replication(Database db, Uri remote, bool continuous, IHttpClientFactory clientFactory, TaskFactory workExecutor) { sessionID = $"repl{ Interlocked.Increment(ref _lastSessionID):000}"; var opts = new RemoteSessionContructorOptions { BaseUrl = remote, WorkExecutor = workExecutor, Id = _replicatorID, CancellationTokenSource = CancellationTokenSource }; _remoteSession = new RemoteSession(opts); Username = remote.UserInfo; LocalDatabase = db; _eventContext = LocalDatabase.Manager.CapturedContext; Continuous = continuous; // NOTE: Consider running a separate scheduler for all http requests. WorkExecutor = workExecutor; RemoteUrl = remote; #pragma warning disable 618 Options = new ReplicationOptionsDictionary(); #pragma warning restore 618 ReplicationOptions = new ReplicationOptions(); if (RemoteUrl.Query != null && !StringEx.IsNullOrWhiteSpace(RemoteUrl.Query)) { Authenticator = AuthenticatorFactory.CreateFromUri(remote); // we need to remove the query from the URL, since it will cause problems when // communicating with sync gw / couchdb try { RemoteUrl = new UriBuilder(remote.Scheme, remote.Host, remote.Port, remote.AbsolutePath).Uri; } catch (UriFormatException e) { throw Misc.CreateExceptionAndLog(Log.To.Sync, e, Tag, "Invalid URI format for remote endpoint"); } } Batcher = new Batcher<RevisionInternal>(workExecutor, INBOX_CAPACITY, ProcessorDelay, inbox => { try { Log.To.Sync.V(Tag, "*** {0} BEGIN ProcessInbox ({1} sequences)", this, inbox.Count); if(Continuous) { FireTrigger(ReplicationTrigger.Resume); } ProcessInbox (new RevisionList(inbox)); Log.To.Sync.V(Tag, "*** {0} END ProcessInbox (lastSequence={1})", this, LastSequence); } catch(Exception e) { throw Misc.CreateExceptionAndLog(Log.To.Sync, e, Tag, "{0} ProcessInbox failed", this); } }); ClientFactory = clientFactory; _stateMachine = new StateMachine<ReplicationState, ReplicationTrigger>(ReplicationState.Initial); InitializeStateMachine(); }
public void SetUp() { batcher = new Batcher(Threshold); writer = new NetworkWriter(); }
public override void debugRender( Batcher batcher ) { batcher.drawLine( _particleOne.position, _particleTwo.position, Debug.Colors.verletConstraintEdge ); }
public override void Draw(Batcher batcher, float parentAlpha) { UpdateImage(); base.Draw(batcher, parentAlpha); }
/// <summary>Private Constructor</summary> protected Replication(Database db, Uri remote, bool continuous, IHttpClientFactory clientFactory, TaskFactory workExecutor) { LocalDatabase = db; Continuous = continuous; // NOTE: Consider running a separate scheduler for all http requests. WorkExecutor = workExecutor; CancellationTokenSource = new CancellationTokenSource(); RemoteUrl = remote; Status = ReplicationStatus.Stopped; online = Manager.SharedInstance.NetworkReachabilityManager.CurrentStatus == NetworkReachabilityStatus.Reachable; RequestHeaders = new Dictionary<String, Object>(); requests = new HashSet<HttpClient>(); // FIXME: Refactor to visitor pattern. if (RemoteUrl.GetQuery() != null && !RemoteUrl.GetQuery().IsEmpty()) { var uri = new Uri(remote.ToString()); var personaAssertion = URIUtils.GetQueryParameter(uri, PersonaAuthorizer.QueryParameter); if (personaAssertion != null && !personaAssertion.IsEmpty()) { var email = PersonaAuthorizer.RegisterAssertion(personaAssertion); var authorizer = new PersonaAuthorizer(email); Authenticator = authorizer; } var facebookAccessToken = URIUtils.GetQueryParameter(uri, FacebookAuthorizer.QueryParameter); if (facebookAccessToken != null && !facebookAccessToken.IsEmpty()) { var email = URIUtils.GetQueryParameter(uri, FacebookAuthorizer.QueryParameterEmail); var authorizer = new FacebookAuthorizer(email); Uri remoteWithQueryRemoved = null; try { remoteWithQueryRemoved = new UriBuilder(remote.Scheme, remote.GetHost(), remote.Port, remote.AbsolutePath).Uri; } catch (UriFormatException e) { throw new ArgumentException("Invalid URI format.", "remote", e); } FacebookAuthorizer.RegisterAccessToken(facebookAccessToken, email, remoteWithQueryRemoved.ToString()); Authenticator = authorizer; } // we need to remove the query from the URL, since it will cause problems when // communicating with sync gw / couchdb try { RemoteUrl = new UriBuilder(remote.Scheme, remote.GetHost(), remote.Port, remote.AbsolutePath).Uri; } catch (UriFormatException e) { throw new ArgumentException("Invalid URI format.", "remote", e); } } Batcher = new Batcher<RevisionInternal>(workExecutor, InboxCapacity, ProcessorDelay, inbox => { try { Log.V(Tag, "*** BEGIN ProcessInbox ({0} sequences)", inbox.Count); ProcessInbox (new RevisionList(inbox)); Log.V(Tag, "*** END ProcessInbox (lastSequence={0})", LastSequence); UpdateActive(); } catch (Exception e) { Log.E(Tag, "ERROR: ProcessInbox failed: ", e); throw new RuntimeException(e); } }); SetClientFactory(clientFactory); }
public void draw( Batcher batcher ) { batcher.draw( texture, offset, Color.White ); }
public void DrawInto(Batcher batcher, ref FontCharacterSource text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effect, float depth) { var flipAdjustment = Vector2.Zero; var flippedVert = (effect & SpriteEffects.FlipVertically) == SpriteEffects.FlipVertically; var flippedHorz = (effect & SpriteEffects.FlipHorizontally) == SpriteEffects.FlipHorizontally; if (flippedVert || flippedHorz) { var size = MeasureString(ref text); if (flippedHorz) { origin.X *= -1; flipAdjustment.X = -size.X; } if (flippedVert) { origin.Y *= -1; flipAdjustment.Y = LineHeight - size.Y; } } var requiresTransformation = flippedHorz || flippedVert || rotation != 0f || scale != new Vector2(1); if (requiresTransformation) { Matrix2D temp; Matrix2D.CreateTranslation(-origin.X, -origin.Y, out _transformationMatrix); Matrix2D.CreateScale((flippedHorz ? -scale.X : scale.X), (flippedVert ? -scale.Y : scale.Y), out temp); Matrix2D.Multiply(ref _transformationMatrix, ref temp, out _transformationMatrix); Matrix2D.CreateTranslation(flipAdjustment.X, flipAdjustment.Y, out temp); Matrix2D.Multiply(ref temp, ref _transformationMatrix, out _transformationMatrix); Matrix2D.CreateRotation(rotation, out temp); Matrix2D.Multiply(ref _transformationMatrix, ref temp, out _transformationMatrix); Matrix2D.CreateTranslation(position.X, position.Y, out temp); Matrix2D.Multiply(ref _transformationMatrix, ref temp, out _transformationMatrix); } var previousCharacter = ' '; Character currentChar = null; var offset = requiresTransformation ? Vector2.Zero : position - origin; for (var i = 0; i < text.Length; ++i) { var c = text[i]; if (c == '\r') { continue; } if (c == '\n') { offset.X = requiresTransformation ? 0f : position.X - origin.X; offset.Y += LineHeight; currentChar = null; continue; } if (currentChar != null) { offset.X += Spacing.X + currentChar.XAdvance; } currentChar = ContainsCharacter(c) ? this[c] : DefaultCharacter; var p = offset; if (flippedHorz) { p.X += currentChar.Bounds.Width; } p.X += currentChar.Offset.X + GetKerning(previousCharacter, currentChar.Char); if (flippedVert) { p.Y += currentChar.Bounds.Height - LineHeight; } p.Y += currentChar.Offset.Y; // transform our point if we need to if (requiresTransformation) { Vector2Ext.Transform(ref p, ref _transformationMatrix, out p); } var destRect = RectangleExt.FromFloats ( p.X, p.Y, currentChar.Bounds.Width * scale.X, currentChar.Bounds.Height * scale.Y ); batcher.Draw(Textures[currentChar.TexturePage], destRect, currentChar.Bounds, color, rotation, Vector2.Zero, effect, depth); previousCharacter = c; } }
public void DebugRender(Batcher batcher) { batcher.DrawCircle(Target, TargetRadius, Color.Green, 2f); batcher.DrawCircle(Target, ArrivalRadius, Color.GreenYellow, 2f); }
public override void debugRender(Batcher batcher) { batcher.drawLine(_particleOne.position, _particleTwo.position, DefaultColors.verletConstraintEdge); }
public override void Draw(Batcher batcher, float parentAlpha) { var font = style.Font; var fontColor = (disabled && style.DisabledFontColor.HasValue) ? style.DisabledFontColor.Value : ((_isFocused && style.FocusedFontColor.HasValue) ? style.FocusedFontColor.Value : style.FontColor); IDrawable selection = style.Selection; IDrawable background = (disabled && style.DisabledBackground != null) ? style.DisabledBackground : ((_isFocused && style.FocusedBackground != null) ? style.FocusedBackground : style.Background); var color = GetColor(); var x = GetX(); var y = GetY(); var width = GetWidth(); var height = GetHeight(); float bgLeftWidth = 0, bgRightWidth = 0; if (background != null) { background.Draw(batcher, x, y, width, height, ColorExt.Create(color, (int)(color.A * parentAlpha))); bgLeftWidth = background.LeftWidth; bgRightWidth = background.RightWidth; } var textY = GetTextY(font, background); var yOffset = (textY < 0) ? -textY - font.LineHeight / 2f + GetHeight() / 2 : 0; CalculateOffsets(); if (_isFocused && hasSelection && selection != null) { DrawSelection(selection, batcher, font, x + bgLeftWidth, y + textY + yOffset); } if (displayText.Length == 0) { if (!_isFocused && messageText != null) { var messageFontColor = style.MessageFontColor.HasValue ? style.MessageFontColor.Value : new Color(180, 180, 180, (int)(color.A * parentAlpha)); var messageFont = style.MessageFont != null ? style.MessageFont : font; batcher.DrawString(messageFont, messageText, new Vector2(x + bgLeftWidth, y + textY + yOffset), messageFontColor); //messageFont.draw( batcher.batcher, messageText, x + bgLeftWidth, y + textY + yOffset, 0, messageText.length(), // width - bgLeftWidth - bgRightWidth, textHAlign, false, "..." ); } } else { var col = ColorExt.Create(fontColor, (int)(fontColor.A * parentAlpha)); var t = displayText.Substring(visibleTextStart, visibleTextEnd - visibleTextStart); batcher.DrawString(font, t, new Vector2(x + bgLeftWidth + textOffset, y + textY + yOffset), col); } if (_isFocused && !disabled) { Blink(); if (cursorOn && style.Cursor != null) { DrawCursor(style.Cursor, batcher, font, x + bgLeftWidth, y + textY + yOffset); } } }
public ExpandingIndexedTrianglesMeshBuilder() { batcher = new Batcher <Streams>(Streams.Create); currentStreams = batcher.AllocateBatch().Data; }
internal override void BeginReplicating() { // If we're still waiting to create the remote db, do nothing now. (This method will be // re-invoked after that request finishes; see maybeCreateRemoteDB() above.) if (_creatingTarget) { Log.To.Sync.D(TAG, "creatingTarget == true, doing nothing"); return; } _pendingSequences = new SortedDictionary <long, int>(); if (!Int64.TryParse(LastSequence, out _maxPendingSequence)) { Log.To.Sync.W(TAG, "{0} is not a valid last sequence, using 0", LastSequence); _maxPendingSequence = 0; } if (Filter != null) { _filter = LocalDatabase.GetFilter(Filter); } else { // If not filter function was provided, but DocIds were // specified, then only push the documents listed in the // DocIds property. It is assumed that if the users // specified both a filter name and doc ids that their // custom filter function will handle that. This is // consistent with the iOS behavior. if (DocIds != null && DocIds.Any()) { _filter = (rev, filterParams) => DocIds.Contains(rev.Document.Id); } } if (Filter != null && _filter == null) { Log.To.Sync.W(TAG, "{0}: No ReplicationFilter registered for filter '{1}'; ignoring", this, Filter); } // Process existing changes since the last push: long lastSequenceLong = 0; if (LastSequence != null) { lastSequenceLong = long.Parse(LastSequence); } if (ReplicationOptions.PurgePushed) { _purgeQueue = new Batcher <RevisionInternal>(WorkExecutor, EphemeralPurgeBatchSize, EphemeralPurgeDelay, (revs) => { Log.To.Sync.I(TAG, "Purging {0} docs ('purgePushed' option)", revs.Count); var toPurge = new Dictionary <string, IList <string> >(); foreach (var rev in revs) { toPurge[rev.DocID] = new List <string> { rev.RevID }; } var localDb = LocalDatabase; if (localDb != null && localDb.IsOpen) { var storage = localDb.Storage; if (storage != null && storage.IsOpen) { storage.PurgeRevisions(toPurge); } else { Log.To.Sync.W(TAG, "{0} storage is closed, cannot purge...", localDb); } } else { Log.To.Sync.W(TAG, "Local database is closed or null, cannot purge..."); } }, CancellationTokenSource); } // Now listen for future changes (in continuous mode): // Note: This needs to happen before adding the observer // or else there is a race condition. // A document could be added between the call to // ChangesSince and adding the observer, which would result // in a document being skipped if (Continuous) { _observing = true; LocalDatabase.Changed += OnChanged; } var options = ChangesOptions.Default; options.IncludeConflicts = true; var changes = LocalDatabase.ChangesSince(lastSequenceLong, options, _filter, FilterParams); if (changes.Count > 0) { Batcher.QueueObjects(changes); Batcher.Flush(); } if (Continuous) { if (changes.Count == 0) { Log.To.Sync.V(TAG, "No changes to push, switching to idle..."); FireTrigger(ReplicationTrigger.WaitingForChanges); } } else { if (changes.Count == 0) { Log.To.Sync.V(TAG, "No changes to push, firing StopGraceful..."); FireTrigger(ReplicationTrigger.StopGraceful); } } }
public void drawTile(Batcher batcher, Vector2 position, float layerDepth, int x, int y, float scale) { var tile = getTile(x, y); if (tile == null) { return; } var t = tiledMap.isometricTileToWorldPosition(x, y); var tileRegion = tile.textureRegion; // for the y position, we need to take into account if the tile is larger than the tileHeight and shift. Tiled uses // a bottom-left coordinate system and MonoGame a top-left var rotation = 0f; var spriteEffects = SpriteEffects.None; if (tile.flippedHorizonally) { spriteEffects |= SpriteEffects.FlipHorizontally; } if (tile.flippedVertically) { spriteEffects |= SpriteEffects.FlipVertically; } if (tile.flippedDiagonally) { if (tile.flippedHorizonally && tile.flippedVertically) { spriteEffects ^= SpriteEffects.FlipVertically; rotation = MathHelper.PiOver2; t.X += tiledMap.tileHeight + (tileRegion.sourceRect.Height - tiledMap.tileHeight); t.Y -= tileRegion.sourceRect.Width - tiledMap.tileWidth; } else if (tile.flippedHorizonally) { spriteEffects ^= SpriteEffects.FlipVertically; rotation = -MathHelper.PiOver2; t.Y += tiledMap.tileHeight; } else if (tile.flippedVertically) { spriteEffects ^= SpriteEffects.FlipHorizontally; rotation = MathHelper.PiOver2; t.X += tiledMap.tileWidth + (tileRegion.sourceRect.Height - tiledMap.tileHeight); t.Y += tiledMap.tileWidth - tileRegion.sourceRect.Width; } else { spriteEffects ^= SpriteEffects.FlipHorizontally; rotation = -MathHelper.PiOver2; t.Y += tiledMap.tileHeight; } } // if we had no rotations (diagonal flipping) shift our y-coord to account for any non-tileSized tiles to account for // Tiled being bottom-left origin if (rotation == 0) { t.Y += tiledMap.tileHeight - tileRegion.sourceRect.Height; } // Scale the tile's relative position, but not the origin t = t * new Vector2(scale) + position; batcher.draw( tileRegion.texture2D, t, tileRegion.sourceRect, color, rotation, Vector2.Zero, scale, spriteEffects, layerDepth); }
public override void Draw(Batcher batcher, float x, float y, float width, float height, Color color) { float regionWidth = Sprite.SourceRect.Width * ScaleX, regionHeight = Sprite.SourceRect.Height * ScaleY; int fullX = (int)(width / regionWidth), fullY = (int)(height / regionHeight); float remainingSourceX = (width - regionWidth * fullX) / ScaleX, remainingSourceY = (height - regionHeight * fullY) / ScaleY; float startX = x, startY = y; // draw all full, unclipped first for (var i = 0; i < fullX; i++) { y = startY; for (var j = 0; j < fullY; j++) { batcher.Draw(Sprite, new Rectangle((int)x, (int)y, (int)regionWidth, (int)regionHeight), Sprite.SourceRect, color); y += regionHeight; } x += regionWidth; } var tempSourceRect = Sprite.SourceRect; if (remainingSourceX > 0) { // right edge tempSourceRect.Width = (int)remainingSourceX + 1; y = startY; for (var ii = 0; ii < fullY; ii++) { batcher.Draw(Sprite, new Rectangle((int)x, (int)y, (int)(tempSourceRect.Width * ScaleX), (int)regionHeight), tempSourceRect, color); y += regionHeight; } // lower right corner. tempSourceRect.Height = (int)remainingSourceY + 1; if (remainingSourceY > 0) { batcher.Draw(Sprite, new Rectangle((int)x, (int)y, (int)(tempSourceRect.Width * ScaleX), (int)(tempSourceRect.Height * ScaleY)), tempSourceRect, color); } } if (remainingSourceY > 0) { // bottom edge tempSourceRect.Height = (int)remainingSourceY + 1; tempSourceRect.Width = Sprite.SourceRect.Width; x = startX; for (var i = 0; i < fullX; i++) { batcher.Draw(Sprite, new Rectangle((int)x, (int)y, (int)regionWidth, (int)(tempSourceRect.Height * ScaleY)), tempSourceRect, color); x += regionWidth; } } }
public async Task Batcher_terminates_when_disposed() { var config = new MemstateSettings(); var batcher = new Batcher <int>(config, batch => { }); await batcher.DisposeAsync().ConfigureAwait(false); }
public void DefaultDraw(Batcher batcher, Rectangle finalBounds) { batcher.DrawRect(finalBounds, Color); }
public override void draw(Batcher batcher, Vector2 position, float layerDepth, RectangleF cameraClipBounds) { // offset it by the entity position since the tilemap will always expect positions in its own coordinate space cameraClipBounds.location -= position; var minX = tiledMap.worldToTilePositionX(cameraClipBounds.left); var minY = tiledMap.worldToTilePositionY(cameraClipBounds.top); var maxX = tiledMap.worldToTilePositionX(cameraClipBounds.right); var maxY = tiledMap.worldToTilePositionY(cameraClipBounds.bottom); // loop through and draw all the non-culled tiles for (var y = minY; y <= maxY; y++) { for (var x = minX; x <= maxX; x++) { var tile = getTile(x, y); if (tile == null) { continue; } var tileRegion = tile.textureRegion; var tx = tile.x * tiledMap.tileWidth + (int)position.X; var ty = tile.y * tiledMap.tileHeight + (int)position.Y; var rotation = 0f; var spriteEffects = SpriteEffects.None; if (tile.flippedHorizonally) { spriteEffects |= SpriteEffects.FlipHorizontally; } if (tile.flippedVertically) { spriteEffects |= SpriteEffects.FlipVertically; } if (tile.flippedDiagonally) { if (tile.flippedHorizonally && tile.flippedVertically) { spriteEffects ^= SpriteEffects.FlipVertically; rotation = MathHelper.PiOver2; tx += tiledMap.tileWidth; } else if (tile.flippedHorizonally) { spriteEffects ^= SpriteEffects.FlipVertically; rotation = -MathHelper.PiOver2; ty += tiledMap.tileHeight; } else if (tile.flippedVertically) { spriteEffects ^= SpriteEffects.FlipHorizontally; rotation = MathHelper.PiOver2; tx += tiledMap.tileWidth; } else { spriteEffects ^= SpriteEffects.FlipHorizontally; rotation = -MathHelper.PiOver2; ty += tiledMap.tileHeight; } } batcher.draw(tileRegion.texture2D, new Vector2(tx, ty), tileRegion.sourceRect, color, rotation, Vector2.Zero, 1, spriteEffects, layerDepth); } } }
public void TestBatcherAddAfterCancel() { var evt = new CountdownEvent(1); var scheduler = new SingleTaskThreadpoolScheduler(); var batcher = new Batcher<int>(new TaskFactory(scheduler), 5, 500, (inbox) => { evt.Signal(); }); batcher.QueueObject(0); Assert.IsTrue(evt.Wait(1000), "Batcher didn't initially run"); evt.Reset(2); batcher.QueueObject(0); batcher.Clear(); batcher.QueueObject(0); Assert.False(evt.Wait(TimeSpan.FromSeconds(1.5)), "Batcher ran too many times"); Assert.True(evt.CurrentCount == 1, "Batcher never ran"); }
public void Draw(Batcher batcher) { batcher.Draw(Texture, Offset, Color.White); }
/// <summary> /// renders the bounds only if there is no collider. Always renders a square on the origin. /// </summary> /// <param name="batcher">Batcher.</param> public override void DebugRender(Batcher batcher) { batcher.DrawCircle(Entity.Transform.Position + _localOffset, Radius * Entity.Transform.Scale.X, Color.DarkOrchid, 2); }
public override void Draw(Batcher batcher, float parentAlpha) { Validate(); IDrawable background; if (_isDisabled && style.BackgroundDisabled != null) { background = style.BackgroundDisabled; } else if (_selectBoxList.HasParent() && style.BackgroundOpen != null) { background = style.BackgroundOpen; } else if (_isMouseOver && style.BackgroundOver != null) { background = style.BackgroundOver; } else if (style.Background != null) { background = style.Background; } else { background = null; } var font = style.Font; var fontColor = _isDisabled ? style.DisabledFontColor : style.FontColor; var color = GetColor(); color = ColorExt.Create(color, (int)(color.A * parentAlpha)); float x = GetX(); float y = GetY(); float width = GetWidth(); float height = GetHeight(); if (background != null) { background.Draw(batcher, x, y, width, height, color); } var selected = _selection.First(); if (selected != null) { var str = selected.ToString(); if (background != null) { width -= background.LeftWidth + background.RightWidth; height -= background.BottomHeight + background.TopHeight; x += background.LeftWidth; y += (int)(height / 2 + background.BottomHeight - font.LineHeight / 2); } else { y += (int)(height / 2 + font.LineHeight / 2); } fontColor = ColorExt.Create(fontColor, (int)(fontColor.A * parentAlpha)); batcher.DrawString(font, str, new Vector2(x, y), fontColor); } }
public override void Render(Batcher batcher, Camera camera) { batcher.DrawString(Graphics.Instance.BitmapFont, Input.MousePosition.ToString(), Input.MousePosition, Color.White); }
/// <summary> /// Ends clipping begun by clipBegin(Batcher, float, float, float, float) /// </summary> /// <returns>The end.</returns> public void clipEnd(Batcher batcher) { batcher.enableScissorTest(false); ScissorStack.popScissors(); }
protected void DrawStageBackground(Batcher batcher, float parentAlpha, float x, float y, float width, float height) { style.StageBackground.Draw(batcher, x, y, width, height, ColorExt.Create(color, (int)(color.A * parentAlpha))); }
public abstract void draw(Batcher batcher, Vector2 position, float layerDepth, RectangleF cameraClipBounds);
public override void Draw(Batcher batcher, float parentAlpha) { // update our hoved item if the mouse is over the list if (_isMouseOverList) { var mousePos = ScreenToLocalCoordinates(stage.GetMousePosition()); _hoveredItemIndex = GetItemIndexUnderMousePosition(mousePos); } Validate(); var font = _style.Font; var selectedDrawable = _style.Selection; var color = GetColor(); color = new Color(color, (int)(color.A * parentAlpha)); float x = GetX(), y = GetY(), width = GetWidth(), height = GetHeight(); var itemY = 0f; var background = _style.Background; if (background != null) { background.Draw(batcher, x, y, width, height, color); var leftWidth = background.LeftWidth; x += leftWidth; itemY += background.TopHeight; width -= leftWidth + background.RightWidth; } var unselectedFontColor = new Color(_style.FontColorUnselected, (int)(_style.FontColorUnselected.A * parentAlpha)); var selectedFontColor = new Color(_style.FontColorSelected, (int)(_style.FontColorSelected.A * parentAlpha)); var hoveredFontColor = new Color(_style.FontColorHovered, (int)(_style.FontColorHovered.A * parentAlpha)); Color fontColor; for (var i = 0; i < _items.Count; i++) { if (!_cullingArea.HasValue || (itemY - _itemHeight <= _cullingArea.Value.Y + _cullingArea.Value.Height && itemY >= _cullingArea.Value.Y)) { var item = _items[i]; var selected = _selection.Contains(item); if (selected) { selectedDrawable.Draw(batcher, x, y + itemY, width, _itemHeight, color); fontColor = selectedFontColor; } else if (i == _hoveredItemIndex && _style.HoverSelection != null) { _style.HoverSelection.Draw(batcher, x, y + itemY, width, _itemHeight, color); fontColor = hoveredFontColor; } else { fontColor = unselectedFontColor; } var textPos = new Vector2(x + _textOffsetX, y + itemY + _textOffsetY); batcher.DrawString(font, item.ToString(), textPos, fontColor); } else if (itemY < _cullingArea.Value.Y) { break; } itemY += _itemHeight; } }
/// <summary> /// debug renders the Constraint /// </summary> /// <param name="batcher">Batcher.</param> public virtual void debugRender( Batcher batcher ) {}
public override void Draw(Batcher batcher, Vector2 position, float layerDepth, RectangleF cameraClipBounds) { Draw(batcher, position, Vector2.One, layerDepth, cameraClipBounds); }
internal override void BeginReplicating() { // If we're still waiting to create the remote db, do nothing now. (This method will be // re-invoked after that request finishes; see maybeCreateRemoteDB() above.) if (_creatingTarget) { Log.To.Sync.D(TAG, "creatingTarget == true, doing nothing"); return; } _pendingSequences = new SortedDictionary<long, int>(); if (!Int64.TryParse(LastSequence, out _maxPendingSequence)) { Log.To.Sync.W(TAG, "{0} is not a valid last sequence, using 0", LastSequence); _maxPendingSequence = 0; } if (Filter != null) { _filter = LocalDatabase.GetFilter(Filter); } else { // If not filter function was provided, but DocIds were // specified, then only push the documents listed in the // DocIds property. It is assumed that if the users // specified both a filter name and doc ids that their // custom filter function will handle that. This is // consistent with the iOS behavior. if (DocIds != null && DocIds.Any()) { _filter = (rev, filterParams) => DocIds.Contains(rev.Document.Id); } } if (Filter != null && _filter == null) { Log.To.Sync.W(TAG, "{0}: No ReplicationFilter registered for filter '{1}'; ignoring", this, Filter); } // Process existing changes since the last push: long lastSequenceLong = 0; if (LastSequence != null) { lastSequenceLong = long.Parse(LastSequence); } if (ReplicationOptions.PurgePushed) { _purgeQueue = new Batcher<RevisionInternal>(WorkExecutor, EphemeralPurgeBatchSize, EphemeralPurgeDelay, (revs) => { Log.To.Sync.I(TAG, "Purging {0} docs ('purgePushed' option)", revs.Count); var toPurge = new Dictionary<string, IList<string>>(); foreach(var rev in revs) { toPurge[rev.DocID] = new List<string> { rev.RevID.ToString() }; } var localDb = LocalDatabase; if(localDb != null && localDb.IsOpen) { var storage = localDb.Storage; if(storage != null && storage.IsOpen) { storage.PurgeRevisions(toPurge); } else { Log.To.Sync.W(TAG, "{0} storage is closed, cannot purge...", localDb); } } else { Log.To.Sync.W(TAG, "Local database is closed or null, cannot purge..."); } }, CancellationTokenSource); } // Now listen for future changes (in continuous mode): // Note: This needs to happen before adding the observer // or else there is a race condition. // A document could be added between the call to // ChangesSince and adding the observer, which would result // in a document being skipped if (Continuous) { _observing = true; LocalDatabase.Changed += OnChanged; } var options = ChangesOptions.Default; options.IncludeConflicts = true; var changes = LocalDatabase.ChangesSince(lastSequenceLong, options, _filter, FilterParams); if (changes.Count > 0) { Batcher.QueueObjects(changes); Batcher.Flush(); } if (Continuous) { if (changes.Count == 0) { Log.To.Sync.V(TAG, "No changes to push, switching to idle..."); FireTrigger(ReplicationTrigger.WaitingForChanges); } } else { if(changes.Count == 0) { Log.To.Sync.V(TAG, "No changes to push, firing StopGraceful..."); FireTrigger(ReplicationTrigger.StopGraceful); } } }
/// <summary> /// Calls clipBegin(Batcher, float, float, float, float) to clip this actor's bounds /// </summary> /// <returns>The begin.</returns> public bool clipBegin(Batcher batcher) { return(clipBegin(batcher, x, y, width, height)); }
public override void Draw(Batcher batcher, Vector2 position, Vector2 scale, float layerDepth, RectangleF cameraClipBounds) { batcher.Draw(Texture, position + Offset, null, Color.White, 0, Vector2.Zero, scale, SpriteEffects.None, layerDepth); }
public void Render(Batcher batcher, Camera camera) { batcher.Draw(_sprite, Position, _renderColor, _rotation, _origin, _scale, _spriteEffects, _layerDepth); }
public void TestBatcherLatencyTrickleIn() { doneSignal = new CountDownLatch(10); inboxCapacity = 100; processorDelay = 500; maxObservedDelta = -1L; var scheduler = new SingleThreadTaskScheduler(); var batcher = new Batcher<long>(new TaskFactory(scheduler), inboxCapacity, processorDelay, TestBatcherLatencyTrickleInProcessor); for (var i = 0; i < 10; i++) { var objectsToQueue = new List<long>(); objectsToQueue.Add(Runtime.CurrentTimeMillis()); batcher.QueueObjects(objectsToQueue); System.Threading.Thread.Sleep(1000); } var success = doneSignal.Await(TimeSpan.FromSeconds(35)); Assert.IsTrue(success); // we want the max observed delta between the time it was queued until the // time it was processed to be as small as possible. since // there is some overhead, rather than using a hardcoded number // express it as a ratio of 1/4th the processor delay, asserting // that the entire processor delay never kicked in. int acceptableMaxDelta = processorDelay - 1; Log.V(Tag, string.Format("TestBatcherLatencyTrickleIn : maxObservedDelta: {0}", maxObservedDelta)); Assert.IsTrue((maxObservedDelta < acceptableMaxDelta)); }
/// <summary> /// Default constructor /// </summary> /// <param name="db">The local database to replicate to/from</param> /// <param name="remote">The remote Uri to sync with</param> /// <param name="continuous">If set to <c>true</c> continuous.</param> /// <param name="clientFactory">The client factory for instantiating the HttpClient used to create web requests</param> /// <param name="workExecutor">The TaskFactory to execute work on</param> protected Replication(Database db, Uri remote, bool continuous, IHttpClientFactory clientFactory, TaskFactory workExecutor) { LocalDatabase = db; Continuous = continuous; // NOTE: Consider running a separate scheduler for all http requests. WorkExecutor = workExecutor; CancellationTokenSource = new CancellationTokenSource(); RemoteUrl = remote; RequestHeaders = new Dictionary<String, Object>(); _requests = new ConcurrentDictionary<HttpRequestMessage, Task>(); // FIXME: Refactor to visitor pattern. if (RemoteUrl.GetQuery() != null && !StringEx.IsNullOrWhiteSpace(RemoteUrl.GetQuery())) { var uri = new Uri(remote.ToString()); var personaAssertion = URIUtils.GetQueryParameter(uri, PersonaAuthorizer.QueryParameter); if (personaAssertion != null && !StringEx.IsNullOrWhiteSpace(personaAssertion)) { var email = PersonaAuthorizer.RegisterAssertion(personaAssertion); var authorizer = new PersonaAuthorizer(email); Authenticator = authorizer; } var facebookAccessToken = URIUtils.GetQueryParameter(uri, FacebookAuthorizer.QueryParameter); if (facebookAccessToken != null && !StringEx.IsNullOrWhiteSpace(facebookAccessToken)) { var email = URIUtils.GetQueryParameter(uri, FacebookAuthorizer.QueryParameterEmail); var authorizer = new FacebookAuthorizer(email); Uri remoteWithQueryRemoved = null; try { remoteWithQueryRemoved = new UriBuilder(remote.Scheme, remote.GetHost(), remote.Port, remote.AbsolutePath).Uri; } catch (UriFormatException e) { throw new ArgumentException("Invalid URI format.", "remote", e); } FacebookAuthorizer.RegisterAccessToken(facebookAccessToken, email, remoteWithQueryRemoved.ToString()); Authenticator = authorizer; } // we need to remove the query from the URL, since it will cause problems when // communicating with sync gw / couchdb try { RemoteUrl = new UriBuilder(remote.Scheme, remote.GetHost(), remote.Port, remote.AbsolutePath).Uri; } catch (UriFormatException e) { throw new ArgumentException("Invalid URI format.", "remote", e); } } Batcher = new Batcher<RevisionInternal>(workExecutor, INBOX_CAPACITY, PROCESSOR_DELAY, inbox => { try { Log.V(TAG, "*** BEGIN ProcessInbox ({0} sequences)", inbox.Count); FireTrigger(ReplicationTrigger.Resume); ProcessInbox (new RevisionList(inbox)); Log.V(TAG, "*** END ProcessInbox (lastSequence={0})", LastSequence); } catch (Exception e) { Log.E(TAG, "ProcessInbox failed: ", e); throw new RuntimeException(e); } }); ClientFactory = clientFactory; _stateMachine = new StateMachine<ReplicationState, ReplicationTrigger>(ReplicationState.Initial); InitializeStateMachine(); }
public void TestBatcherBatchSize5() { doneSignal = new CountDownLatch(10); inboxCapacity = 10; processorDelay = 1000; var scheduler = new SingleThreadTaskScheduler(); var batcher = new Batcher<string>(new TaskFactory(scheduler), inboxCapacity, processorDelay, TestBatcherBatchSize5Processor); var objectsToQueue = new List<string>(); for (var i = 0; i < inboxCapacity * 10; i++) { objectsToQueue.Add(i.ToString()); if (objectsToQueue.Count == 5) { batcher.QueueObjects(objectsToQueue); objectsToQueue.Clear(); } } var success = doneSignal.Await(TimeSpan.FromSeconds(35)); Assert.IsTrue(success); }