Dennis_Chikin 3 658 Опубликовано 4 Января 2015 Поделиться Опубликовано 4 Января 2015 (изменено) С чего начинать и где взять. Установка Lua:http://www.amk-team.ru/forum/index.php?showtopic=11584&p=629106 Руководство «Программирование на языке Lua», третье издание:http://www.amk-team.ru/forum/index.php?showtopic=11584&p=905308 Изменено 2 Марта 2015 пользователем Kirgudu Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
Artos 99 Опубликовано 6 Февраля 2012 Поделиться Опубликовано 6 Февраля 2012 (изменено) Ну а по "нормальному", т.е. с проверками корректности заданных строк: prefetch(new_scr) --/ не обязательно, но не помешает ... if type(_G[new_scr]) == 'table' and type(_G[new_scr][func_1]) == 'function' then _G[new_scr][func_1]() --/ вызов функции end Изменено 6 Февраля 2012 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
Malandrinus 615 Опубликовано 6 Февраля 2012 Автор Поделиться Опубликовано 6 Февраля 2012 Artos, все же вариант Real Wolf более общий и гибкий. Примерно так у меня было сделано в моей реализации сохраняемых таймеров. local f, msg = loadstring("return "..timer_class.."(...)" local timer = f() timer_class - это строка с именем класса (функции создания) таймера, которая сохраняется и потом загружается заново. Так я избежал необходимости делить строку на части, т.е. об этом можно вообще не думать. Полный текст приводил в этом посте. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Artos 99 Опубликовано 6 Февраля 2012 Поделиться Опубликовано 6 Февраля 2012 malandrinus, я все же исхожу из контекста вопроса, в котором говорится о некоей таблице и как минимум о раздельном хранении строк имен модулей/скриптов и функций. Ну а что более обще иль гибче - все же опять и от конкретного контекста зависит и от вкусов. Вариант с _G[file_name][func_name] использован разработчиками в том же xr_logic.script, что дает возможность "вспомнить" тем, кто подзабыл как вызвать функцию. "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
Malandrinus 615 Опубликовано 6 Февраля 2012 Автор Поделиться Опубликовано 6 Февраля 2012 Artos, ок, давай обобщим, чтобы была польза от обсуждения. вариант с _G[<имя модуля>][<имя функции>] достоинства: быстрый, годится для частых вызовов недостатки: 1. Требует парсинга исходной строки для разбиения ее на имя модуля / имя функции. 2. Ограничивает общий вид строки с полным адресом функции. Грубо говоря, количество точек должно быть фиксированное. Более точно, строка должна иметь предсказуемый формат для парсинга. вариант с loadstring достоинства: 1. Простой. Код для вызова элементарен 2. Нет ограничения на вид строки с именем вызываемой функции. Это даже может быть что-то нетривиальное, лишь бы было кодом Lua. недостатки: Затратный с точки зрения времени выполнения. loadstring компилирует вспомогательную функцию, что естественно требует затрат. Во многих случаях это не критично, как в упомянутых таймерах. Там это используется для разового действия создания таймера. Частично недостаток можно скомпенсировать, сохранив вспомогательную функцию. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Artos 99 Опубликовано 6 Февраля 2012 Поделиться Опубликовано 6 Февраля 2012 Согласен с таким резюме. Может быть добавил бы еще для _G[<имя модуля>]: Недостаток в том, что при наличии модуля с синтаксической ошибкой в нем в игровой папке скриптов ,попытка включить модуль в глобальную метатаблицу может привести к фатальной ошибке движка с "безлоговым" вылетом. Достоинство - возможность из заготовленного массива имен комбинировать имена модулей и функций, переключаясь на функции в разных модулях. "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
*Shoker* 322 Опубликовано 10 Февраля 2012 Поделиться Опубликовано 10 Февраля 2012 (изменено) Как получить текстовое название скрипта, в котором находится функция? Изменено 10 Февраля 2012 пользователем *Shoker* Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Ссылка на комментарий
Malandrinus 615 Опубликовано 10 Февраля 2012 Автор Поделиться Опубликовано 10 Февраля 2012 *Shoker*, В чистом Lua можно только через debug. В сталкере однако есть небольшое расширение на этот счёт. script_name() - возвращает имя текущего модуля без расширения Также на всякий случай this - ссылка на текущий модуль (таблица) Работает только в файлах с расширением *.script 1 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Nazgool 250 Опубликовано 10 Февраля 2012 Поделиться Опубликовано 10 Февраля 2012 (изменено) *Shoker*, Нужно знать откуда и при каких условиях запрашивается это имя. А в общем случае так : имя файла *.sсriрt является модулем, а значит полем глобальной таблицы luа, с ключем - именем модуля (именем файла) и значением - таблица. В этой таблице находятся все глобально объявленные (для данного модуля) поля. И твоя искомая функция тоже (если не объявлена локально). Вывод. Парси _G на предмет наличия таблиц, в которых есть поле с ключем - именем функции. Ключ найденной таблицы и будет именем файла. Нюансы пока не трогаем. Изменено 10 Февраля 2012 пользователем Gun12 Ссылка на комментарий
Malandrinus 615 Опубликовано 10 Февраля 2012 Автор Поделиться Опубликовано 10 Февраля 2012 Gun12, два вопроса: 1. Как отличить поля с таблицами-модулями от полей просто таблиц, коих в глобальном пространстве имен предостаточно? 2. Как узнать, что это именно твой текущий модуль? Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Nazgool 250 Опубликовано 10 Февраля 2012 Поделиться Опубликовано 10 Февраля 2012 malandrinus, Нюансы пока не трогаем. Нюансы заключаются в том, что хоть в разных модулях и можно создавать поля с одинаковыми именами, но делать этого я бы не стал (без причины). Уникальное имя будет только одно. И оно будет находиться только в той таблице, которая и будет считанным модулем. Ссылка на комментарий
abramcumner 1 153 Опубликовано 10 Февраля 2012 Поделиться Опубликовано 10 Февраля 2012 Gun12, ну, например, функция bind есть в куче модулей. И это хорошо, что она одинаково называется. Ссылка на комментарий
Nazgool 250 Опубликовано 10 Февраля 2012 Поделиться Опубликовано 10 Февраля 2012 abramcumner, Это тоже нюансы. Как упомянул malandrinus this - ссылка на текущий модуль (таблица) Парсим _G и сравниваем с this. Ссылка на комментарий
Malandrinus 615 Опубликовано 10 Февраля 2012 Автор Поделиться Опубликовано 10 Февраля 2012 Gun12, все же куча потенциальнфх проблем: 1. Совпадение имен. Во-первых, а чего плохого в том, что в разных модулях есть функции с разными именами? Наличие функций с одинаковыми именами может быть требованием дизайна, к примеру функции с именами типа init, setup, обработчики событий в модулях, связанных с системами сигналов (наподобие систем xStream или моей). Далее, в некой таблице, не являющейся модулем, может оказаться поле с именем, совпадающим с именем текущей функции. Это может вообще получиться непреднамеренно в ходе динамического заполнения таблицы из файла конфига или именами секций объектов или еще каким-то способом, исключающим контроль на стадии написания кода. 2. Функция может быть безымянной 3. Придется поддерживать синхронность между именем функции, которое в общем может измениться в ходе редизайна кода, и этим фрагментом. Если так рассуждать, то я вероятно выберу из двух зол меньшее: просто буду вставлять вручную строчку с именем модуля. Но однако есть script_name(), так что можно не париться. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
*Shoker* 322 Опубликовано 10 Февраля 2012 Поделиться Опубликовано 10 Февраля 2012 malandrinus, Gun12 Спасибо, подошёл script_name(), самый удобный способ, и без заморочек. Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Ссылка на комментарий
Nazgool 250 Опубликовано 10 Февраля 2012 Поделиться Опубликовано 10 Февраля 2012 malandrinus, То, что в Сталкере есть готовая функция - это конечно хорошо. Но не для меня, раз уж мы в теме о lua. Ну нет, скажем, готовой. Чем не подходит Парсим _G и сравниваем с this А говоря языком lua : Там где нужно парсим _G и сравниваем с _M. Ссылка на комментарий
Malandrinus 615 Опубликовано 10 Февраля 2012 Автор Поделиться Опубликовано 10 Февраля 2012 Gun12, если нужен чистый Lua, то тогда имеет смысл задействовать debug. Кажется функция debug.getinfo позволяет получать нужную информацию. К примеру, debug.getinfo(1,"n") дает имя текущей функции, но там можно получить гораздо больше информации. Может и имя модуля можно, точно не знаю. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Nazgool 250 Опубликовано 10 Февраля 2012 Поделиться Опубликовано 10 Февраля 2012 (изменено) Это известно. Если нужно, можно поговорить и о чистом luа. Но всё же делаем с оглядкой на сталкер. Dеbug исключается. Изменено 10 Февраля 2012 пользователем Gun12 Ссылка на комментарий
Artos 99 Опубликовано 10 Февраля 2012 Поделиться Опубликовано 10 Февраля 2012 (изменено) Что-то вы заспорились ... *Shoker*, задал, как обычно, вопрос с общей формулировкой для довольно локальной своей задачи и стОит ли копья ломать? Если требуется "изнутри" скрипта (игры) определить имя - лучше script_name() не придумать (чего и *Shoker*'у уже достаточно). Если же "снаружи", то вариантов три: 1. Смотрим, как сами разработчики передавали имя скрипта как аргумент в ту же функцию _g.debug_log ... 2. Используем debug.getinfo (для SHoC имеется расширитель от RvP), что и сами разрабы использовали: local script_тame = debug.getinfo(2).short_src:gsub('%.script', "") 3. Парсим, как предложил Gun12, глобальную метатаблицу _G и сравниваем поля с искомой функцией. Каждый выбирает свой путь, исходя из потребностей и возможностей. ИМХО. Изменено 10 Февраля 2012 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
Nazgool 250 Опубликовано 10 Февраля 2012 Поделиться Опубликовано 10 Февраля 2012 Аrtоs, да никто тут копья не ломает. Дискутируем, разбираемся, ищем, находим. Хорошо что есть с кем. А то молчат все, как будто всё знают. Ссылка на комментарий
Malandrinus 615 Опубликовано 10 Февраля 2012 Автор Поделиться Опубликовано 10 Февраля 2012 Gun12, Если нужно, можно поговорить и о чистом luа. Но всё же делаем с оглядкой на сталкер. Dеbug исключается. В сталкере есть готовое решение, в чистом Lua есть debug, да и никто не мешает его расширить по самое нехочу, поскольку Lua встраивается в свою систему в виде исходников. Что касается решения с перебором таблиц. Проблема в его неустойчивости и плохой сопровождаемости. Если объективно взвесить все плюсы и минусы, то получится, что проще в паре мест кода незатейливо вставить строки с именем файла, поставить внятный комментарий в этом месте и потом при случае эти строки обновлять. Можно для контроля соорудить функцию проверки наличия модуля и поставить там ассерты для отлова ситуации, когда имя файла изменилось, а эту строку не поменяли. В итоге, времени на сопровождение или адаптацию кода будет мизерным + код простой и прозрачный. С другой стороны, решение с перебором может в итоге потребовать примерно тех же самых манипуляций да еще и не дает стороцентной гарантии результата. Хотели сделать один раз и забыть, а получили сравнимый геморрой + усложненный код. Мне интересно, в связи с чем потребовалось узнавать имя модуля? У меня самого такая задача тоже возникала, но настолько редко, что я бы не заморачивался на автоматизацию даже при отсутствии штатных стредств. Добавлено через 29 мин.: Artos, Что-то вы заспорились ... так ведь и тема в основном для отвлеченной болтовни =) Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти