Перейти к содержимому

ECS

Гуру
  • Публикации

    533
  • Зарегистрирован

  • Посещение

  • Победитель дней

    203

Сообщения, опубликованные пользователем ECS


  1. 3 часа назад, rootmaster сказал:

    раньше использовал os.getenv("_") но затем окозалось что в rc это не катит(моя модификация rc делает os.setenv("_", path) а стандартная нет)

    да и на бибилтеки тоже не катит хотя и библиотеки могут состоять из нескольких файлов использовать это не реально из за этого ограницения

    Ты используешь getenv не по назначению, отсюда и проблемы. При инициализации библиотек путь к ним не записывается в env, при запуске файлов вручную через filesystem proxy тоже, при чтении rc.d тоже. Это скорее прикладная софтверная фича OpenOS, которую удобно юзать при работе с shell для получения быстрых путей к переменным окружения, и она вовсе не является частью API файловой системы, как может показаться. Поэтому при исполнении файла через shell.execute env будет обновлен, а при исполнении через dofile/loadfile - нет

     

    3 часа назад, rootmaster сказал:

    так как быть? есть ли "легальный" способ узнать где лежит скрипт?

    OpenOS:

    shell.resolve(process.info().path)

    MineOS:

    system.getCurrentScript()

    Что угодно, включая EEPROM:

    local function getCurrentScriptPath()
      local info
    
      for runLevel = 0, math.huge do
        info = debug.getinfo(runLevel)
    
        if info then
          if info.what == "main" then
            return info.source:sub(2, -1)
          end
        else
          error("Failed to get debug info for runlevel " .. runLevel)
        end
      end
    end

     

    • Нравится 4

  2. 1 час назад, rootmaster сказал:

    Например, можно подменить функцию load, чтобы она не только компилировала текстовый код Lua в байткод

    Загрузка байткода недоступна по дефолту без правки конфига мода, проверка зашита в machine.lua. Сомневаюсь, что админы публичных серверов захотят включить эту фичу, пускай даже ради запуска знаменитых безопасных софтин rootmaster'а

    • Нравится 1
    • Одобряю 1
    • В шоке 1
    • Грусть 2

  3. 22 часа назад, kaka888 сказал:

    Наткнулся на печальные баги

    Печальные баги - это, видимо, GUI.menu(1, 1, ...) вместо GUI.menu(1, 2, ...)? Ты же сам расположил менюху на Y = 1, где уже чиллит титловая строка. Разумеется, менюха ее перекрыла

     

    На всякий случай уточню, что гуйка работает с заранее известными координатами и размерами всех объектов, ничего не рассчитывая автоматически без ведома кодера - это не WPF/UWP с адаптивной версткой, т.к. ресурсы компов люто лимитированы. Исключения, конечно, есть в виде всяких GUI.layout или GUI.table, но это капля в море. Поэтому любая смена позиции или ресайз виджетов требует ручной обработки

     

    А, и еще кое-что: GUI.titledWindow tabbedWindow и иже с ними - просто шаблоны, которые создаются буквально в 10 строчек кода на основе базового объекта окна GUI.window, но с учётом твоих личных нужд. В них попросту заранее выставлены нужные координаты и подогнаны размеры, ничего более

    • Спасибо 1

  4. 2 часа назад, Krutoy сказал:

    Как? Я бы рад, но как?

    Может сделать какую то внутреннюю подпрограмму, которая будет расшифровывать все алиасы на месте? Типа, выводить куданибудь в output дерево расшифровки?

    Под мышами я имел в виду нужду в хаотичном скроллинге документации :p

    Было бы клево иметь всю инфу в маркдауновой доке без нужды бегать к комментам в сырцах и обратно, я об этом

     

    2 часа назад, Krutoy сказал:

    Именно в этом шаге ?{<a>==nil} эквивалентно if VARS['a'] == nil, потому что иначе не нужны были бы <>.

    Занятно, а что будет означать конструкция ?{a==nil}? Такая запись вообще валидна или же <> требуется в обязательном порядке? В доке сказано: "You can use <> inside lua code to execute program between <> as commands", из чего я сделал вывод, что <> выполняет некую программу. Но <a> выглядит как переменная, а не программа. Что такое program? Это просто собирательный термин или там действительно какие-то программы поддерживаются? Поясни, пожалуйста

     

    2 часа назад, Krutoy сказал:

    Может, проблема в том, что в языке перемешан синтаксис языка \ алиасы и переменные? Может в таком случае, нужно что бы, например

    • Весь синтаксис только на не-буквеных символах @#$

    Наверное, это было бы правильно, но вкусовщина такая вкусовщина. Имхо, главное, чтобы тебе было удобно и понятно, а невежественный плебс в любом случае подстроится)0

     

    2 часа назад, Krutoy сказал:

    А может подключить юникод и сделать что то такое. Правда, при больших программах это все равно растянется на страницы

    gW79kp4.png

    Выглядит шикарно, особенно если бы это визуализировалось в некой скролл-зоне экрана, в то время сам скрипт писался бы в инпут-панели. Но так и до визуального кодинга недалеко, а это тревожный звоночек шизофрении!

    • Нравится 1

  5. Респект за соулс от мира опенкомпов! Вики очень достойная, но логику работы сложно осилить даже на примере \0ZZ, учитывая необходимость перма-скроллинга то по списку алиасов в сырце, то по списку операторов в самой вики. Да и без поиска тут не обойтись. Пожалей наши мыши! Интереса ради я решил вникнуть в первый пример:

     

    1) Читаю команду \0, понимаю, что это useDown(), вопросов нет

    2) Читаю команду Z, осознаю, что это алиас на %`~F'ta'N` ?M*'F?M`FN``RRMN`', приступаю к расшифровке

    3) Читаю команду %, смекаю, это ещё один алиас на ?{<a>==nil}, отвечающий за проверку истинности результата выполнения некоего Lua-выражения. А какого?

    4) Судорожно ищу, что такое <a>, и вроде бы даже нахожу нужную секцию:

     

    image.png.dbdbb62063cd98165419b1cd5a0c4128.png

     

    То есть, согласно вики, a - это программа, которая... что? Которая названа a

    5) Пытаюсь найти в сырцах некую программу с названием а, но тщетно

    6) Допускаю, что, скорее всего, a - это переменная, которая пока еще не определена в текущем окружении. Вроде бы. То есть, наверное, выражение ?{<a>==nil} эквивалентно if a == nil. Или a - это все же программа? Ладно, хрен с ним

    7) Возвращаюсь к пункту 2, читаю символ `, вновь обращаюсь к сырцам. В сырцах не нахожу. Видимо, оно в вики? Скроллю вики, нахожу искомое:

     

    image.png.3733af878e62513d0f26c76e91134432.png

     

    Так, падаж-ж-жи! Интересно, зачем столько вариантов... для возможности использовать внутри строк другие кавычки, когда требуется? Если да, то это хорошо, хотя классический эскейпинг через \" был бы правильнее, т.к., например, я не смогу заюзать все 3 варианта кавычек в строке "hello `sunny`, you are 'so shiny' and "beautiful"". Или все же смогу? Энивей иду вперед

    8) Натыкаюсь на символ ~, определяющий алиас на подпрограмму ~F'ta'. Судя по вики, у нас теперь определена некая подпрограмма F, выполняющая команды ta

    9) Ищу, что такое t и a. Сырцы говорят, что t отвечает за robot.turn(clockwise). Вероятно, переменная а и отвечает за поворот по часовой стрелке? Вроде бы понятно...

    10) Читаю новый неизвестный символ N. Хоспади, только не алиас... МАМОЧКИ, ЭТО ОН. Ищу в сырцах содержимое, нахожу логику инверсии перменной a -a{not <a>}... не-е-е, все, убейте меня. Софтина хорошая, идея клёвая, но нервная система у меня одна хд

    • Нравится 2
    • Спасибо 1
    • Ха-ха 3

  6. 1 час назад, Fingercomp сказал:

    Всё в Lua сделать можно, я даже статью про это писал. Там про table.pack в основном, но хочу вдобавок напомнить здесь про функцию select, которая умеет как число переданных аргументов возвратить, так и вытащить нужный:

    Да, я поначалу думал заюзать pack/select, но в нашем случае это ломает кейс без таблицы дефолтных значений:

    f = L(function(a, b, c) return 'a:' .. tostring(a) .. ' b:' .. tostring(b) .. ' c:' .. tostring(c) end)
    f(1)(2)(3)

    Здесь невозможно определить, сколько всего аргументов принимает функция f(a, b, c), а затем выполнить её на этапе (3). Хотя, конечно, мы могли бы ограничиться условием, что таблица дефолтных значений требуется всегда, что позволило бы на основании ее размера судить о кол-ве аргументов функции f. Но это уже вопрос к @Krutoy

     

    Зато через pack можно решить проблему с nil в кач-ве последнего аргумента любого из замыканий в цепочке:

     

    Скрытый текст
    
    local function L(f, ...)
      local defaults = table.pack(...)
    
      if defaults.n == 0 then
        return f
      end
    
      local fArgIndex = 1
      local fArgs = {}
    
      local function appendNextArg()
        if fArgIndex > defaults.n then
          return f(table.unpack(fArgs, 1, defaults.n))
        end
    
        return function(...)
          local fArgsParts = table.pack(...)
    
          if fArgsParts.n == 0 then
            fArgs[fArgIndex] = defaults and defaults[fArgIndex] or nil
            fArgIndex = fArgIndex + 1
          else
            for i = 1, fArgsParts.n do
              fArgs[fArgIndex] = fArgsParts[i] or (defaults and defaults[fArgIndex] or nil)
              fArgIndex = fArgIndex + 1
            end
          end
              
          return appendNextArg()
        end
      end
    
      return appendNextArg()
    end
    
    local function test(name, expectedResult, f)
      local result = f()
    
      print("[" .. (result == expectedResult and "Passed" or "Failed") .. "] " .. name)
      print("Expected: " .. tostring(expectedResult))
      print("Got: " .. tostring(result))
      print()
    end
    
    test(
      "test 1: no defaults, no result",
      nil,
      function()
        f = L(function() print('success!') end)
        f()
      end
    )
    
    test(
      "test 2: no nils in defaults",
      "a:a b:e c:c",
      function()
        f = L(
          function(a, b, c)
            return 'a:' .. tostring(a) .. ' b:' .. tostring(b) .. ' c:' .. tostring(c)
          end,
          'a', 'b', 'c'
        )
    
        return f()('e')()
      end
    )
    
    test(
      "test 3: nil at defaults middle",
      "a:a b:nil c:c",
      function()
        f = L(
          function(a, b, c)
            return 'a:' .. tostring(a) .. ' b:' .. tostring(b) .. ' c:' .. tostring(c)
          end,
          'a', nil, 'c'
        )
    
        return f()()()
      end
    )
    
    test(
      "test 4: nil at defaults end",
      "a:1 b:b c:3",
      function()
        f = L(
          function(a, b, c)
            return 'a:' .. tostring(a) .. ' b:' .. tostring(b) .. ' c:' .. tostring(c)
          end,
          'a', 'b', nil
        )
    
        return f(1)()(3)
      end
    )
    
    test(
      "test 5: multiple returns, nil at defaults end",
      "a:a b:2 c:nil",
      function()
        f = L(
          function(a, b, c)
            return 'a:' .. tostring(a) .. ' b:' .. tostring(b) .. ' c:' .. tostring(c)
          end,
          'a', 'b', nil
        )
    
        return f(nil, 2)()
      end
    )
    
    test(
      "test 6: multiple returns with nil at end",
      "a:2 b:b c:nil",
      function()
        f = L(
          function(a, b, c)
            return 'a:' .. tostring(a) .. ' b:' .. tostring(b) .. ' c:' .. tostring(c)
          end,
          'a', 'b', nil
        )
    
        return f(2, nil)()
      end
    )

    image.png.4aff784f31eb3f2aabc088d2b063aa3e.png

    • Нравится 2

  7. 2 часа назад, Krutoy сказал:

    Хотя возможно, в Lua вообще нельзя посчитать количество значений из ..., если они кончаются на nil

    Хе-хе, вот поэтому без внятного ТЗ результат ХЗ: не было ж ни слова про nil'овые дефолты. Вообще вариант у нас лишь один - всегда указывать размер таблицы defaults вручную, если в ней присутствует nil в конце, т.к. lua попросту не воспринимает его ни в случае вараргов, ни при инициализации таблицы напрямую:

    print(#{nil, "b", "c"}) -- 3
    print(#{"a", nil, "c"}) -- 3
    print(#{"a", "b", nil}) -- 2
    print(#{[1] = "a", [2] = "b", [3] = nil}) -- 2

    Поэтому только ручками, видимо:

    local function L(f, fArgsCount, defaults)
      fArgsCount = fArgsCount or 1
    
      if fArgsCount <= 1 then
        return f
      end
    
      local fArgIndex = 1
      local fArgs = {}
    
      local function appendNextArg()
        if fArgIndex > fArgsCount then
          return f(table.unpack(fArgs, 1, fArgsCount))
        end
    
        return function(...)
          local fArgsParts = {...}
    
          if #fArgsParts == 0 then
            fArgs[fArgIndex] = defaults and defaults[fArgIndex] or nil
            fArgIndex = fArgIndex + 1
          else
            for i = 1, #fArgsParts do
              fArgs[fArgIndex] = fArgsParts[i] or (defaults and defaults[fArgIndex] or nil)
              fArgIndex = fArgIndex + 1
            end
          end
              
          return appendNextArg()
        end
      end
    
      return appendNextArg()
    end
    
    local function test(name, expectedResult, f)
      local result = f()
    
      print("[" .. (result == expectedResult and "Passed" or "Failed") .. "] " .. name .. ":")
      print("Expected: " .. tostring(expectedResult))
      print("Got: " .. tostring(result))
      print()
    end
    
    test(
      "test 1: no defaults, no result",
      nil,
      function()
        f = L(function() print('succes!') end)
        f()
      end
    )
    
    test(
      "test 2: no defaults, every argument is passed directly",
      "a:1 b:2 c:3",
      function()
        f = L(
          function(a, b, c) return 'a:' .. tostring(a) .. ' b:' .. tostring(b) .. ' c:' .. tostring(c) end,
          3
        )
    
        return f(1)(2)(3)
      end
    )
    
    test(
      "test 3: no nils in defaults",
      "a:a b:e c:c",
      function()
        f = L(
          function(a, b, c) return 'a:' .. tostring(a) .. ' b:' .. tostring(b) .. ' c:' .. tostring(c) end,
          3,
          {'a', 'b', 'c'}
        )
    
        return f()('e')()
      end
    )
    
    test(
      "test 4: nil at defaults middle",
      "a:a b:nil c:c",
      function()
        f = L(
          function(a, b, c)
            return 'a:' .. tostring(a) .. ' b:' .. tostring(b) .. ' c:' .. tostring(c)
          end,
          3,
          {'a', nil, 'c'}
        )
    
        return f()()()
      end
    )
    
    test(
      "test 5: nil at defaults end",
      "a:1 b:b c:3",
      function()
        f = L(
           function(a, b, c)
            return 'a:' .. tostring(a) .. ' b:' .. tostring(b) .. ' c:' .. tostring(c)
          end,
          3,
          {'a', 'b', nil}
        )
    
        return f(1)()(3)
      end
    )
    
    test(
      "test 6: multiple returns, nil at defaults end",
      "a:a b:2 c:nil",
      function()
        f = L(
           function(a, b, c)
            return 'a:' .. tostring(a) .. ' b:' .. tostring(b) .. ' c:' .. tostring(c)
          end,
          3,
          {'a', 'b', nil}
        )
    
        return f(nil, 2)()
      end
    )

    image.png.25fa99c7c9d700c41fd9cb55514a46e2.png

     

    Фичу мульти-ретурна я сделал, фигня вопрос, однако если какая-то функция из цепочки вернет результат с nil в конце - система сдохнет. Тут уж либо опять вручную указывать кол-во аргументов, либо забить болт:

    test(
      "test 7: multiple returns with nil at end",
      "a:a b:2 c:nil",
      function()
        f = L(
           function(a, b, c)
            return 'a:' .. tostring(a) .. ' b:' .. tostring(b) .. ' c:' .. tostring(c)
          end,
          3,
          {'a', 'b', 'c'}
        )
    
        return f(2, nil)()
      end
    )

    image.png.f201dc29b62bdfe5b4942b25c7c18017.png

    • Нравится 2

  8. local function L(f, ...)
      local defaults = {...}
    
      if #defaults == 0 then
        return f
      end
    
      local defaultIndex = 1
      local fArgs = {}
    
      local function appendNextArg()
        if defaultIndex > #defaults then
          return f(table.unpack(fArgs))
        end
    
        return function(fArg)
          table.insert(fArgs, fArg or defaults[defaultIndex])
          defaultIndex = defaultIndex + 1
    
          return appendNextArg()
        end
      end
    
      return appendNextArg()
    end
    
    f = L(function(a, b, c) return a .. b .. c end, 'a', 'b', 'c')
    print(f()('e')()) -- Нужно что бы вывело "aec"
    
    f = L(function() print('succes!') end)
    f() -- Должно выводить "succes!"

    image.png.70769e92359f13ee1a8ee0bbe1b6fe96.png

     

    В общем, не уверен, что я правильно понял задачу, но ТЗ из второго примера результат соответствует

    • Нравится 1

  9. 1 час назад, Krutoy сказал:

    Такая функция работает при значениях n>=1, но не работает с n=0

    
    f = L(print, 2)
    f(1)(2) -- печатает: 1 2
    
    f = L(print, 0)
    f() -- выдает функцию print

    Если запустить этот пример, то f() не выдает ничего, хотя сказано обратное. Пруф:

     

    image.png.263ecb04670665da57312fce0aeece49.png

     

    image.png.ce69c01c526c01881e0985007d05efff.png

     

    Поясни, пожалуйста, должна ли функция L по ТЗ выдавать функцию print, если n = 0, или же наоборот не должна

    • Нравится 1

  10. Этот параметр сообщает экранному буферу, что нужно отобразить  не только изменившиеся с последней отрисовки пиксели, а вообще все сразу. Обычно эта необходимость возникает при запуске скриптов, работающих с GPU напрямую в обход концепции экранного буфера. То есть в случае майноси практически никогда. Разве что для каких-нибудь старых игр или скринсейверов фича может быть востребованной...

     

    В доке по workspace он указан, хотя и без пояснений. Могу добавить инфу на всякий, если нужно:

     

    image.png.1dda246b8f4ed63840b2616fd6abb322.png

    • Нравится 1

  11. 1 час назад, kaka888 сказал:

    Я тут чекнул твою тему про библиотеку, но там нет инструкции по использованию. Где её можно найти?

    Пардон, старая тема, забыл обновить ссылку:

    https://github.com/IgorTimofeev/GUI/blob/0fadb161469d404d477dd9babfdc9a5aa42ff203/README.md


  12. 47 минут назад, kaka888 сказал:

    А если взять вариант либы для MineOS, но юзать её в OpenOS, то она будет работать так же хорошо или как? Ну типа если я все зависимости типа advancedLua, doubleBuffering и т.д. тоже загружу.

    Хех, она не будет работать вообще никак, т.к. у нее одна зависимость: MineOS целиком.

     

    Если интересны подробности, то вот лонгстори: изначальная версия гуи-либы писалась как простая основа для графической оболочки поверх OpenOS, и "из коробки" она поддерживала лишь наиболее привычные виджеты типа кнопок/картинок/слайдеров (кстати, по ссылке выше как раз та самая версия). MineOS была скорее технодемкой возможностей гуишки. Однако время шло, появилась потребность в перетаскиваемых окошках, файловых модальных диалогах, селекторах цвета и т.п. Также требовалось все больше и больше узкопрофильного функционала - например, почанковое скачивание файлов с обработчиками данных или побитовые приколюхи типа file:readBytesAsNumber(count, isLittleEndian). Все эти мелочи использовались довольно часто как в системных либах по работе с пикчами, так и в прикладном софте типа MIDI-парсера или мини-игр. Изначально я оформлял их в виде дополнительных библиотек типа AdvancedLua или Web, однако просто устал плодить архитектурный говнокод. Контрольным выстрелом оказалась обнова OpenOS (1.6, если не ошибаюсь), где поменялись API process/event, что убило инсталлер MineOS на новых версиях мода. В итоге я решил, что быстрее будет написать чистую ОС с интегрированной UI'шной бизнес-логикой, чем пытаться адаптироваться под существующую

     

    Собственно, вот, интеграция вышла по самые помидоры. Глобальный минус один - либы настолько глубоко засели друг в друге, что проще писать под MineOS, чем пытаться их выдрать и использовать в другой ОС. На всякий случай я сохранил старые версии гуишки в виде легаси - но никаких новых фич и фиксов, конечно, там уже не будет

    • Нравится 1
    • Спасибо 1

  13. 1 час назад, rootmaster сказал:

    я сам хз че норм способом, типо совместимо со всем софтом вот что значит норм способом

    Не-а, из коробки "норм способа" нет. Зато ты можешь написать либу, инкапсулирующую все физические GPU и предоставляющую фейковую GPU, чтобы в автоматическом режиме биндиться к мульти-мониторной конструкции и выводить данные за пределами одного моника. Тогда весь софт действительно будет работать "нормально", если только он не залочен под какое-то константное разрешение. Вопрос лишь в производительности, которой не станет)0


  14. 6 часов назад, rootmaster сказал:

    расталку картинку обезяны? типо я тупой? хреновый програмист? сделал чтото не так?

    Это я себя ассоциирую с невежественной макакой, не осознающей всю гениальность хода творца, лишающего юзера возможности выбирать архитектуру пеки

     

    image.png.9cef08c24e6f2c6ad5f3c7aeaaba8d6d.png

     

    Макака в своих влажных фантазиях уверена, что побитовые операторы имеют эквивалент в виде bit32, а string.unpack заменяется на цикл, формирующий число в big endian без привязки к архитектуре... но макака слишком глупа! Макака извиняется

    • Ха-ха 2

  15. 4 часа назад, rootmaster сказал:

    метод computer.setArchitecture удален так как если переключить архитектуру на lua 5.2 комп перестанет работать а робота и вовсе придеться разбирать

    image.png.287b244c8d5c28ff0a710a8a7342a557.png

     

    3 часа назад, rootmaster сказал:

    все еше нопонятно поч бы автору не засунуть код eeprom в ж@пу папку open computers

    Тебе в любом случае придется работать с тем, что дал ненавистный автор-угнетатель. Что толку возмущаться? Добавь простенькое XOR-хеширование с солью хотя бы, чтобы не хранить пасс в открытом виде

    • Нравится 2

  16. 1 час назад, rootmaster сказал:

    ДО подключения к экрану если gpu 3 будет у экрану 1 подключена то maxDepth будет 1

    Но... ты же сам хотел узнать уровень до подключения к экрану, а теперь ругаешься, что после подключения метод становится невалидным... 

     

    image.png.205b0ef446313523c259a582920b7586.png

     

    12 часа назад, eu_tomat сказал:

    Также computer.getDeviceInfo() возвращает таблицу с параметрами всех подключенных устройств. Уровень можно узнать косвенно, ориентируясь, например, по параметру capacity.

    Еще можно по параметру width. По названию не скажешь, но он как раз олицетворяет предельную глубину цвета для видеокарты. Пример на компьютере с 3 независимыми GPU всех 3 тиров и APU 2 тира, привязанного к экрану 1 тира:

     

    image.png.de99d1639af9cb87598ccb25f01289f7.png

     

     

    • Нравится 1

  17. 16 часов назад, ItsMakar сказал:

    в openos есть библиотека component (которой нет в файлах ос) но мне нужно получить код биоса из своей ос но компонента eeprom не существует

    В дополнение к инфе от @Bs0Dd поясню, что если ты кодишь под биос, то работаешь на самом низком уровне, доступном в моде. Следовательно, фича component.имяКомпонента.метод(...) из OpenOS доступна не будет, т.к. она добавляется на более позднем этапе во время инициализации самой ОС:

     

    https://github.com/MightyPirates/OpenComputers/blob/af2db43c53b9690fceabfb813987572bf2258db5/src/main/resources/assets/opencomputers/loot/openos/boot/04_component.lua#L10-L32

     

    Поэтому для обращения к компоненту из-под биоса есть 2 варианта:

    -- Чтобы обратиться к компоненту, нам нужно знать его уникальный адрес
    -- Список адресов всех доступных компонентов с указанным типом можно получить через метод component.list("имя")
    -- В одном компьтере может быть установлено несколько компонентов одного типа, поэтому метод list 
    -- возвращает функцию-итератор, при каждом вызове которой возвращается адрес следующего компонента
    local gpuIterator = component.list("gpu")
    local gpu1Address = gpuIterator()
    local gpu2Address = gpuIterator()
    
    -- Конструкцию выше можно скомпоновать в цикл
    for address in component.list("gpu") do
      -- Делаем что угодно с каждой имеющейся GPU
    end
    
    -- В случае EEPROM все несколько проще. Поскольку в 1-ом компьютере может быть только 1 EEPROM, то нам
    -- следует вызвать функцию-итератор хотя бы 1 раз, чтобы получить адрес 1-го (и единственного) EEPROM
    local eepromAddress = component.list("eeprom")()
    
    -- Раз адрес компонента EEPROM нам известен, теперь мы можем обратиться к нему и вызвать
    -- какой-нибудь метод. Сделать это можно двумя путями. Первый более линейный, его следует
    -- использовать для каких-то разовых операций "в лоб":
    local data = component.invoke(eepromAddress, "getData")
    component.invoke(eepromAddress, "setData", "sample text")
    
    -- Второй более универсальный, и позволяет создать так называемый прокси компонента, то есть
    -- таблицу в памяти, содержащую все доступные методы компонента. Разумеется, он расходует больше ОЗУ,
    -- однако работать с ним в разы удобнее:
    local eepromProxy = component.proxy(eepromAddress)
    local data = eepromProxy.getData()
    eepromProxy.setData("sample text")

    Кроме того, "чистые" компьютеры без ОС имеют глобальные переменные component, computer и unicode, которые всегда доступны в биосе, и в случае OpenOS "вырезаются", становясь частью глобальной библиотеки package:

     

    https://github.com/MightyPirates/OpenComputers/blob/af2db43c53b9690fceabfb813987572bf2258db5/src/main/resources/assets/opencomputers/loot/openos/lib/core/boot.lua#L94-L112

     

    По этой причине в биосе ты должен обращаться к глобальной библиотеке component, а в OpenOS для этого уже требуется конструкция require("component"). Почему авторы так поступили? Да хрен знает, их ОС - их правила. Но путаницу это вносит знатную

    • Нравится 1

  18. 12 часа назад, eu_tomat сказал:

    А разве нам требуется что-то кроме этого? Во взрослых средах имеются более адекватные источники энтропии. А в среде OpenComputers приходится импровизировать

    Нет, для мода, конечно, не требуется. Я на всякий случай подчеркнул этот момент - вдруг какая-то заблудшая душа будет искать ответ и не поймет, какого ж черта os.clock() - os.clock() может выдавать что-то, отличное от нуля. И будет плакать...

     

    12 часа назад, eu_tomat сказал:

    Достаточно было бы и math.pow(2,52), чтобы перевести в целую часть все разряды мантиссы

    А, вон какая логика была. Занятно, спасибо


  19. 2 часа назад, astral17 сказал:

    Только они чутка бракованные

    Черт, стыдно стало, поправил диапазон :d

     

    2 часа назад, astral17 сказал:

     0 это число длины 1, а должна ли функция его генерировать?

    А тут начинается le classique, то есть выбор между производительностью и охватом всех вероятных условий и ошибок. По ТЗ, формируемому названием функции, - да, должна, а ещё ей по-хорошему не хватает парочки валидаций.

     

    Начнем с того, что количество цифр в генерируемом числе не должно быть < 1, ибо таких чисел не существует. Также оно не может быть больше 18 для 64-битного бинарника Lua, т.к. именно 18 является максимально допустимой степенью показательной функции f(x) = 10 ^ x, значение которой не превышает рабочий диапазон. Пруф:

    math.log(math.maxinteger, 10)
    > 18.964889726831
    
    math.random(10 ^ 18)
    > 902800305889519796
    
    math.random(10 ^ 19)
    > stdin:1: bad argument #1 to 'random' (number has no integer representation)

    И наконец, можно добавить поддержку генерации нуля в крайне странном случае, когда кто-то решил воспользоваться нашей функцией вместо math.random(0, 9):

    local function fixedLengthRandom(digits)
      assert(digits >= 1 and digits <= 18, "Digit count is out of range [1; 18]")
      
      if digits == 1 then
        return math.random(0, 9)
      end
      
      digits = 10 ^ (digits - 1)
      
      return math.random(digits, digits * 10 - 1)
    end

    Это что касается решения "по бумажкам в лабораторных условиях". На практике же оно на фиг никому не упало, и куда предпочтительнее был бы производительный вариант без избыточных проверок, которые имеют свой бюджет вызовов в опенкомпах. Так что же правильнее? Наверное, то, что лично ты считаешь правильным для конкретной ситуации


  20. 12 часа назад, eu_tomat сказал:

    math.randomseed( -1e18*(os.clock()-os.clock()) )

    Идея с clock хорошая, но будет работать только в рамках мода из-за хука на вызовы функций в machine.lua. А как ты выбрал магическую константу? Это явно не math.mininteger/maxinteger, а что-то чернокнижное

    • Нравится 1
×
×
  • Создать...