Перейти к контенту

Рекомендуемые сообщения

@dsh, могут появиться проблемы с внутренним пониманием данных.

При глобально включённом парсинге кастом дата хранится в таблице. Допустим, сырую строку, заданную методом setStringRaw, можно записывать в отдельное свойство. А как писать в нет-пакет? Приоритет сырой строки или таблицы? Или конкатенация того и другого?

Обратная ситуация с чтением из нет-пакета строки. По каким критериям модуль должен решить, что парсить в таблицу, а что оставить в виде строки (если вообще что-то следует оставлять)?

 

ЗЫ: Не переместиться ли нам вместе с несколькими вышенаписанными постами в "скриптование"?

 

 

Рабочее предложение такое:

При чтении из нет-пакета (при глобально включённом парсинге) кастом дата всегда пишется как в таблицу, так и, полной неизменной строкой, в дополнительное свойство.

Метод getStringRaw (или прямой обращение к доп. свойству, скажем ) в таком случае будет возвращать полную строку, а метод getString - строку, полученную из таблицы.

При штатной записи в нет-пакет будет попадать строка, также полученная из таблицы.

Таким образом, работа с нет-пакетом пользователей, привыкших к старой версии модуля, не изменится.

Если ты хочешь записать в кастом дату что-то особенное, используешь метод setStringRaw - в доп. свойство попадает нужная тебе строка, одновременно устанавливается флаг. При записи нет-пакета и наличии этого флага таблица будет игнорироваться, а строка будет писаться из доп. свойства.
Этот же флаг можно взводить вручную для конкретного пакета (например, ещё одним добавленным методом useStringRaw), если кастом дату ты изменять не собираешься, но знаешь, что там могут быть нетипичные данные. Но делать это надо будет при каждом изменении такого нет-пакета и это будет на совести скриптёра. Иначе - в нет-пакет опять пойдет строка, полученная из таблицы.

 

Какие будут мнения?

Изменено пользователем Kirgudu
Ссылка на комментарий
@Kirgudu, да, что-то такое мне и виделось. Другой вариант, это хранить в свойствах сырую строку и в нетпакет всегда записывать ее, а getString() и getTable() бы ее парсили налету и возвращали бы результат, как это есть сейчас. setString() и setTable() бы делали обратную операцию и меняли бы сохраненную сырую строку. Этот вариант мне кажется хоть и более красивым, но более сложным, а значит и более вероятно появление новых граблей, по которым кому-то придется пройти и исправить. Т.ч. я за более простой вариант.
Ссылка на комментарий

@dsh, накидал версию для теста: http://rgho.st/8mRrl2nnz

Конфиг не менялся, здесь только скрипт. Сам проверить не могу, если только в неопределённом будущем.

 

Спецификации такие (примем local cd = data.custom_data в уже прочтённом нет-пакете):

cd:setTable(tbl) - таблицу записывает в свойство-таблицу как и раньше; генерирует строку по этой таблице (сырая строка перезаписывается) и записывает в новое свойство; устанавливает приоритет записи по таблице.

cd:setString(str) - парсит строку в таблицу и записывает в привычное свойство-таблицу как и раньше; записывает эту же строку в новое свойство как есть; устанавливает приоритет записи по таблице.

cd:setStringRaw(str) - таблицу не трогает; записывает строку в новое свойство как есть; устанавливает приоритет записи по сырой строке.

cd:getTable() - возвращает таблицу из свойства-таблицы как и раньше.
cd:getString() - возвращает генерированную строку из свойства-таблицы как и раньше;

cd:getStringRaw() - возвращает текущую сырую строку из нового свойства;

cd:useStringRaw(mode) - если mode имеет значение типа boolean - принудительно устанавливает режим приоритета сырой строки (true) или таблицы (false), в противном случае просто возвращает текущий режим.

 

ИМХО, все необходимые случаи учтены. Сразу после прочтения нет-пакета имеем как нормализованную таблицу, так и сырую строку, содержащую в том числе нетипичные данные. Если хотим работать с форматом ini - используем старые методы, они в этом плане не поменялись. Если хотим работать с сырой строкой - используем новые. Установка кастом даты одним из старых методов автоматически перезаписывает сырую строку с целью её нормализации (и чтобы не мучиться с соединением разных типов) и устанавливает приоритет ini. Установка кастом даты новым методом нормализованные данные не меняет, а меняет только сырую строку, и устанавливает приоритет сырой строки. Если с кастом датой работать не нужно, но есть подозрение, что там могут быть не стандартные данные, перед записью нет-пакета следует принудительно установить режим приоритета строки методом useStringRaw. В противном случае можно ничего не устанавливать, а пользоваться как и раньше.

 

