Artos 99 Опубликовано 26 Декабря 2011 А вот я наоборот ... залез пока в дебри (адаптируя и расширяя функционал данного сэндбокса) и пока не до семантики. ;-) Пока все отлично и работает и пр. ... Ощутимомго ыыигрыша/проигрыша по производительности (пока) нет, но в конечном итоге код получается более законченным, логичным и функциональным. Расширил его на таймеры и, все время терзает вопрос: Судя по несколько раннеей твоей реплике, по таймерам у тебя тоже некий задел/набросок имеется(?). Но, без расширения синтаксиса/семантики интерфейса (хотя бы по аргументам вызова/обращения к объектам класса) тут не обойтись. Ведь требуется и время задавать и прочее ... В этом направлении (применительно к таймерам) ты подразумевала этот же сэндбокс или ...? (вынужден отлучиться до вечера) "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Поделиться этим сообщением Ссылка на сообщение
Artos 99 Опубликовано 26 Декабря 2011 (изменено) xStream, эх, не успел посмотреть ... т.к. по ссылке лежит прежняя версия (1.0.2) в которой только в описании упоминается про hangCheck (в кодах ни разу). Теперь только вечером увижу, а пока - вероятно шли параллельными вариантами, но я все же не доп.методом в(от)ключал проверку, а флагом в арументах при вызовах. Хотя сейчас (пока не все ясно) уже немного по другому. По таймерам чуть позже поясню. Все же это (в моем понимании и в твоих терминах) аналогичные события (events), хотя и зависимые от коллбэка апдейта актора, но "выстреливающие" в строго заданное время. Т.е. все же событие, которое по исполнению кодов зависимо от породившего основное, но автономно по своей сути. Пока, срастив эти два функционала (класс событий и функции таймеров) получилось очень (ИМХО) неплохо (и функционально и логично и надежно). Причешу коды - выложу то, что вышло ... Изменено 26 Декабря 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Поделиться этим сообщением Ссылка на сообщение
Artos 99 Опубликовано 27 Декабря 2011 (изменено) Или я пере...курил или пора с кодингом завязывать ... :-) xStream: Оно использоваться должно там, где кидается ивент, а не где отрабатывается. Пример я в описании привела Хм, это то ясно и из примера и по сути, но: Читаем в readme: NOTE! Включение проверки на зависание биндера производится методом event:hangCheck() ДО "выстреливания" ивента.... Пример: event("actor_spawn"):hangCheck():trigger({data = data}) Но если попытаться применить даже 'в тупую' данный пример и вызвать этот метод - вылет по вызову несуществующему методу гарантирован. Ведь это не некий метод встроенный в компилятор Lua иль опциональный аргумент, а метод(!) который должен быть реализован в кодах класса, к которому применяется. Я так понимаю, что в классе 'event' должно присутсятвокать как минимум типа этого: function event:hangCheck() self.__dbg_check = true --/ флаг необходимости проверки зависших тредов return self --/> end и дополнительно в function trigger(evt), перед собственно циклом проверки массива events_in_process - начинать проверку только при наличии установленного флага разрешения этой проверки, т.е. типа: -- event callbacks can trigger another events but they must have different type local function trigger(evt) ... -- hang debug if evt.__dbg_check and next(events_in_process) then ... Вот тогда и фатальных вылетов не будет при попытках использования несуществующего метода hangCheck и проверки на зависания тредов будут выполняться только в случае установки флага разрешения такой проверки (т.е. только из 'родительских' событий). Да и замена #events_in_process => next(events_in_process) позволит все же проверять неиндексный массив. К сожалению не могу скачать и посмотреть пример для таймеров, т.к. хост Dropbox'а выдает 404-ю ошибку ... Вероятно расширение 'script' у отдаваемого файла не в числе валидных для трансфера по запросам. Просьба, перезалей в виде архива. Изменено 27 Декабря 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Поделиться этим сообщением Ссылка на сообщение
Artos 99 Опубликовано 27 Декабря 2011 (изменено) xStream, предлагаю все же несколько сдержаннее быть в словах ... Ведь написал же не зря: т.к. по ссылке лежит прежняя версия (1.0.2) в которой только в описании упоминается про hangCheck , т.к. по ссылке из поста #213 перекачивал не менее 4-х раз (напрямую и качалками), грехов за прокси провайдера не замечал ... И сам недоумевал по поводу странности с hangChek - поэтому и переспроси и дал обоснование. В архиве от "вчера" описание лехало от 26-го, а xs_sandbox.script от 21-го. Сейчас перекачал, в архиве и обновленные версии скриптов (1.0.3) и вижу срипт по таймерам. Спасибо, смотрю ... Изменено 27 Декабря 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Поделиться этим сообщением Ссылка на сообщение
Artos 99 Опубликовано 27 Декабря 2011 (изменено) Про 404 ошибку писал в контесте ссылки именно на скрипт наработки по таймерам, о чем и про расширение скачиваемого файла упомянул. (ну да этот вопрос уже проехели ... просто я менее спокоен порою чем удав ;-) ) А в чем причина тяготения к варианту: if #events_in_process>0 then ... end ... events_in_process[#events_in_process+1] = evt ... events_in_process[#events_in_process] = nil перед таким: if next(events_in_process) then ... end ... events_in_process[callback_name] = evt ... events_in_process[callback_name] = nil Просто более привычно или имеет более практичный смысл? Изменено 27 Декабря 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Поделиться этим сообщением Ссылка на сообщение
Artos 99 Опубликовано 27 Декабря 2011 (изменено) По таймерам: Есть интересные места, но я пошел вариантом наследования класса таймера от событийного: --/ ----------------------------------------------------------------- class "timer" (event) --/ --/ ----------------------------------------------------------------- function timer:__init(name) super("timer") if name and name ~= "" then self.__tmr_name = name end end --/ start(set) event timer and register callback function --/ call: timer(name):start(func, times(1|3) [,uo]) --/ real-timer(rt): name_timer(1), time_seconds(2) [, params(3)] --/ game-timer(gt): name_timer(1), time_days(2), time_hours(3), time_minutes(4) [ ,params(5)] function timer:start(func,...) if self.__tmr_name and next{...} then Start_Timer(self.__tmr_name,...) if not self:registered(func,self.__tmr_name) then self:register(func,self.__tmr_name) end end end --/ check event timer ... --/ call: timer(name):check([params, flag_mode]) function timer:check(...) return Check_Timer(self.__tmr_name,...) --/> end и есть преимущества в наследовании уже сделанного в ивентах ... Добавлено через 7 мин.: По разнице используемых операторов понял - спасибо за пояснение, я не обратил внимание на то, что может затираться поле с ранее запомненным зависшим тредом с тем же имененем ... Изменено 27 Декабря 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Поделиться этим сообщением Ссылка на сообщение
Artos 99 Опубликовано 27 Декабря 2011 (изменено) Ключевое фраза: "А зачем?" Уже писал ранее, что разница в наших подходах в "чистом" концепте (тут конечно же правила ООП превыше ...) и практического применения концепта к игре с ее кучерявостью. Если таймеры висят на колбэке актора, но "выстреливают" по некоему условию - то это же такие же события как и акторский апдейт (только дочерние) и имеют сутью события именно свой параметр времени (период от одного события до другого). Т.о. для таймерного концепта может связка с родительским событием и никчемна, но применительно к игре - от нее никуда не уйти. Связка же позволяет генерить дочерние таймерные события не только от акторского времени, но и от любого другого, но(!) весь функционал родительского ивента остается доступным и может быть очень даже использован. Добавлено через 3 мин.: Переменное количество параметров, конечно же лучше, чем набор методов для выставления величин (это сарказм был).Ты упускаешь из вида то, что мне приходится иметь дело с наследуемым кодом (AMK+...) и убрать в одночасье все это непросто, а точнее - просто сесть и переписать весь мод ... И если я вижу пока пользу и востребованность того же 'uo' (пользователькие параметры) - то почему в связке с основным концептом использование этого так товою отвергается? Учесть в самом классе всевозможные случаи, порой единичные не сложнее ли испоьзования аргументов при использовании подобного класса? Как раз тут мухи отделяются от котлет, а не городятся "котлеты по-киевски" ... Никогда не был сторонником "чистой науки" - первостепенное значение имеет практическое использование и конечный результат (ИМХО). Изменено 27 Декабря 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Поделиться этим сообщением Ссылка на сообщение
Artos 99 Опубликовано 27 Декабря 2011 (изменено) Вопрос - зачем ты тогда вообще взял эту песочницу, если все равно приводишь ее к процедурному виду? 1. Уже писал, что давно намеревался то, что уже наработано было в моде перевести на класс ... т.е. сделать каркас мода на базе ООП. Т.к. наработанный алгоритм был полностью схож с данной песочницей - перевод/адаптация кода заняла пару суток (мод все же не маленький). 2. Преимуществ использования данной песочницы немало, некоторые уже ранее упоминал. Дополнительно можно упомянуть более централизованное управление и контроль (плюс отлов ошибок). Спрашивать же у кого-то и верить на слово не привык. Предпочитаю перепроверять и делать выводы самостоятельно, а не по предпочтениям и вкусам других. И мен непонятно, о чем му уже ...? О моих неправильных и закостенелых кучерявостях или о том, что и как можно делать с кодами в Lua? ИМХО, было бы что, а уж как это использовать - дело каждого, т.к. не о едином проекте (игре/моде) печемся. А уж у кого лучшЕе - это уже те, кто играет в игру/моды судят. Добавлено через 2 мин.: Под "чистой наукой" имел ввиду в данном случае твое навязывание испльзовать концепт песочницы в чистом виде и не более ... Или же мне отказаться от ее использования раз так "изгаляюсь" над ней? (это вопрос и хотел бы получить ответ) Изменено 27 Декабря 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Поделиться этим сообщением Ссылка на сообщение
Artos 99 Опубликовано 27 Декабря 2011 (изменено) Жаль, что мы не поняли друг друга, а холиварить с тобою (по крайей мере ныне) не имею желания. На сим закругляю это уже оффтопик ... С наступающими! :-) Добавлено через 9 мин.: P.S. kamikazze, не предполагал, что ты из числа ясновидящих и способен читать ненаписанные/неопубликованные коды и мысли других ... И, как уже ранее говорил, привык полагаться на свои выводы и предпочтения, а не довольствоваться тем что дадено, даже если это очень "хорошая весЧь". Если мне требуется досолить иль поперчит - то не вижу в этом ничего запретного иль зазорного и своих вкусов не навязываю (как и не хулю чужие). Изменено 27 Декабря 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Поделиться этим сообщением Ссылка на сообщение
Artos 99 Опубликовано 27 Декабря 2011 (изменено) xStream, не хочу т.к. ... ни тебе, ни себе не хочется портить хоть в мелчах предновогоднее настроение. Все же я пока, если ты заметила, не нападал и даже не защищался, а только пытался с разных сторон рассмотреть как суть так и возможные использования данного решения. И мне достаточно также как и тебе, взгянуть на код, чтобы въехать в него ... дважды иль трижды убеждать меня в чем-то не требуется. Не собираюсь продолжать этот "разговор". Мне ясно - есть хорошее решение , его уже используют и довольны результатом. Это решение дает и некоторые преимушества применительно к моим решениям(по сути являющется следующей их ступенью), но и на данном этапе мне этого в чистом виде недостаточно (наследие прошлого) и очевидно - не хватит и в дальнейшем. Жаль, что так повернулось и автор хорошего решения против его реализации тугодумными кучеряводелами не в чистом виде. Бум думать далее каким путем идти. Для меня более приоритетными критериями перед "чистотой и стройностью кода" является его функциоальность и решение моих задач, даже если ето приводит к кучерявости. Изменено 27 Декабря 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Поделиться этим сообщением Ссылка на сообщение
Artos 99 Опубликовано 27 Декабря 2011 (изменено) Если кого заинтересует и в продолжение мысли "Чистота кода вполне уживается с его практичностью": Несколько ранее тут приводились примеры реализации распределенных обработчиков (см. #52 и ранее). Вот практическая реализация на обсуждаемом в текущее время сэндбоксе: 1. Регистррации всех коллбэков, которые вызываются 1 раз в секуду реализуются в массив: callbacks_recipients.update_1s = {} 2. В каждый цикл апдейта актора вызывается зарегистрированная на это событие функция OnActor_Update, которая и выполняет выбор времени срабатывания и саму функцию их массива подписанных односекундных апдейтов. Каждая из них вызывается по 1 разу в секунду и их вызов "размазан" (распределен по времени) на всю эту секунду. --/------------------------------------------------------------------ local count_1s,index_1s = 0,0 --/ кол-во функций коллбэков и текущий индекс обрабатываемого коллбэка local time_1s,period_1s = 0,0 --/ таймер-счетчик и период его обновления --/ коллбэк на апдейт ГГ function OnActor_Update(e) --/< e.time == time_global() --/ распределенный обработчик события 'update': вызов каждой подписанной функции 1 раз в сек if e.time > time_1s then --/ сверка с текущим временем if index_1s >= count_1s then --/ закончен цикл: переустановка period_1s = 1000 --/ общий период цикла таймера (1 сек) index_1s,count_1s = 1,#callbacks_recipients.update_1s --/ начальный индекс и кол-во вызываемых функций if count_1s > 1 then period_1s = period_1s/count_1s --/ 'распределенный' период вызова функций end else --/ продолжение цикла: index_1s = index_1s +1 --/ обновляем текущий индекс вызываемой функции end local tCb = callbacks_recipients.update_1s[index_1s] if tCb then table.insert(callbacks_recipients.update,{funct=OnUpdate_1s,idx=index_1s}) --/ добавляем 'прокси' обработчик события end time_1s = time_global() + period_1s --/ 'тикает' таймер end end function OnUpdate_1s(e) local tCb = callbacks_recipients.update_1s[e.idx] if tCb then tCb.funct(e) --/> вызов 'зарегистрированной' функции обработки события if e.__removeThisCallback then table.remove(callbacks_recipients.update_1s, e.idx) --/ remove collected callbacks from stack index_1s,count_1s = index_1s-1,#callbacks_recipients.update_1s --/ корректируем начальный индекс и кол-во вызываемых функций end end e.__removeThisCallback = true end --/------------------------------------------------------------------ Суть: Каждый цикл (1сек) подсчитывается кол-во зарегистрированных коллбэков и высисляется период между их вызовами. Далее в каждый такой период выбранный коллбэк добавляется в конец массива коллбэков события "actor_update", после чего удаляется из этого массива (если не была отрегистрирована в апдейте). В последующий период все повторяется с другим коллбэком. Примечание: коды портированы из рабочего варианта с иной нотацией, что возможно повлекло к нестыковкам в обозначениях (хотя вроде как постарался не ошибаться) и на работоспособность в таком виде не проверялись. В результате - имеем гарантированно распределенный по секунде вызов любого кол-ва коллбэков вместо единомоментного (по паре или более) их срабатывания, что позволяет все же избегать лагов в игре вызванных перегрузкой события "actor_update" Изменено 27 Декабря 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Поделиться этим сообщением Ссылка на сообщение
Artos 99 Опубликовано 27 Декабря 2011 (изменено) xStream, тебе не кажется несколько странным то, что все твои высказывания связаны только с твоим вариантом и только твоя точка зрения правильная и только об этом стОит говорить - все остальное чушь и безграмотная дремучесть? Если и есть какие наработки, которые уже решают какие-то задачи (частные или глобальные) - то нам про них не ведомо. Ранее были выложены варианты "распределенных таймеров" (назову их так в силу своей безграмотности в нотификациях и правильных названиязх). Мню приведен вариант решения с учетом текущего в теме разговора, Ввариант уже был сделан и ... непропадать же, может кому сгодится, кто пока не имеет ваших "благополучно решаеых песочницей". Конструктивизм диалога/критики не в том, что сэпать банальными - это нами уже сделано иль это просто сделать иначе, не говоря что и как хотя бы в наметках, а в том, что или указываются конкретные недостатки/ошибки или приводится более правильное/оптимальное решение. Обсуждать, для меня уже достаточно понятный код - вроде как нечего и закончили. Указывать в нем мелкие неточности/описки иль неоптимальности - это мало кому нужно, т.к. все одно для практического применения он должен быть до(пер)работан. Мне совершенно не хочется обсуждать чьи то вкусы или предпочтения более (не)правильные, типа кому хочется кататься на велосипедах иль заморачиваться с грейдером ... Тема форума совершенно не об этом. Есть интересная ИНФОРМАЦИЯ по кодингу для других - мне это интересно, есть вопросы - можно пообсуждать/порешать/поспорить ... а то, чем сейчас перебрасываемся - ничего не принесет, кроме потери времени и настроения и выслушивания очередных "истин". Ну а про пассаж - неужели неясна связка практического решения отдельной задачи с достаточно минимальным вмешательством в 'чистоту' кода сэндбокса? Или все, что не в рамках выложенного сэндбокса - все лажа и никчемность, неимеющая никакой ни практической ценности ни чистоты программисткой мысли? Все, мне малость поднадоело, удаляюсь, а то ... начну парировать. Изменено 27 Декабря 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Поделиться этим сообщением Ссылка на сообщение
Artos 99 Опубликовано 27 Декабря 2011 (изменено) {последняя попытка вести конструктивное обсуждение по поднятой теме} Но все же пару слов: Приписывать голословно ...делать убер-пупер-мегаскрипт - не панацея, зачастую приводящая вообще к ужасному нагромождению кода. Ты же этого в упор не хочешь видетьподспудно задевая эпитетами то что другой сделал - считаю довольно грязным приемом в диалогах. Мною пока почти не было показано что-либо на эту тему, а говорить про "вообще" - смахивает на демагогию. Если мне в твое решение (сэндбох) захотелось (или пока вынужден) добавить (временно или даже на постоянно) некоторые коды, нарушающие твою концепцию - то кажется дал ясно понять, что УЖЕ имеющееся в моде НЕ позволит полностью проверить в реальной работе преимущества и недостатки - соответственно пока приходится и нагромождать совместимость с имеющимся. Видеть в данном решении, как выразился kamikazze, велосипед - не собираюсь. Я вижу в нем очень даже грузоподъемный грузовик, который способен на перевозку достаточно объемных и многочисленных грузов. Добавить ему проходимости и адаптировать под "местные погодные условия" (да хоть на лыжи поставить) - не вижу пока никаких ограничений. И всегда считал универсальность достоинством, а не недостатком, когда это не в ущерб функционалу и целевой задаче. И я не защищаю попранную справедливость (не нужно опять высокой демагогии!), но действительно уже раздражает неуемность ваших попыток навязать свое (на веру) и охаить даже еще не видимое и не до конца высказанное. Кричать (капсом) о несвязанности таймеров и ивентов и тут же в кодах по сути достаточно тесная их взаимосвязанность - оригинальный вариант объяснения своей позиции. На этом предлагаю не обсуждать личные недостатки/достоинства/вкучы иль привычки, а то закидаем друг друга камнями ... По closures и ранее интересовался и даже указанную страничку (вроде как читал), но ... и как-то неактуально было и, попробовав, не увидел особой выгоды. В даннос слкчае может быть опять красивость кода на высоте, но его восприятие непосвященными становится неочевидным. Если делать что-то по типу: сделал - забыл, тоэто одно. А вот если через пол-годика приходится вновь копаться в кодах - можно и оступиться, если из головы выветрилось. Вероятно должны быть довольно весткими аргументы и/иль выгода применения closures, чтобы отказаться от привычных построений кодов. Предлагаешь поисследовать/пообсуждать этот вопрос? kamikazze, (алаверды) Ты что не в курсе что ли о том, что распределение по времени и распараллеливание совершенно разные понятия и в том, что мною описано и предожено, ни коим образом не говорится о распределении потоков иль запуске одновременно ... Под единомоментным в данном контексте подразумевается 'единой последовательной цепочкой вызовов в одном и том же цикле апдейта актора'. Неужели совсем разучился читать код (даже не на венгерке написанный)? Данное решение как раз и создает единый счетчик-распределитель, который ты предлагаешь встроить в каждый вызов. Мда ... уж. Ну похвастай как это у вас на евентах реализовано, утри нос неумехе! ;-) [x] Изменено 27 Декабря 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Поделиться этим сообщением Ссылка на сообщение
Artos 99 Опубликовано 27 Декабря 2011 (изменено) Отвечу только в котексте того, что применимо к игре/моддингу, а не вообще ... - безымянными пользуюсь, хотя не часто; - по замыканиям уже выше отвечал, что прочитав - попробовал и ... забросилю Может где в кодах мода рудимент и остался; - кастомными классами ООП - если пояснишь несколько более определенно что под этом подразумеваешь, то смогу ответить, но скорее всего нет. Слово "потребуется" наверное все же не совсем тут уместно. И мало кто не знает зачастую, что может ему потребоваться завтра, хотя сейчас вроде как не требуется. Нередко многие не подозревают, что есть нечто, что ими может даже очень быть востребованным, а они обходятся без ... Применительно ко мне, то мне интересно то, что и полезно и может даже сейчас не требуется, но может быть востребовано и то, что заставляет поломать голову в поисках интересных решений иль расширения возможностей/оптимизации. Если считаешь, что то, о чем говоришь может быть востребовано другими - ИМХО, не стОит ждать ответа, кто-то и отсутствует а кто-то и через неделю (пере)прочтет - просто начать давать информацию и ... по ходу будет понятно, востребовано иль пока еще рановато. Изменено 27 Декабря 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Поделиться этим сообщением Ссылка на сообщение
Artos 99 Опубликовано 27 Декабря 2011 (изменено) Наверное все же замыкания (closures) интересно обсудить, но не в контексте красивых примеров из теории, а в контексте их практического применения ... Все же это скорее изюминки, и каши из него не сварить, хотя добавить по-вкусу - очень даже неплохо может получиться. Тут все же нужны интересные находки, которые и обсудить (разобрать по косточкам) можно и которые могут послужить катализатором для дальнейших подобных находок (изюминок) применения. Ну а по кастом классам ООП (если я правильно понял), то ... боюсь я их (вернее псевдо-их) наплодил уже больше чем во всех остальных модах вместе взятых ;-). Хотя это пока скорее и "проба пера" и чисто практический подход по разделению одного класса по некоему признаку, дабы удобнее было бы использовать. Боюсь что и тут камни полетят по поводу глупого использования ООП не к месту и не по делу ... Так что, для меня, например это интересно, но давай аккуратнее/терпимее относиться к причудам других. Т.о. если не считать псевдо-классов, в которые выделены аномалии (плюс мины/костры), некие фейк предметы и заглушки для совместимости мо классам ТЧ и ЗП, то мои попытки создать на базе ТЧ нормальный кастом ООП класс пока не увенчались каким-либо успехом (очень куций нелп-материал нам достался от разрабов), хотя несколько позже (после некоего релиза текущего состояния мода) как раз собирался покопаться поосновательнее. Изменено 27 Декабря 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Поделиться этим сообщением Ссылка на сообщение
Artos 99 Опубликовано 28 Декабря 2011 (изменено) xStream, Прекрасно понимаю, что доказывать что ты (в смысле я) не верблюд - совершенно не зачем, но и не могу, почему ты все время предполагаешь в собеседнике худшее? Если ты считаешь, что я вешаю лапшу на уши, стараясь побольше надуться - то ... переубедить конечно могу, но стОит ла тратить время на это и в очередной раз накалять градус диалогов? Повторяю, про замыкания попался на глаза материал где-то полгодика назад. Заинтересовало, но, как часто бывает и не в тему было и не нашел полезного применения и, как то промелькнуло мимо енто дело ... Как в прчем и по таймерам, которые ты сейчас оформила в виде класса, а мною (плоский код) был заброшен до лучших времен. Но об этом может быть чуть позже ... По "изюминкам": Полностью тут согласен, чем больше будут появляться от участников форума/топика различные "изюминки" - тем конечно же и интереснее и полезнее для всех нас. Поэтому и сам порою подбрасываю такие "изюминки" ... Но моя мысль была ранее о том, что (не принимай на свой счет полностью!) негоже превращать изюминки в панацеи и стараться навязывать их применение везде и всегда и в неизменном виде. Также не следует голословно и/или демагогично отвергать то, что предлагает другой. Даже в ошибочном или неудачнм решении часто содержится информация, которые вполне могут быть полезны для дальнейшего развития мысли и нахождения очередной "изюминки". Т.о., считаю, что делиться своими находками в дебрях Lua (иль кодов игры) - стОит как можно чаще, не увлекаясь мелочевкой и не хая 'не свое и не по-вкусу'. Осмелился все же пристроить предложенный вариант твоего таймерного класса к своим кодам (помимо класса событийных таймеров на базе ивент-класса). Сейчас как раз, закончив адаптацию всего мода, ударился в исследования связки безымянных функций и замыканий (как ты приписываешь мне - в теорию). Получаются порой довольно интересные варианты использования ... если что-то откопаю действительно заслуживающее внимания относительно игры или кодинга - обязательно поделюсь. По 'uo': любовь к этому варианту привили как раз АМК-коды ;-), но, по большому счету, вообще то не очень то мною любимы (именно в форме разно-колличественных кучек значений), т.к. по-возможности я их переделывал в таблицы с нужыми по-случаю параметрами. Так что, то, что ты сейчас называешь 'заменой пачки', собственно уже ранее в плоском коде было оформлено во многих вариантах как массив. сейчас мне очень просто было портировать все это под ООП. Но в отличии от тебя, я не считаю 'защиту извне' таким уж преимуществом ... Не спорю, это порой очень востребовано, но порою и мешает. Тут как говорится - зависит от контекста и задачи/цели. Вот по применимости безымянок к диалогам - спасибо(!) В очередной раз даешь пинок в сторону искоренения различных аттавизмов в кодах мода/игры. Как то задался целью перевести многие диалоги на скриптовые формы, уйдя от закостенелых html-ек, но ... трудоемкость надолго уронила желание ковыряться с портированием диалогов. Вот если бы еще найти вариант вмешетельства в дерево уже сформированного при загрузке диалога ... было бы совсем интересно перелопатить диалоги и писать по-новому (но это уже больше к игре относится а не к Lua). Кстати, вариант с таймерами на базе родительского класса ивентов очень и очень неплохо показал себя в кодинге и в игре. Если учесть, что у меня под него все уже было ранее реализовано (сохранения/загрузки, оптимизации и пр.) то удобство и фукциональность возрасли, с сохранением надежности и малой ресурсоемкости. Несмортя на твое отрицательное к этому (к связке) отношение - все же большое спасибо за начальную идею! :-) Изменено 28 Декабря 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Поделиться этим сообщением Ссылка на сообщение
Artos 99 Опубликовано 28 Декабря 2011 (изменено) xStream, предлагаю прекратить комментировать и транслировать высказывания не по теме топика. Не пытаюсь ничего приписать или задеть. Я просто дал некоторое уточнение по теме (о защите из вне), которое на мой взгляд имеет для меня значение и по истории появления 'uo'. Не более ... Но и опять готов не согласиться с категоричным с твоей стороны утверджением о: При любом раскладе функторы компактнее, лаконичнее и удобнее, чем массивы и организация синхронизации этих самых юзер-обжектовВсегда найтутся и исключения из правил, а данном случае их немало. Вытащить из функтора исходно неизвестные данные далеко не простое занятие, а навязанный обязательный формат для записи в функтор хорош для вновь создаваемого и стандартизованного проекта, а не для кучи разномастных кодов (которые собственно и составляет игра/моды). Добавлено через 19 мин.: Хотел бы опять уточнить небольшой момент по применению выбранного варианта получения идентификаторов для реализации в таймерах: В текущем исполнении идентификаторы будут линейно возрастать до бесконечности (до ограничения по разрядности в движке). Так же для чего в таблицу заносить идентификаторы строкою, а не числом? Ведь этот вариант вполне пригоден: timers_holder = {} function check_timers(e) for _,tmr in pairs(timers_holder) do if t.trigger_time and t.trigger_time <= time_global() then event("timer_"..t.id):trigger() end end end --/ --------------- class "timer" --/ --------------- function timer:__init() self.__once = true self.id = self:gen_id() timers_holder[self.id] = self end function timer:gen_id() local id = 1 while timers_holder[id] ~= nil do id = id +1 end return id --/> текущий индекс (для имени таймера) end ... и позволяет держать значения индексов в разумных пределах, переиспользуя уже использованные индексы. Или я опять некий нюанс упускаю? (не считая небольшой потери производительности при выборе очередного идентификатора) Изменено 28 Декабря 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Поделиться этим сообщением Ссылка на сообщение
Artos 99 Опубликовано 28 Декабря 2011 (изменено) xStream, именно "засорение" таблицы итемов и имел ввиду (в первую очередь) говоря о разрастании значений индексов, а не про оптимизацию (ведь наоборот произвоительность при выборе падает). Т.е. выбранный вариант - это только тех-оснастка примера, как я понял. Хотя цель записывать в таблицу таймеров именно по строчным ключам (""..id) - осталась непонятна, что отвлекает от основной цели примера. Изменено 28 Декабря 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Поделиться этим сообщением Ссылка на сообщение
Artos 99 Опубликовано 28 Декабря 2011 (изменено) По строковым понятно. Пытаюсь сейчас найти приемлемый вариант, чтобы и не мусорить и производительно ... Ну а по производительности - то как раз почему же примеров нет. ;-) Даже далеко ходить не нужно, те же таймеры, хотя и не совсем то, о чем ты говоришь ( ... обвешен кучей проверок и исполняется дольше, чем полезный, рабочий код), но и кол-во многочисленных коротких проверок вместо одной общей - тоже имеет отношение к производительности. Взять тот же цикл для примера и представить что таймеров не один десяток/сотня: function check_timers(e) for _,tmr in pairs(timers_holder) do if t.trigger_time and t.trigger_time <= time_global() then event("timer_"..t.id):trigger() end end end получаем, что все таймеры перепроверяются на достижение своего зачения. На СП это уже обсуждалось и Gun12 тогда заметил (общий смысл): "А зачем каждый раз проверять все? Не достаточно ли вычислить ближайщее и ждать его? После чего определять следующее ближайшее и т.д.". Этот вариант и реализован и вполне неплох. Так что экономить стОит и в таких мелочах (ИМХО). Вот пример для указанного случая: local nearest_time = nil function check_timers(e) if nearest_time ~= nil then local current_time = time_global() if current_time <= nearest_time then nearest_time = nil for _,tmr in pairs(timers_holder) do if t.trigger_time then if t.trigger_time <= current_time then event("timer_"..t.id):trigger() elseif t.trigger_time < (nearest_time or 9^9) then nearest_time = t.trigger_time end end end end end end --/ --------------- class "timer" --/ --------------- function timer:__init() self.__once = true self.id = self:gen_id() timers_holder[self.id] = self end function timer:gen_id() local id = 1 while timers_holder[id] ~= nil do id = id +1 end return id --/> текущий индекс (для имени таймера) end function timer:run(time_seconds) if self.trigger_time then return end nearest_time = 0 --/ reset! ... Примечание: Тот же ранее приведенный пример с распределенным 1-о секундным апдейтом - из разряда аналогичных мелких оптимизаторов. В принципе, этот вопрос (по производительности) скорее из категории незнания/не желания многих модмейкеров/кодеров вникать в глубину кода, и довольствуются наспех написанным, но рабочим ... Тут как раз брать примеры и тыкать бы носом, но ... результат будет скрее обратным. Т.е. вместо учебы - получаем обиды ... Изменено 28 Декабря 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Поделиться этим сообщением Ссылка на сообщение
Artos 99 Опубликовано 28 Декабря 2011 (изменено) (обновил верхний пост, т.к. не успел до падения форума подправить) xStream, пример с таймерами взят как один из типовых, а не некий написанный наспех и не имеющий целью быть включенным в рабочие коды как есть ... Мы же в топике по программированию, который читают и те, кто как раз и пишут в своих модах так, что еще похлеще с производительностью выходит ... Кстати, думаю, что такие примеры тоже служат помимо хорошего дела и ... в виде медвежьей услуги. Поясню: ведь немало тех, кто заглянув и мало что поняв, хватают вот такие упрощенные коды и начинают их вовсю использовать ... У них заимствуют другие и ... так и расползаются технологические примеры-времянки в моды. :-( Добавлено через 29 мин.: P.S. Что-то у нас достаточно беспредметный разговор пошел ... Вроде как о важном/нужном, но ... только об общем. :-( Вот ты говоришь, важно про произвоительность, а примеров нет. Н у а что мешает поговорить именно на примерах, только не на академических, на на реальных?! Брать чьи-то давно вышедшие коды/моды - наверное достаточно буссмысленно. Ну так и давайте говоить о текущих! Что мешает выкладывать на разбор полетов наработки? Мои текущие коды-наработки постоянно доступны и актуализируются не реже раза в месяц. Что мешает взять их в качестве примеров и врезать по полной программе за гриворукость иль за разгильдяйство? :-) Что мешает выложить вам (вроде как и kamikazze сюда заглядывает и кидает реплики) выложить для обсуждения то, что отнисится к теме? Хотя бы ту же песочницу, чтобы не голословно утверждать иль намекать, а получить по полной программе за хороший иль корявый алгоритм? ;-) Вот и будет и тема и реальные примеры ... Изменено 28 Декабря 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Поделиться этим сообщением Ссылка на сообщение