
Антон
05.04.2017
09:13:23
выводит в итоге только
lua: test 1
lua: quest init 1
lua: quest init 2
lua: quest run
lua: test 2
у меня вопрос поччему quest init 3 не выводится и почему корутина не запускается
вот так пытаюсь запустить:
function attempt0()
print('test 1')
local quest = Quest(function(quest)
print('coroutine print 1')
local condition = function ()
print('coroutine condition print')
return 'success'
end
print('coroutine print 2')
quest.interrupt(condition)
print('coroutine print 3')
end)
quest.run()
print('test 2')
end

Snusmumriken
05.04.2017
09:18:46
Тут не так много знатоков корутин, потому что они не дают объективных преимуществ по скорости, являясь декораторами асинхронных вызовов, чтобы писать асинхронщину так же красиво как простой линейный код.
На тему ООП:

Google

Антон
05.04.2017
09:19:44
ну я не думаю что проблема в корутине я думаю проблема в том как создаю/передаю в нее функцию
а это вопрос синтаксиса луа
в этом то тут должны быть специалисты?
print('quest init 3') не вызывается, тоесть такое ощущение что из init-а вылетает в тот момент когда я пытаюсь корутину создать


Snusmumriken
05.04.2017
09:21:29
Вот пример ооп без дополнительных библиотек, который гарантированно работает как ожидается.
Button = {}
Button.__index = button
setmetatable(button, {
__call = function(self, text, x, y, w, h)
return setmetatable({
text = text,
x = x,
y = y,
width = w,
height = h,
}, self)
end
})
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
function Button:get() return self.toggled end
function Button:draw()
-- обрезаем всё что вылезло за пределы
love.graphics.setScissor(self.x, self.y, self.width, self.height)
love.graphics.rectangle('fill', self.x, self.y, self.width, self.height)
love.graphics.printf(self.text .. (self.toggled and 'X' or 'O'), self.x, self.y, self.w)
love.graphics.setScissor()
end
btn1 = Button('Button1', 10, 20, 50, 30)
btn1:toggle(love.mouse.getPosition())
function love.draw()
btn1:draw()
end


Антон
05.04.2017
09:22:34
у меня ооп работает, ну тоесть конструкторы и методы вызываются
у меня почемуто происходит выход из функции

Snusmumriken
05.04.2017
09:22:45
Он, конечно, использует функции фреймворка love2d, но это не важно.
Оки, ща будем смотреть

Антон
05.04.2017
09:23:45
классы делаю по этой методичке http://lua-users.org/wiki/SimpleLuaClasses - вариант для луа 5.3

Snusmumriken
05.04.2017
09:24:41
Дык версия тут не важна :3
Повсеместно используется 5.1 и 5.3, у которых практически не различается ООП.

Антон
05.04.2017
09:24:52
ну малоли

Google

Snusmumriken
05.04.2017
09:26:51
Блин, какая странная классовая библиотека :3
И я не уверен что ты нигде не опечатался, потому что виду незавершенную функцию interrupt

Антон
05.04.2017
09:29:52
а че там незавершенного?

Snusmumriken
05.04.2017
09:29:59
Нет end.

Антон
05.04.2017
09:30:23
function interrupt(condition)
local listener = EventListener(this.cor, condition)
gloabalDispatcher.addListener(listener)
coroutine.yield()
end
есть

Snusmumriken
05.04.2017
09:30:45
А, оно просто длиннее чем показалось.

Антон
05.04.2017
09:33:04
function __init(body)
print('quest init 1')
this.body = body
print('quest init 2')
this.cor = coroutine.create(body)
print('quest init 3')
end
вот тут он почемуто 3й лог не выводит, тоесть выводит 1 2 а потом выходит из функции и выводит уже то что там написано

Tverd
05.04.2017
09:36:02
http://siffiejoe.github.io/lua-prototype/

Антон
05.04.2017
09:36:41
а чем это поможет? какие варианты исключит?
кстате в чем разница между object.lalala() и object:lalala()?

Philipp
05.04.2017
09:39:56
В первом случае не передается self
(This)
И его нужно передавать явно

Антон
05.04.2017
09:40:54
просто я тут немного биндил, и получилось вот так
match:PlayerAtIndex(2):CreateUnit(52, 32, 'awac'):PlaceUnitOnMap(false)
матч это с++ объект, и у него забиндены все эти методы. CreateUnit возвращает уже созданного юнита и дальше его метод вызыается

Snusmumriken
05.04.2017
09:42:10
Двоеточие.
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)

Google

Антон
05.04.2017
09:42:31
class ScriptProxy_GameMatch: public ScriptProxy_Base {
public:
static void BindToContext(LUAContext *context);
int ToString(lua_State *L);
virtual ScriptProxy_GameMatchPlayer *ScriptProxy_PlayerAtIndex(int index);
};
а понял, тоесть по сути это биндинг делал вместо меня

Snusmumriken
05.04.2017
09:45:01
Чтобы поместить код, пихай его в блок из трёх "`". Типа такого:
'''
код, много кода(фуу, бар, фубар)
ещё больше кода
'''
Только тут используются кавычки вместо апострофов, дабы не произошла автозамена.

Антон
05.04.2017
09:45:21
нука
биндинг выглядит так:
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
05.04.2017
09:45:53
В одинарных апострофах пихается инлайн-код.

Антон
05.04.2017
09:46:10
а както еще раньше можно было красить
пока они макосевый клиент на свифт не переписали