Правки сделаны в районе строк 202-269 и 538-550 - это если сам захочешь внести свою лепту.

Если ошибок не обнаружится, описание новой возможности причешу и обновлю скрипт в опубликованных мной комплектах.

Изменено пользователем Kirgudu
Ссылка на комментарий

@Kirgudu, выглядит вроде нормально, только я бы вместо вот этого изменения

-		pk:w_stringZ(val:getString()) --/< from helpers
+		if val:useStringRaw() then
+			pk:w_stringZ(val:getStringRaw()) --/< from helpers
+		else
+			pk:w_stringZ(val:getString()) --/< from helpers
+		end

эту проверку бы делал в getString()

function custom_data:getString()
	return self:useStringRaw() and self:getStringRaw() or _fill_custom_data(self.data) --/>
end

Мне кажется, что это внутреннее дело custom_data и другим знать об этом не обязательно.

Ссылка на комментарий

@dsh, я думал об этом, но сознательно сделал именно так.

Дело в том, что я хотел не только добавить новую возможность, но также для тех людей, у которых модуль давным-давно используется, оставить его работу строго такой же, какой она была до того.

Если в каком-либо моде для каких-либо целей используется метод getString() и ожидается, что он возвращает очищенные от неканонических значений данные - он должен делать это и впредь. А это значит, что проверку флага таки надо выносить в сохранение нет-пакета.

Не думаю, что это так уж плохо. Да и обращаюсь я не к флагу напрямую, а вызываю публичный метод класса; другие методы и так уже вызываются там же.

 

Проверь по возможности в игре, плз. Я уже давно пишу скрипты "вслепую". И хотя явных ошибок не видно, лучше всё-таки перебдеть.

Ссылка на комментарий

он должен делать это и впредь

Так он и продолжит так делать, пока этот кто-то, сознательно, не установит соотв. флаг.

Проверь по возможности в игре

Проверю, но только искусственно, в синтетических ситуациях. В самом моде использовать не буду. Мне хватило пробежки по граблям в прошлый раз. :) Лучше я эту штуку больше трогать не буду.

Ссылка на комментарий

Мм... хорошо, скажем так: не хотелось менять действие имеющихся публичных методов. Ни просто так, ни в зависимости от добавленного флага. :)

Ссылка на комментарий

@Graff46,

[logic]\nactive = remark\n[remark]\nanim = guard\nmeet = default_meet

 

{
  ["logic"] = {
    ["active"] = "remark"
  },
  ["remark"] = {
    ["anim"] = "guard",
    ["meet"] = "default_meet"
  }
}

 

Аддон для ОП-2.09.2: Яндекс/Google/GitHub

naxac.gif

Ссылка на комментарий

@Kirgudu, по тестировал немного на контейнере с артефактом и на соляночном Акиме. Проблем не заметил, в обоих режимах работает.

Добавлено Kirgudu,

Ну и славно. Спасибо.

Если категорических возражений нет, завтра-послезавтра выложу обновлённые комплекты со своим вариантом реализации, без какого-либо изменения функционала старых методов.

Ссылка на комментарий

@Graff46, вот именно в виде такой таблицы возвращает кастом-дату метод :getTable(), о чём мы тут и говорим битых 2 страницы. :) Это удобно, но был недостаток в виде безальтернативной фильтрации "неправильных" данных, от которого мы теперь избавились.

 

Кстати, как и обещал, обновил описание m_netpk в соответствии с изменениями и выложил обновлённые комплекты. Всё, как и раньше, лежит здесь.

Изменено пользователем Kirgudu
Ссылка на комментарий

Нашел ошибку в m_netpk. Долго голову ломал, что за чудеса у меня иногда случаются, а оно вон где. Вот исправление: https://github.com/dsh2dsh/op2ogse/commit/87463b600f2cbd3d33677b08d1cfa15d5167811a

По диффу все понятно, я думаю. Посмотрите в соседнюю _w_uCTime.

 

И потоптавшись по этой ошибке я пришел к выводу, что нетпакеты смартов лучше не трогать. Там из-за того, что делается в :STATE_Read(), твориться жуть что.

Изменено пользователем dsh
  • Полезно 1
Ссылка на комментарий

Из тутора по m_netpk для работы с "абстрактными" пакетами:

	3) В метод STATE_Write (см. выше) добавить строку:
		function se_outfit:STATE_Write(packet)
			if self.cb_netpk then self.cb_netpk(self, packet) end -- коллбэк для изменения свойств пакета
			cse_alife_item_custom_outfit.STATE_Write(self, packet)
		end

