PDA

Просмотр полной версии : Языковой модуль


MerlinTwi
25.08.2006, 15:31
Хочу обсудить организацию многоязычной программы. Допустим html страницы будут разные, и теге вызова флешки прописан язык test.swf?language=ru
Флешка первым делом подгружает файл с указанным языком и далее везде, где выводится текст идет обращение к глобальной переменной, в которой и хранятся тексты.

Как я это делал в AS2:
Языковой файл lang_ru.fla
#include "lang_ru.as"
lang_ru.as выглядит так:
_global.LANG = {
YES:"ДА",
NO:"НЕТ",
. . .
};
В основной флешке для вывода текста
trace(LANG.YES);
Так же это нормально работает и в подгружаемых модулях.
Лучше делать swf, чем подгружать чистый текст или XML, т.к. swf за счет сжатия получается в 5 раз меньше.

Как же поступить в AS3 ?
Вариант 1.
package {
import flash.display.MovieClip;
public class LANG extends MovieClip {
static public const YES:String = "ДА";
static public const NO:String = "НЕТ";
}}
В принципе работает, вот только размер swf файла почему-то получается примерно в 2 раза больше, чем в варианте для AS2. Неудобно, что слишком много лишнего текста static public const ... :String

Вариант 2.
Воспользоваться встроенной в AS3 поддержкой XML:
public class LANG extends MovieClip {
static public var texts:XML = <RU
YES="ДА"
NO="НЕТ"
/>;
}
Обращаться к тексту придется
trace(LANG.texts.@NO);
Лишние .text.@, что несмертельно, но файл в 215кб. текста компилируется очень долго. Если вариант для AS2 компиляция за 2сек., то вариант с XML около 2-х минут. При этом, если в тексте есть ошибка, незакрытая кавычка к примеру, то найти ее нереально, компилятор ничего не говорит о строчке, только ругается:
TypeError: Error #1090: XML parser failure: element is malformed.

Вариант 3.
Переделка второго, вместо XML делаем Object.
public class LANG extends MovieClip {
static public const texts:Object = {
YES:"ДА",
NO:"НЕТ",
}
}
Обращаться к тексту придется
trace(LANG.texts.NO);
Так же нормально работает.

Что выбрать? Может есть еще варианты?

etc
25.08.2006, 15:41
Хранить обе версии текстов в XML и иметь возможность смены всех текстов налету.

ALiEN2006
25.08.2006, 16:40
А можно еще вот так:

package {
import flash.display.MovieClip;
public class a extends MovieClip {
public var YES:String = "ДА";
public var NO:String = "НЕТ";

}
}

Тогда что бы прочитать значения надо сделать так:

LANG = new a();
trace(LANG.YES);

Nirth
25.08.2006, 17:06
ALiEn2006
дам вам совет который поможет вам в будущем, если вы продолжите кодить в таком же стиле, то когда объем вышего кода начнет превышать 40 строк, никто туда даже не заглянет, почитайте про стилистику ActionScript, в кратце
методы начинаются с маленькой буквы, каждое будущее слово с прописной ( myMethod), свойства аналогично.

приватные переменные имена которых совпадают с свойствами иногда начинают с двух подчеркиваний
(__value)

классы с пропписной буквы - MySuperClass всегда.

Константы - все прописные буквы, разделяется символом нижнего подчеркивания - MY_CONSTANT, в ActionScrpt для констант используется слово const

publis static const MY_CONSTANT

ALiEN2006
25.08.2006, 18:29
Nirth, спасибо за совет. Но есть разные стили написания.

etc
25.08.2006, 18:35
Nirth, спасибо за совет. Но есть разные стили написания.
Есть стили, а есть стандарты. Твой код -- стиль написания, к тому же компилятор, увидев такой код, не даст его скомпилировать.

Nirth
25.08.2006, 18:53
Есть стиль признаный ActionScript Сommunity и Adobe Corp.
если ты его не придерживаешься ( а так делают многие скажем С++ программисты которые привыкли к другому стилю) должен быть готов к тому, что другие люди могут просто ленится разбиратся в твоем коде ( например такие как я =)

в этом нет ничего критического.

ALiEN2006
25.08.2006, 19:18
Есть стили, а есть стандарты. Твой код -- стиль написания, к тому же компилятор, увидев такой код, не даст его скомпилировать.

Этот код легко компилируется, не понимаю, о чем ты говоришь.

package {
import flash.display.MovieClip;
public class a extends MovieClip {
public var YES:String = "ДА";
public var NO:String = "НЕТ";

}
}

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

etc
25.08.2006, 19:47
Компилятор должен был сказать, что имя класса должно начинаться с прописной буквы.

ALiEN2006
25.08.2006, 20:00
В окно вывело только - ДА.

etc
25.08.2006, 20:16
Тем не менее, называть классы со строчной буквы недопустимо.

MerlinTwi
25.08.2006, 20:40
Хранить обе версии текстов в XML и иметь возможность смены всех текстов налету.
XML хорошо в случае когда текстов мало. Если их под 300кб, а в .swf это 45кб., то разница существенна.
Возможность переключать язык на лету, это круто, но применительно к жизни, не вижу смысла.

А можно еще вот так:

package {
import flash.display.MovieClip;
public class a extends MovieClip {
public var YES:String = "ДА";
public var NO:String = "НЕТ";

}
}
Это тот же вариант 1, вид сбоку.

Тогда что бы прочитать значения надо сделать так:

