xStream 87 Опубликовано 8 Января 2012 (изменено) Viнt@rь, ну у меня и используется цикл в той реализации, что я выкладывала. При срабатывании таймера, не только находим тот, который будет выполнен в следующий раз, но еще и смотрим, есть ли еще такие, что должны сработать сейчас? Если есть - отрабатываем их. Однако в реализации Gun12 это чревато нагромождением кода, лучше уж рекурсию допустить. Фризы же будут либо при тысячах таймеров, одновременно срабатывающих, либо если они дергают "тяжелые" колбеки. В реальности ни того, ни другого на практике нет. Если же случится такая ситуация, то это явный признак того, что в программе явно что-то не так и надо заняться ее ревизией Идея с флагом по сути оптимизация, но преждевременная. Надо стараться оценивать реальные ситуации, в которых этот код будет работать. В случае появления проблем делаются тесты, замеры и тогда уже делается оптимизация. Практика показывает, что оптимизировать надо зачастую совсем не там, где ты ожидаешь Добавлено через 4 мин.: Тема, кстати, тоже хорошая - циклы vs рекурсия. Выбор должен определяться условиями и окружением твоего кода, а не личными предпочтениями. Имхо. Изменено 8 Января 2012 пользователем xStream Все, кто стоит на моем пути: идите нахрен и там погибните! © Поделиться этим сообщением Ссылка на сообщение
xStream 87 Опубликовано 8 Января 2012 И правильно думал, что вероятность... Она действительно мала в реальных условиях. Учитывая архитектуру твоего кода, это можно делать через рекурсию. Все, кто стоит на моем пути: идите нахрен и там погибните! © Поделиться этим сообщением Ссылка на сообщение
xStream 87 Опубликовано 9 Января 2012 (изменено) Gun12, type(tonumber(time)) == 'number' Хм. А это что за покемон? В чем сакральный смысл? Я просто в восторге. Аж дух захватывает. Это здорово. Что сам думаешь про такой подход вместо createTimer(xxx,xxx,xxx)? На самом деле, тоже въехала в код, в который раз ЛУА меня удивил своими возможностями. Финты ушами такие можно делать, что мама не горюй. У тебя практически уже около ООП что-то: есть "описание класса" timer, и есть "конструктор" __call. И работаешь с инстансами. Круто. Чуть-чуть доработать и будет почти тот же функционал, что дает луабинд Изменено 9 Января 2012 пользователем xStream Все, кто стоит на моем пути: идите нахрен и там погибните! © Поделиться этим сообщением Ссылка на сообщение
xStream 87 Опубликовано 9 Января 2012 (изменено) Не хочу, чтобы сюда попали другие данные, кроме числа. А ты посмотри, что ты делаешь Сначала приводишь параметр к числу и проверяешь, число ли у тебя... Ну конечно число! Ты же только что приведение типа сделал Не нужен там tonumber, он тебе всю твою задумку ломает. Ибо type(tonгmber(x)) всегда 'number' Двойка мне за знание матчасти. Все верно у тебя. Вот еще один нюанс луа с приведением типов обнаружился... Изменено 9 Января 2012 пользователем xStream Все, кто стоит на моем пути: идите нахрен и там погибните! © Поделиться этим сообщением Ссылка на сообщение
xStream 87 Опубликовано 9 Января 2012 (изменено) Это немного отличается от того, как сделано в луабинде. Там все намного более семантично сделано. В твоем примере ты получаешь "класс", вызвав функцию class(). Это не является определением класса, имею ввиду, что это не общепринятый синтаксис, как во многих других языках. Стандартно пишется "ключевое слово", обозначающее, что сейчас будет определен класс, а потом - имя класса. Зачастую идет третий "параметр" - родительский(ие) класс(ы). Суть в ЛУА не меняется. Эта информация так, для общего развития. Лично мне просто привычнее работать именно так, после С++, Java, Питона, ПХП. В Javascript используется прототипирование, там вообще все по-другому, как раз больше похоже на то, что ты описал. Может оффтоп, а может информация для общего развития ИМХО, такое нужно применять для чего-то более масштабного чем таймеры в моей интерпритации : Лично мне такой способ объявления "дочерних классов" очень неудобен. Но это именно мое имхо и мои привычки. Но ООП на этом действительно можно спокойно реализовывать. И вообще, я где-то говорила, что это проблема? Луабинд все это реализовывает именно таким вот хитрым путем. Принцип его работы очень легко повторить. Изменено 9 Января 2012 пользователем xStream Все, кто стоит на моем пути: идите нахрен и там погибните! © Поделиться этим сообщением Ссылка на сообщение
xStream 87 Опубликовано 9 Января 2012 Попрошу не путать Луабинд ничего не добавляет к луа. Он реализует, образно говоря, некий функционал, используя только возможности самого луа. Если очень приспичит, я могу написать обертку, которая будет делать практически то же самое, что и луабинд - предоставлять возмжность создавать "классы" и реализовывать "наследование". Там всего-то две функции, а остальное игра с метатаблицами. Смысла только не вижу. Если хочется обсудить принцип реализации луабиндом этой фишки - прошу в личку. Еще раз - луабинд НИКАК не расширяет синтаксис ЛУА, а просто имеет "встроенный" дополнительный функционал. Вот что главное. ------------------------ Вывод всего этого - метатблицы и переопределение операторов - рулез. Добавлено через 5 мин.: А вообще, понятие "чистый ЛУА" смысла не имеет. Если вспомнить, что можно к интерпретатору подключать различные библиотеки, "базовая" комплектация содержит только самое основное. Никто не гнушается подключать библиотеки к интерпретатору. Потому мне кажется, что твое желание "изучить чистый ЛУА" не сильно логично. Лучше уж знать максимум, исопльзовать что нужно для своих целей исходя из задач. Все, кто стоит на моем пути: идите нахрен и там погибните! © Поделиться этим сообщением Ссылка на сообщение
xStream 87 Опубликовано 10 Января 2012 (изменено) Gun12, Viнt@rь, вот для общего развития. Реализация "классов", подобная реализации луабинд. Можно "наследовать" классы, форма записи - такая же (определение классов). Как видно из кода - реализация примитивнейшая средствами ЛУА, но результат... _G.class = function (cls_name) if type(cls_name)~='string' then return function() end end local cls = {} local cls_mt = {} cls_mt.__call = function(...) local cls_obj = { parent = cls_mt.__index -- imitate parent class, allows call parent's methods } local cls_obj_mt = { __index = cls, __gc = function () if cls_obj.__finalize then cls_obj:__finalize() -- imitate destructor end end } setmetatable(cls_obj, cls_obj_mt) if cls_obj.__init then cls_obj:__init(...) -- imitate constructor end return cls_obj end setmetatable(cls, cls_mt) _G[cls_name] = cls return function(parent_cls) cls_mt.__index = parent_cls end end --================================================ class "A" function A:__init() self.bar = "A says yahoo" print("A:__init called") end function A:foo() print("A:foo called") end function A:__finalize() print("A instance is destroyed") end --------- class "A_der" (A) -- this class is derived from A function A_der:__init() self.parent:__init() -- calls parent method print("A_der:__init called") end function A_der:lol() print("A_der:lol called") end --------- class "B" function B:__finalize() print("B instance is destroyed") end function B:__init() self.bar = "B says boooo" print("B:__init called") end function B:foo() print("B:foo called") end --------- local a = A_der() local b = B() a:foo() -- calls A:foo a:lol() -- calls A_der:lol b:foo() -- calls B:foo print(tostring(a.bar)) print(tostring(b.bar)) a = nil b = nil collectgarbage() Функционал даже чуть-чуть шире, чем у той версии луабинда, что использована в сталкере. У каждого объекта класса есть свойство self.parent, указывающее на "родительский класс", если такой есть. Это полезно, когда и в родительском и в дочернем классе существуют методы с одинаковыми именами. Можно вызвать из дочернего метода родительский. Редко бывает нужно, но бывает. self.parent:__init(...) абсолютно идентично super(...) в сталкере - вызов конструктора родительского класса (опять же - если есть). Ну и еще одно отличие - классы помещаются в глобальную область видимости. Изменено 10 Января 2012 пользователем xStream Все, кто стоит на моем пути: идите нахрен и там погибните! © Поделиться этим сообщением Ссылка на сообщение
xStream 87 Опубликовано 11 Января 2012 (изменено) Gun12 Что-то как-то громоздко. И я не понимаю интерфейса (имхо, тоже перегружен - мне кажется, геттеры и сеттеры в чистом виде не нужны. В "методы" обернуть бы более комплексную логику). Зачем ограничение, что таймер нельзя сохранять в переменной? Это не удобно, всегда присваивать имя. Это аналогично безымянным функциям - они есть, работают, можно передавать, но имени нет. ИМХО. Изменено 11 Января 2012 пользователем xStream Все, кто стоит на моем пути: идите нахрен и там погибните! © Поделиться этим сообщением Ссылка на сообщение
xStream 87 Опубликовано 11 Января 2012 Gun12, да никакого высшего пилотажа там нет Только синтаксис ЛУА. Класс - таблица-прототип, хранящая логику. Объект класса - тоже таблица, но хранящая данные. По метаметоду __index ссылается на таблицу-прототип. Наследование реализуется тоже с помощью __index - таблица-прототип ссылается на другу (другой класс) получая оттуда другую логику. Элементарно. Все, кто стоит на моем пути: идите нахрен и там погибните! © Поделиться этим сообщением Ссылка на сообщение
xStream 87 Опубликовано 11 Января 2012 Andrey07071977, Как быть в ситуациях когда в классе несколько методов которые необходимо подписать на разные события? Например, есть класс "actor_hit_effect", в нем два метода-подписчика - один на actor_hit, другой на item_use. Или же я что-то недопонял? Использовать замыкания. Я раньше писала, как это делать. Я не знаю, зачем такие сложности Саша придумал Вот вариант: function bind_method_x(obj) return function (...) return obj:method_x(...) end end local funct = bind_method_x(megaobject) --в переменной funct окажется функция, которую можно передать куда угодно. Все, кто стоит на моем пути: идите нахрен и там погибните! © Поделиться этим сообщением Ссылка на сообщение
xStream 87 Опубликовано 11 Января 2012 Andrey07071977, http://www.amk-team.ru/forum/index.php?s=&...st&p=661284 Там более развернуто, с созданием переменных, но это не обязательно. Пример выше - гораздо компактнее. Но делает то же самое. Добавлено через 5 мин.: Да, правильно. Можно, правда, еще короче: function object_execute(obj) return function (...) return obj:execute(...) end end function object_execute_1(obj) return function (...) return obj:execute_1(...) end end Все, кто стоит на моем пути: идите нахрен и там погибните! © Поделиться этим сообщением Ссылка на сообщение
xStream 87 Опубликовано 11 Января 2012 Andrey07071977, Разве это не проверка перед сохранением? А смысл мне от этой проверки? Это проверяется при сохранении и получаем ошибку. Функция set была изначально организована так, что возвращала булевое значение - успешность помещения переменной в хранилище. Тогда, программист, получив false, мог бы принять меры - уменьшить как-то размер таблицы. (Черт! Надо еще длину у строки проверять!) А так. Он запихнул, а потом огреб ошибку, и как ее обрабатывать? Все, кто стоит на моем пути: идите нахрен и там погибните! © Поделиться этим сообщением Ссылка на сообщение
xStream 87 Опубликовано 11 Января 2012 (изменено) Саш, дополнительные параметры в инетрфейсе, использование метатаблиц - это не сложности? По сравнению с одним единственным замыканием - еще какие. Изменено 11 Января 2012 пользователем xStream Все, кто стоит на моем пути: идите нахрен и там погибните! © Поделиться этим сообщением Ссылка на сообщение
xStream 87 Опубликовано 11 Января 2012 Andrey07071977, прикол в том, что боттлнека, кстати, не будет при таком подходе: при set производится одна сериализация, при сохранении в "оптимизированном" варианте - при сохранении сериализуется все. В первом подходе нагрузка распределена по времени. И влияние на производительность оказывает небольшое. Зато мы сразу предупреждаем программиста - у тебя тут гавно, срочно принимай меры. Все, кто стоит на моем пути: идите нахрен и там погибните! © Поделиться этим сообщением Ссылка на сообщение
xStream 87 Опубликовано 11 Января 2012 Саш, peace Просто ты привел такие примеры. Ну а насчет интерфейсов я все равно настаиваю, что они должны быть как можно проще и как можно меньше вариаций иметь Все, кто стоит на моем пути: идите нахрен и там погибните! © Поделиться этим сообщением Ссылка на сообщение
xStream 87 Опубликовано 11 Января 2012 (изменено) Объект и биндер - Саша делал. В коде указано же было. Добавлено через 25 мин.: Только вот прописывать их в АСДС смысла нет. Они спавнятся только скриптами. В редакторе не имеют вообще никакого визуала и не несут никакой нагрузки. То есть в спавне им делать в принципе нечего. Изменено 11 Января 2012 пользователем xStream Все, кто стоит на моем пути: идите нахрен и там погибните! © Поделиться этим сообщением Ссылка на сообщение
xStream 87 Опубликовано 11 Января 2012 (изменено) Хех, я бы не сказала, что интерфейс простой (по мне так он сильно перегружен параметрами, пусть даже в виде таблицы), но да ладно. А что касается таймеров. Лично я придерживаюсь все же подхода - все из коробки, как готовый продукт. Есть класс и используй для чего хочешь и как хочешь. У тебя надо что-то создавать. По-моему переусложнение для конечного пользователя. В С++ это еще б имело смысл, но не в луа. Так же как и передача селф+метод вместо простой функции - чисто Сишная примочка, я знаю. И так же создание описаиния слота. Когда вместо этого можно работать все с теми же замыканиями и безымянными функциями. И интерфейс проще и внутренний код системы. Но это просто имхо, чтоб ты знал его А что касается приоритетов, это вообще отдельный разговор. Я всегда очень отрицательно отношусь к таким вещам, где может производиться при определенных условиях переполнение очереди. Я, конечно, гляну сигналы, но что-то мне подсказывает... Изменено 11 Января 2012 пользователем xStream Все, кто стоит на моем пути: идите нахрен и там погибните! © Поделиться этим сообщением Ссылка на сообщение
xStream 87 Опубликовано 12 Января 2012 Так, доработка по библиотеке пакетов. Мануала все ще нет, но как допроверю, что все ок, будет. http://dl.dropbox.com/u/46539648/xs_netpk.script 1) Да, оно завязано на мою песочницу, так что надо прописать, если используется эта песочница. 2) Кто любит все переделывать, типа Artosa, могут так же переделать и это, суть понятна, мне кажется. Собственно, какие изменения: Попробовала учесть все замечания по неправильному содержимому пакетов, опечатки и прочее. Добавлен класс для работы с абстрактной частью пакетов - описание в шапке файла. ЗЫ Да, лакончино, скомкано и т.п. Все будет развернуто, когда доберусь до мануала. А пока тот, кто понимает, прошу вас это посмотреть, потестить. Нужен фидбек по ошибкам. Заранее спасибо. Все, кто стоит на моем пути: идите нахрен и там погибните! © Поделиться этим сообщением Ссылка на сообщение
xStream 87 Опубликовано 12 Января 2012 (изменено) abramcumner, что такое bind в переводе с английского? Что касается поворота - мб. Там всего лишь написано, что мне подсказали. Изменено 13 Января 2012 пользователем xStream Все, кто стоит на моем пути: идите нахрен и там погибните! © Поделиться этим сообщением Ссылка на сообщение
xStream 87 Опубликовано 13 Января 2012 (изменено) Еще раз - советую вспомнить/посмотреть перевод слова bind. Хорошенько вникнуть. Для аналогии и стимуляции мышления могу подкинуть слово 'luabind'. Изменено 13 Января 2012 пользователем xStream Все, кто стоит на моем пути: идите нахрен и там погибните! © Поделиться этим сообщением Ссылка на сообщение