Перейти к публикации
Форум - ComputerCraft

ECS

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

    214
  • Пожертвование

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

  • Посещение

Все публикации пользователя ECS

  1. Стопудова у тебя включены обои, они жрут чуть ли не четверть имеющейся оперативы. Оффни, если это так. Но вообще странно: только что ябез каких-либо проблем распечатал несколько дефолтных обоин, и память лишь на 74% забилась при наличии двух планок 3.5
  2. Угу, для контроля ядер реакторов из драконика. Сырцов нет, ничего нет, любви нет, только пара скринов
  3. Хочу поделиться с вами объектно-ориентированной библиотекой, которую я использую повсеместно для написания программ с графическим интерфейсом. Все приложения со скриншотов выше реализованы с ее использованием, и если вам вдруг захочется накодить нечто подобное - то милости прошу. Подробная иллюстрированная документация, способы установки и множество практических примеров доступны по ссылке: https://github.com/IgorTimofeev/GUI
  4. А можно и не парсить вовсе, модемы позволяют отсылать/принимать сетевые пакеты с множеством аргументов: -- Отправка modem.broadcast(port, cmd, cmdX, cmdY) -- Прием local localAddress, remoteAddress, port, distance, cmd, cmdX, cmdY = event.pull("modem_message") Если надо "парсить по пробелам", то уот так уот: local message = "meow 12 -249" for part in message:gmatch("[^%s]+") do print("Кусочек: ", part) end >> Кусочек: meow >> Кусочек: 12 >> Кусочек: -249
  5. local function myYobaPullSignal(...) evt, _, _, _, _, info = computer.pullSignal(...) if evt == "touch" and info == returnuser() or evt == "modem_message" and info == "open" then open() elseif evt == "touch" and info ~= returnuser() then getout() elseif evt == "modem_message" and info == "ping" then modem.broadcast(1, "pong") end end ... local function sleep(timeout) local deadline = computer.uptime() + (timeout or 0) repeat myYobaPullSignal(deadline - computer.uptime()) until computer.uptime() >= deadline end ... while true do myYobaPullSignal() end
  6. Раз уж на форуме появился специализированный раздел, посвященный операционным системам, то грех не выложить свою. Сама система является графической оболочкой к дефолтной OpenOS со множеством собственных библиотек, основной упор при ее написании делался на визуальную составляющую и общее быстродействие. Ключевые особенности: Многозадачность Оконный интерфейс с двойной буферизацией графики Поддержка анимаций, обоев, заставок и цветовых схем Поддержка языковых пакетов и локализации ПО Поддержка авторизации пользователя по паролю и биометрике Поддержка обмена файлами по локальной сети через модемы Поддержка клиентского подключения к реальным FTP-серверам Система отчетов об ошибках с возможностью отправки информации разработчикам Магазин приложений с возможностью публикации собственных творений и системой пользовательских рейтингов Интегрированная IDE с отладчиком и значительное количество разнообразного прикладного ПО Открытое системное API и подробная иллюстрированная документация к библиотекам Собственная прошивка EEPROM с возможностью выбора/форматирования загрузочного тома и восстановлением через интернет Полная совместимость с OpenOS-софтом Установка: Для запуска инсталлера введите следующую команду: pastebin run 0nm5b1juПеред вами появится симпатичный интерфейс, где вы сможете выбрать параметры установки: к примеру, загружать ли все имеющиеся приложения, либо оставить только системные, а также загружать ли обои рабочего стола. Лицензионное соглашение шуточное, всерьез можно не воспринимать. Исходники: https://github.com/IgorTimofeev/MineOS Люди, прямо или косвенно участвовавшие в разработке: Тимофеев Игорь - рефакторинг, оптимизация и вылизывание кода Трифонов Глеб - разработчик формата изображений OCIF и методов цветовой обработки Веревкин Яков - консультант по вопросам векторно-матричных преобразований Шестаков Тимофей - специалист по UI/UX-дилеммам Смирнов Алексей - тестировщик ПО Богушевич Виктория - синтаксический корректировщик и отвлекающий фактор Витвицкая Яна - позитивистский мотиватор и не менее отвлекающий фактор Какой-то Андрей - эксперт в области оценки красоты кода Ярычев Никита - компаньон в обсуждениях философских нюансов Пакин Максим - автор нескольких приложений Тиунов Дмитрий - консультант по нюансам веб-запросов Маяковский Константин - товарищ со уникальным духовно-пофигистическим характером Сазонов Слава - автор пары оптимизационных моментов и любитель кратких диалогов Омелаенко Максим - анализатор рынка ПО и конкурентных решений Просин Михаил - генератор мотивации по генерации идей по улучшению ПО Чернышева Дарья - моральная поддержка команды Палиев Егор - очень хотел в этот список
  7. ECS

    MineOS

    В маркете появился ВК-клиент местного разлива. Поскольку VK API с недавних пор стало зашибенно удобным в плане уменьшения количества веб-запросов, то болтать с посонами и посонихами можно с комфортом без ожидания загрузки тонны инфы. На данный момент имеются следующие фичи: • Динамическая подгрузка свежего контента при достижении конца имеющегося • Отображение информации профилей • Просмотр списка друзей с имеющимися тегами • Просмотр новостной ленты • Просмотр списка диалогов, истории переписки, отправки сообщений и файлов (к примеру, можно закинуть какой-нибудь скрипт прямо себе на аккаунт) • Индикатор сетевой занятости, чтобы никто ничо там не подумал, мол, "говнософт завис!!1" • Рекурсивное отображение всех медиавложений, репостов и прочей атрибутики • Раздел настроек с кастомизацией количества загружаемой инфы по категориям Планирую сделать поддержку двухфакторной авторизации, раздел документов и скачивание присланных доков. Пока что софтина чуть сыровата, но вполне себе юзабельна. Напоследок немножечко скринов:
  8. Когда она там релизнется, кстати?
  9. Чего сразу ECS-то? Это все он, это он, не впутывайте! Либа - полный аналог опеносовской. Разница в том, что она работает шустрее, не подменяет pullSignal на кастомный, не требует внешних либ по типу keyboard, а также позволяет отключать и кастомизировать коды клавиш прерывания. Работать оно работает на всех версиях OC, скачивание вместо дефолтной комп не взорвет. Усе.
  10. ECS

    MineOS

    Огрызкоподобное обновление: добавлено приложение "Settings", объединяющее в себе всевозможные настройки системы. Софтина разделена на модули и имеет следующий функционал: • Выбор активного монитора и смена разрешения как в автоматическом режиме без черных полос, так и в ручном • Смена обоев рабочего стола и выбор заставки с задержкой • Кастомизация размеров иконок, отображение расширений и скрытых файлов, изменение цветовой схемы оси • Система автозапуска скриптов как до инициализации десктопа, так и после • Дисковая утилита для смены имен, форматирования и установки загрузочных томов • Настройки сети для передачи файлов по модемам в виде монтированных файловых систем • Смена языка системы. Имеются английский, русский и французский • Выбор часового пояса и настройка отображения времени: либо в виде реального таймштампа, либо в виде игрового • Выбор архитектуры ЦП, выгрузка библиотек как в ручном, так и в автоматическом режиме Ну, а заодно верхняя менюха универсализировалась для каждого приложения а-ля OS X - при переключении окон она индивидуально перестраивается под выбраное:
  11. Доброго времени суток. Захотелось написать клиент для работы с гитхабом через API, однако для заливки файлов на репозиторий требуется отправка PUT-запроса с соответствующим содержимым: Вопрос: это вообще реализуемо через интернет-карту? Если тут имеются эксперты в области веб-запросов, то подскажите, как познать сию магию. Наиболее логичным мне показалось решение ниже, однако увы: local handle = require("component").internet.request( "https://api.github.com/repos/IgorTimofeev/Test/contents/Meow.cpp", '{"path":"meow.cpp","message":"lol","content":"aGVsbG8gd29ybGQ="}', { ["User-Agent"] = "Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:42.0) Gecko/20100101 Firefox/42.0", ["Authorization"] = "Basic base64encoded login:pass pair", ["Content-Type"] = "application/application/json", } ) for i = 1, 30 do print(handle.read(math.huge)) end handle.close() В то же время через специализированный софт все прекрасно заливается: И, разумеется, вариант с консольным curl также вполне себе рабочий: curl -ivX PUT -u login:pass -d '{"path": "meow.cpp", "message": "lol", "content": "aGVsbG8gd29ybGQ="}' https://api.github.com/repos/IgorTimofeev/Test/contents/meow.cpp { "content": { "name": "meow.cpp", "path": "meow.cpp", "sha": "95d09f2b10159347eece71399a7e2e907ea3df4f", "size": 11, "url": "https://api.github.com/repos/IgorTimofeev/Test/contents/meow.cpp?ref=master", "html_url": "https://github.com/IgorTimofeev/Test/blob/master/meow.cpp", "git_url": "https://api.github.com/repos/IgorTimofeev/Test/git/blobs/95d09f2b10159347eece71399a7e2e907ea3df4f", "download_url": "https://raw.githubusercontent.com/IgorTimofeev/Test/master/meow.cpp", "type": "file", "_links": { "self": "https://api.github.com/repos/IgorTimofeev/Test/contents/meow.cpp?ref=master", "git": "https://api.github.com/repos/IgorTimofeev/Test/git/blobs/95d09f2b10159347eece71399a7e2e907ea3df4f", "html": "https://github.com/IgorTimofeev/Test/blob/master/meow.cpp" } }, "commit": { "sha": "38e198640380a061ec9357677fa275ed2a450202", "node_id": "MDY6Q29tbWl0MTQ3ODczMzQzOjM4ZTE5ODY0MDM4MGEwNjFlYzkzNTc2NzdmYTI3NWVkMmE0NTAyMDI=", "url": "https://api.github.com/repos/IgorTimofeev/Test/git/commits/38e198640380a061ec9357677fa275ed2a450202", "html_url": "https://github.com/IgorTimofeev/Test/commit/38e198640380a061ec9357677fa275ed2a450202", "author": { "name": "Igor", "email": "sosi@mail.ru", "date": "2018-09-07T22:37:07Z" }, "committer": { "name": "Igor", "email": "sosi@mail.ru", "date": "2018-09-07T22:37:07Z" }, "tree": { "sha": "86d1529b4193d66705cc2272715009166deb16b2", "url": "https://api.github.com/repos/IgorTimofeev/Test/git/trees/86d1529b4193d66705cc2272715009166deb16b2" }, "message": "lol", "parents": [ { "sha": "db4b95734315298cad0e733421051524b4e32fc1", "url": "https://api.github.com/repos/IgorTimofeev/Test/git/commits/db4b95734315298cad0e733421051524b4e32fc1", "html_url": "https://github.com/IgorTimofeev/Test/commit/db4b95734315298cad0e733421051524b4e32fc1" } ], "verification": { "verified": false, "reason": "unsigned", "signature": null, "payload": null } } }
  12. Проблема решена окольным путем через множество GET/POST-запросов. Если кто-то столкнется с апи гитхаба и аналогичной ситуацией, то вот мануал: http://www.levibotelho.com/development/commit-a-file-with-the-github-api/ Единственный нюанс: в последнем пункте требуется использование метода PATCH, однако POST с задачей также прекрасно справился.
  13. Что ж, спасибо за инфу. Видимо, судьба тонко намекает, что оно не очень-то уж и надо хд Либу опробовать, увы, не удалось из-за тонны зависимостей. Вручную качать сдохну, а Hel все лежит и лежит, дыа
  14. Раз уж речь зашла об идеях и медалях, то у нас была мыслишка накатать мод, рендерящий полученные награды в виде оверлея в дополнение к надетой броне, чтобы деды-ветераны форума имели возможность блеснуть ими не только на сайте. Единственной проблемой стало отсутствие личного форума и, разумеется, сервера
  15. Нашел среди старых коммитов русскую версию. Для ознакомления сойдет, но учти, что в последних версиях либы очень многое изменилось, поэтому претензий никаких не предъявлять: https://github.com/IgorTimofeev/MineOS/blob/00f19b2c460bc82a4ae5fc593c367f0fbfd5ccdd/Documentation/GUI.md
  16. Но... там же примеров кода больше, чем страниц в "Ордене Феникса"... И английский на уровне пятого класса...
  17. Ссылка на скачивание: pastebin get CcusRikg lib/scale.luaДанная библиотека избавит вас от надоедливых "черных полос", возникающих при выставлении собственного разрешения экрана. Она крайне проста в использовании: --Подгружаем библиотеку local scale = require("scale") --Выставляем масштаб монитора scale.set(1) Функция scale.set() требует одно-единственное число в диапазоне от 0.1 до 1, при этом 1 представляет собой максимальный масштаб. Она универсальна, работает с любыми типами мониторов и видеокарт, работает также с вертикальной ориентацией экрана. Ниже несколько примеров использования:
  18. Если приложение уже создано, то пкм - показать содержимое пакета - двойной клик по пикче - рисуешь - сохраняешь - пкм в пустоту - обновить - профит. Если приложения нет, то открываешь Picture Edit и вручную создаешь пикчу размером 8х4 пикселя. Это ж вообще элементарно, ты чо
  19. Ты не обновляешь контейнер раз в секунду, а отрисовываешь его содержимое раз в секунду - это большая разница. Пожалуйста, читай документацию более вдумчиво: в ней подробно описана концепция либы. Для твоей задачи логичнее всего было бы создать пустой GUI.object вместо GUI.label и присвоить ему метод отрисовки, выводящий os.time на экран: -- Создаем главный контейнер и добавляем в него темно-серую фоновую панель local mainContainer = GUI.fullScreenContainer() mainContainer:addChild(GUI.panel(1, 1, mainContainer.width, mainContainer.height, 0x2D2D2D)) -- Добавляем объект, выводящее в экранный буфер системное время каждую операцию отрисовки mainContainer:addChild(GUI.object(3, 2, 1, 1)).draw = function(object) local text = os.date("%d %b %Y %H:%M:%S", os.time()) object.width = #text buffer.drawText(object.x, object.y, 0xFFFFFF, text) end -- Разово отрисовываем содержимое главного контейнера и запускаем обработку событий с интервалом 0 mainContainer:drawOnScreen(true) mainContainer:startEventHandling(0) Однако если по каким-то причинам тебе требуется использовать именно GUI.label, то можно использовать обработчик событий, обновляющий текст лейбла при каждом событии: -- Создаем главный контейнер и добавляем в него темно-серую фоновую панел local mainContainer = GUI.fullScreenContainer() mainContainer:addChild(GUI.panel(1, 1, mainContainer.width, mainContainer.height, 0x2D2D2D)) -- Добавляем лейбл и создаем функцию-обработчик событий, которая при каждом событии (даже отсутствующем) будет обновлять текст лейбла и отрисовывать изменения на экране local label = mainContainer:addChild(GUI.label(3, 2, 10, 1, 0xFFFFFF, "")) mainContainer.eventHandler = function() label.text = os.date("%d %b %Y %H:%M:%S", os.time()) mainContainer:drawOnScreen() end -- Разово вызываем созданную функцию для обновления текста mainContainer.eventHandler() -- Запускаем обработку событий с интервалом 0 mainContainer:startEventHandling(0) Старая версия либы была лютым калом: она отрисовывала изменения в экранный буфер во время клика на вкладку, затем вызывала метод .onTouch, а после вновь отрисовывала изменения. Я счел этот подход неразумным, т.к. незачем нагружать компьютер без четких на то указаний. Короче, добавь строку mainContainer:drawOnScreen() в конец метода .onTouch для каждой вкладки - и все будет шоколадно Как говорится, ложь, говнокод и провокация. Скорее всего, ты сначала создаешь объекты под жирное разрешение экрана, затем изменяешь его на меньшее, позабыв изменить размеры объектов. Пруфскрипт: -- Изменяем разрешение экрана на требуемое buffer.setResolution(80, 50) local mainContainer = GUI.fullScreenContainer() mainContainer:addChild(GUI.panel(1, 1, mainContainer.width, mainContainer.height, 0x2D2D2D)) -- Добавляем селектор цвета local colorSelector = mainContainer:addChild(GUI.colorSelector(3, 2, 30, 3, 0xFF00FF, "Цвет")) colorSelector.onColorSelected = function() GUI.alert("Ты выбрал новый цвет") end mainContainer:drawOnScreen(true) mainContainer:startEventHandling(0) Результат:
  20. Берешь FOV камеры, а также ее текущий поворот, например, по горизонтали. Через цикл изменяешь угол будущего луча в диапазоне [поворот камеры - FOV / 2; поворот камеры + FOV / 2] с заранее рассчитанными шагом, равным ширина экрана / FOV (чтобы число лучей было равным ширине экрана). Далее необходимо прокастовать луч, следующий вдоль полученного угла вплоть до желаемой дистанции прорисовки. Поскольку рейкастинг всегда выполняется с определенной точностью, то разумнее всего будет разово высчитать итеративное смещение кусочка луча по оси X через sin(угол луча) * точность и по оси Y через cos. Полученные значения необходимо раз за разом прибавлять к точке старта луча, чтобы усмешно достигнуть конца. Ну, а далее проще простого: пробегаешься циклом по всей длине луча, попутно вычисляя мировые координаты вокселя по горизонтали. А затем повторяешь вышеописанное для вертикальной ориентации, проверяя наличие вокселя в обоих плоскостях и делая с ним все, что только заблагорассудится. Соль подобного подхода в том, что число тригонометрических операций будет эквивалентно ширина * высота экрана: и никаких тебе векторных вращений и бессмысленных расчетов. Цветами выделил инфу из этой пикчи: Значит, ищи ошибку. Я твой софт не кодил, и дебажить его не намерен. Формулы выше я скопипастил с собственного 3D-движка для опенкомпов, который с удовольствием их кушает. К слову, несмотря на наличие динамического освещения с полной перспективной коррекции, реализован он безо всяких углов Эйлера, матриц, кватернионов и прочей чуши на чистой линейной математике уровня 9 класса Зачем, заче-е-ем? К чему этот геморрой, когда сам алгоритм проще пареной репы? Подобное еще на Сегу во времена Вульфа кодили, слухом не слыхивая о подобной терминологии в компьютерной графике. Ты точно рейкастинг имеешь в виду, а не полноценное трехмерное проецирование со всеми вытекающими?
  21. Интересно, для чего тебе вращение трехмерных векторов при написании рейкастера, если соль алгоритма именно в минимизации векторных расчетов и статичной производительности? Но хозяин - барин. Во-первых, на кой дьявол постоянно использовать конверсию из градусов в радианы? Сожрет же львиную долю ресурсов ЦП, а толку ноль. Юзай сразу радианы, а в человекопонятный градусный формат выводи лишь в интерфейсе. Во-вторых, очень много локальных переменных - рендерер загнется от "out of memory" на сценах с удаленной от точки каста геометрией, т.к. GC не успеет подтереть кучки локального навоза. В-третьих, незачем столь часто обращаться к таблице math и вычислять значения синусов: достаточно разово передать их в расчетную функцию. Также разумнее использовать векторные координаты в качестве последних аргументов функций, чтобы более эффективно передавать результат расчетов из одной функции в другую, хотя лично я бы вообще ограничился тремя локальными переменными для всех векторов и работал бы только с ними. В-четвертых, в нормализации углов особого смысла нет, т.к. тригонометрические функции автоматом работают с углами любого формата. Разве что если ты захочешь сделать заранее вычисленную таблицу косинусов/синусов и получать значения углов уже из нее - вот тогда да, приводить углы к диапазону [-2π; +2π] уже разумно, хотя на практике прирост производительности толком не заметен.
  22. Ни для кого не секрет, что существует множество занятных софтин для работы с геосканером и вывода результата на голопроектор, очки из OpenGlasses или просто в виде сечения на экран. Мне захотелось пополнить их коллекцию программой для просмотра результата сканирования от первого лица в трехмерном пространстве. Работает детище по принципу рейкастинга и на данный момент имеет следующие фичи: Сканирование местности по указанному радиусу (до 32 блоков), сохранение и загрузка результата Примитивная мини-карта для упрощения ориентации в пространстве Кастомизация дистанции прорисовки, полей зрения игрока и уровня детализации Выбор палитры (оттенки серого или спектральная) Изменение размеров окна курсором Разумеется, оперативку оно жрет быстрее, чем репликаторы поглощали флот Гоа'Улдов, а также требует топовый ПК для работы, т.к. хранит безумное количество данных о результатах сканирования. Изначально я хотел замутить софтину для управления дроном-грифером, делающего снимки местности для упрощения воровства картошки с полей, однако по факту получилась просто занятная игрушка без какого-либо практически полезного с точки зрения выживания функционала. Поэтому хотелось бы услышать предложения по использованию подобных технологий именно в сурве. Команда для установки, чтобы пощупать ручками: pastebin run Gm8t26kd
  23. Вставлю свои пять копеек, чтобы правильность была еще более правильной. Ох уж эта правильность... В общем, так как время, затрачиваемое на вызов функций в Lua значительно превышает время осуществления иных операций, следует использовать итеративный метод расчетов вместо рекурсивного. Кроме того, как вполне грамотно заметил товарищ с e-maxx.ru, для определения четности числа имеет смысл заменить "n % 2 == 0" на "n & 1 == 0". В итоге времечко сократится еще втрое. Собсна, пруф: https://ideone.com/t9Yv5F
  24. Файл либы должен возвращать таблицу с созданными функциями: local liba = {} function liba.menu() ... end function liba.test() ... end return liba
  25. Пробежимся по твоему скрипту: во-первых, что за странный бесконечный цикл в начале программы? while true do local adresses = { ... Метод :startEventHandling() автоматически обрабатывает все события бесконечно вплоть до завершения программы. Зачем нужен while true do? Нипанятна. Во-вторых, почему ты заносишь адреса компонентов реакторов вручную, да еще и по их аббревиатурам? Почему бы не использовать автоматическое получение proxy? local reactors = {} for address in component.list("reactor") do table.insert(reactors, component.proxy(address)) end Если это сделано с какой-то определенной целью, например, ради работы с небольшой группой реакторов из большого множества, то прошу прощения. В-третьих, почему бы не использовать циклы для создания виджетов? Неужели самому не лень копипастить тонну однотипного кода? -- Разметка layout:setCellPosition(1, 1, layout:addChild(GUI.text(1, 1, clr_main, "№"))) for i = 2, 7 do layout:setCellPosition(i, 1, layout:addChild(GUI.text(1, 1, clr_main, "№" .. (i - 1)))) end -- Заполняем Layout начиная со 2 колонки и 2 столбца local column, row, counter = 2, 2, 1 for address in component.list("reactor") do -- Добавляем виджет local widget = layout:setCellPosition(column, row, layout:addChild(GUI.text(1, 1, 0x0, "Реактор " .. counter))) -- Присваиваем виджету ссылку на proxy компонента реактора widget.reactorProxy = component.proxy(address) row, counter = row + 1, counter + 1 if row > 10 then column, row, counter = column + 1, 2, 1 end end В-четвертых, разумеется, изменений на экране у тебя нет. Как программа поймет, что состояние реакторов изменилось? Откуда она знает, что ты от нее хочешь? Накодь соответствующий функционал и наслаждайся. А если требуется обновлять температуру реакторов периодически, то используй нечто подобное: -- Создаем обработчик событий главного контейнера mainContainer.eventHandler = function(mainContainer, object, eventData) -- Если события нет, то следует обновить состояние реакторов и отрисовать изменения на экране if not eventData[1] then -- Перебираем все виджеты Layout начиная с 9 (все предыдущие - это чисто информация) for i = 9, #layout.children do -- Задаем им нужный цвет layout.children[i].color = layout.children[i].reactorProxy.producesEnergy() and 0xFF0000 or 0x00FF00 end -- Отрисовываем изменения на экране mainContainer:drawOnScreen() end end -- События пуллятся раз в 1 секунду по аналогии с computer.pullSignal(timeout) mainContainer:startEventHandling(1) Насчет отрисовки содержимого контейнера на экран - тут вообще все просто. Это основа основ, присутствующая в каждом примере кода в документации к либе: mainContainer:drawOnScreen() И наконец, где отступы? Ну рили, 2018 год на дворе, эпоха Sublime/Atom/Notepad++, где отступыЫыЫыЫ?
×