Помощь - Поиск - Пользователи - Календарь
Полная версия: Помогите освоить LUA
UoKit.com Форумы > Кликер > UO Pilot
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
sutra
Начал осваивать LUA, помогите пожалуйста, в справке нет многих операторов.
Сразу возник вопрос, как загрузить массив из файла (аналог load_array), наверняка ответ на форуме есть, но я не нашёл. В обычном скрипте код такой.

load_array %cfg $ConfigFile

Ну и сохранить соответственно тоже не знаю как.
cirus
чтение/запись файла
Код
--lua
log "clear"  log "mode compact"
local f = io.open([[C:\111.txt]], "r")  -- открыть файл для чтения

if f then    -- если файл открылся
    local cfg = {}    -- объявили массив
    for v in f:lines() do       -- читаем файл 111.txt по строкам
        cfg[#cfg+1]=v           -- добавляем в массив
    end
    f:close();   -- закрыть файл
    log(table.concat(cfg, " "))    -- вывести массив в лог

    for i=1, #cfg do         -- для всех элементов массива
        cfg[i]=tostring(i) .. " " .. cfg[i]  -- вначале строки добавим номер строки
    end

    f = io.open([[C:\222.txt]], "w")  -- открыть файл для записи
    if f then
        for i=1, #cfg do         -- для всех элементов массива
            f:write(cfg[i] .. "\r\n")  -- запись в файл
        end
        f:close();   -- закрыть файл
    end
end
DarkMaster
Поскольку lua весь на деревьях и размеры массивов могут быть различными даже в части вложенности элементов (они не прямоугольные в lua), то лучше использовать что-то более серьезное, хотя в базовом виде работать бесспроно будет.
Например есть вот такое творение:
http://lua-users.org/wiki/TablePersistence
оригинал

Код
local write, writeIndent, writers, refCount;

persistence =
{
    store = function (path, ...)
        local file, e = io.open(path, "w");
        if not file then
            return error(e);
        end
        local n = select("#", ...);
        -- Count references
        local objRefCount = {}; -- Stores reference that will be exported
        for i = 1, n do
            refCount(objRefCount, (select(i,...)));
        end;
        -- Export Objects with more than one ref and assign name
        -- First, create empty tables for each
        local objRefNames = {};
        local objRefIdx = 0;
        file:write("-- Persistent Data\n");
        file:write("local multiRefObjects = {\n");
        for obj, count in pairs(objRefCount) do
            if count > 1 then
                objRefIdx = objRefIdx + 1;
                objRefNames[obj] = objRefIdx;
                file:write("{};"); -- table objRefIdx
            end;
        end;
        file:write("\n} -- multiRefObjects\n");
        -- Then fill them (this requires all empty multiRefObjects to exist)
        for obj, idx in pairs(objRefNames) do
            for k, v in pairs(obj) do
                file:write("multiRefObjects["..idx.."][");
                write(file, k, 0, objRefNames);
                file:write("] = ");
                write(file, v, 0, objRefNames);
                file:write(";\n");
            end;
        end;
        -- Create the remaining objects
        for i = 1, n do
            file:write("local ".."obj"..i.." = ");
            write(file, (select(i,...)), 0, objRefNames);
            file:write("\n");
        end
        -- Return them
        if n > 0 then
            file:write("return obj1");
            for i = 2, n do
                file:write(" ,obj"..i);
            end;
            file:write("\n");
        else
            file:write("return\n");
        end;
        if type(path) == "string" then
            file:close();
        end;
    end;

    load = function (path)
        local f, e;
        if type(path) == "string" then
            f, e = loadfile(path);
        else
            f, e = path:read('*a')
        end
        if f then
            return f();
        else
            return nil, e;
        end;
    end;
}

-- Private methods

-- write thing (dispatcher)
write = function (file, item, level, objRefNames)
    writers[type(item)](file, item, level, objRefNames);
end;

-- write indent
writeIndent = function (file, level)
    for i = 1, level do
        file:write("\t");
    end;
end;

-- recursively count references
refCount = function (objRefCount, item)
    -- only count reference types (tables)
    if type(item) == "table" then
        -- Increase ref count
        if objRefCount[item] then
            objRefCount[item] = objRefCount[item] + 1;
        else
            objRefCount[item] = 1;
            -- If first encounter, traverse
            for k, v in pairs(item) do
                refCount(objRefCount, k);
                refCount(objRefCount, v);
            end;
        end;
    end;
end;

-- Format items for the purpose of restoring
writers = {
    ["nil"] = function (file, item)
            file:write("nil");
        end;
    ["number"] = function (file, item)
            file:write(tostring(item));
        end;
    ["string"] = function (file, item)
            file:write(string.format("%q", item));
        end;
    ["boolean"] = function (file, item)
            if item then
                file:write("true");
            else
                file:write("false");
            end
        end;
    ["table"] = function (file, item, level, objRefNames)
            local refIdx = objRefNames[item];
            if refIdx then
                -- Table with multiple references
                file:write("multiRefObjects["..refIdx.."]");
            else
                -- Single use table
                file:write("{\n");
                for k, v in pairs(item) do
                    writeIndent(file, level+1);
                    file:write("[");
                    write(file, k, level+1, objRefNames);
                    file:write("] = ");
                    write(file, v, level+1, objRefNames);
                    file:write(";\n");
                end
                writeIndent(file, level);
                file:write("}");
            end;
        end;
    ["function"] = function (file, item)
            -- Does only work for "normal" functions, not those
            -- with upvalues or c functions
            local dInfo = debug.getinfo(item, "uS");
            if dInfo.nups > 0 then
                file:write("nil --[[functions with upvalue not supported]]");
            elseif dInfo.what ~= "Lua" then
                file:write("nil --[[non-lua function not supported]]");
            else
                local r, s = pcall(string.dump,item);
                if r then
                    file:write(string.format("loadstring(%q)", s));
                else
                    file:write("nil --[[function could not be dumped]]");
                end
            end
        end;
    ["thread"] = function (file, item)
            file:write("nil --[[thread]]\n");
        end;
    ["userdata"] = function (file, item)
            file:write("nil --[[userdata]]\n");
        end;
}

Пример использования:
Код
t_original = {1, 2, ["a"] = "string", b = "test", {"subtable", [4] = 2}};
persistence.store("storage.lua", t_original);
t_restored = persistence.load("storage.lua");

Это позволит сохранят таблицы с любой структурой при этом сохраненный файл является полностью валидным lua кодом и может быть загружен через loadstring (что на самом деле и делает функция persistence.load). Вид при этом читабельный, никаких дурных проблем с зарезервированными символами и т.д.

Почему для себя я бы не стал это использовать... Сделано оно так, что должно находиться в коде скрита, а не подгружаться из отдельного файла. Это просто не удобно. К тому же мы получаем километровое название функции которое еще и правильно нужно написать. Поэтому для себя я сделал небольшие модификации.
Допиленный вариант
Код

local write, writeIndent, writers, refCount;

local persistence =
{
    save = function (path, ...)
        local file, e = io.open(path, "w");
        if not file then
            return error(e);
        end
        local n = select("#", ...);
        -- Count references
        local objRefCount = {}; -- Stores reference that will be exported
        for i = 1, n do
            refCount(objRefCount, (select(i,...)));
        end;
        -- Export Objects with more than one ref and assign name
        -- First, create empty tables for each
        local objRefNames = {};
        local objRefIdx = 0;
        file:write("-- Persistent Data\n");
        file:write("local multiRefObjects = {\n");
        for obj, count in pairs(objRefCount) do
            if count > 1 then
                objRefIdx = objRefIdx + 1;
                objRefNames[obj] = objRefIdx;
                file:write("{};"); -- table objRefIdx
            end;
        end;
        file:write("\n} -- multiRefObjects\n");
        -- Then fill them (this requires all empty multiRefObjects to exist)
        for obj, idx in pairs(objRefNames) do
            for k, v in pairs(obj) do
                file:write("multiRefObjects["..idx.."][");
                write(file, k, 0, objRefNames);
                file:write("] = ");
                write(file, v, 0, objRefNames);
                file:write(";\n");
            end;
        end;
        -- Create the remaining objects
        for i = 1, n do
            file:write("local ".."obj"..i.." = ");
            write(file, (select(i,...)), 0, objRefNames);
            file:write("\n");
        end
        -- Return them
        if n > 0 then
            file:write("return obj1");
            for i = 2, n do
                file:write(" ,obj"..i);
            end;
            file:write("\n");
        else
            file:write("return\n");
        end;
        if type(path) == "string" then
            file:close();
        end;
    end;

    load = function (path)
        local f, e;
        if type(path) == "string" then
            f, e = loadfile(path);
        else
            f, e = path:read('*a')
        end
        if f then
            return f();
        else
            return nil, e;
        end;
    end;
}

-- Private methods

-- write thing (dispatcher)
write = function (file, item, level, objRefNames)
    writers[type(item)](file, item, level, objRefNames);
end;

-- write indent
writeIndent = function (file, level)
    for i = 1, level do
        file:write("\t");
    end;
end;

-- recursively count references
refCount = function (objRefCount, item)
    -- only count reference types (tables)
    if type(item) == "table" then
        -- Increase ref count
        if objRefCount[item] then
            objRefCount[item] = objRefCount[item] + 1;
        else
            objRefCount[item] = 1;
            -- If first encounter, traverse
            for k, v in pairs(item) do
                refCount(objRefCount, k);
                refCount(objRefCount, v);
            end;
        end;
    end;
end;

-- Format items for the purpose of restoring
writers = {
    ["nil"] = function (file, item)
            file:write("nil");
        end;
    ["number"] = function (file, item)
            file:write(tostring(item));
        end;
    ["string"] = function (file, item)
            file:write(string.format("%q", item));
        end;
    ["boolean"] = function (file, item)
            if item then
                file:write("true");
            else
                file:write("false");
            end
        end;
    ["table"] = function (file, item, level, objRefNames)
            local refIdx = objRefNames[item];
            if refIdx then
                -- Table with multiple references
                file:write("multiRefObjects["..refIdx.."]");
            else
                -- Single use table
                file:write("{\n");
                for k, v in pairs(item) do
                    writeIndent(file, level+1);
                    file:write("[");
                    write(file, k, level+1, objRefNames);
                    file:write("] = ");
                    write(file, v, level+1, objRefNames);
                    file:write(";\n");
                end
                writeIndent(file, level);
                file:write("}");
            end;
        end;
    ["function"] = function (file, item)
            -- Does only work for "normal" functions, not those
            -- with upvalues or c functions
            local dInfo = debug.getinfo(item, "uS");
            if dInfo.nups > 0 then
                file:write("nil --[[functions with upvalue not supported]]");
            elseif dInfo.what ~= "Lua" then
                file:write("nil --[[non-lua function not supported]]");
            else
                local r, s = pcall(string.dump,item);
                if r then
                    file:write(string.format("loadstring(%q)", s));
                else
                    file:write("nil --[[function could not be dumped]]");
                end
            end
        end;
    ["thread"] = function (file, item)
            file:write("nil --[[thread]]\n");
        end;
    ["userdata"] = function (file, item)
            file:write("nil --[[userdata]]\n");
        end;
}

return persistence

Пример использования:
Код
local tableToFile = require[[luaPlugins\tableToFile]] -- объявляется один раз в начале скрипта.
-- Объявляем массив
local arr = {10,9,8,7,6,5,4,3,{21,22,23,"'}\"\t\'",{}},1,0}
-- Сохраняем массив
tableToFile.save("1.txt",arr)
-- Закгружаем массив
arr2=tableToFile.load("1.txt")

Изменения оригинального кода - минимальные. Просто теперь можно спокойно подгрузить одной строкой, а не таскать весь код каждый раз за собой. Ну и store нам save поменял.
DarkMaster
Предчувствуя следующий вопрос:
Отобразить содержимое таблицы
Код
local function lg(data, comment)
    if  comment ~= nil then
        log(comment)
    end
    
    local tab = ""
    local deep = 0
    
    local function show(data)
        -- Пишем в лог комментарий.
        deep = deep + 1 -- Уровень вложенности вызовов функции.

        if type(data) == "table"    then
            local element_counter = 0
            for k,v in pairs(data) do
                element_counter = element_counter + 1
                if  type (v) == "table" then
                    log(tab..'table: '..k)
                    tab = tab .. "    "
                    show(v)
                    tab = string.sub(tab, 1, -5)
                else
                    if     type(v) == "nil"       then v = "nil"
                    elseif type(v) == "string"    then v = '"' .. v .. '"'
                    elseif type(v) == "number"    then v = tostring(v)
                    elseif type(v) == "function"  then v = tostring(v)
                    elseif type(v) == "thread"    then v = tostring(v)
                    elseif type(v) == "userdata"  then v = "userdata"
                    elseif type(v) == "boolean"   then v = tostring(v)
                    elseif type(v) == "table"     then
                        log(tab..""..k.." = "..v or "nil")
                    else
                        v = "uknown data type"
                    end
                    log(tab..""..k.." = " .. v)
                end
            end    
            log("Elements in table: " .. element_counter)
        else
            log('table is "' .. type(data) .. '" data type. Value: ' .. tostring(data))
        end
        -- Пишем в лог комментарий.
        deep = deep - 1 -- Уровень вложенности вызовов функции.
    end
    
    show(data)
end

Выдернуто куском из кода, там чуть лишнего есть. Использование:
lg(table, "комментарий")
Комментарий можно не писать.
sutra
Спасибо большое парни! Оба здорово помогли мне. Сделал средний вариант, не так сложно как у Дарка, но с поддержкой двумерных строково-числовых массивов. И на будущее ещё много чего понял. Ещё раз спасибо.
DarkMaster
Цитата
Сделал средний вариант, не так сложно как у Дарка

Смысл в том, что это делать уже не надо - оно уже сделано. Достаточно просто подключить. В итоге получается обыкновенная функция, а что там внутри наворочено вам и не нужно знать по большому счету.
sutra
Дарк, а есть такая возможность получить некий результат в виде переменной из скрипта Lua в обычный скрипт? Или только через файл. Замечание я принял, спасибо. Но я всё люблю попробовать сам и понять как это работает, так сказать на всякий случай, в целях самообразования. Просто читаешь иногда посты, там говорят что мол это невозможно, а начинаешь пробовать и всё получается. Вот не помню уж где-то видел, что нельзя анализировать звук, а я анализирую без проблем.
DarkMaster
Цитата
Дарк, а есть такая возможность получить некий результат в виде переменной из скрипта Lua в обычный скрипт?

Нет. И подозреваю, что даже между запущенными на луа скриптами будет определенная проблема передать данные. Изначально там была глобальная область видимости для глобальных переменных, т.е.
local a = 10 -- видно в пределах вкладки
a = 10 -- видно из любой. Но т.к. это приводило к катастрофам - все было разделено.
Так что только файликами. В луа думаю можно поискать дллки чтобы с ком портами работать, но в стандартном синтаксисе это только плагин писать либо какими-то невероятным костылями со сторонними exe, и может буфером.

Про звук поделиться не хотите?
WKnight
Цитата
а есть такая возможность получить некий результат в виде переменной из скрипта Lua в обычный скрипт?

Теоретически есть. А смысл?
sutra
Смысла нет, просто скрипт огромный, хотел частями попробовать, так что проехали.

А про звук ... Ну программер из меня хреновый, а вот придумывать я мастак. Сначала хотел всё делать "по уму", но как я уже сказал, программер из меня... Поэтому сделал просто. Вывожу микшер куда мне надо (засунул на второй монитор в самый низ). А потом всё тем же Файндом просто контролирую шкалу громкости. Как минимум длительность звука и его пиковые пороги контролировать элементарно. Теоретически можно и синусоиду контролировать, тогда нужно чтобы постоянно висела какая-нибудь программулина, но это уж точно изврат.

Файнды - ЭТО СИЛА. Думаю в Lua всё будет "летать" и я никаких проблем и ограничений для себя не вижу. Ещё раз спасибо Кнайту. Несмотряна то, что я нищий, если заведу себе яндекс деньги, то отблагодарю.

С одним монитором в полноэкранном режиме естественно не прокатит. А меня вполне устраивает. А по уму надо как я понимаю плагин прикручивать. Только как вытащить туда звуки системы я не знаю, но теоретически однозначно можно. Микшер то вытаскивает ...
sutra
В башке "месиво" сплошное от всех этих языков, тяжко продвигается. То set поставлю, то вместо "==" одиночное "=", то then забуду. Залез тут как-то в Делфи, про begin-ы и точки с запятыми забываю, ну там быстро напоминают, ещё до компиляции. Никаких стандартов, каждый норовит своё придумать, ладно хоть Escape у всех одинаково работает, а вот уже с Enter-ом проблемы встречаются. По уму должны перевод строки приклеивать, но это не факт.
olduo.com
Цитата(sutra @ 26.10.2018, 16:49) *

В башке "месиво" сплошное от всех этих языков, тяжко продвигается. То set поставлю, то вместо "==" одиночное "=", то then забуду. Залез тут как-то в Делфи, про begin-ы и точки с запятыми забываю, ну там быстро напоминают, ещё до компиляции.

проблема в том, что твое месиво в башке ты не знаешь углубленно =)
не забывай ставить ; в луа, это удобно если не знаешь на чем будешь кодить завтра =) из личного опыта)
а так луа это школьный язык, его там нужно вместо паскаля и бесика преподавать)
DarkMaster
Цитата
а так луа это школьный язык, его там нужно вместо паскаля и бесика преподавать)

