Example: Color interval written with manual iterators
In some cases, the item you want to iterate
across does not implement the ISequenceable
interface. You cannot modify it to directly implement this interface
because it is a Java class from a third-party library. Although you cannot
use Gosu shortcuts for custom iterable intervals using sequenceable items,
you can still implement an iterable interval.
The following example demonstrates creating a custom iterable interval. Suppose you want to create a new iterable interval that can iterate across a list of predefined and ordered color names with a starting and ending color value. Define an enumeration containing the possible color values in their interval:
package example.gosu.interval
enum Color {
Red, Orange, Yellow, Green, Blue, Indigo, Violet
}
All Gosu enumerations automatically implement the
java.lang.Comparable interface,
which is a requirement for intervals.
Next, create a new class that extends the following type:
IterableInterval<Color, Integer, void, ColorInterval>Next, implement the methods
from the IIterableInterval
interface. It is important to note that in this example the iterator
classes are inner classes of the main ColorInterval
class.
package example.gosu.interval
uses gw.lang.reflect.interval.IterableInterval
class ColorInterval extends IterableInterval<Color, Integer, java.lang.Void, ColorInterval> {
construct(left : Color, right : Color, stp : Integer) {
super(left, right, stp)
//print("new ColorInterval, with 2 constructor args")
}
construct(left : Color, right : Color, stp : Integer, leftOpen : boolean,
rightOpen : boolean, rev: boolean) {
super(left, right, stp, null, leftOpen, rightOpen, rev)
//print("new ColorInterval, with 6 constructor args")
}
// Get the Nth item from the beginning (left) endpoint
override function getFromLeft(i: int) : Color {
return Color.AllValues[LeftEndpoint.Ordinal + i]
}
// Get the Nth item from the right endpoint
override function getFromRight(i : int) : Color {
return Color.AllValues[RightEndpoint.Ordinal - i]
}
// Return standard iterator
override function iterateFromLeft() : Iterator<Color> {
var startAt = LeftEndpoint.Ordinal
if (!LeftClosed) {
startAt++
}
return new ColorIterator(startAt)
}
// Return reverse order iterator
override function iterateFromRight() : Iterator<Color> {
var startAt = RightEndpoint.Ordinal
if (!LeftClosed)
startAt--
return new ReverseColorIterator(startAt)
}
// DEFINE AN INNER CLASS TO ITERATE ACROSS COLORS -- NORMAL ORDER
class ColorIterator implements Iterator<Color>{
protected var _currentIndex : int;
construct() {
throw "required start at # -- use other constructor"
}
construct(startAt : int ) {
_currentIndex = startAt
}
override function hasNext() : boolean {
return ((_currentIndex) <= (RightEndpoint.Ordinal - (RightClosed ? 0 : 1)))
}
override function next() : Color {
var i = _currentIndex
_currentIndex++
return Color.AllValues[i]
}
override function remove() {
throw "does not support removing values"
}
}
// DEFINE AN INNER CLASS TO ITERATE ACROSS COLORS -- REVERSE ORDER
class ReverseColorIterator extends ColorIterator {
construct(startAt : int ) {
super(startAt)
}
override function hasNext() : boolean {
return ((_currentIndex) >= (RightEndpoint.Ordinal + (LeftClosed ? 0 : 1)))
}
override function next() : Color {
var i = _currentIndex
_currentIndex--
return Color.AllValues[i]
}
}
}
Note the parameterized element type using Gosu generics syntax. It enforces the property that elements in the interval are mutually comparable.
Finally, you can use your new intervals
in for loop declarations:
uses example.gosu.interval.Color
uses example.gosu.interval.ColorInterval
print("Red to Blue as a closed interval...")
var colorRange = new ColorInterval(
Color.Red, Color.Blue, 1, true, true, false )
for (i in colorRange) {
print(i)
}
print("Red to Blue as an open interval...")
var colorRangeOpen = new ColorInterval(
Color.Red, Color.Blue, 1, false, false, false )
for (i in colorRangeOpen) {
print(i)
}
This code prints:
Red to Blue as a closed interval...
Red
Orange
Yellow
Green
Blue
Red to Blue as an open interval...
Orange
Yellow
Green
See also
