Dmitry
добавил
Dmitry
а где каталоги этих чатов
Иван
Народ. Я тут третий раз написал один и тот-же код: for x, row in ipairs(map) do for y, cell in ipairs(row) do do_somethyng(x, y, cell) end end И естественно захотел вынести это в хелпер, чтобы юзать так: h.each2d(map, function(x, y, cell) { .... }) Но задался вопросом: а каков в луа оверхед на замыкания? Можно ли считать за никакой?
Tverd
Лично на мой взгляд, можно пренебречь, если цикл большой... Но можно и протестировать
Tverd
Создание функции конечно занимает время, но мало
Snusmumriken
На замыкания - оверхед как будто функцию лишнюю объявили и вызвали.
Иван
Спасибо
Иван
В крайнем случае на этапе оптимизации на хардкод заменю
Dmitry
https://github.com/radiotail/lua_memleak/blob/master/memleak.lua
Tverd
https://github.com/tverd/moonclass это на всякий случай, если кому либо нужно
Snusmumriken
Хех, штука забавная. На практике, правда, я всю дорогу использовал две вещи. 1. http://pastebin.com/K1yRyE1T 2. Class = {} Class.__index = Class setmetatable(Class, { __call = function(self, ...) local o = {} o.foo = {...} return setmetatable(o, {__index = self}) end, __index = parent_class }) function Class.bar() return self.foo end obj = Class(x, y, z) Причём второе - чаще, потому что в модуле чаще всего нужны один-два класса. Хм. На самом деле, я бы не отказался от препроцессора lua, который добавлял бы, например, стрелочные функции с макросами и прочей мелкой мелочёвкой. Опционально типизированные аргументы функций, например, чтобы ошибки возвращали и принимали целый список возможных типов ибо полиморфизм.
Tverd
Второе тоже использую часто, если на чистом луа. Нормальный стандартный подход )
Snusmumriken
Первое - просто моя либа. У меня где-то болтался сокращённый вариант без всяких хаков типа __gc для таблиц в lua5.1, который помещается в функцию из десятка строк. Лень подключать модули для ООП, поэтому в корень проекта просто копируется функция.
Tverd
Насчет препроцессора тоже сижу думаю, тут либо самому писать, либо заюзать luamacro все таки. Второй путь проще, но не все можно сделать.
Snusmumriken
Metalua - можно почти всё сделать.
Tverd
Да, согласен. Ты использовал его для какого-нить проекта?
Snusmumriken
Не а :) Не нужно. У меня задачи простые, расширять семантику особо не требуется. Примеры типичных моих задач - на том же пастбине, у того же пользователя. Там есть очень-очень хитрые хаки, но всё таки расширение семантики лишнее.
Tverd
Окай, глянем. Кстати знаешь хак для gc в 5.1 луа?
Tverd
А то я смотрю в объекте его нет
Tverd
А нет, сорь ))) есть
Snusmumriken
Он описан в пасте которую я скинул первой.
Tverd
Уже увидел, гуд
Snusmumriken
Читы, читы. Ещё был вариант с множественным наследованием, перебиравшим ключи родителей, но мне стало страшно от скорости работы и чудовищности самой концепции. Плюс многие классы требуют вызова собственной инициализации, и одними методами тут не расширишь. И метаметоды не подцепишь.
Tverd
Делал то же самое но для магических методов. А так обычные методы спокойно наследуются.
Tverd
Но конечно только для одного
Tverd
Тут наверно проще делать через mixin
Snusmumriken
Где в lua есть mixin? Или ты про отдельную реализацию?
Tverd
Отдельную, к сожалению этого нет в чистом луа
Snusmumriken
Хех, кстати забавно то, что миксины, технически, делаются просто присваиванием одному классу методов другого. Это симпатишно, но отладка превращается во что-то страшное. На моей практике, быстрая отладка оказывается доминирующим фактором против множественного наследования и подобных расширений. Лучше уж наследоваться один раз.
Tverd
Пока сильно не отлаживал ) а миксины делал максимум по 3 фукции в одной таблице, даже без инициализации пока, думаю что поэтоваться придется.
Snusmumriken
Хм. Кстати, без наследования, миксины делаются экстремально просто. В моём "втором" варианте - вместо __index-ссылки на parent - ссылка на миксин как сет функций/констант, использующихся в разных классах. Ох уж эти __index'ы.
Tverd
А есть поподробнее глянуть, на слух не пойму...
Tverd
Кстати вот для этого миксины делал
Tverd
http://www.codingcookies.com/2013/04/01/building-a-roguelike-in-javascript-part-1/
Snusmumriken
mixin = {} function mixin:foo() print(self.x, self.y) end ClassFoo = {} ClassFoo.__index = Class setmetatable(Class, { __call = function(self, x, y) return setmetatable({x = x, y = y}, {__index = self}) end, __index = mixin }) function ClassFoo.bar() return self.x - self.y end ClassBar = {} ClassBar.__index = Class setmetatable(Class, { __call = function(self, x, y, w, h) return setmetatable({x = x, y = y, w = w, h = h}, {__index = self}) end, __index = mixin }) function ClassBar.bar() return self.x + self.y + self.w + self.h end obj1 = ClassFoo(x, y, z) obj1:bar() --> self.x - self.y -- из класса obj2 = ClassBar(x, y, z) -- из класса obj2:bar() --> self.x + self.y + self.w + self.h obj1:foo() --> print(self.x, self.y) -- из миксина obj2:foo() --> print(self.x, self.y) -- тоже из миксина
Snusmumriken
Хм, надо бы скопировать куда, чтобы не было проблем с длиной строк и отображением на телефонах, но лень.
Tverd
я с компа, уже скопировал. Я так понимаю что один миксин в двух классах. А если несколько миксинов? Или я опять чего-то не доглядел...
Tverd
Ну думаю что вариант такой, тупо в каждый миксин вставлять индекс на предыдущий, но это надо копировать таблицу что бы не засорять миксин
Snusmumriken
Несколько миксинов - сложнее. Или у каждого миксина в __index ссылка на следующий, тогда объект будет наследовать кусок цепочки миксинов. Ну там, mixinA -> mixinB -> mixinC. Класс с mixinA получит и A и B и C, а класс с mixinB - получит B и C. То есть, тут только цепочка. Или, как вариант, в __index сидит функция, которая выбирает миксин из списка, если не находит ключа в одном. Как ты понимаешь, порядком обхода функции задаётся приоритеты миксинов, на случай одинаковых ключей. Множественное наследование делается аналогично.
Snusmumriken
Пример: __index = function(obj, key) for i, v in ipairs(self.parents) do if v[key] then return v[key] end end end
Tverd
Ну да, в общем так и делал... Брал миксин на этапе создания объекта вставлял из него методы и переменные в нужный класс... Твой вариант более медленный, понятно что постоянный прогон при поиске будет не фонтан.
Snusmumriken
Для объектов с часто вызывающимися методами не приоритетных родителей - не фонтан.
Tverd
Вот, в фабрике делал проще - на этапе описания объекта уже вставлял миксин )))) это было очень быстро.
Snusmumriken
Но объекты создаются медленнее. Впрочем, для всяких синглтонов это не так важно.
Tverd
Ну да, если мы не создаем, не убиваем по 100к объектов в секунду )
Snusmumriken
В играх, довольно часто создаются и убиваются 100к объектов в секунду :3 Особенно если это пули, и у тебя есть механика синергии эффектов на пулях. Ну там, подобрал один предмет - пули изменили тип на взрывающиеся ракеты, подобрал другой - и взрывающиеся ракеты ещё и стали лететь по синусоиде.
Alexander
В какой-то момент прочёл "токсин"
Snusmumriken
Да, токсин убивающий возможность сопровождения :3
Snusmumriken
Можно пул. Я вообще избалован FFI а луях, и использую его где ни попадя. Считай что сишка в луа. Кусок магии с компиляцией C-кода и возможностью цепляния ООП к сишным структурам.
Tverd
В общем частная фабрика хранит уже готовый класс, с вставленными методами из миксина...
Tverd
Это да, в короне этого сильно не хватает
Snusmumriken
Это ещё и даёт +200 к скорости, особенно математики и длинных циклов без сложных ветвлений. Имхо, лучше таки два раза переписать, но шоб понятно было (+копипастить в любой другой модуль), чем миксины пихать. Стрёмное дело.
Tverd
Ну стараюсь использовать больше компонентное программирование, чем наследование с 10 родителями. Я-то вспомню что там и как, а если другому человеку давать и править базовые классы, то можно все сломать.
Tverd
Кстати я так понимаю ты с love2d дружишь. С рекламными сетями там как? Ручками прикручивать?
Snusmumriken
Угу))) На андроиде можно извращаться: накатать на сишке либу которая грузит и высвечивает рекламу поверх экрана, с трансляцией в luaState набора методов, или FFI-биндинг стандартных ведро-либ для тех же целей. Хотя можно и совсем ручками: лишнее игровое состояние "показ рекламы", который грузит вебгетом или чем-то ещё ролик/картинку из сети, конвертит в читаемый для love2d вариант и рисует на экранчике с таймером и кнопкой "закрыть".
Tverd
Эх... ) Тогда почему не кокос? Или реклама не сильно пока нужна?
Snusmumriken
Потому что кокос - движок, а love2d - фреймворк. И есть JIT с огромной кучей плюх. Сахарную луа со скоростью сишки я ни на что не променяю, простите.
Tverd
Ну тут ты кокос не удивишь джитом. А вот что фреймворк, да... Хотя по мне так кокос тоже не шибко прям движок. До юнити в плане удобства не дотягивает
Tverd
Даже урхо3д уже с джитом идет
Tverd
Только корона без оного.
Snusmumriken
Движок - среда для наполнения контентом. Всякие менеджеры сущностей с анимациями/коллизиями/игровыми состояниями и прочей лабудой. В ловке этого нема, но тут есть полная свободка действий. Я - тот самый извращенец который делает на ловке микросервисы, тулзы и прочую нагруженную фигню. Далеко не только игры.
Tverd
Даже так? там графика не обязательна?
Snusmumriken
Где-то графика не нужна, а где-то требуется. Ну там, микросервис который не только отвечает на запросы мониторинга, но и рисует графички загруженности. Что-то такое. Звук и физон тут не нужен, конечно.
Tverd
Ну я имею ввиду, что можно ли юзать love2d в консоли... Если там есть таймеры, сеть и все это можно запустить без графики, то очень прикольно
Snusmumriken
Конечно можно использовать в консоли. В конфигурационном файле отрубаешь окно и графику, получая чисто консольную ловку. Даже консольный музыкальный проигрыватель можно сделать. И клиент ВК, рисующий фотачки друганов в ASCII и с музычкой ))) Но это для особых мсье.
Tverd
Заинтриговал )))) Посмотрю внимально на эту штуку.
Snusmumriken
#conf.lua function love.conf(t) t.window = false t.graphics = false t.console = true end Прекол ещё в том, что ловка работает проигрывателем для кода. Имея дистр, можно легко и непринуждённо открывать им разные .love-файлы, которые суть zip-архивы с кодом и ресурсами типа картинок.
Tverd
это да, я видел. Исходники марио ковырял.
Snusmumriken
Ну, двиглы типа кокоса добавляют слишком много лишнего, жрут дофига места, памяти (в т.ч. оперативной, из-за неотключаемых штук) и ваще не выполняют суть linux-way: одна маленькая программа, которая делает только одну задачу, но делает это очень хорошо. Ещё веселее: отключаем и окно и консоль. Получаем аналог сервиса, который, правда, виден в диспетчере задач, но это и к лучшему.
Tverd
Насчет движков тут понятно. Для этого он и движок, что бы все делать )
Snusmumriken
Слишком вумный для меня. Предпочту работать с либами и иметь полный контроль над происходящим.
Tverd
Не знаешь как его компилять? cmake . - ругается
Snusmumriken
Visual studio. Я ещё mingw компилил.
Tverd
под линух ) точнее под фряху
Snusmumriken
Смотри чем он ругается :3
void *
Хочу написать графический движок на crystal, прикрутить ode и интерпретатор lua
void *
Рейт замысел
Snusmumriken
Для чего? : )