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 Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
Shredder 49 Опубликовано 12 Июня 2013 Поделиться Опубликовано 12 Июня 2013 Я уже давно использую функционал xr_s.script, хотя и немного правленый для моих целей, но мне не разу не приходилось регистрировать одну и ту же функцию несколько раз. Можешь привести практический пример, для чего это нужно? Ссылка на комментарий
ColR_iT 171 Опубликовано 12 Июня 2013 Поделиться Опубликовано 12 Июня 2013 (изменено) @Shredder, я ни слова не сказал, что я регистрирую одну и туже функцию несколько раз, т.к. это не логично, ведь она будет затираться последующими регистрациями. Именно поэтому пришлось сделать шесть функций с разным названием, но проделывающие абсолютно одинаковый алгоритм действий. Нужно мне это как раз в практических целях, когда необходимо медленно восстанавливать разные свойства ГГ: здоровье, выносливость, радиацию, при этом абсолютно независимо, поскольку действие на какое-либо свойство может прекратиться в любой момент. А так-как функций - шесть, решил сократить код, за что, собственно, спасибо Charsi, Gun12 и malandrinus - ваши советы, оказались как нельзя к стати. Изменено 12 Июня 2013 пользователем ColR_iT Ссылка на комментарий
Malandrinus 615 Опубликовано 12 Июня 2013 Автор Поделиться Опубликовано 12 Июня 2013 По поводу скрипта xr_s.script. По мне так нет смысла использовать такой упрощённый и древний подход, при том что имеются продвинутые системы сигналов.Я лично использую свою систему, но с таким же успехом можно использовать систему xStream. Вот последние версии (за песочницу xStream не уверен, это то, что мне доступно)."Песочница" от xStream. В архиве вложен файл описания xs_sandbox_manual.txtМенеджер сигналов. Описание добавлено комментариями в файле ogse_signals.script 2 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Shredder 49 Опубликовано 12 Июня 2013 Поделиться Опубликовано 12 Июня 2013 Можешь написать, в чём профит продвинутых систем? Глянул описание. В "Песочнице" принципиальной разницы не увидел, разве что пара плюшек (e:stop(), e:removeThisCallback()), но у меня такой надобности не возникало. В ogse_signals принцип регистрации практически тот же, про слоты не понял. Ссылка на комментарий
Malandrinus 615 Опубликовано 12 Июня 2013 Автор Поделиться Опубликовано 12 Июня 2013 про слоты не понял. слоты и сигналы Слот - это термин для колбеков, принятый в BOOST. В других местах могут называть по другому, к примеру делегатом. Сигнал тоже могут называть по-разному, событием к примеру. На терминологии лично я не настаиваю, главное, чтобы понимали друг друга. в чём профит продвинутых систем? Пожалуйста: xr_s.script Регистрация нового колбека требует изменения системного по сути скрипта, что плохо само по себе. Как следствие, добавляемый туда код каждый раз повторяет уже существующий (перебор таблицы и вызов), т.е. надо заниматься копипастой. Это тоже плохо само по себе, но вдобавок как следствие, если потребуется реализовать некий дополнительный сервис, обрамляющий вызов колбека (что имеется в виду поясню далее), то это будет затруднительно сделать, поскольку придётся добавлять этот код в каждый из уже добавленных колбеков. Впридачу добавление подобного сервиса затруднит добавление новых колбеков (надо будет каждый раз копипастить ещё больше кода). Функции используются в качестве ключей. Это не самый большой недостаток и легко преодолевается, как мы выяснили. Тем не менее в таком виде это исключает некоторые варианты использования, в частности использование в качестве колбеков методов классов. Система сигналов. Регистрация колбека не требует изменения системного модуля. Нужно получить ссылку на экземпляр менеджера сигналов с помощью глобальной функции, после чего зарегистрировать колбек с помощью методов этого менеджера. Максимум для подписки модуля надо прописать его имя в таблице в отдельном файле. Таким образом, создание нового колбека полностью локализовано в том модуле, где этот колбек используется. Регистрация минимальна, в самом простом случае всего одна строка. Никакого дублирования кода. Код перебора прицепленных колбеков один на всех, скрыт внутри менеджера сигналов и его не надо дублировать, да и знать о нём не надо. Унификация вызова колбеков позволила добавить несколько дополнительных сервисов: а) детектирование подвисаний движковых колбеков. Поскольку этот код интегрирован в менеджер сигналов, то он автоматически распознаёт подвисания всех прицепленных через эту систему колбеков. Ровным счётом ничего для этого делать не нужно. б) возможность распределения нагрузки в виде низкоприоритетных (или очерёдных колбеков). Это реализовано в моём менеджере. В основном это имеет смысл только для использования вместе с сигналом update, тем не менее весьма полезно. Без такой фишки приходится делать это вручную со счётчиком, километровым кодом с if-ами и т.п. в) взаимодействие между прицепленными к одному сигналами колбеками. Два случая, когда это особенно полезно - работа с инвентарными предметами и обработка нажатий клавиш (если такие колбеки добавлены). Вот к примеру пошла обработка съеденного инвентарного предмета. К событию съедания может быть прицеплено несколько колбеков, каждый из которых проверяет свой тип предмета и что-то делает, если это "его" предмет: сон от спального мешка, лечение от аптечки, диалог радио от радио и т.д. В зависимости от стратегии работы с предметом он либо удаляется движком либо скриптом и восстановить его скриптом надо или не надо. Если надо предмет удалить, то после этой операции продолжат срабатывать колбеки, которым передаётся уже удалённый предмет (серверной части нет). Во-первых, это потенциально вызывает сбои, если колбеки выполняют проверки, рассчитывая на существование серверной части. Т.е. даже если колбек ничего не собирается делать с предметом, а просто хочет что-то проверить, то всё равно можно получить вылет. Значит, надо навешивать дополнительные проверки, усложнять код. Кроме того, эти вызовы уже попросту лишние, поскольку тот колбек, которому этот вызов был адресован, уже отработал. Выходом является простой приём. Если колбек возвращает true, то менеджер сигналов завершает цепочку вызовов, и все оставшиеся в цепочке колбеки не срабатывают. Из тех же соображений это полезно при обработке нажатий клавиш и в ряде других случаев. Обработку возвращаемого значения выполняет менеджер сигналов в том самом унифицированном коде. Ещё пара фишек, которые реализованы в моём менеджере: Возможность подключения в качестве колбека метода класса. При регистрации надо передать ссылку на объект класса, так что при вызове колбека будет передан неявный аргумент self. С xSream у меня был диспут на тему полезности этой фишки, но я её использую в своих скриптах довольно активно. Одним из примеров является реализация таймеров. Таймер - объект класса. При создании он сам себя подписывает на событие апдейта (точнее один из своих методов), а после срабатывания - отписывает. Красота подхода оказалась в том, что пользователю-программисту даже не надо нигде хранить ссылку на этот таймер, поскольку он хранится как ссылка на self во внутренней таблице менеджера сигналов и автоматически удаляется при отрегистрации. Автоподключение модулей. Страшно удобно для отладочных модулей. Используя эту фишку я могу написать модуль с колбеками, не изменив вообще ни строки ни в одном другом модуле. Всё, что надо сделать для его использования, просто поместить файл в папку scripts. Например, я могу написать модуль, который выводит на худ информацию об объекте под прицелом по нажатию сочетания клавиш (нужны естественно колбеки на клавиши), или удаляет объект под прицелом, или меняет его свойства, или телепортирует актора на три метра вперёд, или открывает окно тестового спавна и т.п. Не нужен модуль, просто убрал его из папки со скриптами. Не знаю, насколько это фишка, но менеджеров сигналов может быть несколько. Когда я это делал, то планировал использовать это для более надёжного разделения пространств имён сигналов, но потом пришёл к мысли, что проще задать сигналу сложное имя, чтобы оно не пересекалось ни с чём. Тем не менее, возможность заведения нескольких менеджеров сигналов осталась. В целом примерно так, хотя может и забыл что-то. Система xStream, за исключением особенностей, которые я явно указал, функционально эквивалентна и обладает теми же достоинствами. Из различий могу отметить принятый стиль передачи аргументов в колбек. У меня передача аргументов традиционная, просто список аргументов. Они все будут переданы каждому колбеку для этого сигнала. В "песочнице" принят способ передачи всех аргументов через таблицу. В том числе в таблицу записывается код возврата, сигналящий о том, что этот вызов должен быть последним. В подходе с таблицей есть свои преимущества. К примеру, всегда строго один аргумент в колбеке, проще изменить/дополнить список аргументов колбека, выглядит более унифицированно и можно наладить общение между колбеками через эту общую таблицу (сомнительная возможность, колбеки лучше изолировать друг от друга). Такой подход используется в частности в системе делегатов в .NET (там конечно не таблица, а экземпляр класса). В целом, никто не мешает сделать так и в моей системе, и передавать не произвольное число аргументов, а одну таблицу. У меня это скорее вопрос соглашения, чем требования. 4 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Nazgool 250 Опубликовано 13 Июня 2013 Поделиться Опубликовано 13 Июня 2013 Это типа func2 = function(val) func(val) end ? Как то пропустил это сообщение и подумал, а ведь если слово "замыкание" не вызывает однозначного ответа, то хоть и существует множество примеров данной "фишки", почему и не попробовать разложить " по полочкам". Не знаю как получится, но .. попробую. Возьму стандартный пример : function f(mem) return function (val) return val * mem end end И вызов : x = f(2) Переменной x присваивается значение, возвращаемое функцией f Функция f возвращает только что созданную (новую) функцию! Т.е. на данный момент (после вызова - f(2)) x - это функция, которую позже можно вызвать Вызывая f(2) , в функцию f передаётся аргумент - число 2. Это значение присваивается переменной mem - f(mem) Но новая (возвращаемая) функция тоже использует значение с именем mem, поэтому для неё mem это то значение, которое было на момент вызова f Т.е. в данном случае функция, которая сохранилась в x, "запомнила" внутри себя значение mem как 2 (в строке return val * mem) И теперь, вызвав x (она же функция) можем передать в неё некое значение. local v = x(3) Функция x (которую мы получили) принимает аргумент val как число 3 и возвращает вычисленное значение (return val * mem) val мы её только что передали. Это 3, а mem она "помнит" - это 2 В результате получим 3х2=6 Это позволяет "заряжать" функции различными данными, так как каждый раз вызывая f(mem) создаётся новая функция, в каждой из них храниться собственное значение mem. А затем добавляя новые данные (как val) производить нужные действия. Ссылка на комментарий
Malandrinus 615 Опубликовано 15 Июня 2013 Автор Поделиться Опубликовано 15 Июня 2013 Замыкания конечно полезная штука, но есть и недостатки. Замыкания отчасти пересекаются с идеей классов, в том смысле, что объединяет действия и состояние. Однако, полноценной замены классам никак составить не могут. Всё таки действие всего одно, да и всех прочих фишек классов нет. Неявность создания с одной стороны хорошо, поскольку не требует от программиста особенных усилий, с другой - эта же неявность может сильно усложнить сопровождение программы, а в итоге повысить общую стоимость разработки. О чём здесь речь, набор данных, связанных таким образом с функцией, программисту не виден и задаётся неявно, текстом функции. Разобраться в такой программе сложнее, чем в устройстве класса, где всё задано явно. Другой аспект, а если есть конфликты имён, переменные на разных уровнях с одинаковыми именами. Легко сделать ошибку и крайне трудно её выловить, поскольку всё неявно. Я бы из этих соображений принял некое эмпирическое правило, замыкание использовать только в случае количества внешних переменных не более скажем двух-трёх. Другой аспект, из-за неявности всей конструкции вряд ли получится как-то сохранить её состояние, что в другую переменную, что на устройство хранения, что ещё ограничивает область применения. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
*Shoker* 322 Опубликовано 19 Июня 2013 Поделиться Опубликовано 19 Июня 2013 Не могу понять, толи я что то делаю не правильно, то ли это последствия обрезанного Lua, но возникла необходимость узнать какими методами обладает объект с экспортированным из движка классом. local pe = ps:get_element_by_bone_name("link") -- (C++ class physics_element) -- pe считается как userdata -- Этот метод вылетает с руганью, что в pairs передана не таблица for k, v in pairs(pe) do Log(tostring(k).." = "..tostring(v)) end -- Этот метод рабочий, но выводит только стандартные функции луавских мета-таблиц (__pow, __add, __index,...) for k, v in pairs(getmetatable(pe)) do Log(tostring(k).." = "..tostring(v)) end По интернету судя по всему работают оба этих варианта, так что не могу понять - то ли это особенность сталкерского луа, то ли я не правильно пытаюсь получить список методов объекта. Про lua_help.script знаю, интересует вариант без его участия. (Обрезанный Lua 5.1 из ЧН) Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Ссылка на комментарий
abramcumner 1 145 Опубликовано 19 Июня 2013 Поделиться Опубликовано 19 Июня 2013 @*Shoker*, вообще это из-за расширенного луабиндом луа. Поэтому средствами луа до методов классов не докопаешься. По идее такие функции должны быть в луабинде, по идее с помощью них lua_help и генерировался. 1 Ссылка на комментарий
*Shoker* 322 Опубликовано 19 Июня 2013 Поделиться Опубликовано 19 Июня 2013 (изменено) Логично, погуглил - нужны методы class_info() и class_names() Оба не подключены к игре. В игре нашёл тока class_registrator - таблицу, щас гляну что это. ___Ничего интересного, таблица с функциями для регистрации классов. Видимо без изменения luabind методы классов получить нельзя. Изменено 19 Июня 2013 пользователем *Shoker* Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Ссылка на комментарий
Malandrinus 615 Опубликовано 19 Июня 2013 Автор Поделиться Опубликовано 19 Июня 2013 последствия обрезанного Lua Не первый раз слышу про "обрезанный" Lua. Ерунда это. Lua в сталкере совершенно стандартный, точнее соответствует своей версии. Более того, включены опции для расширенной совместимости со старыми версиями. Например, можно взаимозаменяемо использовать string.gmatch и string.gfind. Библиотек некоторых нет, но это не относится к языку, да и исправляемо в общем.Как совершенно верно заметил abramcumner, язык напротив расширен. В luabind для вызова методов классов используется метаметод "call" пользовательского объекта. Т.е. он внутри себя выбирает функцию, которую надо вызвать по аргументу этого метода - имени функции. Без специальных средств выяснить список методов класса не получится. 1 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Nazgool 250 Опубликовано 20 Июня 2013 Поделиться Опубликовано 20 Июня 2013 (изменено) ... -- Этот метод вылетает с руганью, что в pairs передана не таблица...По интернету судя по всему работают оба этих варианта,... Интересно, каким это образом pairs, которая может работать только с lua-таблицами, разберёт, "судя по интернету" userdat-у? Где такое написано в интернете? Более того, включены опции для расширенной совместимости со старыми версиями Да во всех версиях 5.1 работают "старые" string.gfind, table.foreach (i), table.getn. Так что "более того" совсем и не более. А luabind...на LuaForge столько всего, что можно прилепить к lua. Но вроде же говорилось только о стандартном наборе. Изменено 20 Июня 2013 пользователем Gun12 Ссылка на комментарий
Malandrinus 615 Опубликовано 20 Июня 2013 Автор Поделиться Опубликовано 20 Июня 2013 , в официальном описании версии 5.1 функции string.gfind нет, значит всё-таки "более". И я вообще-то пытался сказать, что Lua в сталкере не обрезанный, только и всего. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
abramcumner 1 145 Опубликовано 22 Июня 2013 Поделиться Опубликовано 22 Июня 2013 Интересно, каким это образом pairs, которая может работать только с lua-таблицами, разберёт, "судя по интернету" userdat-у?pairs работает со всем, у чего есть метаметод __pairs. У юзердаты он тоже мог бы быть. pairs (t) If t has a metamethod __pairs, calls it with t as argument and returns the first three results from the call. Otherwise, returns three values: the next function, the table t, and nil, so that the construction for k,v in pairs(t) do body end will iterate over all key–value pairs of table t. Ссылка на комментарий
Nazgool 250 Опубликовано 23 Июня 2013 Поделиться Опубликовано 23 Июня 2013 аbrаmcumnеr, вы несомненно будете правы, когда Сталкер напишут на Luа 5.2. Но пока *Shokеr* явно указал, что у него версия 5.1 Ссылка на комментарий
Nazgool 250 Опубликовано 26 Июня 2013 Поделиться Опубликовано 26 Июня 2013 (изменено) Однако, полноценной замены классам никак составить не могут. Всё таки действие всего одно, да и всех прочих фишек классов нетLua в принципе очень маленький и подключаемый! к хосту язык программирования. Чего же от него ещё требовать? Замыкания это просто фишка. Не более того. Но существует немало реализаций классов, которые мало в чём уступают монстру С(++). Скорость выполнения, конечно, уступает. Но писать то на нём (нам, простякам) на порядок легче. Поэтому выбора и не остаётся. Пишем как умеем. Замыкания - так замыкания. А если не поможет, помогут расширения Изменено 29 Декабря 2014 пользователем Dennis_Chikin орфо Ссылка на комментарий
RayTwitty 492 Опубликовано 8 Июля 2013 Поделиться Опубликовано 8 Июля 2013 Есть такой вопрос. В созданном скриптовом классе, на стадии __finalize обязательно следует всем переменным класса присваивать nil или уборщик сам уберет? В примерах смотрел, везде по-разному. Где-то делают, где-то нет. Ссылка на комментарий
Malandrinus 615 Опубликовано 8 Июля 2013 Автор Поделиться Опубликовано 8 Июля 2013 Shadows,чаще всего смысла уже нет, поскольку вызов этого метода уже есть следствие работы уборщика. Вообще использовать этот метод практически никогда нет особенной нужды, и можно его просто не заводить. Его назначение - почистить некие ресурсы, связанные с экземпляром класса, но являющиеся внешними по отношению к объекту. Ну например я завёл некий контрол на худе и завёл скриптовый таймер, по срабатыванию которого этот контрол должен быть удалён или как-то изменён. Вот в этом методе его и можно удалить. А на практике, никто не мешает этот контрол удалить в методе обработки срабатывания таймера и не заморачиваться на дополнительный и неизвестно когда срабатывающий метод. 1 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
*Shoker* 322 Опубликовано 13 Сентября 2013 Поделиться Опубликовано 13 Сентября 2013 (изменено) А вот такой вопрос назрел, когда допустим в Lua в функцию tostring() передаётся таблица или функция, то она возвращает что то вроде table: 0xАдрес Так вот я хотел уточнить два момента у знающих людей: 1) Чем является возвращаемый адрес, это относительный адрес от начала приложения или же вообще адрес объекта во всей ОЗУ (я не очень разбираюсь как это работает, поэтому мог бред сказать) Если что игра возвращает адрес пустой таблицы типа такого: FFBEA6C8. 2) Есть ли методы (чистые, без ковыряния исходников Lua) получения адреса у любого объекта? Изменено 13 Сентября 2013 пользователем *Shoker* Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Ссылка на комментарий
Malandrinus 615 Опубликовано 13 Сентября 2013 Автор Поделиться Опубликовано 13 Сентября 2013 @*Shoker*, 1. В реализации под виндой скорее всего полный адрес в виртуальном пространстве процесса. Должен быть уникальным, чтобы можно было сравнивать на равенство. Я думаю, не имеет смысла задумываться о точной природе этого числа. Использовать его по-любому не получится никак, кроме как сравнить с другим таким же числом и выяснить, равны они или нет. 2. Методов нет (по крайней мере я таких не знаю). Опять же, если подумать, то вряд ли имеет смысл пытаться получить такой адрес. Это будет сильная привязка к платформе и кроме того к реализации самого языка. Объекты же завёрнуты в некие внутренние структуры, да и указатели, вообще говоря, не всегда можно представить одним числом. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти