-
Число публикаций
618 -
Регистрация
-
Последнее посещение
-
Дней в топе
1 -
AMKoin
37 [Подарить AMKoin]
Весь контент пользователя Nazgool
-
По поводу определения типа таблиц. Набросок без итераторов. Проверку на пустую таблицу и скорость не делал. function GetTabStatus(tab) if #tab ~= 0 and not next(tab, #tab) then return 'index' -- индексирудмый массив else return 'hash' -- всё подряд end end
-
Можно без '0x' (на всякий случай уточню) в чистом lua hex = string.format('%x', 65535) dec = tonumber(hex,16) Спасибо. Проверил: в игре такой вариант работает. --/ Artos
-
Я поленился на теле набирать, но ведь tonumber ещё не отменяли :-) dec = string.format('%d', tonumber('0x'..hex)) Или Сталкер и этого не понимает? К сожалению ... Метод 'tonumber' ожидает только десятичное представление числа символами строки. Любой не 'числовой' символ ('x') - воспринимается как буква и => 'nil'. --/ Artos P.S. Подзабыли про параметр '16' для метода ... :-)
-
Artos По первому вопросу боюсь что без перебора не получиться. В принципе есть идея чтобы не перебирать. Но это когда буду дома. По второму вопросу могу пока предложить string.format hex = string.format('%x', 65535) dec = string.format('%d', '0x'..hex) У меня есть доморощенная функция преобразования DЕС/НЕХ, но я сейчас с тела. Вечером сравню скорости и сообщу. Метод 'string.format('%d', '0x'..hex)' - не применим для игры, т.к. ожидается только численное значение и стринг не приемлем (=> фатал еррор) --/ Artos
-
Плз, покажи код, как создавала. Плз, покажи код как учила.
-
Справочник по функциям и классам
Nazgool ответил на тему форума автора Malandrinus в Скрипты / конфиги / движок
Не один раз на разных форумах задавали вопрос о том что-же такое шаблон и с чем его едят. Совсем недавно подобный вопрос всплыл и тут. Вот и решил , за отсутствием специализированного топика по lua, выложить материал тут. Но прежде всего хочу сказать, что всё сказанное мною относиться к заре моего познавания Lua. Сейчас нет времени исправлять то, чего не знал, не так объяснил и не правильно понимал. Поэтому выкладываю как было на тот момент. Всё же лучше чем сухие предложения из официального мануала. С вопросами (а также тонкостями) составления шаблонов обращаться либо в ПМ, либо (лучше в плане всеобщего образования) в теме "Скриптование, спавн и логика ". Хватит лирики, вот ссылка на страничку из моего манула по Lua 2-x двухгодичной давности : http://ifolder.ru/25675390 -
Artos Мои результаты в тесте (пост #320 стр.16 "Справочника") говорят об обратном. Concat оказался быстрее. Не на много, но факт.
-
Artos Наверное следует вспомнить про дедушку Эйнштейна. Если смотреть относительно заранее проинициализированных строками переменных, то простая конкатенация конечно будет работать быстрее, чем tаblе.соnсаt, для использования которого необходимо понести накладные расходы на создание массива. Если же смотреть относительно заранее созданой таблицы с массивом конкатенируемых строк, то быстрее будет tаblе.соnсаt, т.к. расход понесет простая конкатенация, для выполнения которой нужно выбирать значения из таблицы. В общем нужно исходить из конкретных ситуаций.
-
singapur22 Поступил по твоей аналогии и заключил все варианты в функции. Оставил общую таблицу как "точку отсчёта".
-
Справочник по функциям и классам
Nazgool ответил на тему форума автора Malandrinus в Скрипты / конфиги / движок
Изначально, вместо unpack я писал tb[1], tb[2], tb[3], tb[4], tb[5]. Результат был ещё хуже. Как бы ещё немного помог ей. P.S. Что-то мне подсказывает, что мы не в той теме общаемся. Нам бы в "Скриптование..." перейти. -
Справочник по функциям и классам
Nazgool ответил на тему форума автора Malandrinus в Скрипты / конфиги / движок
Теперь я забираю свои слова, сказанные выше, назад. Если поставить все тестовые варианты в равные условия, то результаты сильно изменяться. Изначально я создал таблицу строк, а потом использовал обращение к ней из каждого варианта. Для string.format создал идеальные условия, т.к. иначе проигрыш будет слишком очевиден. -
Справочник по функциям и классам
Nazgool ответил на тему форума автора Malandrinus в Скрипты / конфиги / движок
singapur22 Вот спасибо. Теперь можно внести дополнение в определение - "При работе с заведомо длинными строками (100 и более символов) следует использовать string.format, который будет работать быстрее чем table.concat" -
Справочник по функциям и классам
Nazgool ответил на тему форума автора Malandrinus в Скрипты / конфиги / движок
Да, попробуйте сделать строки длиной по 99 символов (ужасная задержка), а затем по 100 (обыгрывает concat) и сравните результаты. Это только у меня format так себя ведет? -
Справочник по функциям и классам
Nazgool ответил на тему форума автора Malandrinus в Скрипты / конфиги / движок
malandrinus, RvP По следам разбора конкатенации... Найду свободное время - поэкперементирую, но пока вот мои результаты в SciTE (??? не вписываются в заключение ???) : table 1.875 concat 0.344 format 1.5 Добавлено через 9 мин.: Ага. Увеличил размер строки и всё стало на свои места. malandrinus, удали пожалуйста мой пост. При разных длинах строк происходят совершенно интересные вещи. Разберу - отпишусь конкретнее. -
Artos Да я вот тоже до сих пор ломаю голову, зачем нужно вот это : elseif type(Mode) == "number" then --//таблица '[idx] = число или стринг' for sValue in sStr:gmatch(sPatt) do tRet[#tRet+1] = tonumber(sValue) or sValue end end
-
В любом справочнике по luа. В сети их не так уж и мало. Правда сухие фразы определений это плохой помощник для новичка. Может прийдет вдохновение - напишу подробнее. Добавлено через 308 мин.: Если расставлять приоритеты (в принципе), то борясь за каждую миллисекунду всякими контролями можно пренебречь. И если я сам пишу код, то наверняка знаю что, куда и как писать. И зачем мне думать, что кто-то там полезет в него и накосячит. Я, например, могу пожертвовать этим ради скорости. Не знают - нечего лезть. Т.е. вот это : local sPatt = '[%w%_]+' --/ дефолтный патерн (разделение по 'словам') --/ если задан сепаратор: разделяем по сепаратору if type(sDiv) == "string" then sPatt = '%s*([^'..sDiv..']+)%s*' --/ по разделителю (исключая начальные и заключительные пробелы) --/ если указан шаблон: используем шаблон elseif type(sPattern) == "string" then sPatt = sPattern end Я записал бы так (пусть, например, паттерн будет приоритетнее сепаратора): local sPatt = sPattern or sDiv and '%s*([^'..sDiv..']+)%s*' or '[%w%_]+' А если уж ставил бы проверки, то тотальные. Первой же строкой что-то типа : if not sStr then return '' end sDiv экранировать спец. символы (вдруг кто-то забыл, не знал) sPattern в локальной функции сделал бы проверку на корректность составления паттерна (то, что я до сих пор не внёс в script Syntax Checker)
-
Artos Вот что ты мне напомнил ненароком. Нужно внести эту информацию в справочник : coroutine не даёт возможности многопоточности. Подпрограммы выполнятся так же как и обычные функции - в одном потоке. А вот "размазать по времени" вполне можно.
-
Справочник по функциям и классам
Nazgool ответил на тему форума автора Malandrinus в Скрипты / конфиги / движок
По совету Artos-а решил изложить материал, касающийся работы с coroutine тут, поскольку данная таблица входит в пакет Lua СТАЛКЕР-а, и более подходящей темы трудно найти. Нужность/ненужность данной информации оставлю на рассмотрение malandrinus-а, т.к. практическое использование подпрограмм пока находится под большим вопросом. Тем не менее есть люди интересующиеся, поэтому продолжу... Итак, обо всё по порядку (malandrinus-у. Можно я буду писать частями? Хочется сделать не только информативно, но и придать внешний вид. А вот со свободным временем у меня не очень.) : ---------------------------------------------------------------------------------------------------------------------------------------- Операции для работы с подпрограммами собраны в виде подбиблиотеки базовой библиотеки и содержатся внутри таблицы coroutine. Эта таблица содержит всего шесть функций : create wrap resume yield status running Я их подразделяю на основные : create и wrap - создают подпрограмму resume - запускает или продолжает выполнение подпрограммы yield - приостанавливает выполнение подпрограммы И служебные : status - возвращает состояние подпрограммы running - возвращает саму подпрограмму Рассмотрим их подробнее. -
"Поисследовал" я это дело уже давно, только почему-то убедил себя в том, раз уж нет ни IО, ни DЕВUG, то и СОRОUTINЕ путь заказан. Тут получается так, что основная задача уже не сам факт возможности прерывания выполнения функции, а сохранение и восстановление (после загрузки например) текущего состояния и данных. Хорошо если эти данные простого типа (числа, стринги, булевы значения). А если данные какого-то объекта (или же сам объект), который на момент работы своей очереди выполнения подпрограммы существовал, потом был удалён? И при загрузке текущего состояния нужны будут либо сам объект, либо его данные? Короче, подумаю над этим. Про работу СОRОUTINЕ постараюсь сегодня рассказать подробнее.
-
Artos Не знаю, писать ли тутор, или по ходу дела будет видно. Coroutine мало кому известны, поэтому покажу как проверял, а потом уже, наверное, будут вопросы, ответы на которые и введут в курс дела. Хотя не уверен что кому-то понадобиться. Пошел по самому быстрому пути (несчастный bind_stalker ). Решил для наглядности прерывать цикл. В качестве "генератора" вызовов использовал не менее несчастный "update(delta)". Каждые 5 секунд прерывал работу цикла и затем снова продолжал: ..... co = coroutine.create(function (a) for i=1,10 do coroutine.yield(a+i) end end) local ttt = time_global() function actor_binder:update(delta) if time_global() - ttt >= 5000 then if coroutine.status(co) ~= "dead" then local _, result = coroutine.resume(co, 5) if result then news_manager.send_tip(db.actor, result) end end ttt = time_global()+5000 end ..... В результате каждые 5 секунд выводились сообщение 5,6,7,8 ... 15. Прошу заметить, что целью было не осуществление перебора (для этого есть более простые способы). Смысл coroutine в том, что (например) при первом обороте цикл останавливается, и ждёт до тех пор, пока не произойдёт следующий вызов. Игра идёт своим чередом дальше. и вызывать можно хоть отсюда. хоть из другого скрипта - не важно. Важно задать имя подпрограммы (co) глобально, чтобы была возможность последующего вызова из любого скрипта. Добавлено через 40 мин.: Забыл сказать, что на момент остановки можно получать текущие данные, а в момент запуска-продолжения передавать новые для обработки.
-
Может кому интересно? Когда-то кто-то (и не один) спрашивал, - "Можно ли приостановить выполнение функции?" Ковырялся в таблице _G СТАЛКЕР-а и наткнулся на поле coroutine и вспомнил тут же про упоминание о coroutine в безымянном файле *.script. В общем проверил. Можно. Если кому нужно - обращайтесь, а если это уже было - удалите, плз, пост.
-
[SoC] Ковыряемся в файлах
Nazgool ответил на тему форума автора Halford в Скрипты / конфиги / движок
Artos Пусть и углубились. Для людей будет повод задуматься и начать понимать (изучать) то, о чём мы говорим Дальше по сути. Как? добавить копии - не проблема. А вот для чего? Если очень нужно, то можно ПОвыяснять. Единственное что мне не понятно - для чего тебе нужно удалять занесенный в глобальный массив модуль? Но в любом случае интересно и об этом подумать. -
[SoC] Ковыряемся в файлах
Nazgool ответил на тему форума автора Halford в Скрипты / конфиги / движок
Разреши дать "ДО"толковалки, т.к. не могу гарантировать достоверность всей информации, но не могу не дополнить. Информация ниже дана не для "профессионалов", а только в качестве разъяснения. То, что нашёл, излагаю ниже (факты с моими комментариями - "ДО"толковалками и пояснениями): Итак факты : 1. Для таблицы _G (т.е. для глобальной таблицы Lua) в СТАЛКЕР-е существует СВОЯ метатаблица. 2. В этой метатаблице есть только одно поле с ключем __index и значением function 3. У каждого, уже ПОДКЛЮЧЁННОГО!, к игре файла-модуля (*.script) тоже существует своя метаблица с единственным полем __index и значением таблица. Этой таблицей является глобальная таблица Lua _G P.S. Всё далее, конечно, опровержимо, но... (...позволю себе умозаключения) При обращении (например, при вызове "if какой_то_ещё_не_ни_разу_не_запрашиваемый_файл then") в таблице _G происходит поиск поля с ключём "какой_то_ещё_не_ни_разу_не_запрашиваемый_файл". Естественно, не найдя его в себе (таблице _G), происходит обращение к метатаблице таблицы _G. И поскольку в этой метатаблице только одно поле с ключём __index и значением function, происходит вызов этой функции. Проверки показали, что при подобном вызове в глобальной таблице Lua (_G) сразу же появляется поле с ключём "какой_то_ещё_не_ни_разу_не_запрашиваемый_файл" и значением таблица. Т.к. не могу заглянуть в движок, могу только предполагать что эта функция зугружает файл как модуль, устанавливает для неё метатаблицу с индексом на таблицу _G. Короче, промоделировал подобный код в SciTE (Плохо, но зато быстро ) -- Тут вроде как прочитанные данные из 'fsgame.ltx' game_scripts = 'F:\\Games\\S.T.A.L.K.E.R.\\gamedata\\scripts\\' -- типа путь к папке 'scripts' package.path = game_scripts.."?.script" -- это для Lua-интерпритатора(не обр. внимания) -- Далее метатаблица для _G local mt_G = {__index = function(t,k) -- тут вызывается функция local scr_path = game_scripts..k..'.script' -- типа путь к файлу local f = loadfile(scr_path) if f then module(k, package.seeall) -- объявляем файл как модуль и устанавливаем "видимость" (package.seeall) setfenv(f,_M) -- поскольку loadfile "работает" в своём окружении (окружением для неё является _G), то назначим ей окружением загружаемый модуль (т.е. проведём операцию загрузки - содержимого файла в...) новый модуль. f() -- загружаем содержимое файла-модуля setmetatable(_M, {__index = _G}) -- как я уже констатировал факт, для этого модуля устанавливается метатаблица, ссылкой из которой является таблица _G) return require(k) -- ну и возвращаем подключённый модуль как таблицу end end } -- для глобальной таблицы Lua "_G" устанавливается метатаблица 'mt_G' setmetatable(_G, mt_G) Ну и дальше любой вызов вызов ещё несуществующего для игры файла (или ещё_несуществующего_файла.ещё_не_видимой_функции) приводит к запуску "механизма"(на моём скромном примере ) создания этой записи и вызова функции. Ну, например, при загрузке новой игры нет поля с индексом xr_effects. Обратившись : if xr_effects then ... Сначала происходит нечто, описанное сначала моего поста. И если файл-модуль с именем "xr_effects" существует и правильно загрузиться, то ... Дальше что там Вы хотите. Примерно так, ИМХО. -
Ulman Хотел подробнее?...
-
[SoC] Ковыряемся в файлах
Nazgool ответил на тему форума автора Halford в Скрипты / конфиги / движок
КОКС local string1 = "12.00" local string2 = "12.0" local string3 = "12" local string4 = "12.05" local string5 = "12.50" tonumber(string1) --> 12 tonumber(string2) --> 12 tonumber(string3) --> 12 tonumber(string4) --> 12.05 tonumber(string5) --> 12.5
- [ЧН] OGSM CS 1.8 CE Fixes
- [ЧН] HARDWARMOD 3.2
- [ЗП] The Long Road
- [ЧН] New vision of War
- [ЧН] Old Good Stalker Mod - Clear Sky
- [ЗП] Unofficial Patch
- [ЗП] Смерти вопреки
- [ЗП] Контракт на хорошую жизнь
- [ЗП] Shoker Weapon Mod 2.1
- [ЗП] Hardcore pack for SGM 2.2
- [ЗП] Контракт Синдиката
- [ЗП] Клондайк 2.0
- ...и другие моды