From: Rico Tzschichholz Date: Sun, 2 Oct 2016 15:28:37 +0000 (+0200) Subject: tests: Add async generator example to cover an edge case X-Git-Tag: 0.35.1~120 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6e89b7b5d8112925cb8f07234a85ea1dba1e32e6;p=thirdparty%2Fvala.git tests: Add async generator example to cover an edge case https://bugzilla.gnome.org/show_bug.cgi?id=763345 --- diff --git a/tests/Makefile.am b/tests/Makefile.am index 0fd49d9fa..8ff0f3da3 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -208,6 +208,7 @@ TESTS = \ asynchronous/bug661961.vala \ asynchronous/bug742621.vala \ asynchronous/closures.vala \ + asynchronous/generator.vala \ asynchronous/yield.vala \ dbus/basic-types.test \ dbus/arrays.test \ diff --git a/tests/asynchronous/generator.vala b/tests/asynchronous/generator.vala new file mode 100644 index 000000000..f31e12a42 --- /dev/null +++ b/tests/asynchronous/generator.vala @@ -0,0 +1,60 @@ +// This is based on Luca Bruno's Generator. It illustrates using async methods +// to emulate a generator style of iterator coding. Note that this runs fine +// without a main loop. + +abstract class Generator { + bool consumed; + unowned G value; + SourceFunc callback; + + public Generator () { + helper.begin (); + } + + async void helper () { + yield generate (); + consumed = true; + } + + protected abstract async void generate (); + + protected async void feed (G value) { + this.value = value; + this.callback = feed.callback; + yield; + } + + public bool next () { + return !consumed; + } + + public G get () { + var result = value; + callback (); + return result; + } + + public Generator iterator () { + return this; + } +} + +class IntGenerator : Generator { + protected override async void generate () { + for (int i = 0; i < 10; i++) { + if (i % 2 == 0) + yield feed (i); + } + } +} + +void main () { + var gen = new IntGenerator (); + string result = ""; + + foreach (var item in gen) + result += "%i ".printf (item); + + assert (result == "0 2 4 6 8 "); +} +