Здесь опишу такие штучки, которые могут потребоваться продвинутым OC-программистам (да и просто Луа-программистам).
Busy Idle
С помощью этого трюка можно делать довольно точные задержки, причём с длительностью менее тика.
local lastSleep = os.clock()
local function sleep(t)
local begin = os.clock()
while os.clock() - begin < t do
if lastSleep - os.clock() >= 3.5 then -- В конфигурации дефолтное значение = 5 секунд, ставим на 1.5 меньше для безопасности.
os.sleep(0.05) -- Вынужденная задержка.
lastSleep = os.clock()
t = t - 0.05
end
end
end
Проверка по значению
Очень часто в моих программах нужно найти ключ, значение которого соответствует данному. Для этого я написал простую функцию:
local function isin(tbl, value)
for k, v in pairs(tbl) do
if v == value then
return true, k
end
end
return false
end
На огромных массивах может и затормозить — скорость работы прямо зависит от длины массива.
Табличная магия
Рассмотрим этот на первый взгляд обычный пример кода:
local tbl1 = {"My", "super", "table", 42}
local tbl2 = tbl1
tbl2[2] = "cool"
for _, tbl in pairs({tbl1, tbl2}) do -- Напечатать значения таблиц
for k, v in pairs(tbl) do
print(k, v)
end
end
Разумно ожидать такое:
1 My
2 super
3 table
4 42
1 My
2 cool
3 table
4 42
Но вместо этого получаем:
1 My
2 cool
3 table
4 42
1 My
2 cool
3 table
4 42
Как видно, изменив значение в одной таблице, изменилась и другая.
Дело в том, что переменная хранит указатель на таблицу, а не саму таблицу. Соответственно, и tbl1, и tbl2 ссылаются на один и тот же массив.
На первый взгляд это кажется ненормальным. Как скопировать-то таблицу?
local function copy(tbl)
if type(tbl) ~= "table" then
return tbl
end
local result = {}
for k, v in pairs(tbl) do
result[k] = copy(v)
end
return result
end
Но из этого можно извлечь очень полезное применение. Когда мы передаём таблицу в аргументы функции, массив не копируется, а даётся указатель на тот же самый. Поэтому можно сообразить такой код:
local function removeOddNums(tbl)
for k, v in pairs(tbl) do
if tonumber(v) and v % 2 == 1 then
tbl[k] = nil
end
end
end
local table = {5, 26, 249586, 457139, 876, 42, 153}
removeOddNums(tbl)
И он будет работать. Этим и объясняется, почему table.sort не возвращает таблицу. У меня не самое полезное применение, однако с помощью таблицы можно создавать "поинтеры", например, так: local numPtr = {42}, а в функциях использовать так: local value = numPtr[1]; numPtr[1] = 666. И уже использовать их в своих вычислениях.
Думаю, вы найдёте применение этим фокусам. Не самые очевидные моменты, однако иногда требуется.
The end.