summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/dat/clua/iter.lua
diff options
context:
space:
mode:
authorJude Brown <bookofjude@users.sourceforge.net>2009-11-29 15:32:50 +1000
committerJude Brown <bookofjude@users.sourceforge.net>2009-11-29 15:38:17 +1000
commit2943dc2999832721dddb7a591a927e9eb2eb4976 (patch)
tree9d5a356975c1a2e64ac2f3b7bdb37fc79bb6467c /crawl-ref/source/dat/clua/iter.lua
parente44ce374c8feff8cd3a7848195e2aa851d5ff971 (diff)
downloadcrawl-ref-2943dc2999832721dddb7a591a927e9eb2eb4976.tar.gz
crawl-ref-2943dc2999832721dddb7a591a927e9eb2eb4976.zip
New Lua iterators: point_iterator, slave_iterator, tweaks.
The first (point_iterator) accepts a table of points (such as the ones return by dgn.find_marker_positions_by_prop, or any other function which returns points) and is filterable and stateful. The second is a quick wrapper over dgn.find_marker_positions_by_prop. Tweaked rectangle_iterator to supply an "rvi" (return value instead) which will store the value of the filter instead of expecting the filter to return a true or false value. Setting this to false will behave as before; setting it to true allows us to have the filter alter the point (mons_at, items_at, marker_at_pos, etc).
Diffstat (limited to 'crawl-ref/source/dat/clua/iter.lua')
-rw-r--r--crawl-ref/source/dat/clua/iter.lua87
1 files changed, 79 insertions, 8 deletions
diff --git a/crawl-ref/source/dat/clua/iter.lua b/crawl-ref/source/dat/clua/iter.lua
index f9371d81eb..ba5b7bd6cf 100644
--- a/crawl-ref/source/dat/clua/iter.lua
+++ b/crawl-ref/source/dat/clua/iter.lua
@@ -32,7 +32,7 @@ function iter.rectangle_iterator:_new ()
return m
end
-function iter.rectangle_iterator:new (corner1, corner2, filter)
+function iter.rectangle_iterator:new (corner1, corner2, filter, rvi)
if corner1 == nil or corner2 == nil then
error("need two corners to a rectangle")
end
@@ -51,6 +51,7 @@ function iter.rectangle_iterator:new (corner1, corner2, filter)
mt.cur_x = corner1.x - 1
mt.cur_y = corner1.y
mt.filter = filter or nil
+ mt.rvi = rvi or false
return mt:iter()
end
@@ -64,15 +65,15 @@ function iter.rectangle_iterator:next()
if self.cur_y > self.max_y then
point = -1
else
- point = dgn.point(self.cur_x, self.cur_y)
- if not self:check_filter(point) then
+ point = self:check_filter(dgn.point(self.cur_x, self.cur_y))
+ if point == nil then
point = -2
end
end
else
self.cur_x = self.cur_x + 1
- point = dgn.point(self.cur_x, self.cur_y)
- if not self:check_filter(point) then
+ point = self:check_filter(dgn.point(self.cur_x, self.cur_y))
+ if point == nil then
point = -2
end
end
@@ -89,12 +90,16 @@ end
function iter.rectangle_iterator:check_filter(point)
if self.filter ~= nil then
if self.filter(point) then
- return true
+ if self.rvi then
+ return self.filter(point)
+ else
+ return point
+ end
else
- return false
+ return nil
end
else
- return true
+ return point
end
end
@@ -319,3 +324,69 @@ function iter.subvault_iterator (e, filter)
return iter.rect_iterator(top_corner, bottom_corner, check_mask)
end
+
+-------------------------------------------------------------------------------
+-- Marker iterators
+-- firstly, a point iterator. It's really just a fancy ipairs(), but stateful
+-- and with the ability to filter points.
+-------------------------------------------------------------------------------
+
+iter.point_iterator = {}
+
+function iter.point_iterator:_new ()
+ local m = {}
+ setmetatable(m, self)
+ self.__index = self
+ return m
+end
+
+function iter.point_iterator:new (ptable, filter, rv_instead)
+ if ptable == nil then
+ error("ptable cannot be nil for point_iterator")
+ end
+
+ local mt = iter.point_iterator:_new()
+ mt.cur_p = 0
+ mt.table = ptable
+ mt.rvi = rv_instead or false
+ mt.filter = filter or nil
+
+ return mt:iter()
+end
+
+function iter.point_iterator:next()
+ local point = nil
+ local q = 0
+ repeat
+ q = q + 1
+ self.cur_p = self.cur_p + 1
+ point = self:check_filter(self.table[self.cur_p])
+ until point or q == 10
+
+ return point
+end
+
+function iter.point_iterator:check_filter(point)
+ if self.filter ~= nil then
+ if self.filter(point) then
+ if self.rvi then
+ return self.filter(point)
+ else
+ return point
+ end
+ else
+ return nil
+ end
+ else
+ return point
+ end
+end
+
+function iter.point_iterator:iter ()
+ return function() return self:next() end, nil, nil
+end
+
+-- An easier and more posh way of interfacing with find_marker_positions_by_prop.
+function iter.slave_iterator (prop, value)
+ return iter.point_iterator:new(dgn.find_marker_positions_by_prop(prop, value))
+end