И да и нет. Пока не лезешь в классы и метатаблицы - да. И вопрос не в том, что это что-то невероятно сложное, тут скорее проблема читаемости и понимания структуры кода. В рамках луа, который гибкий просто до безобразия в свой функциональщине, считаю использование классов нежеланием переучиваться плюсовиков.
Cockney
Цитата
считаю использование классов нежеланием переучиваться плюсовиков.


Да вот только сам по себе луа пустой. Его сфера применение - встраивание. И как бы если луа может реализовывать классы, то не факт что те же плюсы смогут реализовать фичи луа (имеется ввиду из коробки). Да и к тому же, есть устоя́вшиеся нормы и правила написания софта. Класс - удобно, красиво, хоть иногда и громоздко. А луа сегодня есть, завтра нет...отсюда как бы еще и вытекает вопрос а зачем собственно и переучиваться на луа и вникать в него, если он не востребован практически нигде(по сравнению с питоном, js и другими) ?
DarkMaster
Цитата
Да вот только сам по себе луа пустой.

Классы этого никак не меняют.
Цитата
Его сфера применение - встраивание.

И справляется на самом деле очень неплохо. Тем не менее есть те же сокеты, биндинги под wxWidgets и Qt. Т.е. на нем пишут. Его распространненость скорее следствие работы не шибко большой группы и отсутствия макетинга. Это не Google который штампует языки и на них _будут_ писать вне зависимости от качества продукта.
Цитата
Класс - удобно, красиво, хоть иногда и громоздко.