Snusmumriken
05.04.2017
09:47:33
Ну как тебе сказать. Всё ООП в луа - прототипное.

Tverd
05.04.2017
09:47:46
да можно и так и так.... хочется чисто объектов и не вникать никуда - middleclass

Антон
05.04.2017
09:49:11
ну это я поянл, я просто под себя пытаюсь систему создать чтобы было компромиссно между подходами типичными для луа и подходами которые я в остальных яп применяю. напирмер корутины это вообще новая для меня концепция) на с/с++ и прочем я такое делал через 2 лока 1 анлок

Антон
05.04.2017
09:49:21
когда берешь мьютекс, лочишь его 2 раза сразу))

Snusmumriken
05.04.2017
09:50:17
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

Антон
05.04.2017
09:50:41
ты какбе сам себе дедлок создаешь в одном потоке, для того тчобы прервать поток. потом гдето в другом месте анлочишь, ну и 2й раз анлочится уже в твоем потоке. если так комуто интересно)

Snusmumriken
05.04.2017
09:52:34
Извращенец :3
Всю дорогу использовал многопоточку как пул тредов:
запускаем кучу потоков и ждём, пока они не закончат работу, опрашивая по очереди. Да, поток который держит пул может попутно чем-то ещё заниматься, но это вводит избыточную сложность. Избавление от избыточной сложности, даже если это слегка бьёт по производительности = дзен.

Tverd
05.04.2017
09:53:10

Snusmumriken
05.04.2017
09:54:16
Тут потоки, которые являются отдельными процессами, выполняемыми параллельно. Кстати, мне интересно, решили ли в плюсовых тредах проблему "один блок памяти на один цп", или "все настоящие потоки - в разделяемой памяти с общением через пайпы/сокеты/файлы"

Антон
05.04.2017
09:54:19

Tverd
05.04.2017
09:55:54
Это точно не async/await? Я намного раньше про них слышал

Google

Tverd
05.04.2017
09:59:28
хотя бы это
http://log0div0.blogspot.ru/2015/06/boostasio-boostcontext.html

Антон
05.04.2017
09:59:55
ты путаешь асинхронность с корутинами
корутины не асинхронны

Snusmumriken
05.04.2017
10:00:25
Хмм.
Тош, читал эту штуку? Тут популярно описаны корутины.
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/

Антон
05.04.2017
10:00:48
у меня проблема с синтаксисом
а не с пониманием концепции корутин))

Snusmumriken
05.04.2017
10:01:20
Думаю что скорее с концепцией :3

Admin
ERROR: S client not available

Антон
05.04.2017
10:01:38
переписал вот так:
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
так корутина запускается
а при обмазке в класс - перестают?

Snusmumriken
05.04.2017
10:03:59
Мне они за два с половиной года непрерывного написания реально сложных штук так ни разу и не понадобились, ибо оболочка корутино-класса похожа на лапшу из-за избытка goto.

Антон
05.04.2017
10:06:49
ну а ктож эти goto написал -то?
с того и спрашивай)

Snusmumriken
05.04.2017
10:07:13
coroutine.yeld - аналог goto в ту точку, где корутина вызывалась.
И начинает играть очень серьёзную роль порядок вызова корутины.

Антон
05.04.2017
10:09:26
ну не знаю. на первой же лекции по с++ сказали никогда goto не использовать. и всетки goto это не coroutine.yeld - goto может прыгать по меткам вперед - назад, а coroutine.yeld только вперед - это всеже существенное различие

Snusmumriken
05.04.2017
10:10:00
Нет, я не против 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

Антон
05.04.2017
10:10:39
мы отвлеклись от темы

Google

Snusmumriken
05.04.2017
10:10:46
Только вперёд, но сразу гарантированно ВНЕ текущего блока кода, хрен знает куда : )
Мы отвлеклись от темы, но боюсь тебе мало кто поможет, или из-за того что тут никто не использует твою либу классов (ещё нужно время чтобы в ней разобраться), и очень мало кто использует корутины, потому что объективная нужда чаще всего отсутствует.

Антон
05.04.2017
10:13:05
а какаую либу классов вы юзаете?


Snusmumriken
05.04.2017
10:13:35
а) никакой (ибо если файл на один-два класса, проще прописать setmetatable)
б) тебе успели посоветовать middleclass
в)
Ок. Вот тебе самая короткая реализация ООП с наследованием.
Куча магии которая пашет.
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


Philipp
05.04.2017
10:13:58

Snusmumriken
05.04.2017
10:14:10
Да, я дописал свою : 3

Антон
05.04.2017
10:14:38
Ок. Вот тебе самая короткая реализация ООП с наследованием.
Куча магии которая пашет.
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
05.04.2017
10:14:50
Сейчас катаю.
Применение типа:
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) -- наследованный метод

Антон
05.04.2017
10:19:20
foo = Class()
это будет глобальный объект если я его внутри функции объявлю?

Snusmumriken
05.04.2017
10:19:47
Ага.
А если
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.

Vlad
05.04.2017
10:24:13
а как проверить является ли переданный аргумент таблицей?

Snusmumriken
05.04.2017
10:24:32
if type(arg1) == 'table' then ... end

Vlad
05.04.2017
10:24:59
спасибо

Антон
05.04.2017
10:31:47
о вроде сработало
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
05.04.2017
10:32:51
Ну, значит изначальная версия ООП которую ты юзал - несколько странная.

Антон
05.04.2017
10:33:18
да я полагаю что функция в качестве мембер вариабл не сохранялась
вечером еще потесчу