Dennis_Chikin 3 658 Опубликовано 24 Апреля 2014 Поделиться Опубликовано 24 Апреля 2014 (изменено) "Что у нее внутри, и как это сделать лучше". Для тех, кто уже разбирается в скриптах, конфигах, текстурах и "других страшных словах" ©, и имеет желание и время действительно делать их лучше.См. подробности в первом посте.Тема НЕ является ни столом заказов, ни службой техподдержки, ни справочным бюро. Изменено 28 Апреля 2014 пользователем Dennis_Chikin 2 1 Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
kamikazze 266 Опубликовано 7 Июля 2010 Поделиться Опубликовано 7 Июля 2010 (изменено) sapsan В том куске что Колмогор отпостил, там выхода за границы нету, там просто само условие цикла бесконечно выполняется судя по всему. Но! Выход за границы запросто может произойти если где-то в другом месте когда в этот же момент происходит изменение таблички self.spawned_obj. А про table.getn в том контексте вспомнил, что вот так: while table.getn(self.spawned_obj) < self.min_count do Делать вообще нигде крайне нежелательно - вдруг действительно где-то ещё эта табличка сейчас изменяется. Вот так желательно: local tab_size = table.getn(self.spawned_obj) while tab_size < self.min_count do В этом случае тогда уже можно сделать так: local tab_size = table.getn(self.spawned_obj) while tab_size < self.min_count do tab_size = tab_size + 1 . И это - не более, чем оптимизация. sapsan table.getn вообще в условиях циклов пользовать нельзя категорически. Добавлено через 2 мин.: Kolmogor По-моему нормальный цикл - собственно этот цикл еще с оригинальной ТЧ идет Роман, я тебя умоляю, где ты видел в оригинальном коде нормальные циклы - я столько там ошибок находил в свое время, причём тупых до ужаса... Добавлено через 7 мин.: sapsan Ну не совсем оптимизация. Скорее "обезопаснивание". Потому как если таким образом сделать, то переменная tab_size получит значение однократно перед выполнением тела цикла и на его протяжении значение менять будет только итератором. А если пользовать внутри условия table.getn, то получится что в условии каждый раз проверяемое значение рассчитывается заново. А оно может крайне опасным получиться в случае нештатной ситуации и циклу кранты. Добавлено через 5 мин.: Kolmogor Хотя может и наоборот уйти ото всех функций table.* Обоснованно, кстати, было бы. Я давно уже ушёл, прямой инициализации строк присвоением значения по ключу и их обниления вполне достаточно. Изменено 7 Июля 2010 пользователем kamikazze Отладчик и скриптер мода OGSE. Автор схемы "Компаньоны", стреляющего БТРа и многих других полезностей Ссылка на комментарий
Dennis_Chikin 3 658 Опубликовано 7 Июля 2010 Поделиться Опубликовано 7 Июля 2010 (изменено) Кстати, о птичках. while c рассчетом чего-либо непосредственно в условии, если это не одно сравнение, работает вообще как-то странно. sapsan, если бы... Скорее, наоборот: в отличии от for оно явно делает что-то лишнее. Изменено 7 Июля 2010 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
sapsan 336 Опубликовано 7 Июля 2010 Поделиться Опубликовано 7 Июля 2010 (изменено) Kolmogor, kamikazze, уходить от использования table. нужно или глобально, или только в работе со своими таблицами, к которым никто другой не доступается и в комментариях описать данных "уход", или вообще не уходить с целью даже будущей совместимости. А ведь есть ещё table.sort и table.concat. Добавлено через 19 мин.: Dennis_Chikin, скорее всего там условие проверяется "ленивым" способом. Тоесть если в условии (а или б) значение а == истина, то б уже не проверяется и не расчитывается. Аналогично с условием (а и б) - если значение а == ложь, то б уже не проверяется и не расчитывается. Добавлено через 32 мин.: Dennis_Chikin, тесты, тесты и ещё раз тесты Добавлено через 25 мин.: Ещё по "уходу" - кроме других table-функций есть ведь ещё и оригинальные скрипты от GSC. Поэтому уходить или вместе с ними или только для своих таблиц. Изменено 7 Июля 2010 пользователем sapsan Ссылка на комментарий
kamikazze 266 Опубликовано 7 Июля 2010 Поделиться Опубликовано 7 Июля 2010 (изменено) sapsan Ну совсем от функций table не отказаться, всё таки table.sort и table.concat нам нужны ещё однозначно, но вот удаление добавление строк надо просто условиться делать только напрямую, ручками. И считывать число строк только через #. Насчёт родных скриптов от GSC - уходить разумеется вместе с ними, потому как там кое-где есть такие обработки, и я часть из них, показавшихся наиболее подозрительными, у нас в OGSE переделал. Никаких проблем с ними не было после этого. UPD: Вообще же я от циклов for по таблице, с условием заданным на число строк давно уже вообще отказался и где это только возможно использую конструкцию for k,v in pairs(table) do Этой обработке совершенно безразлично что происходит с таблицей, она работает пока не получит последнюю пару из неё. Добавлено через 331 мин.: dimos Самое интересное, что вылета не было и игра пошла спокойненько дальше, чего-то планировщик там проапдейтил... Вот это кстати хреново, это симптом того, что функция abort периодически не срабатывает. Это несрабатывание может в итоге привести к незамеченному сбою, который в итоге вызовет цепную реакцию наслаивания разных глюков друг на друга вплоть до зависания алайфа и в итоге порчи сейвов. По уму надо это бы abort доработать так, чтобы при его вызове откуда либо вылет был гарантирован. Я у нас вот так переделывал: -- Крешнуть игру (после вывода сообщения об ошибке в лог) function abort(fmt, msg) local message = tostring(msg) local reason = string.format(fmt, message) assert("ERROR: " .. reason) printf("ERROR: " .. reason) dbglog("%s", reason) printf("%s") local crash local ooops = 1/crash end Добавленные строки - две последних. В итоге если при вызове вылет не случился на операторе printf("%s") (как по идее должен), то игра 100% вывалится на арифметической операции с неинициализированной переменной crash. Изменено 7 Июля 2010 пользователем kamikazze Отладчик и скриптер мода OGSE. Автор схемы "Компаньоны", стреляющего БТРа и многих других полезностей Ссылка на комментарий
Arhara 32 Опубликовано 8 Июля 2010 Поделиться Опубликовано 8 Июля 2010 *Razor*, Я хотел сделать так. Но подумал - зачем? Добавил сразу все локи из ЗП... Залил полуадаптированную версию... С чего и получил адекватную помощь по текстурам, картам, укрытиям и прочим мелочам, для вас незаметным. Хотя - за каждой навешенной вновь дверью или лампочкой стоит нелёгкий труд. Адаптировал скрипты и прочую лабуду. Проверил - всё адекватно работает. А качать (по желанию) - вам придётся всего один раз. Еще 10 лет таких цен, зарплат и пенсий, и вместо переписи населения будет перекличка Ссылка на комментарий
kamikazze 266 Опубликовано 10 Июля 2010 Поделиться Опубликовано 10 Июля 2010 (изменено) Dennis_Chikin Логи не глядел, так как в Солянке не ковырялся сильно сам, однако касательно удаления монстров вот чего могу сказать из собственного опыта: 1) Монстра нельзя безболезненно отрелизить если он жив и уже в онлайне. Если он в онлайне, самым простым методом будет его сначала прибить, любым типом хита с запредельным уроном, чтобы он издох. Затем отрелизить трупик с небольшим интервалом, в треть секунды хотя бы, чтобы удаление происходило когда он точно помер. Попытка отрелизить из онлайна живого монстра на очень многих зверюках вызывает вылеты либо повисания алайфа, что ещё хуже. Из оффлайна же - можно без проблем. Поэтому проверь алгорим прибивания монстров и если надо внеси соотв. коррективы. 2) Касательно psy_dog_phantom - это очень странные фантомы собак в игре, и часто глюкавят. Они периодически косо сохраняются в сейвах, причем не одна битая например, а все и сразу. Сейв в итоге не грузится. Я у нас в OGSE не мудрствуя сделал просто их автоприбивание ещё при спавне на загрузке сейва, пси-псина всё равно если рядом находится моментально нарожает новых. Тебе тут возможно стоит сделать их автоприбивание при завершении игры. Изменено 10 Июля 2010 пользователем kamikazze Отладчик и скриптер мода OGSE. Автор схемы "Компаньоны", стреляющего БТРа и многих других полезностей Ссылка на комментарий
sapsan 336 Опубликовано 11 Июля 2010 Поделиться Опубликовано 11 Июля 2010 Из экспериментов с таблицами: 1) После вставки с помощью выражения t[#t+1] = 1 получить правильную длину таблицы с помощью table.getn нельзя, но с помощью # можно. 2) Если делать удаление элемента с помощью присваивания nil, то таблица не утрясается и тогда все последующие обращения к ней нужно проводить с проверкой на ~= nil или, если это цикл, с помощью in pairs. Также размер таблицы нельзя получить правильно ни с помощью table.getn, ни с помощью # (разве только вручную вести счетчик). P.S. Вот и все "странности". Так что либо держать все ниточки в своих руках, либо откатываться на стандартные методы... Второе - надёжнее. Ссылка на комментарий
Shadowman 939 Опубликовано 11 Июля 2010 Поделиться Опубликовано 11 Июля 2010 (изменено) либо держать все ниточки в своих руках, либо откатываться на стандартные методы... Второе - надёжнее sapsan, стоит все же доделать начатое, как думаешь? Вместо присваивания nil вполне можно использовать table.remove. Ведь результат проверки наличия в таблице что переменной, которой присвоен nil, что вообще не существующей там переменной одинаков. А то, что проверки на ~= nil нужны - так это и так давно известно (и не только в случае с таблицами). table.getn не составит труда вообще глобально заменить на # Учитывая вышесказанное про циклы по таблицам, меняющие число записей самих таблиц - придётся проанализировать, что именно делает цикл. Возможно, где-то я погорячился, заменив for k,v in pairs(table) do на for i=1, #table do. Делал это не просто так: скорость работы второго метода в разы больше первого. Хорошо, что не так много нужно пересмотреть function my_binder:net_spawn() в netpacket_pda_binder.script при каких условиях должен отрабатывать ? Dennis_Chikin, в любом биндере net_spawn() одинаково работает: при загрузках лок и сейвов в этом самом xr_logic.script на pstor_load_all() внимательно Dennis_Chikin, "последняя рука" - моя, что там не так? Если ты о том, что при обработке зависов пропускается ГГ, то иначе никак, мы ведь просто удаляем зависших. ГГ - не удалишь. Ошибка же 1490 - лишь результат неправильной записи в пстор актора (точнее, записи чего-то левого). При чтении это уже не исправишь. При записи же стоят заглушки, какие можно. Разве что при загрузке при попадании в условие потенциального зависа вместо ctr = 0 поставить return. Но там и так дальше идет цикл, который сработает только если ctr > 0 ----- Проверка на classname == nil ничего не даст - тут вылет даже нужен, т.к. все одно это означает, что в сейве уже побитый пстор. Проверяй, не проверяй - с этим уже ничего не сделаешь. В нет_пда мусора не будет - там не пишутся ничего такого (разве что гпс-маячки). Если есть желание - попробуй проверку сделать По-хорошему, нужно искать где и когда делается неправильная запись пстора. Изменено 11 Июля 2010 пользователем Shadowman Железо: Intel Core i5 9400F / 16Gb DDR4 2400MHz / SSD NVMe M.2 Samsung 970 EVO Plus 256Gb / GF GTX 1050Ti 4Gb Ось: Win10x64 Ссылка на комментарий
Dennis_Chikin 3 658 Опубликовано 11 Июля 2010 Поделиться Опубликовано 11 Июля 2010 (изменено) Понятно. Похоже, случайно нашел один из признаков надвигающегося xr_logic: 1490 Кто-нибудь поглядел бы еше в этом самом xr_logic.script на pstor_load_all() внимательно. Shadowman, ну, скажем, на предмет classname == nil. И на предмет мусора в этом classname. И диагностику вменяемую этому самому net_pda_чего-то, у которого pstor с мусором, вывести в лог не помешает. Upd: у себя - уже. И это был единственный раз ошибки 1490, который вообще случился за последние пол-года. Был именно мусор. На фоне пачки лагов. (Маячками не пользуюсь.) kamikazze, имеет смысл подкрутить для начала update_monster_factor ? И, да, с радиусом alife=250 лог стал похож на человеческий. Если не считать внезапно !SV:ge_destroy: [7080] not found on server для патронов у неписей. Однако я не понял, зачем тогда тот же net_destroy() вызывать при загрузке для трупов ? По-моему- одно из двух. P.S. Я правильно понимаю, что нанесение хитов - это только в он-лайне ? А обнуление - это для офф-лайна ? Изменено 11 Июля 2010 пользователем Dennis_Chikin Солянка обезжиренная, диетическая, полезные советы по "солянке", текущий тестовый патч Ссылка на комментарий
kamikazze 266 Опубликовано 11 Июля 2010 Поделиться Опубликовано 11 Июля 2010 (изменено) sapsan Ну собственно что я и предлагал. Пользовать для количества строк # и как самый безопасный вариант цикла - in pairs. Проверку же ~nil надо в любом случае выполнять всегда и везде где только можно, и я это обычно всегда и делаю, сразу избавляясь от возможных с этим проблем. Dennis_Chikin Касательно сакрального смысла net_destroy() - этот метод автоматически вызывается когда монстр или непись уходит в оффлайн, а не при смерти. Это нормальное поведение, так и должно быть. И если монстр носится на границе расстояния переключения, то он будет постоянно в онлайн и затем снова в оффлайн прыгать. Касательно того же что там в обработке напихано я если честно вообще половину не пойму зачем туда запихали. Там ещё и перезапись таблички рестрикторов в нетпакете сидит непонятно зачем, конечно оно тормозить будет как сумасшедшее, обработка нетпакетов на запись работает очень медленно, и к тому же её нельзя слишком часто производить, так как есть вероятность повредить данные. И ещё торможения при этих обработках вызывают выводы в лог - они тоже довольно тормозные. Изменено 11 Июля 2010 пользователем kamikazze Отладчик и скриптер мода OGSE. Автор схемы "Компаньоны", стреляющего БТРа и многих других полезностей Ссылка на комментарий
Monnoroch 6 Опубликовано 11 Июля 2010 Поделиться Опубликовано 11 Июля 2010 (изменено) kamikazze, Вот по поводу этой проверки на нил. Самый главный вопрос, на который я пока не видал ответа - откуда вообще берутся эти нилы? То есть, конечно, кривые руки, да, но есть куски кода в которых я уверен - не будет нила, хоть тресни, а поди ж ты. Есть еще фактор странных апдейтов - бывает в мотиваторе:update() удалил переменную а в актор биндере:update() вызываешь, ну или нечто подобное. Да. Но опять же есть куски кода где я уверен - с этим все в порядке. И таки все равно нилы вылезают периодически. Был просто момент, когда я вообще не написал ни одной такой проверки (код-то быстрее), где был уверен - а замучался. Проверял-перепроверял - ниоткуда берутся. Добавлено через 4 мин.: Shadowman, for k,v in pairs(table) - это ты зря убрал,там же ключи не обязательно 1..#table, но раз скорость выше в разы,то и заменять везде на эту конструкцию тоже нельзя, безопасность - да,но не в ущерб производительности. Проще действительно на нил проверять. Эх,жаль макросов нет в интерпритаторе... Изменено 11 Июля 2010 пользователем Monnoroch Ссылка на комментарий
kamikazze 266 Опубликовано 11 Июля 2010 Поделиться Опубликовано 11 Июля 2010 (изменено) Monnoroch Всё правильно, ниоткуда. Я сам когда-то голову сломал искаючи. Впечатление такое будто это вызывают некоторые рассинхронизации при обработке внутренних потоков данных в движке игры. Вроде того, что данные когда запрашиваются - ещё "не готовы" к употреблению. Доискиваться исходных причин тут неблагодарное дело, поэтому проще просто не забывать эти проверки ставить. К слову, чаще такие пропажи переменных происходят на отломанной игре, так что скорее всего это именно рассинхронизация потоков. UPD: Ну и ещё иногда бывает дурацкий недогляд - когда переменную вместо того чтобы просто присваивать, объявляют как local внутри определённй кодовой ветки. Изменено 11 Июля 2010 пользователем kamikazze Отладчик и скриптер мода OGSE. Автор схемы "Компаньоны", стреляющего БТРа и многих других полезностей Ссылка на комментарий
Monnoroch 6 Опубликовано 11 Июля 2010 Поделиться Опубликовано 11 Июля 2010 (изменено) Далее, присваивание нила элементу таблицы - фэйловая вещь, поскольку не высвобождается память, не уменьшается длина таблицы - а нам ведь надо побыстрее в цикле ее прокрутить потом. Далее,частенько ты присваиваешь нил когда тебе совсем не надо удалять элемент,а просто показать,что временно там ничего нет (потом будет),ну и вообще,какойто странный метод - вставлять нолики по всей памяти,не доведет это до добра. Добавлено через 1 мин.: kamikazze, Ну я и сказал,бывает кривые руки Так что видимо действительно нельзя забить на проверки. Но эти проверки на самом деле жутко вредная вещь в плане того, что расслабляешься - думаешь все фигня,если че и не так,отсеется... А вообще я так почитал тут ваши пыхтения - по мне так не гуд это - такой подход. Либо переписывать все с нуля либо не лезть в разрабовский код, я так думаю. Свои скрипты ладно, но оригинальные - ну их. Просто по своему опыту смотришь - думаешь: "ууу, херни понаписали", а переписываешь - не работает. Возникает ощущение, что пол игры держится на принципе "четного количества ошибок в знаке". Я их вообще стараюсь не трогать - так, колбэки разве что расставляю. Изменено 11 Июля 2010 пользователем Monnoroch Ссылка на комментарий
kamikazze 266 Опубликовано 11 Июля 2010 Поделиться Опубликовано 11 Июля 2010 Monnoroch Нормальный метод, надо просто не забывать потом вставлять в идловое время, когда табличку ничто не трогает, микроцикл, который будет вышибать уже из неё как положено заниленные строки. А на проверки да, забывать нельзя. Впрочем я в любом случае их вставляю тогда когда код уже 100% проверен в работе. Насчёт родного кода, да, часто такое ощущение что он построен буквально на взаимоисключающих багах. Кстати, коллбэки родные вот как раз надо пошагово отлаживать местами. Я же таки победил стандартный вылет smart_terrain:1137 - который в функции on_death - он представлял собой как раз вполне реальный пример "плавающего" бага. Это тот который при вызове obj:smart_terrain_id(). Изрядно повеселился, когда выяснилось что код теряет работоспособность при определённом форматировании (!!!). Т.е. логически верен, ни одной опечатки, но стоит изменить отступы и форматирование строк - начинаются сверхстранные вылеты, словно в движке есть какая-то привязка на номер строки кода в этом скрипте. Я это дело и как вылечил в итоге описывал в статейке на stalkerin, сюда кидать не буду, там много очень. Отладчик и скриптер мода OGSE. Автор схемы "Компаньоны", стреляющего БТРа и многих других полезностей Ссылка на комментарий
Malandrinus 615 Опубликовано 11 Июля 2010 Поделиться Опубликовано 11 Июля 2010 Возникает ощущение, что пол игры держится на принципе "четного количества ошибок в знаке". Приходит сын к папе программисту. Тот в мыле сидит, аврально дорабатывает что-то. - папа-папа, а знаешь, что нам сегодня на уроке рассказали? Оказывается, Земля вращается вокруг Солнца! Тот подымает на сына мутный взор. - Что, правда? - Ну да.. - Вот так сама вертится и не останавливается? - Так нам училка сказала. - ВОТ И НЕ ТРОГАЙ! Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Ссылка на комментарий
sapsan 336 Опубликовано 11 Июля 2010 Поделиться Опубликовано 11 Июля 2010 (изменено) kamikazze, получается, что удаление элемента из таблицы путём присваивания nil нельзя, если собираешься потом получить её длину (ни table.getn, ни # корректную длину не возвращают). Или вести счетчик руками... А если для проверки условий по количеству ? В общем - небезопасно это в плане корректности данных. Изменено 11 Июля 2010 пользователем sapsan Ссылка на комментарий
kamikazze 266 Опубликовано 11 Июля 2010 Поделиться Опубликовано 11 Июля 2010 sapsan Это смотря для чего получать её длину - если для прогонки по ней цикла, то это в принципе безразлично, что у неё длина та же останется - вставить просто оператор на пропуск заниленных строк, и собственно все дела. Отладчик и скриптер мода OGSE. Автор схемы "Компаньоны", стреляющего БТРа и многих других полезностей Ссылка на комментарий
Shadowman 939 Опубликовано 11 Июля 2010 Поделиться Опубликовано 11 Июля 2010 (изменено) for k,v in pairs(table) - это ты зря убрал,там же ключи не обязательно 1..#table Monnoroch, Я сначала смотрел, что за таблица и, естественно, делал это только на тех таблицах, у которых автоматический числовой индекс. Фактически, сделано это пока только в одном-двух скриптах, только вот запамятовал, в каких именно malandrinus, прямо в точку Но с другой стороны... под лежачий камень вода-то не течёт. Просто так ведь не трогали бы ничего. sapsan, если есть серьёзные сомнения по поводу определенного кода - можно и откатить часть правок, вызывающих сомнение. И, наверное, не стоит делать впоследствии такого количества правок одновременно, потому как точно не выплывем потом из этого всего. Предлагаю на данный момент откатить все присвоения t[#t+1] = 1 и удаления путём "обниления" из "чужих" скриптов и оставить их только в "своих", которые знаем от корки до корки. И также оставить кеширование конфигов. sapsan sapsan, Наверное, так... Жаль, не один час на это потрачен. offline_alife один чего стоит - там этого добра - вагон dimos, "аборт" в Соли вообще ничего кроме записи в консоль не делает А на предмет "there is no specified level in the game graph" Сапсан точно что-то делал и выкладывал (что-то вроде проверки валидности level'a) Изменено 12 Июля 2010 пользователем Shadowman Железо: Intel Core i5 9400F / 16Gb DDR4 2400MHz / SSD NVMe M.2 Samsung 970 EVO Plus 256Gb / GF GTX 1050Ti 4Gb Ось: Win10x64 Ссылка на комментарий
dimos 10 Опубликовано 12 Июля 2010 Поделиться Опубликовано 12 Июля 2010 Вот это кстати хреново, это симптом того, что функция abort периодически не срабатывает. Это несрабатывание может в итоге привести к незамеченному сбою, который в итоге вызовет цепную реакцию наслаивания разных глюков друг на друга вплоть до зависания алайфа и в итоге порчи сейвов. По уму надо это бы abort доработать так, чтобы при его вызове откуда либо вылет был гарантирован. ...................... Самое интересное, что таких глюков в консоли бывает по н-дцать штук и не вылетает (или вылетает, но очень нескоро), но только на лицухе. Пр игре на крякнутой версии при попадании на кривой респавнер или кривой объект в алспавне - вылет без лога 100%. То ли на лицухе не срабатывает аборт, то ли этот планировщик - такая полезная штука... По крайней мере, на лицензии\правильной топологии можно посмотреть в чем именно проблема и переделать. В процессе добавления\ковыряния локаций иногда натыкался на ругань в консоли типа: ! Cannot build GAME PATH .... и вылеты типа: there is no specified level in the game graph. Может и "боян", но я нигде не находил решения, сколько не искал. Проблема заключается в том, что какая-то собачка\кошечка\тушканчик заблудились и не могут попасть на другую локацию, которая прописана у них в пути, но ИИ-связи между этими локациями в гейм.графе нету. Просто добавление дополнительной ИИ-связи с помощью утилитки Колмогора между графпойнтами локаций, прописанных в пути животин, решает эту проблему. Можно и сами пути переделать, но можно сделать и так. З.Ы. Было предложение Сапсана ставить проверку на нил как один из методов, претендующих на звание универсальных борцов с багами, но сама причина в отсутствии связей. Цензура ограничивает творчество © by me Ссылка на комментарий
Kolmogor 5 Опубликовано 12 Июля 2010 Поделиться Опубликовано 12 Июля 2010 (изменено) Далее, присваивание нила элементу таблицы - фэйловая вещь, поскольку не высвобождается память, не уменьшается длина таблицы - а нам ведь надо побыстрее в цикле ее прокрутить потом. Далее,частенько ты присваиваешь нил когда тебе совсем не надо удалять элемент,а просто показать,что временно там ничего нет (потом будет),ну и вообще,какойто странный метод - вставлять нолики по всей памяти,не доведет это до добра. Таблицы в луа - это не то же самое, что массивы в с++, это скорее как std::map в с++. Поэтому присваивание нила - освобождает память и уменьшает длину таблицы. Ведь если присвоить нил и перебрать всю таблицу, то нилового значения там не будет 2All Вообще, по-моему, наблюдается слабое понимание таблиц и функций table.* Таблицы в луа - это ассоциативный массив. Хранятся пары - ключ, значение. Но их можно использовать как массивы, списки, стек и прочее(см. список структур данных). Оператор # возвращает не длину таблицы Он возвращает номер элемента после которого идет nil. То есть в частном случае когда в таблице нилов нет, вернется длина таблицы. В общем, как только начали баловаться присвоением нилов, вернет длину до первого нила. Это по документации было На практике по-другому функции table.insert, table.getn, table.remove и прочие полагают, что таблица используется как массив, то есть ключом является целое число, в значениях ключа нет пропусков. table.getn Вот ее код на луа(взято с http://luagml.ucoz.ru/doc/lua/c5.html): function getn (t) if type(t.n) == "number" then return t.n end local max = 0 for i, _ in t do if type(i) == "number" and i>max then max=i end end return max end Видно, что возвращается значение n, если оно число или перебираются все элементы и возвращается максимальное значение ключа-числа. Длина таблицы n из скрипта не доступна, то есть получить значение t.n нельзя, но она есть. table.insert Код: function tinsert (t, ...) local pos, value local n = getn(t) if arg.n == 1 then pos, value = n+1, arg[1] else pos, value = arg[1], arg[2] end t.n = n+1; for i=n,pos,-1 do t[i+1] = t[i] end t[pos] = value end При вставке в середину сдвигает хвост и увеличивает внутреннюю длину таблицы n table.remove function tremove (t, pos) local n = getn(t) if n<=0 then return end pos = pos or n local value = t[pos] for i=pos,n-1 do t[i] = t[i+1] end t[n] = nil t.n = n-1 return value end При удалении элемента, оставшиеся сдвигаются, чтобы не было пробелов. И уменьшает внутренню длину таблицы n Я привел псевдокод, чтобы было видно, что эти функции не просто тормозные и глючные версии функций вставки, удаления. Они работают в предположении, что таблица это массив и сохраняют это. При замене функций на что-то другое это надо учитывать Изменено 12 Июля 2010 пользователем Kolmogor Ссылка на комментарий
Рекомендуемые сообщения