Line 2: |
Line 2: |
| -- more generic interface and compositions (filtering, grouping, mapping, sorting, etc.) | | -- more generic interface and compositions (filtering, grouping, mapping, sorting, etc.) |
| -- prevent clients from infinite loops | | -- prevent clients from infinite loops |
| + | -- load modules more lazily? |
| + | -- generalize equipment/enemy iterators |
| | | |
| local U = require('Module:Utils') | | local U = require('Module:Utils') |
| local EquipmentData = require('Module:EquipmentData') | | local EquipmentData = require('Module:EquipmentData') |
| local CollectionEquipment = require('Module:Collection/Equipment') | | local CollectionEquipment = require('Module:Collection/Equipment') |
| + | local EnemyShip = require('Module:EnemyShip') |
| + | local CollectionEnemy = require('Module:Collection/EnemyShips') |
| | | |
| local Iterator = {} | | local Iterator = {} |
Line 31: |
Line 35: |
| return context and tonumber(context[name .. (n and tostring(n) or '')]) or default | | return context and tonumber(context[name .. (n and tostring(n) or '')]) or default |
| end | | end |
| + | |
| + | -- * Equipment iterators. |
| | | |
| function Iterator.equipmentBy(context, n, pred, pre) | | function Iterator.equipmentBy(context, n, pred, pre) |
Line 127: |
Line 133: |
| end) | | end) |
| end | | end |
| + | |
| + | -- * Enemy iterators. |
| + | |
| + | function Iterator.enemiesByType(context, n) |
| + | local collection = U.imap(CollectionEnemy, function(name) |
| + | return EnemyShip(name) |
| + | end) |
| + | table.sort(collection, function(a, b) |
| + | local ai = U.ifind(CollectionEnemy, a:base_name()) |
| + | local bi = U.ifind(CollectionEnemy, b:base_name()) |
| + | if ai and bi and ai ~= bi then |
| + | return ai < bi |
| + | else |
| + | return a._id < b._id |
| + | end |
| + | end) |
| + | local type = numberKey('type', context, n) |
| + | local pred = function(e, i) |
| + | return e:type() == type |
| + | end |
| + | local pre |
| + | local i = 1 |
| + | local current = nil |
| + | local preFlag = true |
| + | return { |
| + | next = function() |
| + | for _ = i, #collection do |
| + | local e = collection[i] |
| + | if pred(e, i) then |
| + | if pre and preFlag then |
| + | local value = pre(e, i) |
| + | if value then |
| + | current = value |
| + | preFlag = false |
| + | return true |
| + | end |
| + | end |
| + | current = e:lua_name() |
| + | i = i + 1 |
| + | preFlag = true |
| + | return true |
| + | end |
| + | i = i + 1 |
| + | end |
| + | current = nil |
| + | return false |
| + | end, |
| + | current = function() |
| + | return current |
| + | end, |
| + | } |
| + | end |
| + | |
| + | -- * Tests. |
| | | |
| function Iterator.test() | | function Iterator.test() |
Line 133: |
Line 193: |
| mw.log(name) | | mw.log(name) |
| while iterator.next() do | | while iterator.next() do |
− | mw.log(' ' .. iterator.current()) | + | mw.log(' ' .. (iterator.current() or '?')) |
| end | | end |
| mw.log() | | mw.log() |
Line 143: |
Line 203: |
| testIterator('equipmentByTypeAndIcon', { type = '1', icon = '16' }) | | testIterator('equipmentByTypeAndIcon', { type = '1', icon = '16' }) |
| testIterator('equipmentBy', { pred = 'is_large_caliber_main_gun', sort = '_type' }) | | testIterator('equipmentBy', { pred = 'is_large_caliber_main_gun', sort = '_type' }) |
| + | testIterator('enemiesByType', { type = '2' }) |
| end | | end |
| -- p.test() | | -- p.test() |
| | | |
| return Iterator | | return Iterator |