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

Malandrinus

Жители
  • Число публикаций

    1 930
  • Регистрация

  • Последнее посещение

  • Дней в топе

    13
  • AMKoin

    160 [Подарить AMKoin]

Весь контент пользователя Malandrinus

  1. Malandrinus

    X-Ray extensions

    Earth2Space, Чем именно, искать авторов правок или заниматься реверс-инженирингом этих правок и воспроизводить их в этом проекте? Если серьёзно, то сейчас весьма сильно занят. Правки делаются в основном под конкретные текущие нужды, а не вообще и не про запас. Shadows дал хороший совет насчёт использования уже патченного файла. Экзешник так использовать не получится, поскольку в этом проекте принят за основу файл от штатовской версии (без защиты), но xrGame должен подойти. Я так даже делал, вполне работает. И кстати, а что там за правки в экзешнике?
  2. Замыкания конечно полезная штука, но есть и недостатки. Замыкания отчасти пересекаются с идеей классов, в том смысле, что объединяет действия и состояние. Однако, полноценной замены классам никак составить не могут. Всё таки действие всего одно, да и всех прочих фишек классов нет. Неявность создания с одной стороны хорошо, поскольку не требует от программиста особенных усилий, с другой - эта же неявность может сильно усложнить сопровождение программы, а в итоге повысить общую стоимость разработки. О чём здесь речь, набор данных, связанных таким образом с функцией, программисту не виден и задаётся неявно, текстом функции. Разобраться в такой программе сложнее, чем в устройстве класса, где всё задано явно. Другой аспект, а если есть конфликты имён, переменные на разных уровнях с одинаковыми именами. Легко сделать ошибку и крайне трудно её выловить, поскольку всё неявно. Я бы из этих соображений принял некое эмпирическое правило, замыкание использовать только в случае количества внешних переменных не более скажем двух-трёх. Другой аспект, из-за неявности всей конструкции вряд ли получится как-то сохранить её состояние, что в другую переменную, что на устройство хранения, что ещё ограничивает область применения.
  3. Malandrinus

    X-Ray extensions

    Ну так надо найти и попросить.
  4. Malandrinus

    X-Ray extensions

    Саншафты в основном - это шейдеры, поддержка в бинарниках минимальная. О подробностях лучше спрашивать KD87, рендер - в основном его вотчина. И при чем здесь коллизия трупов? Или имелось в виду всё, что упоминалось в той теме, а не только в посте по ссылке? А кто автор тех фиксов? По-моему, все эти люди имеют доступ к этому проекту. Почему бы их и не попросить включить эти правки сюда?
  5. Malandrinus

    X-Ray extensions

    Я про бинарники. В том пакете библиотеки рендеров из этого проекта. А саншафты - это шейдеры, к бинарным фиксам это не относится.
  6. Malandrinus

    X-Ray extensions

    @Earth2Space, "это" и есть проект x-ray extensions.
  7. слоты и сигналы Слот - это термин для колбеков, принятый в BOOST. В других местах могут называть по другому, к примеру делегатом. Сигнал тоже могут называть по-разному, событием к примеру. На терминологии лично я не настаиваю, главное, чтобы понимали друг друга. Пожалуйста: xr_s.script Регистрация нового колбека требует изменения системного по сути скрипта, что плохо само по себе. Как следствие, добавляемый туда код каждый раз повторяет уже существующий (перебор таблицы и вызов), т.е. надо заниматься копипастой. Это тоже плохо само по себе, но вдобавок как следствие, если потребуется реализовать некий дополнительный сервис, обрамляющий вызов колбека (что имеется в виду поясню далее), то это будет затруднительно сделать, поскольку придётся добавлять этот код в каждый из уже добавленных колбеков. Впридачу добавление подобного сервиса затруднит добавление новых колбеков (надо будет каждый раз копипастить ещё больше кода). Функции используются в качестве ключей. Это не самый большой недостаток и легко преодолевается, как мы выяснили. Тем не менее в таком виде это исключает некоторые варианты использования, в частности использование в качестве колбеков методов классов. Система сигналов. Регистрация колбека не требует изменения системного модуля. Нужно получить ссылку на экземпляр менеджера сигналов с помощью глобальной функции, после чего зарегистрировать колбек с помощью методов этого менеджера. Максимум для подписки модуля надо прописать его имя в таблице в отдельном файле. Таким образом, создание нового колбека полностью локализовано в том модуле, где этот колбек используется. Регистрация минимальна, в самом простом случае всего одна строка. Никакого дублирования кода. Код перебора прицепленных колбеков один на всех, скрыт внутри менеджера сигналов и его не надо дублировать, да и знать о нём не надо. Унификация вызова колбеков позволила добавить несколько дополнительных сервисов: а) детектирование подвисаний движковых колбеков. Поскольку этот код интегрирован в менеджер сигналов, то он автоматически распознаёт подвисания всех прицепленных через эту систему колбеков. Ровным счётом ничего для этого делать не нужно. б) возможность распределения нагрузки в виде низкоприоритетных (или очерёдных колбеков). Это реализовано в моём менеджере. В основном это имеет смысл только для использования вместе с сигналом update, тем не менее весьма полезно. Без такой фишки приходится делать это вручную со счётчиком, километровым кодом с if-ами и т.п. в) взаимодействие между прицепленными к одному сигналами колбеками. Два случая, когда это особенно полезно - работа с инвентарными предметами и обработка нажатий клавиш (если такие колбеки добавлены). Вот к примеру пошла обработка съеденного инвентарного предмета. К событию съедания может быть прицеплено несколько колбеков, каждый из которых проверяет свой тип предмета и что-то делает, если это "его" предмет: сон от спального мешка, лечение от аптечки, диалог радио от радио и т.д. В зависимости от стратегии работы с предметом он либо удаляется движком либо скриптом и восстановить его скриптом надо или не надо. Если надо предмет удалить, то после этой операции продолжат срабатывать колбеки, которым передаётся уже удалённый предмет (серверной части нет). Во-первых, это потенциально вызывает сбои, если колбеки выполняют проверки, рассчитывая на существование серверной части. Т.е. даже если колбек ничего не собирается делать с предметом, а просто хочет что-то проверить, то всё равно можно получить вылет. Значит, надо навешивать дополнительные проверки, усложнять код. Кроме того, эти вызовы уже попросту лишние, поскольку тот колбек, которому этот вызов был адресован, уже отработал. Выходом является простой приём. Если колбек возвращает true, то менеджер сигналов завершает цепочку вызовов, и все оставшиеся в цепочке колбеки не срабатывают. Из тех же соображений это полезно при обработке нажатий клавиш и в ряде других случаев. Обработку возвращаемого значения выполняет менеджер сигналов в том самом унифицированном коде. Ещё пара фишек, которые реализованы в моём менеджере: Возможность подключения в качестве колбека метода класса. При регистрации надо передать ссылку на объект класса, так что при вызове колбека будет передан неявный аргумент self. С xSream у меня был диспут на тему полезности этой фишки, но я её использую в своих скриптах довольно активно. Одним из примеров является реализация таймеров. Таймер - объект класса. При создании он сам себя подписывает на событие апдейта (точнее один из своих методов), а после срабатывания - отписывает. Красота подхода оказалась в том, что пользователю-программисту даже не надо нигде хранить ссылку на этот таймер, поскольку он хранится как ссылка на self во внутренней таблице менеджера сигналов и автоматически удаляется при отрегистрации. Автоподключение модулей. Страшно удобно для отладочных модулей. Используя эту фишку я могу написать модуль с колбеками, не изменив вообще ни строки ни в одном другом модуле. Всё, что надо сделать для его использования, просто поместить файл в папку scripts. Например, я могу написать модуль, который выводит на худ информацию об объекте под прицелом по нажатию сочетания клавиш (нужны естественно колбеки на клавиши), или удаляет объект под прицелом, или меняет его свойства, или телепортирует актора на три метра вперёд, или открывает окно тестового спавна и т.п. Не нужен модуль, просто убрал его из папки со скриптами. Не знаю, насколько это фишка, но менеджеров сигналов может быть несколько. Когда я это делал, то планировал использовать это для более надёжного разделения пространств имён сигналов, но потом пришёл к мысли, что проще задать сигналу сложное имя, чтобы оно не пересекалось ни с чём. Тем не менее, возможность заведения нескольких менеджеров сигналов осталась. В целом примерно так, хотя может и забыл что-то. Система xStream, за исключением особенностей, которые я явно указал, функционально эквивалентна и обладает теми же достоинствами. Из различий могу отметить принятый стиль передачи аргументов в колбек. У меня передача аргументов традиционная, просто список аргументов. Они все будут переданы каждому колбеку для этого сигнала. В "песочнице" принят способ передачи всех аргументов через таблицу. В том числе в таблицу записывается код возврата, сигналящий о том, что этот вызов должен быть последним. В подходе с таблицей есть свои преимущества. К примеру, всегда строго один аргумент в колбеке, проще изменить/дополнить список аргументов колбека, выглядит более унифицированно и можно наладить общение между колбеками через эту общую таблицу (сомнительная возможность, колбеки лучше изолировать друг от друга). Такой подход используется в частности в системе делегатов в .NET (там конечно не таблица, а экземпляр класса). В целом, никто не мешает сделать так и в моей системе, и передавать не произвольное число аргументов, а одну таблицу. У меня это скорее вопрос соглашения, чем требования.
  8. По поводу скрипта xr_s.script. По мне так нет смысла использовать такой упрощённый и древний подход, при том что имеются продвинутые системы сигналов. Я лично использую свою систему, но с таким же успехом можно использовать систему xStream. Вот последние версии (за песочницу xStream не уверен, это то, что мне доступно). "Песочница" от xStream. В архиве вложен файл описания xs_sandbox_manual.txt Менеджер сигналов. Описание добавлено комментариями в файле ogse_signals.script
  9. ColR_iT, сделай регистрацию не по самой функции, а по некому имени. Т.е. заведи ключ в виде строки, а саму ссылку на функцию помести в ту же таблицу, где и аргумент. tbl = {} function Register(call_name,f,v) tbl[call_name]={f=f, v=v} end function Unregister (call_name) tbl[call_name]=nil end --#--------- function update () for _,param in pairs(tbl) do param.f(param.v) end end
  10. ColR_iT, Возвращаясь к исходному вопросу. Мне непонятно вот что. Если у тебя шесть одинаковых функций, то зачем они вообще нужны, шесть одинаковых? Почему не одна? Производный отсюда вопрос. Если они одинаковые, то естественно использовать их в качестве ключа не получится, это одно значение. Но и вообще, зачем хранить шесть ссылок на одну и туже функцию? Храни только разные данные, а функцию (одну) вызывай по глобальной ссылке. Если же надо, чтобы при вызове шести этих функций делалось что-то разное, то тогда либо таки создавать разные функции, замыкание или динамическая компиляция из составляемых строк в помощь, либо используй метод объекта (или перегруженный оператор вызова объекта, т.е. функциональный объект) примерно с тем же эффектом. Вообще же, без пояснения, зачем это надо, сложно что-то обсуждать. Конечная задача совершенно неочевидна.
  11. Malandrinus

    X-Ray extensions

    Включил в проекте настройку "Allow non-members to review code". Это то, что надо? По поводу правок. А нет ли желания у уважаемого kstn самому добавить эти правки? Включить в проект не проблема.
  12. Ну так я же фактически так и написал в начале. Правильнее использовать не '*', а '+', поскольку требуется вхождение как минимум одного символа. Вообще же, сама идея задачи мне кажется не совсем правильной. Подстраивать алгоритм под максимально широкий разброс вариантов - это неправильно. Неправильно потому, что слишком широкий разброс входных данных резко снижает надёжность системы в целом. Всегда останутся лазейки для неправильного набора данных. Ограничение допустимого множества входных значений - это первый путь повышения надёжности. Короче, наложить условия на конфиги легче и надёжнее, чем сделать алгоритм, работающий надёжно на любом мусорном вводе.
  13. @Dennis_Chikin, ну смотри, у тебя "разделители" и "символы строки" - это два взаимоисключающих множества. Любое из них можно определить через другое как [^]. Но по-любому одно из них определить придётся. Выбери то, которое меньше по объёму. Я выбрал явное задание множество символов строки, а разделители задал как обратное ему. Ты говоришь, оно может быть больше. Значит, придётся явно перечислить все символы разделители, а "символы строки" определить, как противоположность "символов разделителей". Либо так либо иначе, но другого пути нет.
  14. Dennis_Chikin, типа такого не пойдёт? s1, s2 = s:match("([%wа-яА-Я_]+)[^%wа-яА-Я_]+([%wа-яА-Я_]+)")
  15. Malandrinus

    X-Ray extensions

    @Scarabay, увы, нет =( К слову, для ТЧ/ЧН это были одни из самых муторных правок.
  16. Viнt@rь, Этот класс является базовым для всех объектов с визуалом и костями. Однако в скриптах он никак прямо не используется, поскольку нет функции приведения к этому классу. Остался скорее всего по недосмотру. Вероятно, на каком-то этапе была функция приведения, наподобие get_holder_class(), но потом убрали. Сейчас для вызова метода проигрывания анимации есть метод play_cycle класса game_object, который внутри как раз и вызывает метод PlayCycle класса IKinematicsAnimated. lsclon, Это функция серверного класса, которая отвечает за сохранение клиентских данных. Как и другие методы серверного класса, метод keep_saved_data_anyway можно перегрузить в скриптах. Он должен возвращать логическое значение. Если возвращает false, то клиентские данные не сохраняются. Если не ошибаюсь, то эти данные - это то, что сохраняет/читает клиентский объект в методах биндера save/load. Наверное, надо бы что-то добавить о стратегии применения этой функции, но тут не много скажу. Обычно возвращает true, т.е. всё храним. Вероятно, когда-то имеет смысл эти самые данные обнулять.
  17. Viнt@rь, Вероятно активное окно всегда перекрывает другое top-level окно. Ну значит штатными средствами никак, только с расширениями.
  18. Irish Rover, Смотри здесь. Тебе нужен метод с указанием родителя.
  19. Shadows, у лампочек нет ни смерти ни здоровья, поскольку они не живые объекты. "Смерть" лампочки наступает от первого хита, что реализуется движком. Вроде как и колбек на хит работает, хотя сейчас точно не вспомню. Правда это всё в оригинале криво работает. После перезагрузки включается опять и т.д.
  20. mumie, Можно попытаться вывести нужный тебе элемент не на самом окне инвентаря, а поверх отдельным окном. Визуально разницы не будет.
  21. @Grand, это резервная копия, сделанная WinMerge.
  22. abramcumner, Пожалуйста: Определяем class1 и class2, унаследованный от class1 class "class1" function class1:__init() end function class1:fun() log1("fun 1") end class "class2" (class1) function class2:__init() end создаём экземпляры классов local a1 = class1() local a2 = class2() вызываем методы a1:fun() -- fun 1 a2:fun() -- fun 1 Результат пока вполне ожидаемый. Вызывается один и тот же метод. Теперь переопределяем метод класса class1 function class1:fun() log1("fun 2") end Проверяем: a1:fun() -- fun 2 a2:fun() -- fun 1 Метод унаследованного класса не изменился, зато изменился метод базового. Это повлияло и на экземпляр класса. Теперь заменяем метод не класса, а экземпляра класса function a1:fun() log1("fun 3") end Проверяем: a1:fun() -- fun 3 a2:fun() -- fun 1 Унаследованный, как и раньше, не поменялся. Метод конкретного этого экземпляра изменился. Проверяем, как изменение метода экземпляра повлияло на класс. Создаём экземпляры заново. local b1 = class1() local b2 = class2() Проверяем b1:fun() -- fun 2 b2:fun() -- fun 1 Т.е. изменение метода экземпляра на сам класс не повлияло. Здесь в принципе работает прототипное ООП. Ну если я не пытаюсь менять уже сделанные классы/объекты, то внешне разницы никакой. Разница возникает, если я пытаюсь менять определения классов или менять заменять методы экземпляров уже во время выполнения, вот как выше показано к примеру. Там конечно искусственная ситуация и на мой взгляд, не так уж много выгоды вообще в попытках менять классы. Хотя этого категорично утверждать и не буду, но я не встречал задач, где это реально могло бы принести пользу.
  23. Оба способа имеют свои достоинства и недостатки. При каскадировании можно динамически менять базовый класс и это скажется на наследованном. Вероятно, не всегда это и выгода. При делегировании изменение базового класса не скажется на унаследованном. Также очевидно снижаются расходы на вызов метода. В самом деле индексация будет всегда по одному списку методов, вместо вложенного поиска по всем базовым классам. Вероятно, выбор подхода будет зависеть от целей. Что же касается Luabind, то это в сущности и не прототипное ООП в чистом виде, а ближе к имитации класс-ориентированного подхода, поскольку добавляется класс как самостоятельная именованная сущность. Мы этот класс не используем сам по себе, а создаём экземпляры этого класса, используя вызов class_name(<аргументы>). При этом экземпляры класса, хоть и userdata, но технически отличаются от самого класса, который тоже userdata, но специальный. Соответственно, есть два различимых этапа работы с классом: конструирование класса и работа с объектами класса. В связи с этим всё становится совсем весело, поскольку в любой момент мы можем изменить: базовый класс, унаследованный класс, экземпляр базового класса, экземпляр унаследованного. Я проверил влияние изменений одного на другое в разных сочетаниях. Выходит что: 1. Никакие изменения ни базового класса ни его экземпляров не сказываются на унаследованном классе и его экземплярах после выполнения наследования. Значит при наследовании выполняется копирование (делегирование) методов. 2. Изменения класса однако сказывается на экземплярах этого класса уже после того, как экземпляр был создан. Значит в процессе создания экземпляра класса выполняется каскадное прототипирование. Но это обстоятельство не так уж и интересно. П.1 гораздо важнее. Так что в целом выходит, в Luabind при наследовании методы копируются. При этом я не уверен, что это справедливо для всех версий Luabind. По крайней мере это так в сталкеровской версии.
  24. Gun12, и какое отношение смысл ООП имеет к делегированию или каскадированию методов? В прототипном ООП используются оба подхода. Чем выбор одного из них может противоречить основам ООП?
×
×
  • Создать...