Fingercomp
-
Публикации
1 629 -
Зарегистрирован
-
Посещение
-
Победитель дней
283
Сообщения, опубликованные пользователем Fingercomp
-
-
Завтра будет возможность проверить свою программу на арене. Если кто-то хочет, отпишитесь.
-
1
-
-
Просто Фингер видел не один десяток "программ начинающих программистов", где с оформлением всё жуть-жуть. Это и понятно. И в других прогах сильно не парятся над этим. У меня же всё опрятно, ровно, конфиги есть и т. д. Зайди в соседний топик и глянь, как выглядит. А если не нравится — смени цвета.
-
2
-
-
Короче, заказ можно считать выполненным: прогу я написал при непосредственном общении с реквестером. Моё решение не требует дополнительных модов и очень удобно в использовании. И выглядит офигенно.
-
Хей! У меня тут очень крутой пример для либы charts появился. Либа мне нравится невероятно, потому с таким же усердием я решил что-нибудь наваять. Тем более, что @mercurial как раз публиковал заказ на такую прогу.

Установка
- Качаем hpm: http://computercraft.ru/topic/1855-repozitorii-programm-hel/?do=findComment&comment=27287
- Ставим: hpm install railtank.
Использование
К подопытной цистерне из Рейла ставим адаптер, в него пихаем Tank Controller Upgrade (апгрейд контроллера цистерн, что-то типа этого), а потом проводами цепляем к компу. Можно порыться в конфиге /etc/railtank.cfg: настроить количество цистерн для показа, интервал обновления графиков, выставить свои цвета интерфейсу. А потом запускаем прогу: railtank. Вуаля.
Чтобы выйти, нажмите Ctrl + C (без альта!).
Программа автоматически примониторит ещё цистерну при её подключении и уберёт из мониторинга при отключении. Так что не парьтесь :P
Ну и ссылка на пакет: https://hel.fomalhaut.me/#packages/railtank
-
7
-
То, что я не публикую посты с обновлением каждый день, не значит, что ивент умер. Люди пишут программы, UT будет на этой неделе. Переносить больше не буду.
-
Поставь OpenPeripherals. Он добавляет компонент для вальвы.
-
1
-
-
да нет, версии последнии, можешь пожалуйста видео записать как ты подключаешь?)
Подключать просто надо к Valv'ам, в имени конмпонента же написано. Ставить танк, вниз цепляешь валв, к нему адаптер и кабелями к компу.
-



Вот такая красота теперь возможна благодаря моей новой либе 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) endlocal 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. Так что теперь вам, слава коду, не придётся больше никогда писать опять свои ловисипеды для этого. Либу, однако, я продолжу допиливать. У меня есть ещё несколько идей насчёт очень крутых фич, которые я как-нибудь потом реализую.
Установка
- Установите hpm: http://computercraft.ru/topic/1855-repozitorii-programm-hel/?do=findComment&comment=27287
- Поставьте пакет с помощью данной команды: hpm install charts.
-
7
-
Обновление 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
-
Комплектация продумана полностью. Забрать монетку, выплюнуть в сундук и ориентироваться можно без каких-либо дополнительных запчастей.
-
У меня не парсер, а кастомное окружение для скрипта и выхлопа, которое позволяет программисту не париться с дефолтными значениями везде, а юзеру — легко редактировать конфиг.
-
- Я же писал обновление неделю назад, где ответил на оба вопроса. Почему не читаете?
Вы или с мыслями соберитесь, или используйте кнопку "Изменить". Не надо на форуме флудить по вопросу на пост с дельтой в 2 минуты. -

Из одиннадцати форумчан, захотевшие поучаствовать, о готовности проги написал только @electronic_steve. Переносим поэтому ивент на неделю вперёд. Ждём хотя бы 8 участников, чтобы был какой-то интерес.
-
Именно этим занимается стандартный Serialization API.
Он превращает Lua табличку в текстовый Lua-код, и обратно.
С тем отличием, что не дает сериализовывать функции.
Плюс - невозможность инъкции. Минус - в конфиге нельзя ничего вычислять. В принципе, конфиг и не для этого.
Сериализованные строки требуют запятую в конце строки, которую я лично, например, постоянно забываю в файлах programs.cfg в репах своих, из-за чего клиент матерится. Мой вариант же позволяет эти запятые не ставить, что очень удобно. Ну и молчу уже про то, что в конфиге можно задавать даже функции.
-
1
-
-
Вполне можно использовать и Луа-конфиги. Достаточно немного обёртки. чтобы защититься от "вандализма" в конфиге.
Конфиг:
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
-
-
Очков в CX нет >_>
Тыкай IC2 Alt Key и IC2 Hub Expand Key.
-
если руки не из таза
Ну это уже не проблемы модпака. Пусть учатся юзать OC.
-
Основной интересный мод — это OpenComputers. Небольшое (по твоим меркам) число модов подталкивает решать задачи нестандартно, скажем так. Как раз интереснее будет. А с OC так вообще половина модов становится ненужной.
-
4
-
-
А, ну да, точняк. Креативные корпуса же могут быть использованы только игроком в режиме креатива.
-
К чёрту магию. Не того оно совсем. Наплодились уже однажды норкомаги, уши вяли от них на форуме круглые сутки. И так достаточно модов для глобального фана, я считаю. Думаю, можно уже переключаться на релиз: делать карту, твикать конфиги и прочее.
-
2
-
-
FastLeafDecay надо, думаю, а то висящие листья раздражают чутка.
-
В чём опасность открытой двери? Она же заблокирована роботом всё равно, фиг пролезешь. А если и пройти, то без робота.

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

Мониторинг цистерн RailCraft
в Инфраструктура
Опубликовано:
Да, всё так.