2016-11-29 4 views
1

Я использую Lua в игровом движке. Мне часто приходится делать что-то в заданный промежуток времени, и метод грубой силы должен сделать переменную для каждой вещи, которую мне нужно сделать, чтобы отслеживать последний раз, когда я это делал. Это загромождает мой код переменными, которые я не хочу видеть, поскольку они более ориентированы на работу, чем ориентированные на цель. Поэтому у меня возникла идея сделать функцию, которая сделает это автоматически для меня. Все, что мне нужно предоставить, это интервал и функция, которую я определяю в строке того, что мне нужно сделать на этом интервале. (в моем примере я использую «классы», поэтому я также определяю объект).uniquely Id a function in lua

Конечно, мне все равно нужно сделать последние переменные обновления для отслеживания каждого из них, но если я смогу замаскировать это внутри этой функции, тогда код, который я должен написать, чтобы использовать его, просто становится проще. Так что на моем переданном в obj мне нужно сделать уникальную переменную для каждого утверждения, когда я вызываю функцию. Я думал, что могу использовать строковое имя функции обратного вызова, но каждый раз, потому что это анонимная функция. Есть ли в любом случае анонимная функция, которая может генерировать уникальное имя переменной, поэтому мне не нужно отслеживать что-либо при использовании этой системы? Поскольку никакие 2 анонимные функции для одного и того же объекта не были бы похожими на хэширование самой функции? Не уверен, что если вы можете сделать это в Lua, хотя

function DoEvery(interval, obj, method) 
    -- somehow I need a way to uniquely ID the passed in method so I can make a variable on the passed in obj that tracks it's last time called 
    print(tostring(method)) -- this gives a new address each cycle so that won't work 
end 

Script = {} 

function Script:Create() 
    local obj = {} 

    obj.name = "Mike" 

    for k,v in pairs(Script) do 
     obj[k] = v 
    end 

    return obj 
end 

function Script:Update() 
    DoEvery(250, self, function(self) 
     print(self.name) 
    end) 
end 


local script = Script:Create() 

script:Update() 
script:Update() 
script:Update() 
+0

Определение имени локальной функции 'функция print_name (само) печать (self.name) end' вне' сценария: Update() 'и использовать' DoEvery (250, самость, print_name) 'как' Script: Update () 'body. Таким образом, у вас будет один и тот же аргумент 'method' в функции' DoEvery() 'при каждом вызове' script: Update() '. Вы можете использовать либо 'tostring (method)', либо 'method' как ключ внутри объекта' script' для хранения последнего времени доступа. –

+0

Я хочу, чтобы функция была встроенной, так как вы читаете код, который вам не нужно искать в другом месте, чтобы увидеть, что происходит. Я хочу, чтобы это было похоже на лямбда-выражение. – user441521

+0

Добавьте еще один аргумент - краткое описание вашего намерения: 'DoEvery (250,« print name », self, function (self) ... end)' Этот строковый аргумент будет действовать как комментарий (чтобы упростить понимание вашего кода) и как уникальный ключ. –

ответ

2

Это решение требует доступа к debug библиотеке и компилирования источников без зачистки отладочной информации (если ваши Lua файлы хранятся в виде скомпилированных байт-кода).

function DoEvery(interval, obj, method) 
    local info = debug.getinfo(method, "S") 
    local id = info.linedefined..info.source 
    print(id) 
    -- "id" consists of line number and file name 
    -- where "method" function was defined 
    -- so it is unique 
    -- (unless you write two anonymous functions on the same line) 
end 
+0

Это работает на https://www.lua.org/cgi-bin/demo. Я проведу его сегодня вечером в своем игровом движке. Если это сработает, это будет блестящим, и я приму это как ответ. – user441521

+1

Игровые движки обычно не имеют доступа к библиотеке отладки. –

+0

Игровой движок действительно поддерживает его! Это будет отлично работать! – user441521