Перейти к контенту

Язык Lua. Общие вопросы программирования


Рекомендуемые сообщения

С чего начинать и где взять.

 

Установка 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

Изменено пользователем Kirgudu
Ссылка на комментарий

kamikazze, все же жду ответа о "злобных привнесенных косяков", на то и запостил, чтобы может быть упущенное выяснить и исправить.

 

Andrey07071977, да, компрессор несколько уже доработанный, но этого плана. Чуть его подправил и логику выдачи ошибки привнес.

 

P.S. Компрессор-сериализатор выложу, но требуется время, т.к. он у меня в мод вшит. Причешу под внешнее использование (день/два) и выложу, т.к. связка получается очень неплохой. Перенос сохранения тайников из pstor'а актора в састом-сторадж дал выигрыш, освободив от забот по переполнению акторского, но ... просто сериализатор, где булевы значения вместо одного байта по 4-5 забирают - трастранжиривание. В тайниках 2/3 - это булевы. Так что компрессор ужимает на 70% от сериализатора.

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Artos

 

Да за меня уже всё xStream по сути ответила, там ничего не прибавить. А да, одно только - компрессия нагрузку при сериализации куда больше дает. Так что далеко не факт что будет производительность выше, скорее наоборот. И насчет переполнения хранилища - поверь, это очень просто сделать. Сам лично переполнял, и лечил у других :)

 

 

 

Добавлено через 2 мин.:

А, да, и ещё - если "случайно" попадется таблица с метатаблицей, то сериализуется хрен знает что. Тоже учитывай.

Никто этого почему-то не учитывает (метатаблицы и рекурсию) как правило.

 

Добавлено через 2 мин.:

Хммм, и в компрессоре, где числовые ключи, предусмотрена ситуация, когда они идут не по порядку?

Ибо t[10] = nil, к примеру, не приведет к переиндексации и будет "дырка", если забить на это, то потом получим совсем другую таблицу

Изменено пользователем kamikazze

Отладчик и скриптер мода OGSE. Автор схемы "Компаньоны", стреляющего БТРа и многих других полезностей :wink:

Ссылка на комментарий

kamikazze, ну наверное за широкую спину прекрасного пола не следует отступать, сказав что-то от себя и ... "злобный косях", как я понял это один пока, что при эффемерной вероятности кого-то нерадивого засунуть в хранилище табличку с четырех-томником "войны и мира", такой чудак не получит отлупа?

Да, косяк ... хотя в выложенном тут Вашем варианте этот недотепа ничего все одно не увидит, даже в логе. Сорри, но для меня этот "косяк" скорее достоинство.

Ну а то, что компрессия конечно же несколько больше ресурсов требует - так и делается она единожды на сэйв и пока при моих стрес-тестах не смог отличить от иных вариантов.

Зато выигрыш 8кБ +40% - немалая компенсация (ИМХО).

 

Ну а остальной (к паре) какой косяк?

 

Давайте НЕ хаять не свое, а обсуждать и вырабатывать или нечто обобщенное для других или учиться друг у друга, признавая и свои ошибки и чужие удачные решения.

 

P.S. Ну а по поводу "ошибок" копресии и пр. - тут уже была разборка ... неплохо бы тебе почитать.

1. Смею тебя заверить, что за уже более чем годичную практику использования в моде каких-либо коллизий из-за компресии не обнаружено ни в теории ни на практике, хотя гоняется в моде в хвост и гриву.

2. Ну по метатаблицам - вот как раз выше и писал, что и подработан немного, и пример от xStream, конечно же полезен и будет встроен (уже встроен вчерне).

 

Добавлено через 59 мин.:

malandrinus, xStream, просьба уточнить/поправить строку ниже, т.е. чье авторство (или совместное) на упомянутое ниже:

;--/ by Malandrinus & xStream

CUST_ST = custom_storage, cse_alife_dynamic_object ;se_custom_storage

Эти данные нужно бы дать KD87 для внесение в коды универсального ACDC, дабы учитывались для работы с секциями/классами для all.spawn'а.

 

P.P.S. Спасибо за пояснение. Т.к. в первичным по времени был xs_stor и в нем не достаточно ясный thanx - поэтому и решил уточнить.

Цель - же 'занятые' наменования секций и/или clsid'ов, указанные в общем для многих инструменте (ACDC), могут помочь в совместимости модов и/или исключить возможные пересечения в названиях.

Само собою, что в all.spawn'e ничего по стораджу не должно быть (не требуется), но универсальный ACDC сканирует конфиги и наткнувшись на секцию "custum_storage" с неизвестным классом (class = CUST_ST) - возникает хотя и не фатальная, но неопределенность и соотв.запись в конфиге секций.

Поэтому и возможно занесение в его конфиг (иль скрипты), для однозначности и определенности соответствий секций классам.

Также, в модуле m_net_utils (а это уже в игре/скриптах) также используется предварительная идентификация всех классов и наименования, с указанием источника/авторства, упоминаются в конфиге.

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Объект и биндер - Саша делал. В коде указано же было.

 

Добавлено через 25 мин.:

Только вот прописывать их в АСДС смысла нет. Они спавнятся только скриптами. В редакторе не имеют вообще никакого визуала и не несут никакой нагрузки. То есть в спавне им делать в принципе нечего.

Изменено пользователем xStream

Все, кто стоит на моем пути: идите нахрен и там погибните! ©

Ссылка на комментарий

Слегка поменял описание под спойлером для системы событий. Примеры выделены, пример для методов класса поставлен вторым, для функционального объекта спрятан под спойлер и снабжён соответствующим комментарием.

Ссылка на пост

 

xStream,

Саш, peace :)

Мир, дружба, жвачка =)

 

Просто ты привел такие примеры.

Но однако интересно, выходит, до последнего примера никто дочитать не утрудился. Лентяи...

 

Ну а насчет интерфейсов я все равно настаиваю, что они должны быть как можно проще и как можно меньше вариаций иметь

 

Да куда там проще? Один дополнительный и вообще опциональный параметр. Агрегация свойств слота в таблицу-дескриптор на мой взгляд получилась удачным решением, поскольку упрощает отписывание. И потом, возможность подписать произвольный метод без дополнительных затрат упрощает жизнь программисту. К примеру, можно подписать метод биндера одного объекта на событие другого. Или вот у меня в таймерах это используется именно таким образом, как я выше показывал в примере.

-- Запуск таймера, аргумент задаёт использование проверки с низким приоритетом
function quick_timer:start(low_priority)
    if self.timeout then -- если при создании задавали таймаут
        self.termination_time = time_global() + self.timeout -- то запоминаем время останова
    end
    self.slot_desc = {signal = "on_update", self = self, fun = self.aux_cond, queued = low_priority}
    ogse_signals.get_mgr():subscribe(self.slot_desc)
end
-- останов таймера
function quick_timer:stop()
    ogse_signals.get_mgr():unsubscribe(self.slot_desc)
end

Это пример для "быстрого" таймера. В сохраняемых это работает примерно так-же, только там кода больше, для примера не так хорошо выглядит.

 

"Быстрые" таймеры я сделал почти год назад, тогда это была просто обёртка над движковыми же вызовами set_call и классом client_spawn_manager. Если кому интересно, можете взглянуть на эту старую реализацию.

http://rghost.net/35857622

С использованием сигналов реализация сильно упростилась.

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий

Хех, я бы не сказала, что интерфейс простой (по мне так он сильно перегружен параметрами, пусть даже в виде таблицы), но да ладно.

А что касается таймеров. Лично я придерживаюсь все же подхода - все из коробки, как готовый продукт. Есть класс и используй для чего хочешь и как хочешь. У тебя надо что-то создавать. По-моему переусложнение для конечного пользователя. В С++ это еще б имело смысл, но не в луа. Так же как и передача селф+метод вместо простой функции - чисто Сишная примочка, я знаю. И так же создание описаиния слота. Когда вместо этого можно работать все с теми же замыканиями и безымянными функциями. И интерфейс проще и внутренний код системы.

Но это просто имхо, чтоб ты знал его :)

А что касается приоритетов, это вообще отдельный разговор. Я всегда очень отрицательно отношусь к таким вещам, где может производиться при определенных условиях переполнение очереди. Я, конечно, гляну сигналы, но что-то мне подсказывает...

Изменено пользователем xStream