Тут холивар может быть очень большим. Я не сторнник ооп. Да, оно бывает в определенных ситуациях нужно, но количество этих ситуаций и количество "написал на классах потому, что модно и современно" я не считал. Для меня очень неожиданно было, когда случайно наткнутся на статистику кода в линях: кода на чистом си оказалось в 2.5 раза больше, чем на плюсах. Заставило задуматься на самом деле.
Цитата
А луа сегодня есть, завтра нет...отсюда как бы еще и вытекает вопрос а зачем собственно и переучиваться на луа и вникать в него, если он не востребован практически нигде(по сравнению с питоном, js и другими) ?

У него есть своя ниша в которую он плотно засел - геймдев. Сейчас по сути он там стандарт. Тот же wow по части аддонов полностью на нем написан (это просто дикий объем кода - их сотни тысяч), GTA вся логика на lua описывается. Причем если вов был изначально такой, то переход на lua такой большой корпорации, как Rockstar не мог не быть тщательно взвешан. Так же в обработке траффика его частенько используют - nginx, wireshark. Это маркеры. Серьезные проекты и встаривание в них было вполне успешным. Да, язык не топ популярности, но ниша занята, его там никто не теснит, а нужное он делает на 5.
Зачем переучиваться? Ну я, например, знаю одну студию разработки в которой плюсовики нафигачили кода с классами и кучей переназначений в метатаблицах. Т.е. использовали возможности языка на все 100%. Вот только когда приходишь со своим самоваром в другой язык, то не очень хорошо получается в плане результа. Потом команда сильно разосралась, т.к. натуральным луашникам этот изврат не очень нравился, а плюсовикам было все пофигу и пальцы веером. В итоге выкинули всех за не совсем адекватность, уже год ищут луашников именно для переписывания всей этой крутоты на классах. Обрывки кода видел лично - искать где, что править в 10 раз переназначенных метаблицах полный бред. Это нужно делать либо тому человеку, который это писал, либо сидеть с маном в котором вся структура чуда. Луа не святой, есть свои огрехи, си я уважаю больше, асм еще больше, но у всего есть ниша и причины почему ни один язык не стал универсальным и доминирующим везде. Это я все к чему - со своим самоваром не стоит =)
Cockney
Цитата(DarkMaster @ 27.10.2018, 14:00) *