Как я понял мы пишем состояние объекта в его же пакет. Если так, то зачем? У только созданного объекта "абстрактный" пакет пуст и мы его заполняем "вручную"? 

Если объект подергать по оффлайнам и онлайнам "абстрактный" пакет "соберётся"?

Ссылка на комментарий

Кстати, насчет:

Цитата

 

function se_outfit:STATE_Write(packet)

     if self.cb_netpk then

          self.cb_netpk(self, packet)

     end

     cse_alife_item_custom_outfit.STATE_Write(self, packet)

end

 

Если я правильно понимаю написанное выше, то cb_netpk должно быть членом класса(а судя по тому, что мы туда передаем два аргумента -то конкретно ф-цией класса) se_outfit ? Тогда зачем в ф-цию класса передавать сам объект класса ? Ведь внутри ф-ции мы его можем получить этим самым "self" ?

Ссылка на комментарий

@UnLoaded ты не обратил внимания, что там self.cb_netpk, а не self:cb_netpk, т.е. обращение к полю, а не вызов метода. В это поле содержится указатель на функцию, которая не имеет никакого отношения к этому классу. И этой функции передается объект и пакет, с которыми ей нужно что-то сделать.

Ссылка на комментарий

Вот пара функций к m_netpk.script

Скрытый текст

function myspawn (sct_obj, pos, lv, gv) -- имя секции объекта; позиция спавна (готовым вектором); левел вертекс; гейм вертекс
	local sobj = alife():create(sct_obj, pos, lv, gv)
	local pk = m_netpk.get(sobj)
	local data, sini, abs_tbl, abs_flag = pk:get(),  system_ini(), {}, false
	local out_tbl = {}
	if sini:section_exist(sct_obj) and pk:isOk() then get_console():execute("ok")
		for i=1, sini:line_count(sct_obj) do 
			local all_line, key, value = sini:r_line(sct_obj,i,"","") --get_console():execute(tostring(all_line).."__"..key.."__"..value)
			if string.sub(key, 0,5) == '&std.' then
				data[string.sub(key,6 ,-1)] = value
				--get_console():execute(string.sub(key,6 ,-1).."__"..value)
			elseif string.sub(key, 0,5) == '&upd.' then
				data.upd[string.sub(key,6 ,-1)] = value
				--get_console():execute('&upd.__'..string.sub(key,6 ,-1).."__"..value)
			elseif string.sub(key, 0,5) == '&abs.' then
				abs_flag = true
				abs_tbl[string.sub(key, 6, -1)] = value
			end
		end
		if abs_flag then
			abs_flag = false
			out_tbl[1] = pk:setCallback(abs_tbl)
		end
		out_tbl[1] = pk:set(data)
	end
	out_tbl[2] = sobj
	return out_tbl
end

function net_edit (obj, idx, tbl) -- желательно серверный объект; индекс получения пакета (как в pk:Get(obj, индекс) (см. инструкцию к m_netpk.script)); таблица = {свойство=значение}
	local pk = m_netpk.get(obj, idx)
	if idx and idx==0 then
		return pk:setCallback(tbl)
	else
		local data = pk:get()
		for k,v in pairs(tbl) do 
			data[k] = v
		end
		return pk:set(data)
	end
end

См

myspawn - (почти all.spawn на скриптах)

Скрытый текст

В ИНИ файле с секциями спавн объектов (часто это spawn_sections.ltx) укажите дополнительные поля для редактирования через нэт пакеты спавненного объекта. Поля должны быть такого вида


&префикс.имяНэтПакета = значение

Виды префиксов:

  • &std. - для state пакетов,
  • &upd. - для update пакетов,
  • &abs. - нет-пакет 'abstract';

Пример: 


[test]:stalker
$spawn = "respawn\esc_salaga_chast"
character_profile = esc_salaga
spec_rank = regular
community = military
custom_data = scripts\test.ltx
&std.visual_name = actors\hero\stalker_novice

 

net_edit - быстрое редактирование нэт-пакетов объекта.

*для работы с нет-пакетами вида 'abstract' - читайте инструкцию к m_netpk.script! 

Всё это будет включено в новую версию скрипта nt.script...

Изменено пользователем Graff46
Ошибки исправлял
Ссылка на комментарий

Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

Создать аккаунт

Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

Зарегистрировать новый аккаунт

Войти

Есть аккаунт? Войти.

Войти
  • Недавно просматривали   0 пользователей

    • Ни один зарегистрированный пользователь не просматривает эту страницу.
  • Куратор(ы) темы:

×
×
  • Создать...