Все, кто стоит на моем пути: идите нахрен и там погибните! ©

Ссылка на комментарий

xStream,

Хех, я бы не сказала, что интерфейс простой (по мне так он сильно перегружен параметрами, пусть даже в виде таблицы), но да ладно.

event("event_name"):register(funct)

sm:subscribe({signal = "signal_name", fun = funct}) -- если не используем self

сложнее?

 

Кстати, я здесь не предлагаю ничего оригинального. Вот для примера установка колбека на биндер

self.object:set_callback(callback.on_item_take, self.on_take, self)

Видим все те-же самые элементы: имя сигнала, вызываемый метод, ссылка на сам объект, которая будет передана в виде аргумента self. Никого же это не смущало до сих пор. И по поводу того, что это С++ подобный стиль. Не соглашусь. Как раз в С++ для реализации подобного надо городить весьма брутальные решения с оберткой вокруг класса на шаблонах и прочими радостями. Все потому, что this там - внутреннее дело компилятора. А здесь self - всего лишь часть синтаксического сахара и позволяет простые манипуляции с собой. Так что это ООП, но не в стиле С++, а просто ООП. А интенсивное использование замыканий - это как раз не ООП, а из области функционального программирования. Дело хорошее не спорю, но это альтернативный подход, к ООП не имеющий отношения.

 

А что касается таймеров. Лично я придерживаюсь все же подхода - все из коробки, как готовый продукт. Есть класс и используй для чего хочешь и как хочешь. У тебя надо что-то создавать. По-моему переусложнение для конечного пользователя.

Надо написать класс, да. Очень простой класс, пишется по шаблону. У меня таймеры инкапсулируют действие и произвольное условие. Для того, чтобы хранить данные для проверки условия и данные для отложенного выполнения действия идея объекта достаточно удобна и в общем-то очевидна. Это и есть ООП, идея инкапсуляция в чистом виде. Мне это видится достаточно структурированным подходом: вот мой класс который хранит всё необходимое, вот метод-условие, вот метод-действие, вот методы сохранения/загрузки, если это сохраняемый таймер. Всё в одном флаконе. Если учесть, что объекты лежат в основе всей скриптовой системы сталкера, то это не так уж и сложно. И потом, класс пишется один раз, а запуск его вообще тривиален.

 

А что касается приоритетов, это вообще отдельный разговор. Я всегда очень отрицательно отношусь к таким вещам, где может производиться при определенных условиях переполнение очереди.

Откуда переполнение? Там просто две таблицы вместо одной. В зависимости от параметра queued слот помещается в одну или в другую. Из одной вызывается как обычно, все пачкой, а из другой только один - по циклическому счётчику.

Изменено пользователем malandrinus
 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий

Так, доработка по библиотеке пакетов. Мануала все ще нет, но как допроверю, что все ок, будет.

http://dl.dropbox.com/u/46539648/xs_netpk.script

1) Да, оно завязано на мою песочницу, так что надо прописать, если используется эта песочница.

2) Кто любит все переделывать, типа Artosa, могут так же переделать и это, суть понятна, мне кажется.

Собственно, какие изменения:

Попробовала учесть все замечания по неправильному содержимому пакетов, опечатки и прочее.

Добавлен класс для работы с абстрактной частью пакетов - описание в шапке файла.

ЗЫ Да, лакончино, скомкано и т.п. Все будет развернуто, когда доберусь до мануала. А пока тот, кто понимает, прошу вас это посмотреть, потестить. Нужен фидбек по ошибкам. Заранее спасибо.

Все, кто стоит на моем пути: идите нахрен и там погибните! ©

Ссылка на комментарий

xStream,

поменяй терминологию :) binder - это где-то рядом с object_binder и ко, а-ля bind_stalker.script

Ты же используешь скриптовый серверный класс

 

Ну и если интересно то то, что ты назвала unused_pad - это данные которые сохраняются/загружаются в object_binder:save/load

 

Ну и

Дело в том, что шейпы-параллелепипеды не имеют параметра поворота
неверно. Конечно же поворот там задается.
Ссылка на комментарий

Несколько замечаний несущественного характера:

1. Для "net_alife_item_weapon_shotgun" параметр 'ammo_ids' в игре хранит кол-во идентификаторов типов заряженных патронов, после которого идет список этих идентификаторов типов патронов, который может быть восстребован модмейкерами, но в нынешнем виде считывается в бинарный остаток (tail).

 

2. Для "net_respawn" параметр 'spawned_objects' (в игре и ACDC - 'spawned_obj') хранит кол-во игровых идентификаторов заспавненных объектов, после которого идет собственно их список. Так же может быть восстребован для чистки или иного ...

 

3. Вероятно стОит выкинуть определение в классе 'net_base' незадействованных переменных 'rssz', 'rusz', 'wusz'.

 

 

Добавлено через 8 мин.:

abramcumner, ИМХО как раз наименование 'binder' вполне к месту.

Большинство привыкло биндерами называть биндеры клиентских объектов, хотя серверные объекты имеют аналогичные биндеры (которые, кстати, первичны) с аналогичными методами. Просто, при необходимости, нужно по контексту добавлять уточняющее: клиентский/серверный биндер иль биндер серверного объекта ...

 

И с 'unused_pad' ты что-то не то сказал. Никак 'unused_pad', который в "net_abstract", не может иметь отношение к object_binder:save/load ...

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

abramcumner, что такое bind в переводе с английского?

Что касается поворота - мб. Там всего лишь написано, что мне подсказали.

Изменено пользователем xStream

Все, кто стоит на моем пути: идите нахрен и там погибните! ©

Ссылка на комментарий

xStream,

Что касается поворота - мб. Там всего лишь написано, что мне подсказали.

Поворот задается. Это не 4 вектора, а матрица на самом деле. Матрица трансформации. Берется кубик размером 1 метр с центром в точке 0,0,0 и с помощью этой матрицы превращается в параллелепипед. Матрица трансформации является в свою очередь произведением матриц поворота, масштабирования и сдвига. Сдвиг в SDK не задать (как мне кажется) поэтому центральная часть 3 на 3 обычно представляет собой произведение матриц поворота и вращения. При отсутствии вращения остается только матрица масштабирования, которая в данном случае будет выглядеть как размеры бокса, расположенные по диагонали. Матрица сдвига тривиальна и при умножении просто добавляет три числа в 4-ю строку. Ну и там еще порядок умножения выбран таким, чтобы это было тривиально.

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий

Добавил к своим таймерам простую обёртку для создания таймеров в процедурно-ориентированном стиле.

ogse_st_mgr.start_timer(<строка с именем таймера>, <задержка в секундах>, <строка с полным именем запускаемой функции>, <список аргументов для передачи в функцию произвольной длины>)

пример

ogse_st_mgr.start_timer("test_timer", 30.5, "some_module.some_function", 1, 2.3, "qwerty", false, true)

Будет создан таймер с именем "test_timer", который сработает через 30 с половиной секунд, при этом вызовет функцию some_function из модуля some_module и передаст её при этом аргументы (1, 2.3, "qwerty", false, true)

Если имя не нужно, вместо него поставьте nil, функция должна компилироваться на момент срабатывания, список аргументов может включать только типы: строка, число, логическое значение.

Для вызова таймера в игровом времени есть аналогичный вызов

ogse_st_mgr.start_gtimer()

Вообще, этих обёрток можно наплодить сколько угодно на все случаи жизни: задание в часах, днях, точного времени срабатывания и т.д. Загляните в конец ogse_st_mgr.script, там всё очень просто.

Ссылка на обновлённый пакет скриптов

http://rghost.net/35880388

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий
Добавлено через 8 мин.:

abramcumner, ИМХО как раз наименование 'binder' вполне к месту.

Большинство привыкло биндерами называть биндеры клиентских объектов, хотя серверные объекты имеют аналогичные биндеры (которые, кстати, первичны) с аналогичными методами. Просто, при необходимости, нужно по контексту добавлять уточняющее: клиентский/серверный биндер иль биндер серверного объекта ...

Вообще-то там задается пара серверный/клиентский класс. Они оба биндеры? Тогда в bind_stalker.script задается биндер-биндер???

Там же даже по наследованию видно, что задается наследник серверного класса - зачем наследника называть биндером? Можно просто правильно употреблять термины.

 

