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

Fingercomp

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

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

  • Посещение

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

    283

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


  1. Просто Фингер видел не один десяток "программ начинающих программистов", где с оформлением всё жуть-жуть. Это и понятно. И в других прогах сильно не парятся над этим. У меня же всё опрятно, ровно, конфиги есть и т. д. Зайди в соседний топик и глянь, как выглядит. А если не нравится — смени цвета.

    • Нравится 2

  2. Короче, заказ можно считать выполненным: прогу я написал при непосредственном общении с реквестером. Моё решение не требует дополнительных модов и очень удобно в использовании. И выглядит офигенно.


  3. Хей! У меня тут очень крутой пример для либы charts появился. Либа мне нравится невероятно, потому с таким же усердием я решил что-нибудь наваять. Тем более, что @mercurial как раз публиковал заказ на такую прогу.

     

     

    G2ATMdU.png

     

    Установка

    1. Качаем hpm: http://computercraft.ru/topic/1855-repozitorii-programm-hel/?do=findComment&comment=27287
    2. Ставим: hpm install railtank.

    Использование

    К подопытной цистерне из Рейла ставим адаптер, в него пихаем Tank Controller Upgrade (апгрейд контроллера цистерн, что-то типа этого), а потом проводами цепляем к компу. Можно порыться в конфиге /etc/railtank.cfg: настроить количество цистерн для показа, интервал обновления графиков, выставить свои цвета интерфейсу. А потом запускаем прогу: railtank. Вуаля.

     

    Чтобы выйти, нажмите Ctrl + C (без альта!).

     

    Программа автоматически примониторит ещё цистерну при её подключении и уберёт из мониторинга при отключении. Так что не парьтесь :P

     


     

    Ну и ссылка на пакет: https://hel.fomalhaut.me/#packages/railtank

    • Нравится 7

  4. да нет, версии последнии, можешь пожалуйста видео записать как ты подключаешь?)

    Подключать просто надо к Valv'ам, в имени конмпонента же написано. Ставить танк, вниз цепляешь валв, к нему адаптер и кабелями к компу.


  5.  

     

    C0nTFmj.png


    XFQ0Lnt.png


    SCnOt85.png

     

     

     

    Вот такая красота теперь возможна благодаря моей новой либе charts. Пока что имеем гистограммчики и прогрессбары. У обоих точность до 1/8 символа.

     

    Документация

     

    Контейнер

    Сидит в charts.Container. Его задача: хранить базовые параметры типа цвета по умолчанию, самого графика. Собственно, это абстракция над объектами графика.

     

    Атрибуты

    • Container.gpu — прокси видеокарты, на которой рисовать график.
    • Container.fg — цвет "текста" по умолчанию.
    • Container.bg — цвет фона по умолчанию.
    • Container.x и Container.y — это координаты левого верхнего угла контейнера.
    • Container.payloadX, Container.payloadY — координаты графика относительно левого верхнего угла контейнера. Пока лучше не трогать, потом что-нибудь с ними придумаю.
    • Container.width, Container.height — ширина и высота, соответственно, графика.
    • Container.payload — сам объект графика.

    Методы

    • Container:draw() — рисует график.

    Так как сам по себе бесполезен, пример кода здесь не нужен.

     

    Стороны

    Спит и живёт в charts.sides. Это таблица, которая содержит четыре значения: sides.TOP, sides.BOTTOM, sides.LEFT, sides.RIGHT. Требуется для настройки графиков.

     

    Гистограмма

    Очень прикольная вещь. Рисует вертикальные столбцы шириной в 1 символ с высотой в соответствии с числовым значением из таблицы.

     

    Атрибуты

    • Histogram.values — таблица значений гистограммы.
    • Histogram.align — указывает, как брать значения гистограммы. Если здесь выставить sides.LEFT, то будут браться первые w (по ширине контейнера) значений из таблицы и рисоваться в том же порядке. Если же тут будет sides.RIGHT, то будут браться последние w значений из таблицы и рисоваться в том же порядке, но справа. Короче, проще взять и попробовать.
    • Histogram.colorFunc — это задаваемая функция для рассчёта значений цвета столбца и фона в зависимости. Возвращает цвет столбца и цвет фона. Принимает следующие параметры, по порядку:
      • Индекс элемента в таблице значений.
      • Нормализованное значение (от нуля до единицы), или, если хотите, отношение значения к максимальному.
      • Само значение.
      • Объект гистограммы.
      • Объект контейнера.
    • Histogram.min — самое что ни на есть минимальнейшее возможное значение гистограммы. Все значения должны быть больше или равны этому.
    • Histogram.max — самое что ни на есть максимальнейшее возможное значение гистограммы. Все значения должны быть меньше или равны этому.
    • Histogram.level.y — это высота уровня голограммы. По умолчанию равно нулю, так что все столбцы растут вверх, но можно поднять его. Значение ≥ 1 поднимает уровень на соответствующее число символов. Значение в полуинтервале [0; 1) задают нормализованную высоту уровня (например, 0.5 — это посередине гистограммы). Значения меньше нуля отсчитывают уровень с самой верхней позиции, где -1 — это самая высокая точка.
    • Histogram.level.value — это число, значения ниже которого будут отображаться столбиками, направленными вниз, а значения выше — столбиками, направленными вверх.

    Примеры кода

     

     

    local charts = require("charts")
     
    local container = charts.Container()
    local payload = charts.Histogram()
    payload.max = 80
    payload.align = charts.sides.RIGHT
    payload.colorFunc = function(index, norm, value, self, container)
      return 0x20ff20
    end
    container.payload = payload
     
    for i = 1, 400, 1 do
      table.insert(payload.values, math.random(0, 80))
      container:draw()
      os.sleep(.05)
    end
    

     

     

     

     

     

    local charts = require("charts")
    local event = require("event")
    local gpu = require("component").gpu
    
    local container = charts.Container()
    container.width, container.height = gpu.getViewport()
    
    local payload = charts.Histogram()
    payload.max = 1
    payload.min = -1
    payload.level.value = 0
    payload.level.y = .5
    payload.align = charts.sides.RIGHT
    payload.colorFunc = function(index, perc, value, self, container)
      return value >= 0 and 0xafff20 or 0x20afff
    end
    container.payload = payload
    
    for i = 1, math.huge, 1 do
      table.insert(payload.values, math.sin(math.rad(i * 3)))
      if #payload.values > container.width then
        table.remove(payload.values, 1)
      end
      container:draw()
    
      if event.pull(.05, "interrupted") then
        break
      end
    end
    

     

     

     

    Прогресс бар

    Это прогресс бар.

     

    Атрибуты

    • ProgressBar.value — числовое значение прогрессбара.
    • ProgressBar.max — максимальное значение прогрессбара.
    • ProgressBar.min — минимальное значение прогрессбара.
    • ProgressBar.directionнаправление прогрессбара. Туда будет стремиться полоска, с этой стороны будет конец прогрессбара. Не запутайтесь: это не сторона начала.
    • ProgressBar.colorFunc — функция, возвращающая цвет полоски и фона прогрессбара для переданных аргументов:
      • Самое значение прогрессбара.
      • Нормализованное значение.
      • Объект прогрессбара.
      • Объект контейнера.

    Пример кода

     

     

    local charts = require("charts")
    local term = require("term")
    local event = require("event")
    
    local cleft = charts.Container()
    cleft.x, cleft.y, cleft.width, cleft.height = 1, 1, 50, 2
    local pleft = charts.ProgressBar()
    pleft.direction = charts.sides.LEFT
    pleft.value = 0
    pleft.colorFunc = function(_, perc)
      if perc >= .9 then
        return 0x20afff
      elseif perc >= .75 then
        return 0x20ff20
      elseif perc >= .5 then
        return 0xafff20
      elseif perc >= .25 then
        return 0xffff20
      elseif perc >= .1 then
        return 0xffaf20
      else
        return 0xff2020
      end
    end
    cleft.payload = pleft
    
    local cright = charts.Container()
    cright.x, cright.y, cright.width, cright.height = 1, 4, 50, 2
    local pright = charts.ProgressBar()
    pright.direction = charts.sides.RIGHT
    pright.value = 0
    pright.colorFunc = pleft.colorFunc
    cright.payload = pright
    
    local ctop = charts.Container()
    ctop.x, ctop.y, ctop.width, ctop.height = 55, 1, 2, 20
    local ptop = charts.ProgressBar()
    ptop.direction = charts.sides.TOP
    ptop.value = 0
    ptop.colorFunc = pleft.colorFunc
    ctop.payload = ptop
    
    local cbottom = charts.Container()
    cbottom.x, cbottom.y, cbottom.width, cbottom.height = 59, 1, 2, 20
    local pbottom = charts.ProgressBar()
    pbottom.direction = charts.sides.BOTTOM
    pbottom.value = 0
    pbottom.colorFunc = pleft.colorFunc
    cbottom.payload = pbottom
    
    for i = 0, 100, 1 do
      term.clear()
      cleft.gpu.set(5, 10, "Value: " .. ("%.2f"):format(i / 100) .. " [" .. ("%3d"):format(i) .. "%]")
      cleft.gpu.set(5, 11, "Max:   " .. pleft.min)
      cleft.gpu.set(5, 12, "Min:   " .. pleft.max)
    
      pleft.value, pright.value, ptop.value, pbottom.value = i / 100, i / 100, i / 100, i / 100
    
      cleft:draw()
      ctop:draw()
      cright:draw()
      cbottom:draw()
    
      if event.pull(0.05, "interrupted") then
        term.clear()
        break
      end
    end
    
    event.pull("interrupted")
    term.clear()

     

     

     


     

    Это были два вида графического представления данных, самых распространённых в программах для OpenComputers. Так что теперь вам, слава коду, не придётся больше никогда писать опять свои ловисипеды для этого. Либу, однако, я продолжу допиливать. У меня есть ещё несколько идей насчёт очень крутых фич, которые я как-нибудь потом реализую.

     

    Установка

    1. Установите hpm: http://computercraft.ru/topic/1855-repozitorii-programm-hel/?do=findComment&comment=27287
    2. Поставьте пакет с помощью данной команды: hpm install charts.
    • Нравится 7

  6. Обновление hpm до версии 1.1.0 с кучей очень и очень нужных фич!

    • Теперь для установки пакета OpenPrograms нужно писать не install oppm:package, а oppm:install package. То же с remove. Это позволило мне существенно упросить код.
    • Вместо save теперь нужно давать ключик -s к install.
    • Добавлена команда hel:upgrade, так что теперь обновляться проще простого!
    • Добавлены команды hel:search и oppm:search. Без аргументов принтят список всех пакетов, аргументы фильтруют его.
    • Добавлена команда oppm:info по типу hel:info.
    • Исправлена фигня с планами, возникавшая при передаче нескольких пакетов для установки или удаления.
    • При переустановке пакета зависимые от него пакеты теперь не удаляются.
    • Билды хпма теперь минифицируются отличнейшей прогой LuaMinify. Вместо 192 килобайт кода клиент теперь весит всего лишь 75. Минификатор охренненейший: он даже имена переменных минифицирует. Гораздо круче Crunch или, уж тем более, минификатора, торчащего в меню. Рекомендую.
    • Теперь планы изменений подтверждаются автоматически, только если изменений нет вообще.
    • Пофикшено несколько других багов.

    Устанавливать с помощью команды в посте #4. Потом можно будет просто прописывать hpm upgrade.

    • Нравится 3

  7. У меня не парсер, а кастомное окружение для скрипта и выхлопа, которое позволяет программисту не париться с дефолтными значениями везде, а юзеру — легко редактировать конфиг.


    1. Я же писал обновление неделю назад, где ответил на оба вопроса. Почему не читаете?

    Вы или с мыслями соберитесь, или используйте кнопку "Изменить". Не надо на форуме флудить по вопросу на пост с дельтой в 2 минуты.


  8. Именно этим занимается стандартный Serialization API.

    Он превращает Lua табличку в текстовый Lua-код, и обратно.

    С тем отличием, что не дает сериализовывать функции.

    Плюс - невозможность инъкции. Минус - в конфиге нельзя ничего вычислять. В принципе, конфиг и не для этого.

    Сериализованные строки требуют запятую в конце строки, которую я лично, например, постоянно забываю в файлах programs.cfg в репах своих, из-за чего клиент матерится. Мой вариант же позволяет эти запятые не ставить, что очень удобно. Ну и молчу уже про то, что в конфиге можно задавать даже функции.

    • Нравится 1

  9. Вполне можно использовать и Луа-конфиги. Достаточно немного обёртки. чтобы защититься от "вандализма" в конфиге.

     

    Конфиг:

     

    message.helloworld = "Hello, world!"
    message.error = "I caught an error."
    
    emoji.bomb = ""
    emoji.heart = "♥"
    
    answer = 42
    
    -- what is this?
    coordinates = {1,2,3}
    

     

    Код

     

     

     

    local function loadConfig()
      local base = {
        message = {},
        emoji = {},
        test = {
          test = {}
        }
      }
    
      local default = {
        message = {
          helloworld = "Hey",
          error = "ERR"
        },
        emoji = {
          bomb = "BOMB",
          heart = "<3"
        },
        test = {
          value = "test",
          test = {
            supervalue = "supertest"
          }
        },
        answer = 42,
        coordinates = {1, 2, 3}
      }
    
      local config = {}
    
      local function deepCopy(value)
        if type(value) ~= "table" then
          return value
        end
        local result = {}
        for k, v in pairs(value) do
          result[k] = deepCopy(v)
        end
        return result
      end
    
      local function createEnv(base, default, config)
        return setmetatable({}, {
          __newindex = function(self, k, v)
            if base[k] then
              return nil
            end
            if default[k] then
              config[k] = v
            end
            return nil
          end,
          __index = function(self, k)
            if base[k] then
              config[k] = config[k] or {}
              return createEnv({}, default[k], config[k])
            end
            if default[k] then
              return config[k] or deepCopy(default[k])
            end
          end
        })
      end
    
      local env = createEnv(base, default, config)
      loadfile("./config.cfg", "t", env)()
    
      local function setGet(base, default, config)
        return setmetatable({}, {
          __index = function(self, k)
            if base[k] then
              config[k] = config[k] or {}
              return setGet(base[k], default[k], config[k])
            elseif config[k] then
              return config[k]
            elseif default[k] then
              return default[k]
            end
          end
        })
      end
    
      return setGet(base, default, config)
    end
    
    local cfg = loadConfig()
    print(cfg.message.helloworld)
    print(cfg.test.test.supervalue)
    

     

     

     

    В base находятся категории — это таблицы, которые будут иметь обработку значений из конфига.

    В default, как ни странно, находятся дефолтные значения. Обязательно должны быть все таблицы из base. Кроме того, конфиг не засетит ключ, если его не будет в default.

     

    После запуска код напишет это:

     

    Hello, world!
    supertest
    
    • Нравится 1

  10. Основной интересный мод — это OpenComputers. Небольшое (по твоим меркам) число модов подталкивает решать задачи нестандартно, скажем так. Как раз интереснее будет. А с OC так вообще половина модов становится ненужной.

    • Нравится 4

  11. К чёрту магию. Не того оно совсем. Наплодились уже однажды норкомаги, уши вяли от них на форуме круглые сутки. И так достаточно модов для глобального фана, я считаю. Думаю, можно уже переключаться на релиз: делать карту, твикать конфиги и прочее.

    • Нравится 2

  12. @Asior, нахрена ты ставишь дискету "Network"? Она сломана, не работает или работает очень криво, флудит вот тебе как раз этими сообщениями, а ты сюда пишешь. Не устанавливай софт с неё, если не можешь найти причину таких проблем. Она не нужна для работы сети OpenComputers.

     

    Я даже говорил уже об этом в твоём туторе по установке OpenOS. Забудь про эту дискету, она к чёрту не сдалась. К тому же, она ещё и переписывается полностью автором.

×
×
  • Создать...