Ktlo 789 Опубликовано: 8 июня, 2015 (изменено) Пока я писал свою систему для ComputerCraft, мне пришла мысль изобрести велосипед в виде функции require(), которая была удалена из мода по неизвестным мне причинам. Собственно вот код: function require(...) local i local libs = { } for i=1, #arg do arg[i] = fs.combine("", arg[i]) --В кавычки можно написать путь к директории с вашими библиотеками. if not fs.exists(arg[i]) or fs.isDir(arg[i]) then error("Couldn't find a file by the path #"..i, 2) end local g = getfenv() local t = { } setmetatable(t, {__index = _G}) t.shell = shell t.multishell = multishell setfenv(1, t) local f=function() dofile(arg[i]) end local ok, err = pcall(f) setfenv(1, g) if not ok then error(err..", in #"..i, 2) end libs[i] = t end return unpack(libs) end ,,Что-же эта функция делает?"- может кто-то спросить, а тоже что и раньше. Она загружает библиотеку по выбранному вами пути в таблицу (или правильнее будет сказать, в окружение). Самое главное - это то, что вы сможете загружать любое API в любую переменную, в том числе и локальную. Выглядит это примерно так: local firstVariable, secondVariable = require("APIs/HelloWorld.api", "APIs/Object.lua") Как вы наверное уже поняли, можно загружать не ограниченное количество библиотек за раз. Особенности: загрузка нескольких переменных одновременно; возможность не захламлять глобальное окружение; использование библиотек в любой другой таблице; пропуск shell API и multishell API в окружение вашего API*; запуск вашего файла с библиотекой во время загрузки (ну это я из пальца выжимаю); в отличии от стандартной функции, вы не можете использовать require()для поиска библиотеки среди файлов, но по-моему это лишнее в CC, но вы можете указать одну папку (заметка на счёт этого в коде); вы можете убедится в том, что окружение, куда вы запихнули свою библиотеку, не содержит копию всех функций и переменных из глобального окружения (что хорошо сказывается на производительности). Для того, чтобы использовать эту функцию, просто вставьте её код в вашу программу. Надеюсь, что это кому-нибудь пригодится. Дополнение. Я переделал функцию и добавил взаимодействие с глобальной таблицей package, этот вариант намного лучше предыдущего. Чтобы использовать его скачайте файл с помощью команды: pastebin get naxXwUey package Далее загрузите в глобальное окружение с помощью функции dofile("package"). Теперь рассмотрим, что же я изменил. Во-первых, при повторном вызове функции с одним и тем же API, вы получаете ту же самую таблицу, то-есть: local var1 = require("lib1") local var2 = require("lib1") print(var1 == var2) -->Вывод: true Так получается, потому что каждая новая загруженная библиотека сохраняется в таблице package.loaded, а при повторном вызове, вам выдаётся значение из этой таблицы. Я также внес все стандартные API ComputerCraft'а в эту таблицу. Во-вторых, я добавил значение package.path, оно работает точно также, как и в оригинале. Просто перечисляете директории с библиотеками в током виде: package.path = "/APIs/?.lua;/Lib/?;/?" Вы можете изменить это значение в самом файле, я там оставил комментарий. Также я добавил таблицу package.preload, которая содержит специальные пользовательские функции для загрузки конкретного API, по стандарту я её оставил пустой (что логично). Ключи таких функций являются названиями API, а возвращать они должны функции, которые возвращают само API (правда не знаю, кому это может понадобиться). И наконец, package.loaders, в этом массиве, расположены функции для загрузки всех API. Их пока две. Аргументом этой функции должно быть имя модуля, а возвращать она должна функцию, загружающую API. Для тех, кто ничего не понял, просто знайте второй вариант этой функции с дополнением лучше.))) *Да-да, теперь вам не придётся мучиться и придумывать изощрённые способы получения допуска к функциям этого API в вашей библиотеке! Изменено 9 июня, 2015 пользователем Ktlo 5 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Asummonster 592 Опубликовано: 8 июня, 2015 os.loadAPI чем не устраивал?Но за прошу лайк, часто когда с ок компа сажусь за кк комп, пишу половину функций неверно. Вот только проблемам есть. Кк не поддерживает полную вставку кода, только 1 строка, а смысл этого велосипеда, если придётся писать os.loadAPI? Хотя, можно её как глобальную функцию в стартап вставить Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Ktlo Автор темы 789 Опубликовано: 8 июня, 2015 os.loadAPI чем не устраивал?Но за прошу лайк, часто когда с ок компа сажусь за кк комп, пишу половину функций неверно. Вот только проблемам есть. Кк не поддерживает полную вставку кода, только 1 строка, а смысл этого велосипеда, если придётся писать os.loadAPI? Хотя, можно её как глобальную функцию в стартап вставить Просто, используя эту функцию, можно загружать библиотеки в локальную переменную, не трогая глобальную, а также использовать shell API. Кроме способа, который ты описал, можно использовать функцию dofile("fileName"), если хочешь хранить её в отдельном от программы файле. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Asummonster 592 Опубликовано: 8 июня, 2015 Ах, да. В ок ее вырезали, поэтому забыл. А если переменная не локальная, то вообще легко - shell.run . Просто в кк особой разницы нет, то ли это глобальная пепеменная, то ли локальная. А вот в ок смысл есть, там память конччится. И, желательно, делай програмки на ок, так как кк, как ни странно , тут нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Krutoy 1 169 Опубликовано: 9 июня, 2015 Код хороший, но подожди ка, а где же таблица и функции package? Это ведь специальный инструмент, что бы не забивать оперативную память, и ускорить работу программы при нескольких одинаковых вызовах require(). Больше об этом написано здесь http://ilovelua.narod.ru/about_lua.html#Module_loaders Можешь посмотреть как require и package реализовано в ОС https://github.com/MightyPirates/OpenComputers/blob/master-MC1.7.10/src/main/resources/assets/opencomputers/loot/OpenOS/lib/package.lua Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Asummonster 592 Опубликовано: 9 июня, 2015 Код хороший, но подожди ка, а где же таблица и функции package? Это ведь специальный инструмент, что бы не забивать оперативную память, и ускорить работу программы при нескольких одинаковых вызовах require().Больше об этом написано здесь http://ilovelua.narod.ru/about_lua.html#Module_loaders Можешь посмотреть как require и package реализовано в ОС https://github.com/MightyPirates/OpenComputers/blob/master-MC1.7.10/src/main/resources/assets/opencomputers/loot/OpenOS/lib/package.lua Спасибо!Теперь засуну в прогруженные таблицы computer и component Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Zer0Galaxy 2 187 Опубликовано: 9 июня, 2015 Имею эмулятор СС, но не имею эмулятора ОС. Может быть можно, написав несколько подобных функций, сэмулировать ОС на эмуляторе СС? Вот require мы уже имеем. Теперь надо создать библиотеки computer, component, event и т.д и будем иметь полновесный эмулятор ОС. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Asummonster 592 Опубликовано: 9 июня, 2015 Имею эмулятор СС, но не имею эмулятора ОС. Может быть можно, написав несколько подобных функций, сэмулировать ОС на эмуляторе СС? Вот require мы уже имеем. Теперь надо создать библиотеки computer, component, event и т.д и будем иметь полновесный эмулятор ОС. А зачем эмулировать event? os.pullEvent есть, os.listen сделать просто на параллели и os.pullEvent Зачем эмулировать компонент? Есть же peripheral.wrap и peripheral.call А функции computer api выполняет os Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Zer0Galaxy 2 187 Опубликовано: 9 июня, 2015 А зачем эмулировать event? os.pullEvent есть, os.listen сделать просто на параллели и os.pullEvent Зачем эмулировать компонент? Есть же peripheral.wrap и peripheral.call А функции computer api выполняет os Затем, чтобы можно было программы, написанные для ОС, отлаживать на эмуляторе СС Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Asummonster 592 Опубликовано: 9 июня, 2015 Я для этих целей использую замену текста=) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Ktlo Автор темы 789 Опубликовано: 9 июня, 2015 Код хороший, но подожди ка, а где же таблица и функции package? Это ведь специальный инструмент, что бы не забивать оперативную память, и ускорить работу программы при нескольких одинаковых вызовах require(). Больше об этом написано здесь http://ilovelua.narod.ru/about_lua.html#Module_loaders Можешь посмотреть как require и package реализовано в ОС https://github.com/MightyPirates/OpenComputers/blob/master-MC1.7.10/src/main/resources/assets/opencomputers/loot/OpenOS/lib/package.lua Я изменил код теперь всё должно работать, как было написано в той статье. Спасибо за информацию. Моя программа вышла меньше чем OC. Хотя я её особо не смотрел 2 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах