Snusmumriken
Запускать lua-код так же просто как .exe-шники? Или всё таки пути мутить?
Snusmumriken
Потому что я сейчас просто скомпилил lua-код в .exe-шник и всё ок.
Yogurt
скомпилил или пришил луа к код к интерпритатору?
Snusmumriken
Тут сложнее :3
Snusmumriken
Глянь srlua.
Yogurt
Мне лениво, я спать ложусь
Yogurt
Там что-то стоящее?
Snusmumriken
Там превращение lua в standalone-exe. Всё в порядке.
Yogurt
Ничто не мешает пришить луа к интерпретатору, как делает лав
Yogurt
Это тоже стэндалон экзе
B
хотя даже при таком дешманском подходе через простреленые ноги и ломаные костыли имея полные пути оно к примеру ругается на невозможность нахождения чего либо, при наличии полного пути, вот потому мне и нужно как то понять как бы сделать это в самом луа что б все нормально искало, что б была возможность не выходить за рамки разума и тд тп
B
причем при открытии либо переоткрытии файлов таким шаманством все еще более менее нормально, а вот с подключением чего либо из подпапок в разных местах проекта с таким подходом не работает, пишет что имеются трудности с обнаружением файлов
mva
а вот не использовали б вы в мышлении вендовые особенности всё было бы проще
mva
ну и в любом случае, рекомендую ознакомиться с двумя вещами: 1) http://code.matthewwild.co.uk/squish/ (склеивает весь проект (по желанию и инклуды) в один lua-файл). Правда, я немного подзабыл как быть с C-либами. Но Pure-Lua склеивает вполне прекрасно. Опционально минифицирует, сжимает и перегоняет в байткод 2) уже озвученный srlua. От одного из авторов PUC-Rio Lua. Собирает бинарники не только под Win, но и под любую ОС, под которую собрано само. Так же, LuaJIT умеет делать байткодо-объекты (*.o) которые можно слинковать с любой самописной C-софтиной (вместе с libluajit). При особом желании - даже статически.
Snusmumriken
Братишка, я тут тебе пути завёз.
Antontsue
привет
Antontsue
ай нид халп
Antontsue
я делаю систему для квестов на луа
Antontsue
и у меня проблема с корутинами, классами да и вообщем со всем - я луа не особо знаю, я больше по с++
Antontsue
вообщем я худо-бедно разобрался как классы делать - по этой методичке http://lua-users.org/wiki/SimpleLuaClasses - вариант для луа 5 3
Antontsue
как вы кстате вообще классы используете? какие практики? луа как я понял не особо оопэшный, или все-таки используется наследование? или както иначе все пишется у вас?
Antontsue
написал вот такой классик: Quest = class(function() function __init(body) print('quest init 1') this.body = body print('quest init 2') this.cor = coroutine.create(body) print('quest init 3') end function run() print('quest run') coroutine.resume(this.cor, this) end function interrupt(condition) local listener = EventListener(this.cor, condition) gloabalDispatcher.addListener(listener) coroutine.yield() end end)
Antontsue
вот так пытаюсь запустить: 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
Antontsue
выводит в итоге только lua: test 1 lua: quest init 1 lua: quest init 2 lua: quest run lua: test 2
Alexander
потоки умеешь писать? так вот, корутины не потоки.
Antontsue
дак мне корутины надо а не потоки)
Antontsue
а зачем мне потоки по-твоему?
Antontsue
мне надо чтобы чек выполнялся в определенном потоке - я буду из плюсов его дергать в будущем
Antontsue
ну тоесть без потери общности сейчас можно считать что это все должно работать в гл потоке
Alexander
разница в том, что все корутины выполняются в единственном потоке. I/O блокировка в любой корутине заблокирует всю программу.
Antontsue
ну пусть блокируют, там проверки - типа юинт жив или юнит в зоне там такойта
Antontsue
у меня вопрос поччему quest init 3 не выводится и почему корутина не запускается
Antontsue
а так если тебе общая архитектура интересна - то можно сделать отдельный поток на эти проверки, просто из с++ надо будет вызывать методы из этого потока и все. ну и проследить чтобы синхронизация была на все что ты биндишь в луа. но вопрос то у меня не в этом
Snusmumriken
В целом, обычно в луа вывешивают апишку, и дёргают её там. Ну, то есть плюсы работают автомобилем, а луа -водителем. То что ты хочешь в с++ дёргать луа-методы - это немного странно :3
🦥Alex Fails
типа двусторонний бридж
Snusmumriken
Не уверен что в данном случае - двустороннесть - хорошо. Можно в луа вывести хендлер квеста для перехода между этапами и развилками, хендлер игрока и событий для перехвата условий выполения квестов, и просто дёргать луа-скрипт с квестом. Или луа-скрипт вообще со всеми квестами. Суть: 1. Ядро С++ хранит список активных квестов 2. Новые добавляются и обновляются луа-скриптами (текст и всякие счётчики/ништяки) через хендлер в мастер-скрипте. 3. Мастер-скрипт на луа с хендлером, который подгружает остальные квестовые скрипты, отслеживает события: на некоторые (разговор с персонажем по некоторой ветке диалога с конкретными ID) - отправляет С-ядру запрос на создание нового квеста, а на другие (убийство десяти волков) - дёргает хендлер ядра на тему "квест выполнен". Ядру нужно только дёргать на каждое событие мастер-скрипт, тот всё остальное сделает сам. Событийные системы эффективны. И даже очень. За счёт того что не вызываются каждый кадр, нужен только пул событий и управляющий хендлер, дёргаемый, например, при убийстве того же волка, в пул событий передаётся, например, такая структура: Тип: убийство, субъект: игрок оружие: меч тысячи истин, тип урона: удар по самомнению тип ударов: режущие корень истины броня: штаны из берёзовой коры, объект: волк тип: животное, ареал: лес, образ жизни: хищник локация: тёмная лесная опушка фракция: лесной управдом владелец: баба яга Подобные события - крайне удобны для обработки луа-скриптами.
Snusmumriken
На подобные события уже можно давать квесты а ля: "Убей десять хищников на тёмной лесной опушке, держа в руках меч тысячи истин а на жопе - штаны из берёзовой коры, только погоди, ща сниму тебе твою новую броню". И в принципе, с такой системой, легко менять игроку репутацию во всём королевстве, на тот случай, если он убивает врагов или жителей на его территории. Или вынуждать кого-то нападать игрока за то, что игрок жестоко зарубил хомячка. А за счёт графы субъекта - можно мутить квесты а ля "Помоги моей маме зарубить десять хомяков". Хе-хе, на самом деле это весело.
Antontsue
В целом, обычно в луа вывешивают апишку, и дёргают её там. Ну, то есть плюсы работают автомобилем, а луа -водителем. То что ты хочешь в с++ дёргать луа-методы - это немного странно :3
Странно ты себе представляешь) чтобы чтото откудато дергать из луа с++ программист сначала должен чтото дернуть в луа, чтобы оттуда вы уже дернули назад с++. Просто это не ваша работа вы этого не замечаете скорее всего.
Tverd
Обычно из движка С/С++ приходит update в луа, а вот луа уже начинает дегать все подряд и желательно уложиться в время одного апдейта. Обычно так делается, насколько я знаю.
fgntfg
Из Си дёрнуть Луа, которая дёргает Си.
Antontsue
Не уверен что в данном случае - двустороннесть - хорошо. Можно в луа вывести хендлер квеста для перехода между этапами и развилками, хендлер игрока и событий для перехвата условий выполения квестов, и просто дёргать луа-скрипт с квестом. Или луа-скрипт вообще со всеми квестами. Суть: 1. Ядро С++ хранит список активных квестов 2. Новые добавляются и обновляются луа-скриптами (текст и всякие счётчики/ништяки) через хендлер в мастер-скрипте. 3. Мастер-скрипт на луа с хендлером, который подгружает остальные квестовые скрипты, отслеживает события: на некоторые (разговор с персонажем по некоторой ветке диалога с конкретными ID) - отправляет С-ядру запрос на создание нового квеста, а на другие (убийство десяти волков) - дёргает хендлер ядра на тему "квест выполнен". Ядру нужно только дёргать на каждое событие мастер-скрипт, тот всё остальное сделает сам. Событийные системы эффективны. И даже очень. За счёт того что не вызываются каждый кадр, нужен только пул событий и управляющий хендлер, дёргаемый, например, при убийстве того же волка, в пул событий передаётся, например, такая структура: Тип: убийство, субъект: игрок оружие: меч тысячи истин, тип урона: удар по самомнению тип ударов: режущие корень истины броня: штаны из берёзовой коры, объект: волк тип: животное, ареал: лес, образ жизни: хищник локация: тёмная лесная опушка фракция: лесной управдом владелец: баба яга Подобные события - крайне удобны для обработки луа-скриптами.
Список квестов будет в луа, я не хочу в с++ ничего связанного с квестами тащить. Если интересно почему - это бесполезно с точки зрения переиспользования этого кода в других местах, ограничит возможности самих квестов возможностями апи, мне придется писать само это апи, и мне придется дополнительно писать логику сохранения/загрузки стейтов квестов - сейчас я поанирую дампить весь стейт в сейв (через Eris - это аналог Pluto для луа 5.3 это не я придумал, я изучал кто как делает, нашел несколько примеров использования такого подхода) В остальном примерно похоже - с++ будет на апдейты дергать скрипт и передавать туда что произошло
Tverd
да, есть такая проблема - из С дернуть метод луаджита намного затратнее чем наоборот. Насчет обычного луа не знаю, насколько это затратно.
fgntfg
А зачем вообще Си в этом проекте?
Antontsue
да, есть такая проблема - из С дернуть метод луаджита намного затратнее чем наоборот. Насчет обычного луа не знаю, насколько это затратно.
Буду иметь ввиду, ну пока это норм для меня - я вызываю луа только по событиям, а оттуда уже вызываются сишные методы
Antontsue
А зачем вообще Си в этом проекте?
Кроссплатформенная игра под 5 поатформ
Tverd
На форуме по Urho3D этот вопрос поднимался как-то, почему медленно движок работает с Луа биндингами. Оказывается 60 раз в секунду вместо одного апдейта, идет их штук 20
Antontsue
Нет сишный движок
Antontsue
а по моей проблеме то чтото можете сказать?
Antontsue
вообщем я худо-бедно разобрался как классы делать - по этой методичке http://lua-users.org/wiki/SimpleLuaClasses - вариант для луа 5 3
Antontsue
как вы кстате вообще классы используете? какие практики? луа как я понял не особо оопэшный, или все-таки используется наследование? или както иначе все пишется у вас?
Antontsue
написал вот такой классик: Quest = class(function() function __init(body) print('quest init 1') this.body = body print('quest init 2') this.cor = coroutine.create(body) print('quest init 3') end function run() print('quest run') coroutine.resume(this.cor, this) end function interrupt(condition) local listener = EventListener(this.cor, condition) gloabalDispatcher.addListener(listener) coroutine.yield() end end)
Antontsue
выводит в итоге только lua: test 1 lua: quest init 1 lua: quest init 2 lua: quest run lua: test 2
Antontsue
у меня вопрос поччему quest init 3 не выводится и почему корутина не запускается
Antontsue
вот так пытаюсь запустить: 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
Тут не так много знатоков корутин, потому что они не дают объективных преимуществ по скорости, являясь декораторами асинхронных вызовов, чтобы писать асинхронщину так же красиво как простой линейный код. На тему ООП:
Antontsue
ну я не думаю что проблема в корутине я думаю проблема в том как создаю/передаю в нее функцию
Antontsue
а это вопрос синтаксиса луа
Antontsue
в этом то тут должны быть специалисты?
Antontsue
print('quest init 3') не вызывается, тоесть такое ощущение что из init-а вылетает в тот момент когда я пытаюсь корутину создать
Snusmumriken
Вот пример ооп без дополнительных библиотек, который гарантированно работает как ожидается.
Snusmumriken
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
Antontsue
у меня ооп работает, ну тоесть конструкторы и методы вызываются
Antontsue
у меня почемуто происходит выход из функции
Snusmumriken
Он, конечно, использует функции фреймворка love2d, но это не важно.
Snusmumriken
Оки, ща будем смотреть
Antontsue
классы делаю по этой методичке http://lua-users.org/wiki/SimpleLuaClasses - вариант для луа 5.3
Snusmumriken
Дык версия тут не важна :3 Повсеместно используется 5.1 и 5.3, у которых практически не различается ООП.
Antontsue
ну малоли
Snusmumriken
Блин, какая странная классовая библиотека :3
Snusmumriken
И я не уверен что ты нигде не опечатался, потому что виду незавершенную функцию interrupt
Antontsue
а че там незавершенного?
Snusmumriken
Нет end.
Antontsue
function interrupt(condition) local listener = EventListener(this.cor, condition) gloabalDispatcher.addListener(listener) coroutine.yield() end
Antontsue
есть
Snusmumriken
А, оно просто длиннее чем показалось.
Antontsue
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
а по моей проблеме то чтото можете сказать?
Вариант сделать прототипы, они проще на мой взгляд, хотя для программера на С++ могут показаться страннее.
Tverd
http://siffiejoe.github.io/lua-prototype/