LANG = new a();
trace(LANG.YES);
А вот делать еще одну копию класса "a"... не вижу смысла. Это пустая растрата оперативной памяти. Пусть уж будут все как static.

etc
25.08.2006, 20:43
XML хорошо в случае когда текстов мало. Если их под 300кб
Никто не мешает разбить их на отдельные xml-ки для подразделов.
Забивать железно во флэш текст, который в 80% случаев потребуется редактировать не стоит, хотя бы потому что править постоянно флэш -- трата времени.

MerlinTwi
25.08.2006, 21:22
Редактируется все равно текстовый файл, а нажать Ctrl+Enter не составляет большого труда, никто в shell-е редактировать языковой модуль на сервере не будет.
А представление текстов .swf еще и спасает от банальных опечаток. Если в xml забыть поставить закрывающую скобку, то флэш просто проигнорирует кусок текста, а при компиляции получишь сообщение об ошибке.
Кроме того, парсинг большого XML файла ресурсоемкая задача.
Но не будем разводить полемику, повторюсь, вариант в XML хорош, но для малого объема текста. Хотелось бы услышать, какие еще возможны варианты в этом вопросе.

etc
25.08.2006, 21:30
MerlinTwi, тебе, может и не составляет большого труда, а кому-нибудь надо будет отредактировать текст и будут тебя дёргать.

Вариант с XML хорош всегда и единственный, когда необходимо сделать локализацию чего-либо. Локализовать на третий язык одной лишь правкой XML гораздо проще, чем ковырять флэш.

Например, есть вот такой XML: http://www.bbk-dvd.ru/f/1/demo/screen_data.xml [http://www.bbk-dvd.ru/demo/]
Отредактировав его, можно добавить любое количество языков.
Разбить на части, при большом количестве текста также легко.
Я уж не говорю о том, что можно просто грузить разные XML, английский или русский.

FlexBuilder
29.08.2006, 16:04
2Nirth

приватные переменные имена которых совпадают с свойствами иногда начинают с двух подчеркиваний
(__value)


Не встречал в AS3 свойств начинающихся с подчеркиваний. Пишу приватные поля с одним подчеркиванием, (имхо так оно отныне и будет после перехода с AS2 на AS3), но если честно не встречал подробных документов по стилю, если кинешь ссылку, буду признателен.

Стиль я уважаю, но в приведенных выше постах


public class LANG extends MovieClip { ...
public class a extends MovieClip { ...


меня смущает вовсе не "LANG" и "a" вместо "Lang" и "A", а то, что следует после них, иными словами "extends MovieClip".
Слабо понятно, как приходит в голову наследоваться от MovieClip-а (хотя бы уж от DisplayObject-а если невтерпеж ;) ) а потом удивляться, что откуда-то берутся дикие килобайты.

А вообще по данной теме абсолютно солидарен с __etc. XML без вопросов.
(Единственный раз, когда мне пришлось делать извращение в духе

public final class MyData {
static public const DATA:XML = <data> ...

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

MerlinTwi
29.08.2006, 17:36
Слабо понятно, как приходит в голову наследоваться от MovieClip-а
В моем примере языковой модуль в отдельной .swf и класс LANG это root, а рутовым классом нельзя назначить что-то, что ниже Sprite.

TypeError: Error #2023: Class LANG$ must inherit from Sprite to link to the root.


А вообще по данной теме абсолютно солидарен с __etc. XML без вопросов.
Кстати, XML проигрывает не только по объему трафика, но и по быстродействию:

var i:Number,j:Number,s:String;
var texts:XML = <RU
YES="ДА"
NO="НЕТ"
/>;

s="";
i = getTimer();
for (j=0; j<100000; j++) {
s += texts.@YES;
s += texts.@NO;
}
trace("Test XML: "+(getTimer()-i));

var texts2:Object = {
YES:"ДА",
NO:"НЕТ"
};

s="";
i = getTimer();
for (j=0; j<100000; j++) {
s += texts2.YES;
s += texts2.NO;
}
trace("Test OBJECT: "+(getTimer()-i));

// Test XML: 375
// Test OBJECT: 67

Nirth
29.08.2006, 18:13
глупо очень глупо наследовать класс не от того что нужно.

XML удобен в первую очередь для программиста, да и не вижу проблем со скоростью, 200 миллисекунд разница? пусть даже 1 секунда, ты парсишь хмлку один раз, и потом работаешь с объектами.

FlexBuilder
29.08.2006, 18:50
В моем примере языковой модуль в отдельной .swf и класс LANG это root, а рутовым классом нельзя назначить что-то, что ниже Sprite.

Я так и понял, что ты собираешься подключать их динамически. Но во-первых спрайт все-таки полегче чем MovieClip, а во-вторых данные - не мувиклип, как не крути. Некрасиво это с точки зрения стиля, что им можно сделать gotoAndPlay(6)... Если уж хочется чтобы был подгружаемый swf я бы делал какой-нибудь языковой менеджер, наследуемый от того же спрайта, а он бы уже внутри импортил as-ки с public final class Lang. Но это все-таки не то. Раз уж и так подгружаешь что-то динамически, то XML по любому лучше.

PS Кстати если будешь зашивать большой XML (на несколько сот kb) в статическую константу - компиллятор может подавиться. Был такой опыт.

etc
29.08.2006, 18:53
MerlinTwi, тогда приготовься к тому, что тебя будут дёргать тебя каждый раз, когда потребуется что-то изменить в контенте.
Если тебя не устраивают рекомендации — не используй их, но тогда, в случае проблем, жаловаться не надо.