LeshaInc
-
Публикации
777 -
Зарегистрирован
-
Посещение
-
Победитель дней
68
Сообщения, опубликованные пользователем LeshaInc
-
-
@@Zer0Galaxy, а мантисса обязательно должна храниться в десятичном виде?@@Fingercomp, а насколько критично быстродействие в твоем проекте?Если оба ответа «да», то придется написать другую библиотеку. Иначе потребуется как минимум одна промежуточная строка и три дополнительных преобразования.Насколько я знаю финнгер перешел на другую библиотеку. Хранить числа в виде строки — неэффективно. Куда лучше держать число в массиве чисел. Скорость критична.
Быстрая реализация тут.
В ней нет реализации битовых операций, но даже эмулируя их умножением все работает куда быстрее чем с метачислами.
PS: Да, она только для целыз чисел
PPS: Нет, я не мультиакк фингера
-
Раз пошла такая пьянка, напишу и я свою идейку по этому поводу. В общем всем надоел привычный ик, таум и прочая фигня банальная.
Так что я подумал (нет) и придумал такую лепешку:
- Ну всякая мелочь, опенкомпы, компутероникс и прочая дребедень естественно.
- Чизель, куда же без него.
- Immersing Engineering (тот самый который добавляет
лагопечкикрутые ветряные мельницы и куча механизмов которые можно интегрировать с опенкомпами. - Термалочка, как жи так.
- ЕндерЙошка.
- RFTools, RFDrills, надо же куда то все девать.
- ЕхНихило, раз летать на островах норкомагических захотели.
- BigReactors, строить
лагореакторы которые само собой интегрировать с компами. - Можно влепить MineFactoryReloaded, Forestry, Agricraft, опционально.
Лепешка неплохая думаю получилась бы, главное назначить какого нибудь админа (мецопайку например) на проверку островов и регена лагулек.
-
2
-
Раз в чате скинули ссылку на эту тему, покажу как можно оптимизировать способ @Doob.
code = code .. data
Ну вобщем, тут каждый на каждый чанк вызывается конкатенацтя строк. Но в луа неэффективно много раз конкатенировать строки. Вместо этого лучше создать буффер-таблицу и вставлять в него чанки испоьзуя table.insert, и уже потом получить из таблицы строку через table.concat.Например так:
local code = {} ... table.insert(code, data) ... print(table.concat(code))=)
-
2
-
-
Еще бы OpenFTP-сервер...
OpenComputers умеет только открывать TCP сокеты, а вот создавать TCP слушателя он не может, к сожалению. Я думаю такое искусственное ограничение создано дабы облегчить нагрузку на сервер. Он и так держит соеденение с кучей клиентов, если к этому добавить OpenComputers он вообще грохнется. =)
...Как то не подумал об этом >_<. Ну вобщем будет что то вроде такого когда я буду налаживать кроссплатформеность OpenFTP. А имено: plan9k. На этой операционке клиент запускается, но багает прогрессбар и цветной-убер вывод. Пока правда, к сожалению прогрессбар не получаается починить, тут уж проблема в самой plan9k - не может он выводить юникод из за бага. (Говорил об этом с создателем plan9k).
Браво!Еще бы telnet или ssh, и все барьеры сняты.
telnet реализовать будет не так уж и сложно, а вот с ssh проблемы обеспечены. ssh работае поверх tls сокетов, кои OpenComputers не поддерживает. Потому нужно с ними разбираться, курить тонны rfc-шек и просить помощи у "больших дяденек". =)
Да и скорее всего ssh такой будет требовать дата-карту, ибо tls использует aes шифрование.
-
OpenFTP
Иногда нужно скачать большое количество файлов с FTP сервера. Это затруднительно, когда дело доходит до OpenComputers, потому что FTP клиента попросту нет. Приходится изощряться, заливать файлы на HTTP сервер, pastebin или вовсе вставлять их из буфера обмена.
И все было бы хорошо, если бы были эти способы удобными. Потому написал я FTP клиент для OpenComputers. Название ему — OpenFTP.
Он поддерживает большинство функций, как и старшие братья OpenFTP, такие как FileZilla и bsd FTP.
Интерфейс схож с таковым из bsd FTP. Приятная командная строка, команды похожи на *NIX команды, например rm, ls, rename, mkdir.
Скорость для OpenComputers бомбезная. Почти 50 кб в секунду на чтение, и в 10 раз больше на запись. Учитывая вместимость дисков, это очень хорошие показатели.
Скачать: pastebin get UPcwLA9ep /bin/ftp.lua
Для подключения к серверу набираем ftp <хост сервера> [порт сервера (по умолчанию 21)]. После этого OpenFTP попросит имя пользователя и пароль.
Увидели ftp> — соединение успешно налажено. Теперь мы можем писать команды для общения с сервером.
Команды
- cd <путь> — перейти в директорию по указанному пути. Работает аналогично таковой в OpenOS оболочке.
- .. — перейти в директорию-родитель. Результат будет таким же, как в cd ... Например, если мы были в директории /home/peter/programs, после применения команды мы окажемся в директории /home/peter.
- pwd — указывает директорию в которой мы находимся.
- ls [-s] [путь] — указывает список файлов в указанной директории (по умолчанию — текущая директория). Флаг -s применяется в том случае, если мы хотим неполный вывод, без полезной информации вроде даты изменения и автора.
- rm [-d] <путь> — удаляет файл или папку. Если мы хотим удалить папку, добавляем ключик -d.
- mkdir <путь> — создать новую директорию по указанному пути.
- rename <было> <стало> — переименовать файл или директорию. После выполнения команды, если все пройдет успешно, было сменится на стало. Алиас: rn.
- ascii — переходит в ASCII режим передачи файлов. Использовать не рекомендуется, т.к. возможны последующие искажения файлов.
- binary — переходит в бинарный режим передачи файлов. Рекомендуется использовать именно его, таким образом абсолютно все символы передадутся без потерь. По умолчанию, к слову, используется именно он.
Ох, и самое главное:
- get <путь до файла на сервере> [путь до файла на клиенте] — скачивает указанный файл с сервера.
- put <путь до файла на клиенте> [путь до файла на сервере] — загружает указанный файл на сервер.
- nop — команда которая ничего не сделает. (не шучу, в FTP протоколе правда есть команда такая, правда называется она NOOP = No Operation)
У каждой команды есть также флаг --help, который показывает помощь (на английском)
Хочу также сказать спасибо @Fingercomp за предоставленный прогресс-бар. Без него жизнь малиной не казалась бы =). Также спасибо ему за доступ на свой FTP сервер, где я мог спокойно тестировать программу.
Enjoy!
PS:
=(
-
24
-
1
-
Поддерживаю мнение @@Fingercomp. Игра офигеннейшая.
P.S: Должна победить в конкурсе.
P.P.S: Да я на стива поставил 2 тортика! 100% победит!
-
MoonyLambdaВы наверное знаете что сейчас проходит конкурс MoonJam. В общем суть в том что бы написать что-нибудь на MoonScript за неделю. Как говорил уже тотора, что-то серьезное за неделю не написать, но попробовать, поразвлечься, и написать что-нибудь интересное можно.
В общем в этой теме буду показывать мой проект. И это... Библиотека для функционального программирования (далее просто - ФП)!
Луа не предоставляет стандартных средств для ФП, потому я написал свою библиотеку. Чем то она похожа на реализацию такового функционала в языке Python, а чем то нет.
Суть в том что функциональное программирование очень сильно упрощает работу с данными, например вместо пяти строк мы напишем одну строку.
Все примеры в MoonScript, но в спойлерах будет эквивалент на луа. f - библиотека подключенная через require
Начнем с самого простого, сложить массив чисел.
f.reduce f.add, {1, 2, 3} --> 6f.reduce(f.add, {1, 2, 3}) --> 6Точно таким же образом, мы можем перемножить все числа f.mul вместо f.add, или соответственно разделить, вычесть или возвести в степень - f.div, f.sub и f.pow
А если, к примеру, нам нужно взять массив и выкинуть из него все нечетные числа. Это тоже возможно.
f.filter f.even, {1, 2, 3, 4} --> {2, 4}f.filter(f.even, {1, 2, 3, 4}) --> {2, 4}А теперь, достанем все числа которые одновременно и меньше пяти, и четные. Это не составит труда
f.filter f.even, f.filter ((a) -> a < 5), {1, 2, 4, 5, 6, 7} --> {2, 4}f.filter(f.even, f.filter((function(a) return a < 5 end), {1, 2, 4, 5, 6, 7})) --> {2, 4}Хочу отметить, что нам не обязательно постоянно писать огромные цепочки из вызовов. Все функции в библиотеке каррированы.
selectEven = f.filter f.even selectEven {1, 2, 3, 4, 5} --> {2, 4}local selectEven = f.filter(f.even) selectEven({1, 2, 3, 4, 5}) --> {2, 4}...Но мы можем каррировать свою функцию!
pow = f.curry (a, b) -> a ^ b pow2 = pow 2 pow 3, 3 --> 27 pow2 3 --> 8
local pow = f.curry(function (a, b) a ^ b end) local pow2 = pow(2) pow(3, 3) --> 27 pow2(3) --> 8
К слову, именно так определена в библиотеке функция f.pow.
Каррированная функция сама определяет, что ей вернуть, функцию которая примет недостающие аргументы, или результат. Мы можем каррировать функцию с любым количеством аргументов, так просто!

Реверс таблицы - легко, расплющить таблицу - легко, изменить таблицу - легко.
Но самое главное... Все функции чистые. Ни одна функция этой библиотеки не изменяет данные, и не зависит от внешних данных.
Вполне продакшен-ready пример:
first_letter = (a) -> a\sub 1, 1 f.group first_letter, {"Miku Chan", "Mayonnaise", "LeshaInc", "Loli", "Totoro"} --> {M: {"Miku Chan", "Mayonnaise"}, L: {"LeshaInc", "Loli"}, T: {"Totoro"}}local first_letter = function(a) return a:sub(1, 1) end f.group(first_letter, {"Miku Chan", "Mayonnaise", "LeshaInc", "Loli", "Totoro"}) --> {M = {"Miku Chan", "Mayonnaise"}, L = {"LeshaInc", "Loli"}, T = {"Totoro"}}И все это становится таким простым используя библиотеку MoonyLambda.
Скачать
- Исходный код: pastebin.com/fFEFvX5D
- Скомпилированная и минифицированная версия: pastebin.com/K4b9sREs
Документация
...будет постепенно писаться в этой теме. Ссылки будут тут.
Функциональный стиль выглядит гораздо читаймей, чем императивней стиль. Когда в императивном стиле мы пишем непонятный цикл, который непонятно что делает, тут мы пишем несколько строк кода, который понятен с первого взгляда.
-
3
-
1
-
например по 10 мкc, os.sleep(10^6)Я кажется понял почему ракеты так падают часто.
10^6 = 1 000 000 "спим миллион секунд" вместо "спим 10 микросекунд"Минус потерял ты, os.sleep(10^-6)

-
local component = require("component") local os = require("os") local term = require("term") term.clear() os.execute("resolution 1 1") while true do print("█") term.clear() endпосмотрел код танцпола (вот он ^)... кто мне объяснит зачем он, и зачем цикл тут. кто мешает взять серые блоки? или у нас нанотехнологии тут?
-
4
-
-
Ну так эмуляция же.
Эта "эмуляция" ни капли не похожа на многопоточность. :/
-
Где многопоточность? Может я плохо вижу, к окулисту пора сходить?

-
1
-
-
event.listen forever

Это точно.
Весь код в спойлеры надо добавить.
Со спойлерами пропадает весь запах "крутого туториала".
А еще пропадает юзабилити, надо тыкать на эти кнопуськи "Открыть", не удобно ИМХО. -
Если вы когда нибудь сталкивались с созданием серверов под OpenOS, вам знакома проблема блокирования всего компьютера. Его нельзя использовать, пока сервер не выключится. Некоторые придумывали свои велосипеды, которые запускали event.listen или event.ignore. Но не то это!
Для таких вещей существует rc, в OpenOS. Сейчас я расскажу вам, что это за зверь, где он живет и зачем он нам.
Немного теории
Итак, все скрипты для rc хранятся в папочке /etc/rc.d/. Любой файл с расширением .lua, который находится там, является rc-скриптом.
У такого скрипта все глобальные функции это команды. Запустить такую команду можно командой rc <имя скрипта, без расширения> <имя команды>. Например если мы создадим глобальную функцию start в файлике /etc/rc.d/test.lua, то запустив команду rc test start эта команда выполнится. Все просто.
Получить список команд определенного скрипта можно при помощи команды rc <имя скрипта, без расширения>. Например так: rc test.
RC сам создает некоторые команды, хотя мы их можем переопределить:- enable/disable. Соответственно включают/выключают скрипт. Все включенные скрипты получат команду start при запуске компьютера.
- restart если есть start и stop. Перезапускает скрипт, то есть поочередно запускает stop и start.
Каждый скрипт можно конфигурировать. Конфиг находится в /etc/rc.cfg.
Формат файла прост:<имя скрипта> = <конфиг: все что угодно, таблица, текст, число>
По сути это обычный луа-файл, все глобальные значения из которого считаются полями.
Каждый скрипт может получить доступ к своему конфигу. Конфиг записывается в переменную args.
С теорией покончено, приступим к практике!
Практика
Я предлагаю написать простой эхо-сервер. Он будет слушать определенный порт (из конфига), и отвечать на любое сообщение эхом.
Начнем!
Создадим файл /etc/rc,d/echo.lua, и начнем писать в нем код.
Нам понадобятся некоторые переменные
-- нам понадобятся библиотека event -- что бы установить свой обработчик событий local event = require("event") -- еще нам нужна библиотека computer -- что бы подключить компонент `modem` local component = require("component") -- будем считать количество ответов -- зачем? для диванных аналитиков конечно! local count = 0 -- будем хранить текущее положение -- что б никто не запустил случайно сервер два раза local started = false -- сюда запишем прокси модема, когда убедимся что он есть local modem -- а сюда запишем рабочий порт local portСоздадим обработчик события modem_message. Он будет вызываться при каждом сообщении по сетевой карте.
-- функция ниже будет запускаться -- при каждом сообщении по сетевой плате local function onModemMessage(_, _, snd, prt, _, ...) -- `_` в нашем понимании - неиспользуемый аргумент -- если порт сообщения не совпадает с портом -- из конфига, выходим print(prt) if prt ~= port then return end -- добавим еденицу к счетчику count = count + 1 -- здесь мы уверены, что modem существует -- так как обработчик поставится только если у нас есть модем modem.send(snd, prt, ...) -- / | \ -- получатель, порт, данные -- просто напросто пересылаем отправителю то что он -- отправил нам =) endТеперь мы добавим команду start, которая запустит наш сервер.
-- функция ниже глобальная, `local` нет. -- потому _rc_ ее будет смело считать командой -- а команда эта будет запускать наш сервер function start() -- мы должны проверить, есть ли у нашего сервера -- сетевая карта if not component.isAvailable("modem") then -- если ее нет, мы выводим ошибку и выходим io.stderr:write("Сетевая карта не найдена!") return end -- еще нам нужно проверить, выключены ли мы -- если это не так, снова ошибка if started then io.stderr:write("Сервер уже запущен!") return end count = 0 -- сбросим счетчик started = true -- теперь мы знаем, что с этого момента -- сервер включен. port = args or 666 -- args это переменная, в которую _rc_ запишет данные из конфига -- конфиг находится в /etc/rc.cfg -- но если в конфиге порт не настроен, используем дефолтный modem = component.modem -- мы проверили, что модем существует, -- поэтому смело его подключаем -- откроем порт modem.open(port) -- нам нужно сделать так, что бы все сообщения -- по сетевой карте обслуживались нашей функцией event.listen("modem_message", onModemMessage) -- ну а теперь мы точно включились! endКуда без команды stop? Добавим ее!
-- эта функция тоже глобальная, поэтому считаем ее командой -- эта команда остановит сервер function stop() -- мы должны проверить, включен ли вообще сервер -- если он не включен, какой толк его выключать, верно? if not started then -- если он не включен, выводим ошибку и выходим io.stderr:write("Сервер уже выключен!") return end count = 0 -- опять же сбрасываем счетчик started = false -- запоминаем, что теперь -- сервер выключен -- теперь нам нужно по-настоящему выключить сервер event.ignore("modem_message", onModemMessage) -- все! с этого момента сервер выключен, и не принимает сообщение endЕще самая малость, добавим команду printCount, которая будет отображать количество полученных сообщений.
-- и это тоже команда, думаю вы понимаете -- а эта команда напишет количество отправленных сообщений function printCount() -- выводить информацию будем только если сервер не запущен -- поэтому выведем ошибку, если он не включен if not started then io.stderr:write("Сервер выключен!") return end print(count) -- пишем количество подключений -- диванные аналитики ликуют! endНу вот и все, программа сделана, диванные аналитики ликуют, инженеры недоумевают.

