Skip to content

Commit

Permalink
Remove coroutine wrappers from iterators
Browse files Browse the repository at this point in the history
  • Loading branch information
SinisterRectus committed Nov 16, 2019
1 parent 9e3618f commit f6e7689
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 41 deletions.
20 changes: 12 additions & 8 deletions libs/iterables/ArrayIterable.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ the order may change if the internal array is modified. Some versions may use a
map function to shape the objects before they are accessed.
]=]

local wrap, yield = coroutine.wrap, coroutine.yield

local Iterable = require('iterables/Iterable')

local ArrayIterable, get = require('class')('ArrayIterable', Iterable)
Expand Down Expand Up @@ -83,14 +81,20 @@ function ArrayIterable:iter()
end
local map = self._map
if map then
return wrap(function()
for _, v in ipairs(array) do
local obj = map(v)
if obj then
yield(obj)
local i = 0
return function()
while true do
i = i + 1
local v = array[i]
if not v then
return nil
end
v = map(array[i])
if v then
return v
end
end
end)
end
else
local i = 0
return function()
Expand Down
50 changes: 30 additions & 20 deletions libs/iterables/Iterable.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ all stored objects should have a `__hash` method.
]=]

local random = math.random
local wrap, yield = coroutine.wrap, coroutine.yield
local insert, sort, pack = table.insert, table.sort, table.pack

local Iterable = require('class')('Iterable')
Expand All @@ -21,11 +20,14 @@ local Iterable = require('class')('Iterable')
a `key, value` pair, where `key` is the result of calling `__hash` on the `value`.
]=]
function Iterable:__pairs()
return wrap(function()
for obj in self:iter() do
yield(obj:__hash(), obj)
local gen = self:iter()
return function()
local obj = gen()
if not obj then
return nil
end
end)
return obj:__hash(), obj
end
end

--[=[
Expand Down Expand Up @@ -80,13 +82,18 @@ end
@d Returns an iterator that returns all objects that satisfy a predicate.
]=]
function Iterable:findAll(fn)
return wrap(function()
for obj in self:iter() do
local gen = self:iter()
return function()
while true do
local obj = gen()
if not obj then
return nil
end
if fn(obj) then
yield(obj)
return obj
end
end
end)
end
end

--[=[
Expand Down Expand Up @@ -249,19 +256,22 @@ function Iterable:pick(...)
local keys = pack(...)
local values = {}
local n = keys.n
return wrap(function()
for obj in self:iter() do
for i = 1, n do
local k = keys[i]
if type(k) == 'function' then
values[i] = k(obj)
else
values[i] = obj[k]
end
local gen = self:iter()
return function()
local obj = gen()
if not obj then
return nil
end
for i = 1, n do
local k = keys[i]
if type(k) == 'function' then
values[i] = k(obj)
else
values[i] = obj[k]
end
yield(unpack(values, 1, n))
end
end)
return unpack(values, 1, n)
end
end

return Iterable
19 changes: 11 additions & 8 deletions libs/iterables/TableIterable.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
Some versions may use a map function to shape the objects before they are accessed.
]=]

local wrap, yield = coroutine.wrap, coroutine.yield

local Iterable = require('iterables/Iterable')

local TableIterable = require('class')('TableIterable', Iterable)
Expand All @@ -29,14 +27,19 @@ function TableIterable:iter()
end
local map = self._map
if map then
return wrap(function()
for _, v in pairs(tbl) do
local obj = map(v)
if obj then
yield(obj)
local k, v
return function()
while true do
k, v = next(tbl, k)
if not v then
return nil
end
v = map(v)
if v then
return v
end
end
end)
end
else
local k, v
return function()
Expand Down
12 changes: 7 additions & 5 deletions libs/utils/Emitter.lua
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,15 @@ end
function Emitter:getListeners(name)
local listeners = self._listeners[name]
if not listeners then return function() end end
return wrap(function()
for _, listener in ipairs(listeners) do
if listener then
yield(listener.fn)
local i = 0
return function()
while i < #listeners do
i = i + 1
if listeners[i] then
return listeners[i].fn
end
end
end)
end
end

--[=[
Expand Down

0 comments on commit f6e7689

Please sign in to comment.