ECS
Гуру-
Публикации
533 -
Зарегистрирован
-
Посещение
-
Победитель дней
203
Тип публикации
Блоги
Профили
Форум
Багтрекер
Магазин
Все публикации пользователя ECS
-
Интересно, работает ли либа на Lua 5.2? Возможный диапазон целых чисел на прошлой версии отличается от 5.3:
-
Раз уж на форуме появился специализированный раздел, посвященный операционным системам, то грех не выложить свою. Сама система является графической оболочкой к дефолтной OpenOS со множеством собственных библиотек, основной упор при ее написании делался на визуальную составляющую и общее быстродействие. Ключевые особенности: Многозадачность Оконный интерфейс с двойной буферизацией графики Поддержка анимаций, обоев, заставок и цветовых схем Поддержка языковых пакетов и локализации ПО Поддержка авторизации пользователя по паролю и биометрике Поддержка обмена файлами по локальной сети через модемы Поддержка клиентского подключения к реальным FTP-серверам Система отчетов об ошибках с возможностью отправки информации разработчикам Магазин приложений с возможностью публикации собственных творений и системой пользовательских рейтингов Интегрированная IDE с отладчиком и значительное количество разнообразного прикладного ПО Открытое системное API и подробная иллюстрированная документация к библиотекам Собственная прошивка EEPROM с возможностью выбора/форматирования загрузочного тома и восстановлением через интернет Частичная совместимость с OpenOS-софтом Установка: Для запуска инсталлера введите следующую команду: wget -f https://raw.githubusercontent.com/IgorTimofeev/MineOS/master/Installer/BIOS.lua /tmp/bios.lua && flash -q /tmp/bios.lua && reboot Перед вами появится симпатичный интерфейс, где вы сможете выбрать параметры установки: к примеру, загружать ли все имеющиеся приложения, либо оставить только системные, а также загружать ли обои рабочего стола. Лицензионное соглашение шуточное, всерьез можно не воспринимать. Исходники: https://github.com/IgorTimofeev/MineOS Люди, прямо или косвенно участвовавшие в разработке: Тимофеев Игорь - рефакторинг, оптимизация и вылизывание кода Трифонов Глеб - разработчик формата изображений OCIF и методов цветовой обработки Веревкин Яков - консультант по вопросам векторно-матричных преобразований Шестаков Тимофей - специалист по UI/UX-дилеммам Смирнов Алексей - тестировщик ПО Богушевич Виктория - синтаксический корректировщик и отвлекающий фактор Витвицкая Яна - позитивистский мотиватор и не менее отвлекающий фактор Какой-то Андрей - эксперт в области оценки красоты кода Ярычев Никита - компаньон в обсуждениях философских нюансов Пакин Максим - автор нескольких приложений Тиунов Дмитрий - консультант по нюансам веб-запросов Маяковский Константин - товарищ со уникальным духовно-пофигистическим характером Сазонов Слава - автор пары оптимизационных моментов и любитель кратких диалогов Омелаенко Максим - анализатор рынка ПО и конкурентных решений Просин Михаил - генератор мотивации по генерации идей по улучшению ПО Чернышева Дарья - моральная поддержка команды Палиев Егор - очень хотел в этот список
- 218 ответов
-
- 16
-
-
-
И очень даже неудобно, если требуется запретить прерывание софтины в частности. Если я желаю остановить выполнение зависшего скрипта, использовать фильтры и листенеры, то, очевидно, воспользуюсь библиотекой event, в противном случае я стану использовать нативный метод pullSignal. Увы, эту возможность у кодеров под OpenOS нагло отняли и навязали подмену функции без разумного объяснения причин. Высказывание автора о том, что он "never liked the user solution to be change this openos internal method" я разумным счесть не могу, ибо на производительность OpenOS это никак не повлияет, а немаловажная фича была слита в унитаз. Это не разумная причина, а субъективная придурь, и именно поэтому я и использовал термин "ерунда", и именно поэтому решение ерундовое
-
Фига, не ждал от них подобной ерунды, еще один повод в копилку "отказаться от опеносовской либы". Если по теме, то проверил следующий код на последней версии опенкомпов, интерруптинг отключается без проблем: event.shouldInterrupt = function() return false end event.shouldSoftInterrupt = event.shouldInterrupt
-
Простым решением проблемы будет использование computer.pullSignal() вместо event.pull(), убрав тем самым поддержку прерывания скрипта. В качестве альтернативы предлагаю эквивалентную по структуре либу, где для отключения прерывания необходимо поставить флаг event.interruptingEnabled = false
-
@@Zer0Galaxy, кстати, чет похожее писал давненько. Работало сносно, хоть это и не полноценный мультитрединг:
-
Мини-обновление: добавлен виджет GUI.filesystemChooser для удобной навигации по файловой системе и выбора файлов/папок пользователем. Также поддерживаются фильтры расширений файлов:
-
Ну, в современных фреймворках при изменении размера окна генерируется банальный ивент, и содержимое окна лишь "обрезается" в соответствии с его границами. А уж изменять геометрию содержимого или оставлять прежней - это задача программиста прикладного ПО, так что не вижу в прослушке событий ничего плохого. К примеру, в QT это реализовывается так: void MyMainWindow::resizeEvent(QResizeEvent* event) { QMainWindow::resizeEvent(event); // Do something }
-
Книга "Fundamentals of Computer Graphics", хоть она и не очень: есть пара интересных алгоритмов по быстрой растеризации примитивов, но именно что лишь пара. Да и те пришлось изрядно оптимизировать, чтобы GC не грузили.
-
Годная софтинка. Пожалуй, стырю в качестве скринсейвера, если не против. Есть, правда, парочка деликатных моментов: во-первых, отрисовка линий через atan/sin/cos хоть и проста, но крайне неэффективна. Рекомендую использовать следующий код, основанный на модифицированном алгоритме Питера Ширли и предназначенный специально для низкопроизводительных машин (значительно быстрее, чем классический алгоритм Брезенхема): local function line(x1, y1, x2, y2, color) local inLoopValueFrom, inLoopValueTo, outLoopValueFrom, outLoopValueTo, isReversed, inLoopValueDelta, outLoopValueDelta = x1, x2, y1, y2, false, math.abs(x2 - x1), math.abs(y2 - y1) if inLoopValueDelta < outLoopValueDelta then inLoopValueFrom, inLoopValueTo, outLoopValueFrom, outLoopValueTo, isReversed, inLoopValueDelta, outLoopValueDelta = y1, y2, x1, x2, true, outLoopValueDelta, inLoopValueDelta end if outLoopValueFrom > outLoopValueTo then outLoopValueFrom, outLoopValueTo = outLoopValueTo, outLoopValueFrom inLoopValueFrom, inLoopValueTo = inLoopValueTo, inLoopValueFrom end local outLoopValue, outLoopValueCounter, outLoopValueTriggerIncrement = outLoopValueFrom, 1, inLoopValueDelta / outLoopValueDelta local outLoopValueTrigger = outLoopValueTriggerIncrement for inLoopValue = inLoopValueFrom, inLoopValueTo, inLoopValueFrom < inLoopValueTo and 1 or -1 do if isReversed then -- setPixel(outLoopValue, inLoopValue, color) else -- setPixel(inLoopValue, outLoopValue, color) end outLoopValueCounter = outLoopValueCounter + 1 if outLoopValueCounter > outLoopValueTrigger then outLoopValue, outLoopValueTrigger = outLoopValue + 1, outLoopValueTrigger + outLoopValueTriggerIncrement end end end Во-вторых, я бы использовал либу буферизации графики, чтобы не было "промигиваний", и была возможность выставлять хоть 50 линий за раз. Также она уже имеет функции растеризации отрезков, в том числе полупиксельных:
-
Библиотека обновлена. Исправлены мелкие баги, а также добавлено несколько вкусных плюшек: • Появилась возможность создания автоматических анимаций виджетов: • Контекстное меню заимело фичу скроллинга контента, а также поддержку вложенных контекстных меню: • Значительно улучшен GUI.layout, заимев поддержку абсолютного и релятивного размеров ячеек, возможность выравнивания и отступов по произвольному краю, возможность установки расстояния между элементами, а также фиттинга элементов по размеру ячейки: • Появились два дополнительных варианта отрисовки GUI.button, а также их adaptive-аналоги: • Появился виджет GUI.brailleCanvas, позволяющий быстро и просто отрисовывать мелкую графику при помощи шрифта Брайля:
-
local redstone = require("component").redstone while true do redstone.setOutput(1, math.random(15)) end Что примечательно, эту софтину возможно завершить только путем отсоединения редстоун-компонента. Как верно подметил eu_tomat, каждое обращение к нему ведет себя аналогично .pullSignal(), однако не вызывает его
-
А то. Как раз даже гифочка припасена на всякий пожарный. Вся ОСька по сути - это один жирный контейнер, а палитра и магазин приложений - вложенные контейнеры, стилизованные под окна. Сырец либы тут, дока тут
-
Есть третий принципиально отличающийся вариант: обработка нескольких приложений-окон в общем потоке-контейнере. Из плюсов тут стоит выделить максимальное быстродействие, т.к. выполнение скрипта не будет искусственно замедлено множественными yield() в подмененных функциях, а также простоту написания такого концепта. Из минусов - поддерживать многозадачность будет лишь то ПО, которое написано под данную ОС, все остальное будет работать в штатном режиме. А также имеет место быть стабильный краш главного потока при краше любого из приложений - проблема решается изоляцией пространства приложения от контейнера и кешированием его состояния.
-
Для справки: каждая переменная-указатель на таблицу или функцию в Lua весит в равной мере 9 байт. А теперь немного сухих расчетов: представим простейшую трехмерную сцену из восьми кубиков. Каждый куб имеет 8 вершин, каждая вершина - это трехмерная таблица-вектор с числовой индексацией, в сумме кушающая 40 (table) + 8 (double) * 3 = 64 байта. Все вершины заносятся в массив вершин сцены для минимизации расхода памяти. Также каждый куб имеет таблицу-линковщик, содержащую индексы вершин, образующие треугольники для отрисовки куба в количестве 12 штук. Каждый треугольник с ссылками на три вершины - это такой же трехмерный вектор, кушающий все так же 64 байта. Итого получаем 64 * 8 = 512 байт на вершины и 64 * 12 = 768 байт на линковку вершин, итого 1280 байт на куб. Сколько у нас там их? Восемь? Итого трехмерная сцена выжрет 1280 * 8 = 10240 байт = 10 КБайт. Это тот минимум, который необходим для старта отрисовки графики, материалы и текстуры для простоты рассматривать не будем. Если же использовать локальные переменные-сокращалки, то расход памяти взлетит по экспоненте. Чтобы пруфануть это более наглядно, привожу выдержку из кода движка, содержащую основной цикл, отвечающий за получение соответствующих вершин через треугольники: for triangleIndex = 1, #OCGL.triangles do vertex1[1], vertex1[2], vertex1[3] = renderer.viewport.xCenter + OCGL.vertices[OCGL.triangles[triangleIndex][1]][1], renderer.viewport.yCenter - OCGL.vertices[OCGL.triangles[triangleIndex][1]][2], OCGL.vertices[OCGL.triangles[triangleIndex][1]][3] vertex2[1], vertex2[2], vertex2[3] = renderer.viewport.xCenter + OCGL.vertices[OCGL.triangles[triangleIndex][2]][1], renderer.viewport.yCenter - OCGL.vertices[OCGL.triangles[triangleIndex][2]][2], OCGL.vertices[OCGL.triangles[triangleIndex][2]][3] vertex3[1], vertex3[2], vertex3[3] = renderer.viewport.xCenter + OCGL.vertices[OCGL.triangles[triangleIndex][3]][1], renderer.viewport.yCenter - OCGL.vertices[OCGL.triangles[triangleIndex][3]][2], OCGL.vertices[OCGL.triangles[triangleIndex][3]][3] material = OCGL.triangles[triangleIndex][4] ... Также привожу скриншот с результирующим FPS в 7 единиц и расходом оперативной памяти в 46% от максимального запаса (4 Мб) А теперь намутим-ка локальных сокращений для минимизации нагрузки на ЦП: local ti, ve1, ve2, ve3 for triangleIndex = 1, #OCGL.triangles do ti = OCGL.triangles[triangleIndex] ve1, ve2, ve3 = OCGL.vertices[ti[1]], OCGL.vertices[ti[2]], OCGL.vertices[ti[3]] vertex1[1], vertex1[2], vertex1[3] = renderer.viewport.xCenter + ve1[1], renderer.viewport.yCenter - ve1[2], ve1[3] vertex2[1], vertex2[2], vertex2[3] = renderer.viewport.xCenter + ve2[1], renderer.viewport.yCenter - ve2[2], ve2[3] vertex3[1], vertex3[2], vertex3[3] = renderer.viewport.xCenter + ve3[1], renderer.viewport.yCenter - ve3[2], ve3[3] material = OCGL.triangles[triangleIndex][4] ... Результат плачевный. Не замечено ни прироста, ни убыли значений FPS, однако расход памяти возрос до 61%. Магия? Нет, особенности конкретного ЯП и его интеграции в виде мода.
-
Спасибо за пояснение очевидного. Ты забываешь про буфер хешмапы, ускоряющий поиск часто используемых объектов - в большинстве случаев описанные тобой операции банально "скипаются", особенно в нашем контексте, где используется обращение к одним и тем же вложенным таблицам. Ручной вызов GC в OpenComputers невозможен, эта фича отключена авторами мода по понятным причинам. Если бы я мог активировать сборку мусора - то неужели стал бы писать сюда о проблемах с локальными переменными? Переменная весит столько, сколько определено ее типом: строки занимают 17 байт + длина самой строки, таблица кушает 40 байт + ее содержимое, каждая функция - 20 байт + локальные данные. Пожалуйста, не пиши глупости без знания матчасти. А мне кажется, что кто-то слишком много умничает не по делу. Использование локальных переменных - чуть ли не основа основ при кодинге на любом ЯП. И присвоение переменной nil, как оказалось, отнюдь не ускоряет ее очистку из памяти, ибо, разумеется, этот вариант мы также рассматривали.
-
В большинстве случаев дело именно в реализации, да. Если имеется какой-нибудь вшивый цикл на пару итераций, то куда выгоднее использовать локальные переменные, как ты и предлагал, чтобы минимизировать нагрузку на ЦП, это логично. Однако в нашем случае рассматривается функция, вызываемая весьма часто со множеством вложенных циклов и способная в самый неподходящий момент перегрузить сборщик мусора. В принципе, если памяти хватает - то и фиг с ним. Вообще за наводку на идею ускорения спасибо, можно вынести локальные сокращения за пределы циклов отрисовки - и тем самым сэкономить тики ЦП без ущерба для памяти. Хотя придется изрядно повозиться, да А насчет исходников OpenOS - с каких это пор они стали эталоном грамотного и эффективного кода? Лично я вообще не понимаю, что в ней может кушать столько памяти (пс-с-ст, более 200 КБайт по дефолту, жуть какая). Хотя приведенный тобой пример вносит определенную ясность хд
-
Увы, такой подход крайне нерационален. Безусловно, визуально куда проще выделить локальную переменную под жирную таблицу с множеством вложенных обращений, сэкономив тем самым несколько тиков - однако если бы я использовал такой подход при написании требовательного софта, то он вылетал бы с not enough memory еще до старта. Примером может послужить наш 3D-движок: сборщик мусора банально не успевал очищать локальные переменные-указатели на таблицы векторов при отрисовке сцен, и ошибка о нехватке памяти вылезала как результат. Сократив подобный "некорявый код" до минимума, мы смогли запустить движок всего лишь на 2 МБ RAM. Так что лучше помучиться с лишними буковками, нежели писать неоптимизированное в данном контексте ПО. Имхо, конечно же
-
Он бесплатный с ограничением до 1 млн символов в сутки, увы. Но побаловаться сойдет хд
- 3 ответа
-
- 1
-
-
- GUI
- переводчик
-
(и ещё 1 )
Теги:
-
Не, ну а чо, почему нет? Команда для установки: pastebin run 0wFnKD5k Команда для запуска: /Translate/Main.lua
- 3 ответа
-
- 8
-
-
- GUI
- переводчик
-
(и ещё 1 )
Теги:
-
Ну блин, стараешься тут, стараешься, разбивая код на суб-сегменты по классическим идиомам проектирования, минимизируя нагрузку на оперативку и ЦПУ, а потом его "корявым" называют. Обидно А вообще интересно, каким образом ты уменьшил размер сырцов в 5 раз - уж не путем ли удаления половины "не нужных" для твоей ОС элементов? Го инфу, любопытно стало.
-
Cобсна, программа проста, как три копейки: левый и правый клики по спиннеру меняют его цвет, а нажатие на любую клавишу позволяет выйти. Надеюсь, любители особых извращений оценят ее по достоинству. Команда для установки: pastebin run MMvSd2be Команда для запуска: /Spinner/Main.lua
-
local filesystem = require("filesystem") --------------------------------------------------------------------- function table.unserialize(serializedString) checkArg(1, serializedString, "string") local success, result = pcall(load("return " .. serializedString)) if success then return result else return nil, result end end function table.fromFile(path) checkArg(1, path, "string") if filesystem.exists(path) then if filesystem.isDirectory(path) then error("\"" .. path .. "\" is a directory") else local file = io.open(path, "r") local data = table.unserialize(file:read("*a")) file:close() return data end else error("\"" .. path .. "\" doesn't exists") end end --------------------------------------------------------------------- local myTable = table.fromFile("/myFileWithTable.lua") Десериализация таблицы на чистом луа без лишних библиотек
-
local function sleep(timeout) local deadline = computer.uptime() + (timeout or 0) while computer.uptime() < deadline do computer.pullSignal(deadline - computer.uptime()) end end Держи простейший вариант задержки, учитывающий возможные ивенты, если дефолтный os.sleep юзать не можешь/не хочешь
-
Ага, спасибо. Я вообще не в курсе был про вариант целочисленного деления с двумя слешами в 5.3, заменим в ближайшее время UPD: Существенной разницы при отрисовке сложных сцен не заметно, но сам факт приятен