Классы этого никак не меняют.

И справляется на самом деле очень неплохо. Тем не менее есть те же сокеты, биндинги под wxWidgets и Qt. Т.е. на нем пишут. Его распространненость скорее следствие работы не шибко большой группы и отсутствия макетинга. Это не Google который штампует языки и на них _будут_ писать вне зависимости от качества продукта.


Как бы меняют, ведь qt и виджеты являются ооп (или нет ?). Если бы не поддержка ооп из коробки, он бы загнулся в самом начале.

Цитата

Тут холивар может быть очень большим. Я не сторнник ооп. Да, оно бывает в определенных ситуациях нужно, но количество этих ситуаций и количество "написал на классах потому, что модно и современно" я не считал. Для меня очень неожиданно было, когда случайно наткнутся на статистику кода в линях: кода на чистом си оказалось в 2.5 раза больше, чем на плюсах. Заставило задуматься на самом деле.


это про линуксы ? Статистика чего ? Ядра ? Ну тогда не удивительно, что там си больше. printf быстрее потоков раза в 3 если не больше. А попробуй вывести через него сложную структуру, класс. Неудобно, не так ли ?

Цитата

У него есть своя ниша в которую он плотно засел - геймдев. Сейчас по сути он там стандарт. Тот же wow по части аддонов полностью на нем написан (это просто дикий объем кода - их сотни тысяч), GTA вся логика на lua описывается. Причем если вов был изначально такой, то переход на lua такой большой корпорации, как Rockstar не мог не быть тщательно взвешан. Так же в обработке траффика его частенько используют - nginx, wireshark. Это маркеры. Серьезные проекты и встаривание в них было вполне успешным. Да, язык не топ популярности, но ниша занята, его там никто не теснит, а нужное он делает на 5.