И с 'unused_pad' ты что-то не то сказал. Никак 'unused_pad', который в "net_abstract", не может иметь отношение к object_binder:save/load ...

Ооо, знаток говорит, что не может, значит не может :) Ты бы хотя бы в игре проверил. А почему не может? Почему в серверном биндере не может быть данных клиентского биндера? :)

 

Добавлено через 3 мин.:

abramcumner, что такое bind в переводе с английского?

Переведи, пожалуйста.

 

Ты же когда пример приводила, видела же?

class "se_outfit" (cse_alife_item_custom_outfit)

Теперь наследование называется биндинг?

Изменено пользователем abramcumner
Ссылка на комментарий

Еще раз - советую вспомнить/посмотреть перевод слова bind. Хорошенько вникнуть.

Для аналогии и стимуляции мышления могу подкинуть слово 'luabind'.

Изменено пользователем xStream

Все, кто стоит на моем пути: идите нахрен и там погибните! ©

Ссылка на комментарий

xStream,

:) Inheritance, inheritance, inheritance

Я тоже могу нагуглить пару английских слов. Скажи уж прямо, что ты имеешь ввиду.

 

Добавлено через 20 мин.:

Погуглил luabind - вот что нашел:

Inheritance can be used between lua-classes:

class 'derived' (lua_testclass)

Ты это имела ввиду?

Изменено пользователем abramcumner
Ссылка на комментарий

bind - "привязать". Речь идет о связях скриптовых классов с серверными. При наследовании такая связь теряется, если методы переопределять и используются конструкции типа

    cse_alife_item_custom_outfit.STATE_Write (self, packet)

Мы таким образом все равно вызываем "оригинальный класс"

Однако суть все же не в этом. Семантически все, что мы заэкспортили из двига в ЛУА является "биндингом" - связью ЛУА-инстанса с С-инстансом. То есть вообще все является биндингом. Биндером является то, что делает такую связь принудительно.

В общем, если очень действительно хочется некую терминологию ввести и придерживаться ее, то получается так. Но это все глупо и бессмысленно :) Все равно все по примеру понимают, что надо делать.

 

ЗЫ Например, для таймеров, потом меня осенило, и семантичнее и короче было бы использовать bind и unbind. Но, поскольку уже есть код, завязанный на этом, то оставила register и unregister.

Изменено пользователем xStream

Все, кто стоит на моем пути: идите нахрен и там погибните! ©

Ссылка на комментарий

xStream,

class "se_outfit" (cse_alife_item_custom_outfit)

Конкретно это является наследованием (пусть и от забинденного класса), а не биндингом. И семантически и по-всякому.

И se_outfit не является биндером.

Конкретно мне не нравится упоминание биндера здесь:

1) этот тип объектов должен иметь биндер (то есть то, что будет вызвано, когда объект появится в игре)

Завязка из class_registrator.script:

cs_register (object_factory, "CStalkerOutfit", "se_item.se_outfit", "E_STLK", "equ_stalker_s")

 

2) обязательно сделать метод биндера STATE_Write

Если что, здесь говорится именно про se_outfit

 

Ну и в сталкер-lua сложилась своя терминология биндеры это одно, клиентские и серверные классы другое. Зачем ее менять не понятно.

Никто не называет тот же game_object ни биндером, не забинденным классом и ни чем-либо со словом бинд

Изменено пользователем abramcumner
Ссылка на комментарий

abramcumner,

Конкретно это является наследованием (пусть и от забинденного класса), а не биндингом. И семантически и по-всякому.

Да думай как хочешь, я не знаю, каким местом ты читал мой пост, видимо рандомно по словам... xD

Глупо говорить про терминологию. Давай к авторам обратись еще, как они и что называли. Это, уважаемый, всего лишь твоя точка зрения. Когда увидишь слово "биндер" в тексте, можешь, зажмуриваться, например. :)

Все, кто стоит на моем пути: идите нахрен и там погибните! ©

Ссылка на комментарий

Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

Создать аккаунт

Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

Зарегистрировать новый аккаунт

Войти

Есть аккаунт? Войти.

Войти
  • Недавно просматривали   0 пользователей

    • Ни один зарегистрированный пользователь не просматривает эту страницу.
×
×
  • Создать...