Полный код:
-- нам понадобятся библиотека event -- что бы установить свой обработчик событий local event = require("event") -- еще нам нужна библиотека computer -- что бы подключить компонент `modem` local component = require("component") -- будем считать количество ответов -- зачем? для диванных аналитиков конечно! local count = 0 -- будем хранить текущее положение -- что б никто не запустил случайно сервер два раза local started = false -- сюда запишем прокси модема, когда убедимся что он есть local modem -- а сюда запишем рабочий порт local port -- функция ниже будет запускаться local function onModemMessage(_, _, snd, prt, _, ...) -- `_` в нашем понимании - неиспользуемый аргумент -- если порт сообщения не совпадает с портом -- из конфига, выходим print(prt) if prt ~= port then return end -- добавим еденицу к счетчику count = count + 1 -- здесь мы уверены, что modem существует -- так как обработчик поставится только если у нас есть модем modem.send(snd, prt, ...) -- / | \ -- получатель, порт, данные -- просто напросто пересылаем отправителю то что он -- отправил нам =) end -- функция ниже глобальная, `local` нет. -- потому _rc_ ее будет смело считать командой -- а команда эта будет запускать наш сервер function start() -- мы должны проверить, есть ли у нашего сервера -- сетевая карта if not component.isAvailable("modem") then -- если ее нет, мы выводим ошибку и выходим io.stderr:write("Сетевая карта не найдена!") return end -- еще нам нужно проверить, выключены ли мы -- если это не так, снова ошибка if started then io.stderr:write("Сервер уже запущен!") return end count = 0 -- сбросим счетчик started = true -- теперь мы знаем, что с этого момента -- сервер включен. port = args or 666 -- args это переменная, в которую _rc_ запишет данные из конфига -- конфиг находится в /etc/rc.cfg -- но если в конфиге порт не настроен, используем дефолтный modem = component.modem -- мы проверили, что модем существует, -- поэтому смело его подключаем -- откроем порт modem.open(port) -- нам нужно сделать так, что бы все сообщения -- по сетевой карте обслуживались нашей функцией event.listen("modem_message", onModemMessage) -- ну а теперь мы точно включились! end -- эта функция тоже глобальная, поэтому считаем ее командой -- эта команда остановит сервер function stop() -- мы должны проверить, включен ли вообще сервер -- если он не включен, какой толк его выключать, верно? if not started then -- если он не включен, выводим ошибку и выходим io.stderr:write("Сервер уже выключен!") return end count = 0 -- опять же сбрасываем счетчик started = false -- запоминаем, что теперь -- сервер выключен -- теперь нам нужно по-настоящему выключить сервер event.ignore("modem_message", onModemMessage) -- все! с этого момента сервер выключен, и не принимает сообщение end -- и это тоже команда, думаю вы понимаете -- а эта команда напишет количество отправленных сообщений function printCount() -- выводить информацию будем только если сервер не запущен -- поэтому выведем ошибку, если он не включен if not started then io.stderr:write("Сервер выключен!") return end print(count) -- пишем количество подключений -- диванные аналитики ликуют! endВремя QA!

Симулируем Васю Пупкина...

А вот уже на другом компьютере отправлено сообщение на работающий сервер.

Счетчик тоже работает.

Установим значение в конфиге.

Проверим...

Все работает, инженеры ликуют!

Такую систему очень удобно использовать для всяческих серверов. Сервер может спокойно работать в фоне, а в главном потоке спокойно можно запускать консоль сервера, интерпретатор луа,
rm -rf /...Enjoy!
-
9
-
2
-
Большие сложности - больше лагов. Зачем мне робот который будет тупить или нагружать сервер? Это же луа. Его обработка значительно дольше чем у полноценных яп.
Значит оптимизировать поиск путей, или вообще обойтись без поиска пути и использовать дорожки из специальных блоков. А андроид пусть идет по этой дорожке только
-
1
-
-
Да и как ты себе представляешь запрограммированных роботов? Это не дроны которые летают, придётся алгоритмы обхода препятствий лепить, слишком сложное ПО будет на них. С учётом того что даже на роботов никто не делает этот обход препятствий, а просто ставят улучшение перо.Не любишь сложности?...

-
1
-
-
Я вижу только одну проблему:
- Кто это все реализует
-
7
-
А можно мета-методами для _G определить неприсваеваемый объект, всегда возвращающий nil
setmetatable(_G, { __index = function (self, k) if k == "_" then return nil else return rawget(self, k) end end}) print(_) --> nil _ = 22 print(_) --> nilэто было просто
-
3
-
-
event.pull([eventName: string], [timeout: number])-
2
-
-
Btn3=Form1:addButton(2,5,"ЦИКЛ",function() while true do rs.setOutput(sides.south, 0) rs.setOutput(sides.south, 15) end end)
Я никакого слипа не вижуЛэйн, замени на
Btn3=Form1:addButton(2,5,"ЦИКЛ",function()if noExit==true then noExit=false else noExit=true end while noExit do rs.setOutput(sides.south, 0) os.sleep(длина импульса) rs.setOutput(sides.south, 15) end end)
noExit = not noExit
-
1
-
-
Это чтобы они не слепли от его совершенства.
А вместо этого преисполнялись праведного желания все улушить, и помогали мне с работой. )
Народ, объявленье срочно. Нужно помочь @Totoro с кактусоводством!!!
<LeshaInc> Totoro, где ты работаешь? <Totoro> на кактусовой ферме кактусоводом
-
Топикстартер, как и многие на этом форуме, пришел сюда потому что ему нравится программировать. И не просто программировать, а на Луа. И не просто на Луа, а в среде Майнкрафта. Есть в этом какой-то особый шарм. И указывать ему другие пути самовыражения, на мой взгляд, не корректно.У меня был
, направленный @@qwertyMAN, а не топикстартеру. :P-
1
-
-
Почему скрин моего, человеческого дизайна не добавили? Голосовалку народу!
-
Судя по проделанной работе игра серьёзная, но почему майнкрафт?Можно же скачать какой нибудь движок на lua и писать игры там. И в скорости и в графике не будет ограничений, как в СС и ОС.
Если хочешь создавать действительно серьёзную игру, забрасывай майнкрафт и прогай на полноценном lua движке.
Судя по твоим словам работа была бы проделана очень серьезная, но почему луа?
Можно же скачать какой нибудь двжиок на C++/Rust и писать игры там. И в скорости и в графике не будет ограничений, как в луа.
Если хочешь создавать действительно серьезную игру, забрасывай луа и прогай на полноценном C++/Rust двжике.
-
1
-
-
тут нужна децентрализованная сеть. у меня есть прототип. я бы его продолжал пилить, но проблема, сообщения при маленькой мощности модема теряются, а при большой сложно дебажить, большие расстояния.
буду ждать бумеранга, а там уже думать что то

Библиотека ПИД-регулятора
в Библиотеки
Опубликовано:
Зачем оно нужно рядовому Васе Пупкину который вчера изучил луа и хочет программулек понаписывать? Объясните.