Да никто и не спорит с этим. Только вот учить его чтобы попасть на одну из 2 вакансий в Москве (hh.ru), когда есть unity c# 360+ вакансий.....Это если говорить о реальной его пользе, а не уровне пилота. Конечно, на нем пишут, только где....

Цитата

Зачем переучиваться? Ну я, например, знаю одну студию разработки в которой плюсовики нафигачили кода с классами и кучей переназначений в метатаблицах. Т.е. использовали возможности языка на все 100%. Вот только когда приходишь со своим самоваром в другой язык, то не очень хорошо получается в плане результа. Потом команда сильно разосралась, т.к. натуральным луашникам этот изврат не очень нравился, а плюсовикам было все пофигу и пальцы веером. В итоге выкинули всех за не совсем адекватность, уже год ищут луашников именно для переписывания всей этой крутоты на классах. Обрывки кода видел лично - искать где, что править в 10 раз переназначенных метаблицах полный бред. Это нужно делать либо тому человеку, который это писал, либо сидеть с маном в котором вся структура чуда. Луа не святой, есть свои огрехи, си я уважаю больше, асм еще больше, но у всего есть ниша и причины почему ни один язык не стал универсальным и доминирующим везде. Это я все к чему - со своим самоваром не стоит =)


Не стоит. А еще не стоит ставить человека на луа проект, который знает только c++.

Ради интереса зашел на одну из вакансий по луа:

Цитата
Для этого необходимо:

Опыт разработки на C#/C++
Опыт разработки на Android платформе: SDK, NDK
Английский язык - технический
Умение работать в команде
Желание работать в игровой индустрии
Желание и способность учиться
Необходимо знание языка LUA



И вот риторический вопрос, а зачем знание плюсов, да еще и тем более шарпов (где все классы) луашнику ? Сам по себе луа самодостаточен. Модули, метатаблицы - все что хочешь. Никак работодатель желает биндить классы (ведь для этого нужен опыт шарпа ?) через луа ?
sutra
Во какую тему замутил. А я вот со своим дилетантским взглядом считаю так, что если мне нужно вбить колышек, я беру кувалду, пару раз стукну и всё, а не вызываю машину для забивки свай. 99% пользователей Пилота "забивают колышки". Здесь не игрушки пишут и не рассчитывают турбулентность. Поэтому овчинка должна стоить выделки. Зачем мне тратить уйму времени и забивать голову ненужной информацией если нужно выполнить примитивнейшие действия. Лично для меня язык Пилота был абсолютно понятен сразу на 100%. И я быстро разберусь с любым скриптом, если будут адекватные имена переменных. С Lua намного сложней, там уже нужно частенько вникать подробно и с ходу в чужом коде можно мозги вывихнуть. Для меня Пилот, просто полезный и лёгкий в освоении инструмент. И меня практически всё в нём устраивает, но возникло пару моментов, где не хватает быстродействия, вот и решил перейти на Lua , но придётся потратить немало времени.
DarkMaster
Цитата
Как бы меняют, ведь qt и виджеты являются ооп (или нет ?).

Насколько я понял там вообще пофигу ибо линкуется там все через очередь и пушится каждый параметр. Что есть дикий минус ибо дллки нужно обертывать весьма своеобразно и спокойно ту же сишную либу не подключишь. Так что едва ли =)
Цитата
И вот риторический вопрос, а зачем знание плюсов, да еще и тем более шарпов (где все классы) луашнику ? Сам по себе луа самодостаточен. Модули, метатаблицы - все что хочешь. Никак работодатель желает биндить классы (ведь для этого нужен опыт шарпа ?) через луа

Ну собственно ответ выше. Да и как бы начали с того, что это встраиваемый язык. Встраивать то его тоже надо =) А вот что там классы или не классы суть не важно.
Цитата
Лично для меня язык Пилота был абсолютно понятен сразу на 100%.

И да и нет. Честно? Разницы по сложности - ноль. Самого языка. Вот когда на грабли вставать будете - поймете, что луа намного проще) Разница в том, что луа в рамках пилота не настолько интегрирован. Те же записи/чтения файла. Не так много людей идут на луа (очень зря кстати), а те кто идут зачастую не считают проблемой самим написать такие вещи. Это недоработки интеграции. Пилот 20 лет почти вылизывался, луа - год. Ну и примеров совсем другое количество. Cirus вон какую сказку с допиливанием вики сделал. Для луа этого просто нет. Мне - это не нужно, я и так сориентируюсь по старым примерам, а человеку который только вникает и не имеет опыта программирования - это сложно. Грубо говоря не обжитой он просто.
olduo.com
Цитата(Cockney @ 27.10.2018, 14:48) *

Ради интереса зашел на одну из вакансий по луа:
Цитата
Для этого необходимо:

Опыт разработки на C#/C++
Опыт разработки на Android платформе: SDK, NDK
Английский язык - технический
Умение работать в команде
Желание работать в игровой индустрии
Желание и способность учиться
Необходимо знание языка LUA

И вот риторический вопрос, а зачем знание плюсов, да еще и тем более шарпов (где все классы) луашнику ? Сам по себе луа самодостаточен. Модули, метатаблицы - все что хочешь. Никак работодатель желает биндить классы (ведь для этого нужен опыт шарпа ?) через луа ?

хороший пример, именно потому что из игровой индустрии. большинство серверов с которыми работал в качестве скриптового движка используют луа, но не всегда все его возможности. обычно это просто серверный хук, который вызывает обработку в скрипте. потом ты уверен, что это вакансия луашника? ну т.е. если это серверный программист, то тебе нужно и "Опыт разработки на C#/C++" и "Необходимо знание языка LUA". если это луашник, то согласен, опыт в остальном второстепенен. я както тут писал про пацаньчика, которого взял на серверный луа.
sutra
Я попробовал и даже простейшую функцию не смог сделать в Lua. Что-то не так с видимостью. А что не так пока не понимаю.
cirus
Цитата
Я попробовал и даже простейшую функцию не смог сделать в Lua.

Выкладывайте код, поправим.
Для примера:
Код
--lua
-- функция должна находится выше её вызова
function f(x, y)   -- принимает 2 параметра
    return x+y     -- возвращает сумму
end

local z=f(5, 6)    -- вызов функции
log (z)

sutra
Не смог реализовать goto как только не пробовал, даёт ошибку.

Такая и у меня работает. Мне нужно передать в неё переменную, там с ней выполняются действия и мне нужна модифицированная ПЕРЕМЕННАЯ. А точнее таблица.

То есть я должен передать в функцию таблицу.

Хотя и с обычной переменной ничего не получилось.

Надо типа такого, чего не работает.

--lua
function proba(a)
return a = 12
end
log "clear"
local zz = 5
local tt = proba(zz)
log(tt)

если без return то в основном теле будет nil
cirus
Цитата
Не смог реализовать goto

Лучше сразу забудьте про него.
Код
--lua
function proba(a)
    a = 12
    return a
end

