Jump to content


Photo

Language Strings/dictionary-class


  • Please log in to reply
11 replies to this topic

#1 rincewind

rincewind

    Programming Department

  • Xenocide Programming Department
  • 541 posts

Posted 09 November 2004 - 07:23 AM

Hi,

another nice little design issue to think about:

Currently, we have the language-schema (pinned in this forum) for creating xml-based language-tables that map symbolic names to actual strings (e.g. ITEM_PLASMA_CANNON to Plasma Cannon in English or whatever else in other languages).

Now we somehow have to get this info into the applications. The simplest way is of course to simply load all language tables for the current language in a singleton class. They get put in a std::map and a simple method resolves them.

mytext = LanguageManager::instance().getString("ITEM_PLASMA_CANNON");

Another idea is to have a Dictionary class that can get instanciated several times and has a method loadLanguageTable to load one or more languageTables, so only the strings required for the current screen get loaded.
Btw, the XNet-Texts are somewhere else anyway, so no need to worry about this load of data.

So you would then go:
myDict = new Dictionary();
myDict->loadLanguageTable("itemnames.xml");
mytext = myDict->getString("ITEM_PLASMA_CANNON");


Another issue besides memory consumption is name conflicts, the first approach guarantees that strings are unique and nothing gets defined twice (since we can simply output a warning in the log or on screen if a name conflict is detected while loading).
The second approach might lead to several definitions of the same constant since it gets used in different screens and somehow loading the other screen's table doesn't make sense.

On name conflicts: should we maybe introduce some form of namespaces?

Well, this was what I came up with for now, personally, I favor the first approach. Please post your thoughts.

Greetings,

Rincewind

P.S: Any volunteers for implementation? I'll do it if nobody else is interested (I know it's not the most interesting mini-project)
Posted Image

I love boost!!! The next best thing since the invention of C++.

#2 red knight

red knight

    Xenocide Project Leader

  • Xenocide Inactive
  • 3,310 posts

Posted 10 November 2004 - 06:32 PM

Go for a singleton with an special method named "loadLanguageTable" ;) that would suit both requirements, you have a single point of loading (simplicity) and on the other side you can load other dictionaries if necesary.

Greetings
Red Knight

Edited by red knight, 10 November 2004 - 06:36 PM.

Sourceforge Nick: flois - Federico Andres Lois
Visit my blog at: flois.blogspot.com

Posted Image

Pookie cover me, I am going in.

#3 rincewind

rincewind

    Programming Department

  • Xenocide Programming Department
  • 541 posts

Posted 17 November 2004 - 06:38 AM

Hi,

ok, I coded the singleton variant, it's in xenoui, named Dictionary. Currently xenocidemain.cpp just laods the languagetable named data/languages/english.xml.

The most important method is resolveString(const String & symbolicName), it tries to find the givven string in the table, if it can find it, it returns the translated version, if not, the symbolicName is returned and a message is logged in dictionary.log under xenocidegame/system which should be helpful for translaters and while removing hardcoded strings.

I also wrote a small statuc utility function in UIManager called translateWindowTree(CEGUI::Window * window). It basicly traverses the widget tree under the given window and looks if any of these Widgets have a property called Text, if so, it tries to translate it and puts the replacement in there. Currently, the startscreen uses it already, just take a look at the code.

Another little thing that made it into the current CVS is a working model-view in the XNet. Since I didn't yet relate models to xnet-entries there's always the same model, but at least you can move it around, etc.
Since this uses Ogre's render-to-texture, coudl someone with an older graphics card confirm that their fallbacks work?

Thanks,

Rincewind
Posted Image

I love boost!!! The next best thing since the invention of C++.

#4 red knight

red knight

    Xenocide Project Leader

  • Xenocide Inactive
  • 3,310 posts

Posted 18 November 2004 - 08:11 PM

I can to test in a Radeon 9200, but attach a compiled (deployable) version... sadly this days I dont even have free time to log in... I try to take a look at the code when someone ask for an specific question, but I cant handle to update the whole environment to test it. I hope to get a little more time in the future, but now the most I can do is being a guide in the design. (Unless some company would want to pay me to work full time for Xenocide :P ).

Greetings
Red Knight
Sourceforge Nick: flois - Federico Andres Lois
Visit my blog at: flois.blogspot.com

Posted Image

Pookie cover me, I am going in.

#5 rincewind

rincewind

    Programming Department

  • Xenocide Programming Department
  • 541 posts

Posted 19 November 2004 - 01:03 AM

I can to test in a Radeon 9200, but attach a compiled (deployable) version... sadly this days I dont even have free time to log in...  I try to take a look at the code when someone ask for an specific question, but I cant handle to update the whole environment to test it. I hope to get a little more time in the future, but now the most I can do is being a guide in the design. (Unless some company would want to pay me to work full time for Xenocide :P ).

Greetings
Red Knight

<{POST_SNAPBACK}>


Here's a compiled version: http://www.framesys.de/~je/system.rar

Basicly, it's a zipped up xenocidegame/system dir, so just extract it there. You will also have to update the xenocidegame module from CVS in order to get the data.

Greetings,

Rincewind

Edited by rincewind, 19 November 2004 - 02:10 AM.

Posted Image

I love boost!!! The next best thing since the invention of C++.

#6 SupSuper

SupSuper

    Programming Department

  • Xenocide Programming Department
  • 2,418 posts

Posted 19 November 2004 - 06:55 PM

i tried compiling it myself and i get "c:\XenocideCVS\xenocide\src\client\ui\dictionary\dictionary.h(35): fatal error C1083: Cannot open include file: 'common/xmlutil/xmlutil.h': No such file or directory"

tried the pre-compiled version and it works fine, even with my old geforce2. i take it the model being untextured is intended.

