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

Лидеры


Популярный контент

Показан контент с высокой репутацией 08.06.2020 в Сообщения

  1. 7 баллов
    Да, конечно, почему бы и нет. Сложность в том, что component.componentName возвращает прокси только одного компонента, а нам надо и других тоже получить. Здесь есть 2 варианта действий. 1. component.invoke Эта функция первым аргументом принимает адрес компонента, а вторым — имя метода. Остальные параметры — это аргументы к этому методу. Например, если компонент по адресу "12345678-1234-1234-1234-123456789012" — видеокарточка, поменять разрешение у неё можно вот так: local com = require("component") local address = "12345678-1234-1234-1234-123456789012" com.invoke(address, "setResolution", 80, 25) В одиночестве функция выглядит страшно, если сравнивать с проксями. Обычно её используют, итерируя компоненты с помощью component.list, потому что итератор этот выдаёт адрес очередного компонента: local com = require("component") for addr in com.list("gpu", true) do local w, h = com.invoke(addr, "getResolution") com.invoke(addr, "fill", 1, 1, w, h, " ") end Я предпочитаю использовать этот способ, когда надо в цикле проходиться по всем компонентам и вызывать у них пару-тройку методов. local com = require("component") local event = require("event") local function hsv2rgb(h, s, v) local function f(n) local k = (n + h / 60) % 6 return v - v * s * math.max(0, math.min(k, 4 - k, 1)) end local r = math.floor(f(5) * 0x1f + 0.5) local g = math.floor(f(3) * 0x1f + 0.5) local b = math.floor(f(1) * 0x1f + 0.5) return (r << 10) | (g << 5) | b end repeat for addr in com.list("colorful_lamp", true) do local color = hsv2rgb(math.random(0, 360), math.random(.85, 1), math.random(.85, 1)) com.invoke(addr, "setLampColor", color) end until event.pull(0.1, "interrupted") Здесь у компонента метод вызывается лишь один раз, поэтому проще использовать component.invoke. В противном случае лучше делать прокси. 2. component.proxy Если список компонентов, с которыми работает программа, более-менее статичен, удобнее использовать component.proxy. Это функция, которая возвращает прокси компонента по данному адресу. С проксями мы уже знакомы: когда делаем в коде component.componentName, на самом деле вызывается component.proxy(component.getPrimary("componentName")). Когда компонентов несколько, обычный шаблон — это один раз напихать проксей в таблицу и использовать уже её. local com = require("component") local event = require("event") local gpus = {} for addr in com.list("gpu", true) do table.insert(gpus, com.proxy(addr)) end assert(#gpus >= 4, "4 gpus required") gpu[1].set(1, 1, "first gpu") gpu[2].set(2, 2, "second gpu") gpu[3].set(3, 3, "third gpu") gpu[4].set(4, 4, "fourth gpu") Важно, что после заполнения таблицы компоненты эти отключаться не должны. В противном случае нужно ставить листнеры на component_added, component_removed. Прокси также можно использовать в цикле component.list, как в первом способе, чтобы упростить жизнь, если внутри цикла приходится трогать методы компонента по нескольку раз. Вот программка, которая чистит экран и принтит число почищенных символов. local com = require("component") local event = require("event") for addr in com.list("gpu", true) do local gpu = com.proxy(addr) local litChars = 0 local w, h = gpu.getResolution() local oldBg = gpu.getBackground() gpu.setBackground(0x000000) for x = 1, w, 1 do for y = 1, h, 1 do local char, _fg, bg = gpu.get(x, y) if char ~= " " or bg ~= 0x000000 then litChars = litChars + 1 end gpu.set(x, y, " ") end end gpu.set(1, 1, ("%d lit characters"):format(litChars)) gpu.setBackground(oldBg) end Как видно, я активно использую кучу методов гпу. Вместо того, чтобы каждый раз печатать component.invoke, я один раз взял прокси, а дальше работаю с ним.
  2. 4 балла
    Лайк за ответ, который в 42 раза длиннее вопроса.
  3. 3 балла
    Вероятно, многие хотели запустить несколько программ на одном компьютере (на OpenOS), чтобы они работали одновременно. Моя программа даёт возможность это сделать (программы будут выполняться не совсем одновременно, таково ограничение OpenComputers). Важное условие: в каждой выполняемой программе должен быть os.sleep, event.pull или computer.pullSignal, чтобы она передавала управление другой. Инструкция: 1. Скачайте программу: pastebin get wsJqngC5 parallel.lua 2. Запустите её. 3. Введите пути к программам, которые необходимо выполнить параллельно, через пробел (если программа одна, то введите её один раз). 4. Введите число, сколько раз должна быть запущена каждая программа из списка. 5. Задайте аргументы для каждой запускаемой программы. Если несколько программ должны работать параллельно, то почему бы не запустить их на разных мониторах? Это возможно: просто напишите в аргументы программы %GPU%. Эта строка автоматически заменится на адрес видеокарты. В программе могут встречаться баги и несовместимости с другими приложениями. Просьба сообщать, если таковые найдутся.
  4. 3 балла
    Совсем забыл в видео показать. Демонстрация подключения компонентов "на лету":
  5. 1 балл
    Сделал простенькую читалку для файлов GIF, поддерживает весь функционал со спецификации: слои/кадры, прозрачность, текст, комментарии, расширение NETSCAPE2.0 и прочее. Но не все доп. расширения были найдены, потому реализовал только описанные в интернете. Небольшая предыстория: В общем говоря, захотел я себе как-то анимированный "телек" для дома, в качестве украшения. С отображением были конечно проблемы - голо-проектор не вмещал больше 3х цветов в палитре, но это решалось количеством. Второй проблемой встала сама картинка - пнгшки кадрами собирать было лень, да ещё и в индексы надо переводить все цвета... Подождите-ка индексы, анимация, встроенная палитра... Это-же GIF! Эврика подумал я... Пока не увидел реализацию, а потом меня поглотила пучина гифа... При первом знакомстве GIF показался простым, как пробка, форматом (хотя, так и есть). Но сжатие изображения в LZW немного остудило мой пыл. Мне довольно трудно понимать работу хитроскрученных алгоритмов сжатия, но всё оказалось не так плачевно, и вооружившись методом проб и ошибок, я начал познавать это.. что-то. В конце концов, подняв несколько хабро-статеек, спецификацию, форумы покрывшиеся пылью, я начал открывать другую сторону GIF - она идеально подходит под реалии OpenComputers: 256 цветов, неплохое сжатие, встроенный текст. Всё это приправлено расширениями в виде анимаций, прозрачности слоёв, и разными дополнительными блоками. В конце-концов, этот формат может стать аналогом флеша в истории опенкомпов! Да здравствует новая эра, эра флеш-игр, когда-то покорившая интернет! В итоге всех скитаний по интернетам, мне удалось сделать более-менее полную читалку, хотя некоторые расширения потерялись в могилах истории, и я не решился пока их выкапывать. Саму читалку можно скачать для двух версий Lua: 5.2: wget -f https://github.com/Xytabich/GIF-Lua/raw/master/5.2/gif.lua /lib/gif.lua 5.3: wget -f https://github.com/Xytabich/GIF-Lua/raw/master/5.3/gif.lua /lib/gif.lua Различия между ними несущественны - Lua 5.3 использует встроенные битовые операции, а в Lua 5.2 используется библиотека bit32, соответственно. Функционал читалки: -- Сруктуры -- Заголовок GIF - базовая информация гифки. - width:number - ширина гифки - height:number - высота гифки - colorBits:number - кол-во бит, используемое для цветовой палитры. Устарело, но добавил на всякий. - bgIndex:number - индекс фонового цвета - aspectRatio:number - соотношение сторон, считается как: ширина/высота. Тоже устарело, но мало-ли. - colorsCount:number? - количество цветов в глобальной палитре - colors:number[]? - глобальная палитра цветов 0xRRGGBB, индексация начинается с 0 - extensions:table - список расширений гифки Блок изображения (image) - информация о слое/кадре гифки. Содерижит полное изображение, или только его часть. - x:number - отступ от левого края - y:number - отступ от верхнего края - width:number - ширина изображения - height:number - высота изображения - interlaced:bool - построчная или чересстрочная развертка - colorsCount:number? - количество цветов в локальной палитре - colors:number[]? - локальная палитра цветов 0xRRGGBB, индексация начинается с 0 - pixels:string - пиксели изображения, массив байт 0-255. Пиксель является индексом в локальной/глобальной палитре, и записаны в виде линий, слева-направо сверху-вниз. Порядок линий зависит от interlaced. - extension:table? - расширение изображения, параметры анимации и прозрачности - dispMethod:number - метод очистки экрана перед отображением: 1 - не очищается, 2 - закрасить фоновым цветом, 3 - восстановить состояние перед предыдущим кадром - delay:number - время до следующего кадра, в секундах - inputFlag:bool - ожидать ли ввода пользователя для продолжения отображения - transparentIndex:number - индекс цвета в палитре, использующегося в качестве прозрачного Блок текста (text) - отображает текст над изображением. По спецификации символы 7-bit ASCII, но ничто не мешает засунуть туда utf-8. - x:number - отступ от левого края - y:number - отступ от верхнего края - width:number - ширина текстовой области - height:number - высота текстовой области - charWidth:number - ширина символа - charHeight:number - высота символа - fgIndex:number - цвет символа - bgIndex:number - цвет фона символа - text:string - собственно, сам текст Блок комментария (comment) - произвольная текстовая запись, не влияющая на отображение. По спецификации так-же символы 7-bit ASCII, но и юникод спокойно помещается. Расширение гифки: NETSCAPE2.0 - информация о количестве циклов анимации. - iterations:number - количество итераций цикла (0 - бесконечное) - loop:bool - бесконечный ли цикл -- Функции -- gif.read(stream[, pos=0]):table -- читает весь файл. -- stream - поток данных, например - полученный через filesystem.open(...) -- возвращает заголовок с дополнительным полем - blocks:table {type:string, block:object}. В этом поле содержится список всех блоков в порядке чтения. gif.images(stream[, pos=0]):head, image -- итератор, последовательно считывает изображения. -- stream - поток данных, например - полученный через filesystem.open(...) gif.blocks(stream[, pos=0]):head, type, block -- итератор, последовательно считывает все блоки. -- stream - поток данных, например - полученный через filesystem.open(...) Особо сильно оптимизировать не стал, да и не знаю как, так что если есть предложения - выслушаю и внесу поправки. Один из вариантов ускорения чтения - сделать буферизированный поток данных. Код и тестовые изображения доступны в репозитории на github. В чересстрочной развёртке линии следуют не по прямому порядку, подробнее в выписке из спецификации: Пример приведу на тестовом коде, для проектора на картинке выше. Этот код просто рисует файл, так что настроить пересечение областей проекторов нужно вручную, или использовать один. Для OpenComputers этот формат имеет хорошие возможности, как для простого хранения сжатого изображения, или даже составного изображения из различных слоёв, так и для продвинутых действий: презентаций, анимаций, картинок с подписями. А если совсем заморочиться, то можно сделать свой Anone Gif Player, используя комментарии для записи кода, или собственные расширения приложения. По крайней мере, кинетические новелки возможно сделать и в стоковом варианте. История изменений:
  6. 1 балл
    вместо redstone_changet должно быть redstone_changed
  7. 1 балл
    Версия 1.01: - Оптимизация кода - Убрано использование глобальных ссылок
  8. 0 баллов
    Да, удобно. Считать можно и так, если к результатам расчётов добавлять слово "приблизительно". Для отображения поля символов размером 160x50 требуется приблизительно 445 проекторов, а точнее — 459.
Эта таблица лидеров рассчитана в Москва/GMT+03:00
×
×
  • Создать...