Тексты в одном месте. -
Stepashka - 28.03.2012
По
просьбе трудящихся описываю свой метод хранения текстов на сервере.
"Все гениальное просто." © Геббельс
Предыстория.
Была поставлена задача:
- создать простую систему текстов
- которая бы не являлась набором функций
- была наглядно понятна
- имела возможность легкого перевода на любой язык
- легко определялся смысл текста внутри кода
- высокая скорость работы
Идеи...
Была куча идей по реализации, но практически во всех идеях возникали свои недостатки. Основной проблемой была скорость, следующей по значимости была проблема переводов, и наконец немаловажная проблема наглядности и читаемости текстов, сюда же попадает и простота редактирования.
Реализация.
Долго думая и оценивая все системы, я пришел к одному мнения, точнее не я пришел, а пришли до меня, просто я понял что оно мне подходит. А именно, идею я почерпнул, как ни странно звучит, в
Joomla. У неё была сделана гениальная и до ужаса простейшая система хранения всех шаблонных фраз.
Структура до боли простая, это массив строк, ключ это короткий текст на английском языке в верхнем регистре, значение искомый текст. Для мультиязычности добавлен ещё один уровень, ключи в котором банальные цифры.
Итак что же получилось в итоге:
pawn Код:
#define DEFAULT_LANGUAGE 0
#define LANGUAGE_RU 0
#define LANGUAGE_EN 1
enum languageDataEnum
{
HELLO_WORLD[16],
TEST[8],
}
new languageData[][languageDataEnum] = {
{
"~g~Привет мир",
"-Тест-"
},
{
"~g~Hello world!",
"-Test-"
}
};
Данный код у меня в отдельном инклуде, и я всегда его могу редактировать и расширять не думая о поиски текстов в коде.
Обращение к тестам до неприличного просто:
pawn Код:
GameTextForPlayer(playerid, languageData[DEFAULT_LANGUAGE][HELLO_WORLD], 4000, 1);
print(languageData[LANGUAGE_EN][TEST]);
Я думаю многие скажут что рано или поздно массив разрастется до чудовищных размеров и компилятор начнет ругаться. Согласен, но с другой стороны, чтение тестов из файла или мускула - медленно. Хардкодить тексты это гарантированно отказываться от переводов, если конечно не изобретать дублирующий код, и мучится последующим поиском и редактированием. А если учесть что работа с памятью, для серверной машины, не составляет никакого труда, то я решил пренебречь размером занимаемой памяти.
PS если вам не нужны переводы удалите первый уровень массива.
Re: Тексты в одном месте. -
EvgeN 1137 - 28.03.2012
Quote:
массив разрастется до чудовищных размеров и компилятор начнет ругаться
|
да и фиг с ним, можно и новый создать
Re: Тексты в одном месте. -
jhonyxakep - 29.03.2012
Хмм.. А я для целей перевода использовал ini файлы. На мой взгляд это удобнее: можно и поменять что-то во время работы сервера, и языки легко добавлять. Просто создаем несколько ini и храним названия файлов для языков.
Единственное: Меня ВСЕ ini ридеры разочаровали. Глючили почти на каждой строке с киррилицей.
Re: Тексты в одном месте. -
OKStyle - 29.03.2012
Да эт фигня. У меня в древних мультиязычных модах почти так же, только без enum (и без фиксированного размера, поэтому добавление новых языков и текстов становится легче лёгкого). Я думал, что ты напишешь как подключать файлы, а не инклюды (например, .lng), чтобы производить чтение из них.
Re: Тексты в одном месте. -
Stepashka - 29.03.2012
Quote:
Originally Posted by OKStyle
Да эт фигня. У меня в древних мультиязычных модах почти так же, только без enum (и без фиксированного размера, поэтому добавление новых языков и текстов становится легче лёгкого). Я думал, что ты напишешь как подключать файлы, а не инклюды (например, .lng), чтобы производить чтение из них.
|
чтение файлов очень медленно и не надежно, к тому же размер массива нужно задавать заранее, а для меня это неприемлемо.
Re: Тексты в одном месте. -
EvgeN 1137 - 29.03.2012
Quote:
Originally Posted by OKStyle
Я думал, что ты напишешь как подключать файлы, а не инклюды (например, .lng), чтобы производить чтение из них.
|
https://sampforum.blast.hk/showthread.php?tid=295580
Re: Тексты в одном месте. -
OKStyle - 29.03.2012
Quote:
Originally Posted by Stepashka
чтение файлов очень медленно и не надежно, к тому же размер массива нужно задавать заранее, а для меня это неприемлемо.
|
Не нужно ничего задавать: Languages[][][].
Quote:
Originally Posted by EvgeN 1137
|
Слишком сложно и беспонтово.
Re: Тексты в одном месте. -
Stepashka - 29.03.2012
Quote:
Originally Posted by OKStyle
Не нужно ничего задавать: Languages[][][].
|
не удовлетворяет требованию читаемости внутри кода.
Re: Тексты в одном месте. -
eakwarp - 29.03.2012
Идея мне нравится, а размером массива можно смело пренебречь, если ориентироваться на процессорную оптимизацию. Спасибо.
Re: Тексты в одном месте. -
jhonyxakep - 29.03.2012
Quote:
чтение файлов очень медленно и не надежно, к тому же размер массива нужно задавать заранее, а для меня это неприемлемо.
|
1. Никто не просит каждый раз читать с файла.
2. Ненадежно, да?
3. И причем тут размер массива?
Re: Тексты в одном месте. -
Stepashka - 29.03.2012
Quote:
Originally Posted by jhonyxakep
1. Никто не просит каждый раз читать с файла.
2. Ненадежно, да?
3. И причем тут размер массива?
|
я изменил текст мне нужно заставить сервер обновить тексты, считай на время обновления весь сервер `встал`.
Нет, одна ошибка в файле и все тексты `едут`.
Даже если массив пустой он занимает весь свой размер. При добавлении строки в файле мне нужно увеливичать размер массива.
Re: Тексты в одном месте. -
jhonyxakep - 29.03.2012
Quote:
я изменил текст мне нужно заставить сервер обновить тексты, считай на время обновления весь сервер `встал`.
|
Скорость чтения с файла не так уж мала. Да и что вам мешает использовать SQL БД?
Quote:
Нет, одна ошибка в файле и все тексты `едут`.
|
Что мешает разработать свой формат хранения, при котором тексты не "поедут"?
Quote:
Даже если массив пустой он занимает весь свой размер. При добавлении строки в файле мне нужно увеливичать размер массива.
|
Динамика, не?
Re: Тексты в одном месте. -
Stepashka - 29.03.2012
Quote:
Originally Posted by jhonyxakep
Скорость чтения с файла не так уж мала. Да и что вам мешает использовать SQL БД?
|
а если текстов сотни, я думаю даже в GF сотня наберется.
При использовании SQL можно забыть про наглядность и простоту редактирования.
Quote:
Originally Posted by jhonyxakep
Что мешает разработать свой формат хранения, при котором тексты не "поедут"?
|
нет желания изобретать велосипед. И какое решение вы можете предложить против лишнего символа переноса строки?
Quote:
Originally Posted by jhonyxakep
Динамика, не?
|
что простите, где это вы видели в
pawn динамические массивы?
Re: Тексты в одном месте. -
jhonyxakep - 29.03.2012
Quote:
Зачем изобретать велосипед? И какое решение вы можете предложить против лишнего символа переноса строки?
|
ini,json,xml...
Quote:
При использовании SQL можно забыть про наглядность и простоту редактирования.
|
По моему при использовании SQL простота редактирования умножится в несколько десятков раз.
Quote:
что простите, где это вы видели в pawn динамические массивы?
|
Кхм... И в правду. Только не путайте pawn с SA:MP pawn. В обычном pawn уже давно есть динамические массивы.
Re: Тексты в одном месте. -
Mutha_X - 29.03.2012
Что если использовать gvar плагин, можно было бы SetGVarString(name[], text[], id), где имя - ключевое имя, текст-текст, а ид - номер языка?
Тексты, как уже сказали, можно загружать из файла(1 раз - при старте).
jhonyxakep
Не мысли узко, символ перевода на новую строку просто обходится. Но для этого нужно работать с бинарным потоком.
Тогда условная строка будет иметь такую форму:
2байта - на указание длины ключа(x)|4 байта - на длину текста(y)|2байта - на номер языка или на его короткое название|x байт на ключ|y байт на строку.
Знак | здесь только для визуального разделения разделов, но и можно на него потратиться, только нужно будет прочитать лишние байты.
Принцип - читает первые 8 байт(длина постоянная) > получаем в 3 переменных предварительные данные > читаем последовательно нужное кол-во байт для ключа и текста.
Problem?
Re: Тексты в одном месте. -
Stepashka - 29.03.2012
Quote:
Originally Posted by jhonyxakep
ini,json,xml...
|
т.е. использовать ещё какое-то решение для чтения всего этого, спасибо не надо.
Quote:
Originally Posted by jhonyxakep
По моему при использовании SQL простота редактирования умножится в несколько десятков раз.
|
Т.е. создание методов для хранения и изменения этих данных, зачем, эти тексты константы, они создаются один раз при разработке и редактируются при обновлениях. А о возможности редактирования SQL данных средствами блокнота, извините тот ещё гемор.
Quote:
Originally Posted by Mutha_X
Что если использовать gvar плагин, можно было бы SetGVarString(name[], text[], id), где имя - ключевое имя, текст-текст, а ид - номер языка?
Тексты, как уже сказали, можно загружать из файла(1 раз - при старте).
Stepashka
Не мысли узко, символ перевода на новую строку просто обходится. Но для этого нужно работать с бинарным потоком.
Тогда условная строка будет иметь такую форму:
2байта - на указание длины ключа(x)|4 байта - на длину текста(y)|2байта - на номер языка или на его короткое название|x байт на ключ|y байт на строку.
Знак | здесь только для визуального разделения разделов, но и можно на него потратиться, только нужно будет прочитать лишние байты.
Принцип - читает первые 8 байт(длина постоянная) > получаем в 3 переменных предварительные данные > читаем последовательно нужное кол-во байт для ключа и текста.
Problem?
|
вы прежде чем так много писать и говорить людям как им мыслить читайте поставленные задачи.
И кстати ваше решение это что-то из серии запрячь карету мулами.
Re: Тексты в одном месте. -
jhonyxakep - 29.03.2012
Quote:
И кстати ваше решение это что-то из серии запрячь карету мулами.
|
И ничего, что на принципе файловых потоков работают все файлы подкачки, tempы, и многие программные продукты хранят информацию именно в таком виде?
Quote:
Не мысли узко, символ перевода на новую строку просто обходится. Но для этого нужно работать с бинарным потоком.
Тогда условная строка будет иметь такую форму:
|
Я ведь тоже простоту интерпретации использовать пытался =) Хотя не вижу ничего сложного в такой системе.
Quote:
А о возможности редактирования SQL данных средствами блокнота я ещё не слышал.
|
А я не про блокнот. Вот в блокноте вы не сможете отсеять строки по каким либо критериям, да и вообще SQL позволяет все операции проводить быстрее и безопаснее.
Quote:
Что если использовать gvar плагин, можно было бы SetGVarString(name[], text[], id), где имя - ключевое имя, текст-текст, а ид - номер языка?
|
XD а можно использовать PVar и привязывать язык к каждому пользователю.
Re: Тексты в одном месте. -
Stepashka - 29.03.2012
Из вас двоих кто-нибудь вообще читал поставленные задачи?
Re: Тексты в одном месте. -
Mutha_X - 29.03.2012
Ты уверен что существует, ещё один путь с такими задачами и такой, что лучше твоего? Мы тоже, вот тебе альтернативы на довольствие)
Re: Тексты в одном месте. -
OKStyle - 29.03.2012
Quote:
Originally Posted by Stepashka
не удовлетворяет требованию читаемости внутри кода.
|
pawn Код:
SendClientMessage(playerid, COLOR, Languages[PlayerLanguage[playerid]][0][ROW]);
Нечитаемо?