too bad, now you will never know the ancient secrets of supsupers long gone avatar ;)

Posted Image


#7 rincewind

rincewind

    Programming Department

  • Xenocide Programming Department
  • 541 posts

Posted 20 November 2004 - 06:02 AM

i tried compiling it myself and i get "c:\XenocideCVS\xenocide\src\client\ui\dictionary\dictionary.h(35): fatal error C1083: Cannot open include file: 'common/xmlutil/xmlutil.h': No such file or directory"

tried the pre-compiled version and it works fine, even with my old geforce2. i take it the model being untextured is intended.

<{POST_SNAPBACK}>


Ups, I forgot to commit the xmlutil and also the textures for the model, should all be in there now.

Thanks for testing.

Rincewind
Posted Image

I love boost!!! The next best thing since the invention of C++.

#8 SupSuper

SupSuper

    Programming Department

  • Xenocide Programming Department
  • 2,418 posts

Posted 25 November 2004 - 09:43 AM

ok it builds in Debug config, but gives me lots of 'unresolved external' errors on Release config. mind telling me what libraries does it need?
next time commit the project files too :P

also, model still comes out untextured even with the texture files in place.

too bad, now you will never know the ancient secrets of supsupers long gone avatar ;)

Posted Image


#9 CptJackSparrow

CptJackSparrow

    Sergeant

  • Forum Members
  • PipPipPip
  • 52 posts

Posted 27 November 2004 - 07:16 AM

I know it's not the most interesting mini-project

Don't think of it as a mini-project, because translating text is extremely
complex and... lots of work... :wacko:
We do not only need to translate single vocables, but also overcome
grammatical differences.

E.g. whenever we're using dynamic text (e.g. add a city's name to a
predefined string) we must consider that word-order may be totally
different in another language, so where to put the name in
the translated string? Maybe this could be solved by using template
strings like "Aliens attack $1" and then calling getString with additional
parameters (think of printf()... ). Maybe there is a better solution...

Another example would be plural forms:
In english you just add an 's' in most cases, in german there
is no simple rule for plural and in other languages there are
even more than one plural form per word. A quote from the
GNUgettext documentation:

For example, Rafal Maszkowski <rzm@mat.uni.torun.pl> reports:

    In Polish we use e.g. plik (file) this way:
     

1 plik
2,3,4 pliki
5-21 pliko'w
22-24 pliki
25-31 pliko'w

    and so on (o' means 8859-2 oacute which should be rather okreska, similar to aogonek).


I've been missing for quite a few months and haven't read most of
the new posts (or even code), so "Sorry!" if I'm misunderstanding this
and there is no real problem at all... :rolleyes:

Greets

#10 Serge

Serge

    Project Leader: UFO 2000

  • Xenocide Programming Department
  • 785 posts

Posted 27 November 2004 - 09:35 AM

ok, I coded the singleton variant, it's in xenoui, named Dictionary. Currently xenocidemain.cpp just laods the languagetable named data/languages/english.xml.

The most important method is resolveString(const String & symbolicName), it tries to find the givven string in the table, if it can find it, it returns the translated version, if not, the symbolicName is returned and a message is logged in dictionary.log under xenocidegame/system which should be helpful for translaters and while removing hardcoded strings.

Using that symbolic names is not a very good idea. Just read gettext manual to find out its drawbacks and some interesting information about software internationalization: http://www.gnu.org/s...no/gettext.html

You can also read this http://wesnoth.slack.it/?GetText (it's all about the switch from home brewn internationalization support to gettext)

By the way, UFO2000 is using gettext for internationalization and it works just fine :)
ufo2000 development team
http://ufo2000.sourceforge.net

#11 rincewind

rincewind

    Programming Department

  • Xenocide Programming Department
  • 541 posts

Posted 28 November 2004 - 03:57 AM

Hi everybody,

@SupSuper: I think I committed the project files, but never tested the Release-build, I'm not at my development machine right now, so I can't check.
About the textures, they should show up, I'll also look into it.

@CptJackSparrow, Serge:
thanks for the input, I'm quite aware that translating the entire project is not easily done by simply excluding a couple of static strings. There's also not gone a lot of planning into the dictionary class, but I still think we need something like it.

Basicly, there are two areas of translation: The static labels, etc. found in xml-files for GUI-Layout, X-Net entries, Item-types, etc. These usually don't contain any dynamic part.
On the other hand, there are more or less programmatically constructed strings (e.g. "We detected an Scout/Harvester/... UFO near ...) found in the source-code.

I haven't dug too deep into gettext, but I think it's mainly suited to extract strings from C-sources and not from XML-Files (correct me if I'm wrong).

So what we definitly need is some more research into the language-area, what is needed (can we get away without parametrized strings? Remember we are not doing an RPG) what can be done with what tools and how to best provide them.

Any volunteers?

Greetings,

Rincewind
Posted Image

I love boost!!! The next best thing since the invention of C++.

#12 red knight

red knight

    Xenocide Project Leader

  • Xenocide Inactive
  • 3,310 posts

Posted 01 December 2004 - 01:24 PM

Rincewind, follow the KISS... do the simple thing and support English if over the road we have translators that want to do the job, lets find out the requirements and what we have to change... Up to now we cant know for sure if we ever gonna do it, and/or we dont have a linguist that can give us strict requirements. The IDictionary maybe is not the right name for the interface, it shouldnt be use word wise, but string wise. Dont bother with parametriced approach unless you find that you need it.

Serge: Thanks for the pointer to the internalization article. BTW it was you who contact me by ICQ 3 or 4 days ago?

Greetings
Red Knight
Sourceforge Nick: flois - Federico Andres Lois
Visit my blog at: flois.blogspot.com

Posted Image

Pookie cover me, I am going in.