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

Monnoroch

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

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

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

  • AMKoin

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

Баланс оценок

6

9 подписчиков

Недавние посетители профиля

10 672 просмотра профиля
  1. Вот, еще немного дополненная версия: дефолтные настройки вынесены из логики. malandrinus, теперь если в mon_utils.default_slot поставить unique = true, то получится ровно твоя система, но которую можно использовать более гибко http://ifolder.ru/28160609
  2. Вот, добавил собственно то, что хотел: возможность множественных подключений слотов, возможность это запретить, некоторые настройки с этим связанные и вообще привел в порядок код. http://ifolder.ru/28140737
  3. xStream, Да, я уже это понял Просто в D есть такая штука, что выражения типа void туда пихать можно, в результате всё expression преобразуется в statement и получаются такие вот красивые ветвления.
  4. Вот, для любителей выкладываю слот-сигнальную систему v 2.0 собственного приготовления. Она чуть более ООП, чуть менее суровая и чуть более настраиваемая. http://ifolder.ru/28140737 Ах да, делалась она на основе системы malandrinus, из оригинального кода взято обеспечение корректной работы очередей и каменты, так что не надо удивляться И да, спасибо ему за идею. И таки "a or return" не работает, по крайней мере codepad не понимает, потому там такие штуки везде накомментированы, тоже не надо удивляться... Добавлено через 18 мин.: Если обобщить твой вариант для произвольной функции получится: function dublicat(f, ...) return f(...) end Но это странный вариант. Он не создает новую функцию. А моя функция принимает функцию и возвращает ее копию. А уже копию я могу приписать к тому же сигналу. Хотя тут явная проблема в том, что отписать этот слот будет затруднительно - только если закэшировать...
  5. malandrinus, Ну да, зато у меня можно создавать сколько угодно дубликатов Добавлено через 29 мин.: Кто-нибудь может подсказать, можно ли в lua выражение: if not a then f() end заменить на a or f() И соответственно: if a then f() end заменить на a and f() Чуть более сложнее, может ли там быть statement: a and c = 1 или a or return ?
  6. malandrinus, кстати об этом, а анонимная функция пойдет для решения проблемы? навроде: slt = {fun = function() return f() end} В смысле так же можно? В общем случае сработает ли такое решение: function duplicate(f) return function(...) return f(...) end end ASSERT(f ~= duplicate(f),"?")
  7. malandrinus, Предположим общий включается на первый выброс и после выключается, а частный должен работать всю игру. В добавок, в данном случае три строки не помогут: надо отписать общий случай но сохранить частный. То есть соблюдать вложенность. Я, может, пытаюсь придумать искусственный случай, но в самом деле, кто знает, как будут использовать возможность подписки? Я любитель общих решений И не любитель лезть руками в чужой код, неблагодарное это занятие, может там на четном количестве ошибок в знаке все держится?
  8. malandrinus, Ситуация простая: некий мододел захотел на непися повесить поведение при неком скриптовом событии - например при выбросе. А выброс, так как наша система работает вокруг слот-сигнальной модели, генерирует сигнал. Ну что делает мододел - подписывает слот на сигнал. А теперь другой мододел расщедрился и хочет подписать всех сталкеров на это поведение но не знает что один уже подписан. Вот пожалуйста, двойное подписываени. Слот при этом бутет выглядеть как-то, например, так: slt = {signal = "blowout", self = obj, fun = obj.hit} и так для всех сталкеров. Ну и что, вот человек отлаживает эти моды вместе и видит: в цикле по всем сталкерам оказывается один уже подписан! Ну хорошо, и что ему делать-то? Искать где подписан и отписывать? Это копошение во внутренней реализации мода - не есть хорошо при любом раскладе. Код должен иметь как можно меньшую связность. А если разрешить двойное подписание, то все разруливается: второе подписывание элементарно игнорируется, вернее увеличивается счетчик подписываний до двух. А когда кто-то отписывает его, счетчик уменьшается до одного. А потом до нуля - и тут физически происходит отписывание. А сигнал, сколько бы раз на него слот не подписался, вызывает его, естественно только один раз, зачем ему больше? Хотя тут можно даже параметр сделать, это дело настраивающий: один или несколько.
  9. Andrey07071977, Так ведь нет же, я как раз и пытаюсь протолкнуть идею, что двойные подписки - совершенно нормальное явление. Потому и отлавливать их сомнительный профит, разве только если в конкретных случаях.
  10. malandrinus, Хранить счетчик подписываний, а не подписывать каждый раз. А пример я приводил: вот у меня класс хелпер какой-то. Мне присылают обьект и список эвентов на которые подписать. Задача - подписать на все. Ну понятно же, что не хочется каждый раз проверять - подписан ли уже, и если нет, то подписывать, хочется же сделать код прозрачней. Ну вот метод: function subscribe_all(mgr, slots) for _,v in pairs(slots) mgr:subscribe(v) end end Допустим код одной схемы вызывает: helper.subscribe_all(mgr, {s1,s2,s3}) А второй: helper.subscribe_all(mgr, {s2,s3,s4}) Вон как все красиво. Да, можно всунуть if, но как-то уже не то. Хотя вот я тут подумал - если просто в сам класс подписывателя инкапсулировать этот subscribe_all с if-ом, то будет все хорошо в плане использования. По поводу этого: Я думал обо всей системе, как о библиотеке, у которой есть интерфейс а реализация меня волновать не должна. И конечно пользователь сам может определить subscribe_silent с помощью того же if-а и снаружи библиотеки, но это потенциальное дублирование кода - каждый будет свою версию определять. И потом, тут проблема именно в том, что два разных человека подписывают один и тот же обьект на один и тот же эвент. Ну вот выпал мне этот ассерт - что мне делать? Ставить ту самую явную проверку, вариантов особо других нет. Я же не знаю, всегда ли так получается, что он уже подписан. Это же не мой код. И не ошибка в логике. Ты не пойми неправильно, я не пытаюсь учить ученого, просто мне показался странным подобный дизайн модуля, который потенциально может использоваться кучей народу в куче модификаций Во, кстати, я еще досмотрел и такой вопрос: почему сигнал встраивается в слот? Можно же было бы сделать как-то так: obj:subscribe(signal,slot), тогда один слот мог бы быть подпинан на множество сигналов в разное время разным кодом.
  11. Andrey07071977, Не надо никаких сообщений в лог. Это сажает производительность. Просто далеко не всегда подпись на эвент дважды является ошибкой в логике программы. Особенно учитывая, что мододелов куча и один может в своем моде подписать на A,B,C, а второй на B,C,D и что теперь, совмещающему всматриваться, размышлять? К тому же раскройка модов при совмещении радикально ломает всяческую инкапсуляцию. С другой стороны получается, что теперь всегда вместо одной строки подписания придется писать три строки проверки-подписания, а всегда потому, что откуда кто знает на какие эвенты обьект уже подписан? Ну и зачем увеличивать клиентский код в три раза? Поэтому просто надо тихо return false, кому надо, тот проверит, но чаще всего это излишняя информация.
  12. malandrinus, посмотрел твои эвенты - красота! Но только почему ASSERT, зачем такая жестокость? Обычно в такой ситуации бросают исключение, потому на мой взгляд логичнее было бы просто ничего не сделать и как-то сообщить пользователю, что он не совсем прав. А то сразу assert делать слишком сурово. В добавок мне видится ситуация, когда я хочу подписаться на эвент, если еще не подписан, и ничего не делать если подписан. Замена ассерта на более мягкую обработку ошибки позволит тут избавиться от ветвлений типа if not obj:is_already_subscribed(slot) then obj:subscribe(slot) end К тому же с ветвлением obj:is_already_subscribed вызывается дважды. Либо добавить signals_mgr:subscribe_silently()
  13. То есть разработчики все же не вносили изменений в luabind? Просто не было возможности посмотреть, собирать буст с луабиндом на моем калькуляторе радости мало, и потом, винду еще ставить... но интересно же.
  14. Пытался, не прокатило, но только потому, что я не включил в него luabind. В принципе, есть вероятность что разработчики движка дописать какое-то API сами, но если нет, то в результате, после подключения luabind, должно работать.
  15. kuzia, Да, но это надо много перелопатить. Динамические аномалии создаются скриптами, в то время как оригинальные, насколько я понимаю, были прописаны в all.spawn. Соответственно нужно прописать их заного и выключить скрипт динамических анамалий вашего мода. А это не совсем тривиально обычно, так как он довольно глубоко встроен в остальные механизмы мода.

AMK-Team.ru

×
×
  • Создать...