log "clear"
local zz = 5
local tt = proba(zz)
log(tt)

Код
--lua
log "clear"  log "mode compact"
function f(arr2)
    for i=1, #arr2 do
        arr2[i]=arr2[i]*2     -- умножить все элементы на 2
    end
end

local arr={}
for i=1, 10 do     -- заполнить массив числами от 1 до 10
    arr[i]=i
end

log (table.concat(arr, " "))     -- содержимое массива
f(arr)    -- вызов функции
log (table.concat(arr, " "))     -- содержимое массива после вызова функции
sutra
Спасибо. То есть goto не работает??
cirus
Цитата
То есть goto не работает??

Нет. Он и не нужен.
В луа его вообще нет. Вроде как есть в луа 5.3.
sutra
Меня конечно учили в своё время, что goto использовать является минимум признаком дурного стиля, но иногда это сильно упрощает код.

Всё верно, именно Lua 3 я и смотрел.

Буду думать, если не смогу модифицировать скрипт без goto придётся отказаться от Lua.

Да, конечно можно без goto , но придётся городить огород с кучей while-ов код будет ужасно плохо читаемым. У меня goto использовался например для рестарта скрипта в случае отключения интернета, ну и ещё в 2-х критических случаях, придётся всё заключать в циклы и брейками прерывать скрипт.
DarkMaster
Цитата
Да, конечно можно без goto , но придётся городить огород с кучей while-ов код будет ужасно плохо читаемым. У меня goto использовался например для рестарта скрипта в случае отключения интернета, ну и ещё в 2-х критических случаях, придётся всё заключать в циклы и брейками прерывать скрипт.

Как правило подобные проблемы говорят о том, что изначально структура кода не очень хорошо продумана.
Цитата
Всё верно, именно Lua 3 я и смотрел.

У нас luajit - стабильный релиз которого соответсвует версии 5.1. Это форк с динамической компиляцией, который существенно шустрее в работе. Сейчас он, пожалуй, более распространен, чем оригинальный луа. Можно смело исользовать мануалы от 5.1.
sutra
А оператор continue в цикле while есть?
cirus
В луа нет continue.
sutra
Это очень нехорошо. Если честно, то я не понимаю. С одной стороны типа прогрессивная вещь, а с другой стороны вроде очевидных вещей нет. Придётся буквально весь код запихивать в функции, которые будут содержать куски кода без особой логики. Видимо придётся их так и называть blok01 .. blok77. А основное тело будет состоять из вызова этих кусков. Просто в моём случае десятки раз вызывается функция обработки ошибок и обработки возникших неадекватных ситуаций. Собственно там и были goto которые перенаправляли код на повторные действия. Так что придётся работать брейками и кусками с ретурнами.
DarkMaster
Код
while var > 1 do
    local result = check_some_params()
    if result then
        some_actions()
    end
end

данная конструкция позволит сделать логику аналогичную continue. Согласен, это немного неудобно, непривычно, тем не менее так писать можно и костылей получается избежать. Читаемость кода при этом вполне адекватная.
Цитата
Придётся буквально весь код запихивать в функции,

Он там и должен быть. Весь. Не в функциях у тебя может быть какая-то инициализация (подгрузка параметров из файла настроек, например, или массивов). Кроме этого у меня не в функции вот такая строчка:
main()
Т.е. вызов основной функции. Больше там ничего и не должно быть.
Цитата
Видимо придётся их так и называть blok01 .. blok77

А вот так делать не надо. Уверяю можно найти нормальное решение. smile.gif

Цитата
В луа нет continue.

5.3, но, в классическом 5.1 нет, ну и в luajit релизе тоже нет.
sutra
Спасибо Дарк. Но у меня так не получится. Допустим у меня проверка в 4-ом колене ветвления if . После проверки происходит дальнейшее выполнение кода в этом же ИФе. То есть проверить и по результатам что-то выполнить - это не требуется, а наоборот в обязательном порядке прекратить выполнение кода (ну глупо что-то выполнять если отключили интернет или сервер недоступен) и в данном примере идти почти в самое начало скрипта и крутить цикл пока не появится связь с сервером. Поэтому выход вижу только один всё пихать в функции. После проверки выполнять return из функции, а вот весь остальной код придётся запихивать в if. И таких ифов до конца всего кода будет ну с десяток точно.
sutra
Слишком сложный код. никакого линейного выполнения кода нет. Всё постоянно меняется, поэтому много проверок всяких. Управление конечно попытался упростить насколько смог. Всё управляется несколькими десятками файлов конфигурации. А файлами конфигурации управляет файл сценария. Хотя и сценарий тоже может изменяться по ходу скрипта. В итоге ну полная иллюзия, что играет живой человек. Игра выполняется хоть круглые сутки и нет повторения событий. Я только контролирую и занимаюсь не ерундой, а пытаюсь ещё и чем-то полезным заниматься.

