Antontsue
а чем это поможет? какие варианты исключит?
Antontsue
кстате в чем разница между object.lalala() и object:lalala()?
Antontsue
Antontsue
просто я тут немного биндил, и получилось вот так
Antontsue
match:PlayerAtIndex(2):CreateUnit(52, 32, 'awac'):PlaceUnitOnMap(false)
Antontsue
матч это с++ объект, и у него забиндены все эти методы. CreateUnit возвращает уже созданного юнита и дальше его метод вызыается
Snusmumriken
Двоеточие.
Snusmumriken
class = {}
function class:method(x, y ) ... end
=
function class.method(self, x, y ) ... end
obj:method(x y)
=
obj.method(obj, x y)
Соответственно, при желании, можно применять методы к произвольным таблицам.
class = {}
function class:method(x, y ) self.x, self.y = x, y end
t = {}
class.method(t, 10, 20)
print(t.x, t.y) --> 10, 20
Или даже
obj.method(t)
Antontsue
class ScriptProxy_GameMatch: public ScriptProxy_Base {
public:
static void BindToContext(LUAContext *context);
int ToString(lua_State *L);
virtual ScriptProxy_GameMatchPlayer *ScriptProxy_PlayerAtIndex(int index);
};
Antontsue
а понял, тоесть по сути это биндинг делал вместо меня
Snusmumriken
Чтобы поместить код, пихай его в блок из трёх "`". Типа такого:
'''
код, много кода(фуу, бар, фубар)
ещё больше кода
'''
Только тут используются кавычки вместо апострофов, дабы не произошла автозамена.
Antontsue
нука
Antontsue
биндинг выглядит так:
void ScriptProxy_GameMatch::BindToContext(LUAContext *context)
{
getGlobalNamespace(LUA)
.beginClass<ScriptProxy_GameMatch>("GameMatch")
.addCFunction("__tostring", &ScriptProxy_GameMatch::ToString)
.addFunction("PlayerAtIndex", &ScriptProxy_GameMatch::ScriptProxy_PlayerAtIndex)
.endClass();
}
Snusmumriken
В одинарных апострофах пихается инлайн-код.
Antontsue
а както еще раньше можно было красить
Antontsue
пока они макосевый клиент на свифт не переписали
Antontsue
Snusmumriken
Ну как тебе сказать. Всё ООП в луа - прототипное.
Tverd
да можно и так и так.... хочется чисто объектов и не вникать никуда - middleclass
Antontsue
ну это я поянл, я просто под себя пытаюсь систему создать чтобы было компромиссно между подходами типичными для луа и подходами которые я в остальных яп применяю. напирмер корутины это вообще новая для меня концепция) на с/с++ и прочем я такое делал через 2 лока 1 анлок
Antontsue
когда берешь мьютекс, лочишь его 2 раза сразу))
Snusmumriken
Button = {}
Button.__index = button
setmetatable(button, {
__call = function(self, text, x, y, w, h)
local o = {} -- табличка-прототип объекта
o.text = text,
o.x, o.y = x, y
o.width = w,
o.height = h,
return setmetatable(o, self) -- линкуем табличку с нашим классом
end
})
-- когда будет вызываться метод кнопки, он по __index какк по лесенке доберётся до методов класса
function Button:toggle(x, y)
local touched = self.x < x and self.y < y
and self.width > x and self.height > y
if touched then self.toggled = not self.toggled end
return self.toggled
end
Antontsue
ты какбе сам себе дедлок создаешь в одном потоке, для того тчобы прервать поток. потом гдето в другом месте анлочишь, ну и 2й раз анлочится уже в твоем потоке. если так комуто интересно)
Snusmumriken
Извращенец :3
Всю дорогу использовал многопоточку как пул тредов:
запускаем кучу потоков и ждём, пока они не закончат работу, опрашивая по очереди. Да, поток который держит пул может попутно чем-то ещё заниматься, но это вводит избыточную сложность. Избавление от избыточной сложности, даже если это слегка бьёт по производительности = дзен.
Tverd
Snusmumriken
Тут потоки, которые являются отдельными процессами, выполняемыми параллельно. Кстати, мне интересно, решили ли в плюсовых тредах проблему "один блок памяти на один цп", или "все настоящие потоки - в разделяемой памяти с общением через пайпы/сокеты/файлы"
Tverd
Это точно не async/await? Я намного раньше про них слышал
Tverd
хотя бы это
Tverd
http://log0div0.blogspot.ru/2015/06/boostasio-boostcontext.html
Antontsue
ты путаешь асинхронность с корутинами
Antontsue
корутины не асинхронны
Snusmumriken
Хмм.
Тош, читал эту штуку? Тут популярно описаны корутины.
https://ilovelua.wordpress.com/2012/02/02/%D1%81%D0%BE%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8Bcoroutines/
Antontsue
у меня проблема с синтаксисом
Antontsue
а не с пониманием концепции корутин))
Snusmumriken
Думаю что скорее с концепцией :3
Antontsue
переписал вот так:
local f
f = function(quest)
print('coroutine print 1')
end
initquest(f)
function initquest(body)
print('quest init 2')
local co = coroutine.create(body)
print('quest init 3')
coroutine.resume(co)
end
так корутина запускается
Antontsue
а при обмазке в класс - перестают?
Snusmumriken
В общем, так же как изучая С++ ты сразу же не лезешь в ту же многопоточку, постепенно ощупывая язык, я бы не лез в корутины без крайней нужды : )
Snusmumriken
Мне они за два с половиной года непрерывного написания реально сложных штук так ни разу и не понадобились, ибо оболочка корутино-класса похожа на лапшу из-за избытка goto.
Antontsue
ну а ктож эти goto написал -то?
Antontsue
с того и спрашивай)
Snusmumriken
coroutine.yeld - аналог goto в ту точку, где корутина вызывалась.
И начинает играть очень серьёзную роль порядок вызова корутины.
Antontsue
ну не знаю. на первой же лекции по с++ сказали никогда goto не использовать. и всетки goto это не coroutine.yeld - goto может прыгать по меткам вперед - назад, а coroutine.yeld только вперед - это всеже существенное различие
Snusmumriken
Нет, я не против goto. Когда оно одно в блоке, и всем понятно что оно делает, вроде такого:
function foo(n)
local c = 0
for i 1, 10000 do
if i%2 == 0 then goto continue end
c = c + i
:continue:
end
end
Antontsue
мы отвлеклись от темы
Snusmumriken
Только вперёд, но сразу гарантированно ВНЕ текущего блока кода, хрен знает куда : )
Snusmumriken
Мы отвлеклись от темы, но боюсь тебе мало кто поможет, или из-за того что тут никто не использует твою либу классов (ещё нужно время чтобы в ней разобраться), и очень мало кто использует корутины, потому что объективная нужда чаще всего отсутствует.
Antontsue
а какаую либу классов вы юзаете?
Snusmumriken
а) никакой (ибо если файл на один-два класса, проще прописать setmetatable)
б) тебе успели посоветовать middleclass
Snusmumriken
в)
Snusmumriken
Ок. Вот тебе самая короткая реализация ООП с наследованием.
Куча магии которая пашет.
function Class(name, parent)
local smt, gmt = setmetatable, getmetatable
local parent = parent
local mt, cl = {}, {}
mt.__index = type(parent) == 'table' and parent or parent and error('Class inheritance error: table expected got '..type(parent), 2) or nil
mt.__call = function(self, ...) return self.init and self.init(self, ...) or {} end -- average call method
cl.__name = name or ('class id: %8d'):format(math.random(99999999)) -- name of class for getting
cl.__index = cl
cl.Inst = function(t) return smt(t, cl) end
cl.Super = mt.__index
cl.Type = function(self, obj) return type(obj) == 'table' and gmt(obj) == gmt(self) or self.__name end
cl.IsObjectOf = function(self, class) return rawequal(class, gmt(self)) end
return smt(cl, mt)
end
Snusmumriken
Да, я дописал свою : 3
Antontsue
Ок. Вот тебе самая короткая реализация ООП с наследованием.
Куча магии которая пашет.
function Class(name, parent)
local smt, gmt = setmetatable, getmetatable
local parent = parent
local mt, cl = {}, {}
mt.__index = type(parent) == 'table' and parent or parent and error('Class inheritance error: table expected got '..type(parent), 2) or nil
mt.__call = function(self, ...) return self.init and self.init(self, ...) or {} end -- average call method
cl.__name = name or ('class id: %8d'):format(math.random(99999999)) -- name of class for getting
cl.__index = cl
cl.Inst = function(t) return smt(t, cl) end
cl.Super = mt.__index
cl.Type = function(self, obj) return type(obj) == 'table' and gmt(obj) == gmt(self) or self.__name end
cl.IsObjectOf = function(self, class) return rawequal(class, gmt(self)) end
return smt(cl, mt)
end
а пример использования?
Snusmumriken
Сейчас катаю.
Snusmumriken
Применение типа:
foo = Class()
function foo:init(x, y)
local o = {}
o.x, o.y = x, y
return self.Inst(o)
end
function foo:foobar(z)
self.x, self.y = self.x + z, self.y - z
end
bar = Class('bar', foo) -- наследование
function bar:init(x, y, w, h)
local o = self.Super(x, y)
-- доступ к батьке батьки - self.Super.Super
o.w, o.h = w, h
return self.Inst(o)
end
function bar:bar(z)
self.x = self.x + self.h - z
end
obj = foo(10, 20)
obj:foobar(2)
obj2 = bar(10, 20, 30, 40)
obj2:bar(12)
obj2:foobar(4) -- наследованный метод
Antontsue
foo = Class()
это будет глобальный объект если я его внутри функции объявлю?
Snusmumriken
Ага.
А если
local foo = Class() - то локальный, если ты его куда-то ещё не передашь. С другой стороны, если ты тут же наплодишь объектов, то локальный класс останется висеть в замыкании, пока ты не удалишь все связанные объекты :3
Ну там:
function foo()
local cl = Class()
function cl:init(...) ... end
function cl:foo() ... end
return cl(10, 20, 30)
end
obj = foo() -- класс cl будет висеть в замыкании, пока ты не удалишь obj.
Все объекты по умолчанию глобальны, поэтому советую ставить побольше local.
B
а как проверить является ли переданный аргумент таблицей?
Snusmumriken
if type(arg1) == 'table' then ... end
B
спасибо
Antontsue
о вроде сработало
Antontsue
Quest = Class()
function Quest:init(body)
local o = {}
o.body = body
o.co = coroutine.create(body)
return self.Inst(o)
end
function Quest:run()
print('quest run')
coroutine.resume(self.co, self)
end
function Quest:interrupt()
coroutine.yield()
end
function attempt2()
print('test text')
local f
f = function(quest)
print('coroutine print 1')
quest.interrupt()
print('coroutine print 2')
end
local quest = Quest(f)
quest:run()
end
Snusmumriken
Ну, значит изначальная версия ООП которую ты юзал - несколько странная.
Antontsue
да я полагаю что функция в качестве мембер вариабл не сохранялась
Antontsue
вечером еще потесчу
Antontsue
спасибо
Antontsue
а виртуальные методы?
Snusmumriken
Просто оверрайдишь.
Antontsue
переопределение и вызов супера
Antontsue
типа как новый?
Snusmumriken
Наследуешься и у наследуемого переписываешь метод.
Antontsue
вызову его через self.Super:method()?
Snusmumriken
__index работает как лесенка:
Первая ступенечка - это сам объект. Если не нашли - по __index переходим к другой табличке, и ищем у неё метод. Нашли? Вызвали. Не нашли? Если и у этой таблички есть __index - перешли по ней и там поискали.
Snusmumriken
А родительские методы - да. Только вот так:
self.Super.method(self, ...), иначе двоеточием в функцию перешлётся Super что не есть хорошо.
Tverd
машу головой, все так )
Tverd
Можно было человеку еще предложить MoonScript, там нативные классы
Antontsue
вот проект если интересно
Antontsue
https://www.facebook.com/groups/1420889268172393/