По логике у тебя тоже всё правильно. Собственно так примерно и будет, только эти вайлы будут как снежный ком. И формат уедет настолько сильно вправо, что код будет плохо читаемым. Буду как-то сочетать. Что-то сделаю локальным распихав по функциям, что-то придётся умещать в одном блоке кода.
sutra
Грубо говоря есть определённое количество событий, которые могут вызываться один из другого. И простыми вызовами функций я могу получить неконтролируемую рекурсию. Поэтому в Пилотовском коде я и использовал goto. Тут придётся крепко репу почесать, чтобы было красиво и эффективно.
sutra
local n = "123.txt"
local f = io.open(n, "r")

Не смог открыть файл при помощи переменной. Перепробовал всё что знал - результат нуль. Просветите меня пожалуйста. Что-то мне подсказывает, что намаюсь я ещё. И большая просьба в примерах показывайте работу с переменными, поскольку у меня всё только через переменные.
DarkMaster
Цитата
Не смог открыть файл при помощи переменной

А лежит он где? Рядом с ехе пилота? Пилот перезапускали?

По поводу break можно делать вызов функции через assert и внутри функции потом вызывать ошибку, это приведет к ее завершению.
Тем не менее не забывайте про return. При раскидывании по функциям он зачастую полноценно заменяет break.
sutra
Обычным текстом открывает [[123.txt]]

Минутку, теперь и обычным не открывает, сейчас гляну.

Доигрался, вообще Пилот завис.
cirus
Цитата
вообще Пилот завис.

Скорее всего были какие-то ошибки.
Код
--lua
local n = "123.txt"   -- файл лежит рядом с exe пилота
local f = io.open(n, "r")

log "clear" log "mode compact"
if f then   -- если файл открылся
    log(f:read())  -- первая строка из файла
else
    log ("Файл не открылся")
end
sutra
Перегрузил Пилот через прибивалку, всё заработало, спасибо Дарк.

Видимо крепко я накуралесил, да ещё и игра играет в параллельном скрипте.

И тебе cirus тоже спасибо.


Теперь буду знать, что иногда надо пнуть ногой по баллону.
sutra
Понял причину, забыл поставить двойной слеш при указании полного пути.
DarkMaster
Цитата
Понял причину, забыл поставить двойной слеш при указании полного пути.

Не редактируйте код перед тем, как выложить. Ну либо тестируйте перед тем, как выкладывать =)
Чтобы не писать двойные слэши просто ставьте вместо кавычек [[текст]]
sutra
Я не редактировал. Просто сначала использовал полный путь. Потом пути были без слешей и не работало только с переменной, потом вообще не работало, причину Вы мне подсказали (перегрузить).

Я понял почему изначально не работало.
DarkMaster
Цитата
причину Вы мне подсказали (перегрузить).

это фиксанули буквально пару дней назад
sutra
Добрался до файндов. и как и думал ничего у меня не получилось. Не могли бы кинуть реальный пример findimage. Хотел потестировать косяк. Параметры интересуют когда есть адрес загруженной картинки и адрес области экрана. И думаю, что и с findcolor тоже сам не врублюсь, поэтому и его примерчик тоже неплохо бы самому поглядеть.
sutra
И конечно примеры на lua "надёжно" зарыты. Через спецстраницы, через страницы-сироты. Но и там есть далеко не всё, а если бы было, то дилетанты типа меня не донимали бы элементарными вопросами.
cirus
Цитата
реальный пример findimage

Код
--lua
local a, c = findimage(0, 0, 1920, 1080, {[[C:\Users\abc\Desktop\image.bmp]]}, 2)
-- a - это массив, c - количество картинок или точность поиска, если картинка одна
if a then
    move(a[1][1], a[1][2])
end

Цитата
findcolor

Вроде как не доделан. Поэтому костыль. Передавать все параметры в виде строки.
Код
--lua
local a = findcolor("0, 0, 1920, 1080, 1, 1, 7223552, 2")
hint (a)

Цитата
примеры на lua "надёжно" зарыты

http://uopilot.tati.pro/index.php?title=Список_функций_(Lua)
Только то, что работает в 2.40 (релиз, а не бета).

sutra
Спасибо.
Цитата
Только то, что работает в 2.40 (релиз, а не бета).

Так я и говорю надёжно спрятано. Я случайно туда попал. Надо бы прямую ссылочку сделать.
cirus
Цитата
Надо бы прямую ссылочку сделать.

Когда выйдет полноценная версия пилота на луа, тогда и будет дописана (где-то исправлена) справка и дана ссылка.
sutra
--lua
log "clear" log "mode compact"
addressl, widthl, heightl, lengthl = loadimage ([[C:\TMP\Original.bmp]])
log(widthl, heightl, lengthl)
addressg, widthg, heightg, lengthg = getimage (470, 924, 500, 933)
log(widthg, heightg, lengthg)
local a, c = FindImage(0, 0, 1920, 1080, addressl, addressg, 100)
deleteimage (addressl)
deleteimage (addressg)

Не работает, дает ошибку.

Сорри, забыл на строчные переделать. Спасибо.
cirus
Да, в findimage есть баг, если искать на скрине от координат 0 0, то нормально ищет. Иначе не находит.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.
Русская версия Invision Power Board © 2001-2024 Invision Power Services, Inc.