Bests práticas para textos localizados em aplicações multi-plataforma C ++?

StackOverflow https://stackoverflow.com/questions/403747

  •  03-07-2019
  •  | 
  •  

Pergunta

No atual padrão C ++ (C ++ 03), há muito poucas especificações sobre a localização de texto e que torna a vida do desenvolvedor de C ++ mais difícil do que o habitual quando se trabalha com textos localizadas (certamente o C ++ 0x padrão vai ajudar aqui mais tarde ).

Assumindo o seguinte cenário (que é a partir de casos reais de desenvolvimento de jogos PC-Mac):

  1. responsivo (tempo real) aplicação :. A aplicação tem que minimizar os tempos de não-responsivos para "não visível", assim que a velocidade de execução é importante
  2. localizado textos :. Textos apresentados são localizados em mais de duas línguas, potencialmente mais - não espere um número fixo de línguas, deve ser facilmente extensível
  3. linguagem definida em tempo de execução : os textos não devem ser compilados no aplicativo (nem ter uma aplicação por idioma), você recebe a informação idioma escolhido no lançamento aplicação - o que implica algum tipo de carregamento de texto .
  4. cross-platform : o aplicativo é ser codificado com multi-plataforma em mente (Windows - Linux / Ubuntu - Mac / OSX) para que o sistema texto localizado tem que ser multiplataforma demasiado
  5. aplicação stand-alone : o aplicativo fornece tudo que é necessário para executá-lo; ele não vai usar qualquer biblioteca ambiente ou exigir que o usuário instale outra coisa senão o sistema operacional (como a maioria dos jogos, por exemplo).

Quais são as melhores práticas para gerenciar textos localizados em C ++ neste tipo de aplicação?

Eu olhei para isso ano passado que e as únicas coisas que eu tenho certeza é que você deve usar std::wstring ou std::basic_string<ABigEnoughType> para manipular os textos na aplicação. Parei minha pesquisa porque eu estava trabalhando mais sobre o problema "texto do visor" (no caso de 3D em tempo real), mas eu acho que existem algumas das melhores práticas para gerenciar textos localizadas em matéria C ++ além de apenas que e "uso Unicode" .

Assim, todas as melhores práticas, sugestões e informações (cross-platform torna difícil eu acho) são bem-vindos!

Foi útil?

Solução

Em uma pequena Video Game Company, Black Lantern Studios, eu era o principal desenvolvedor de um jogo chamado trens Lionel DS. Nós localizada em Inglês, espanhol, francês e alemão. Sabíamos todas as línguas na frente, então incluí-los em tempo de compilação era a única opção. (Eles são queimados a uma ROM, você vê)

Eu posso dar-lhe informações sobre algumas das coisas que fizemos. Nossas cordas foram carregados em uma matriz na inicialização com base na seleção de idioma do jogador. Cada linguagem individual entrou em um arquivo separado com todas as cordas na mesma ordem. Cordas 1 sempre foi o título do jogo, corda 2 sempre a primeira opção do menu, e assim por diante. Nós chaveado as matrizes fora de um enum, como indexação integer é muito rápido, e em jogos, a velocidade é tudo. (A solução de ligado numa das outras pesquisas de respostas usos string, que gostaria tendem a evitar.) Quando visualizadas as cordas, utilizou-se uma função de tipo printf() para substituir marcadores com valores. " Train 3 está partindo da cidade 1. "

Agora, para algumas das armadilhas.

1) entre as línguas, a fim frase é completamente diferente. " Train 3 está partindo da cidade 1. " traduzido para o alemão e extremidades traseiras por ser " From City 1, Train 3 está partindo ". Se você estiver usando algo como printf() e sua seqüência é " Train% d está partindo da cidade% d. ", o alemão vai acabar dizendo " From City 3, Train 1 está partindo. " que é completamente errado. Nós resolvemos este forçando a tradução para manter a mesma ordem de palavras, mas acabamos com um pouco de alemão muito quebrado. Se eu fosse fazer isso de novo, eu iria escrever uma função que leva a corda e uma matriz baseada em zero dos valores que colocar nele. Então utilizava como marcadores %0 e %1, basicamente incorporar o índice de matriz na cadeia. Update: @ Jonathan Leffler apontou que um printf() suportes compatíveis com POSIX utilizando marcadores do tipo %2$s onde a porção 2$ instrui o printf() para preencher esse marcador com o segundo parâmetro adicional. Isso seria bastante útil, contanto que é rápido o suficiente. Uma solução personalizada pode ainda ser mais rápido, então você vai querer certificar-se e testar ambos.

2) Idiomas variam muito em comprimento. Qual foi a 30 caracteres em Inglês saiu às vezes tanto quanto 110 caracteres em alemão. Isto significava que muitas vezes não se encaixam as telas que foram colocá-lo. Esta é provavelmente uma preocupação menor para os jogos de PC / Mac, mas se você estiver fazendo qualquer trabalho onde o texto deve caber em uma caixa definida, você vai querer considerar isso. Para resolver este problema, nós despojado como muitos adjetivos de nosso texto quanto possível para outros idiomas. Isso encurtou a frase, mas preservou o significado, se perder um pouco do sabor. Mais tarde projetado um aplicativo que poderíamos usar que conteria a fonte e o tamanho da caixa e permitir que os tradutores para fazer suas próprias modificações para obter o ajuste de texto na caixa. Não tenho certeza se eles já implementou. Você também pode considerar ter áreas de rolagem de texto, se você tem esse problema.

3) Quanto multiplataforma vai, nós escreveu praticamente puro C ++ para o nosso sistema de localização. Nós escrevemos costume codificado arquivos binários para carga e um programa personalizado para converter de um arquivo CSV de texto no idioma em um .h com a enumeração e arquivo a língua mapa, e uma .lang para cada idioma. O mais coisa plataforma específica que usamos foi as fontes e a função printf(), mas você terá algo apropriado para onde quer que você está desenvolvendo, ou pode escrever seu próprio, se necessário.

Outras dicas

GNU Gettext faz tudo.

Eu discordo fortemente com a resposta aceita. Primeiro, a parte sobre o uso pesquisas matriz estáticos para acelerar as pesquisas de texto meramente mostra que a pessoa que faz a otimização é muito inexperiente - Calcular o layout para o referido texto e renderização referido texto usa 2-4 ordens de magnitude mais tempo do que uma pesquisa de hash. Se alguém queria implementar a sua própria biblioteca de linguagem que ele nunca deve ser baseado em matrizes estáticas.

Mas isso não é realmente relevante, porque escrever sua própria biblioteca de linguagem para uso em seu próprio jogo é ainda pior de otimização prematura inútil. Há alguns extremamente boas razões para nunca escrever sua própria biblioteca de localização :

  1. Planning o momento de usar uma biblioteca de localização é muito mais fácil, em seguida, planejar o tempo para escrever uma biblioteca de localização. existem bibliotecas de localização, eles trabalham, e muitas pessoas têm usado-los.

  2. A localização é complicado, então você vai ter coisas erradas. Toda linguagem acrescenta uma nova peculiaridade, o que significa que sempre que você adicionar um novo idioma a sua própria biblioteca homegrown localização você precisará alterar o código novamente para explicar as peculiaridades. Você sabia que algumas línguas têm mais de 2 formas plurais, dependendo do número de itens em questão? Mais de 2 sexos (mais de 10, mesmo)? Além disso, o número ea data formatos variam muito entre diferentes em muitos idiomas.

  3. Quando o aplicativo se torna bem sucedido você vai querer suporte add para mais línguas. Línguas ninguém em sua equipe fala fluentemente. Contratar alguém para escrever uma tradução será consideravelmente mais barato se eles já sabem as ferramentas que eles estão trabalhando.

Um muito conhecido e biblioteca localização completa é GNU Gettext , que utiliza a GPL, pelo que deve ser evitada para o trabalho comercial. em vez disso você pode usar a biblioteca de impulso boost.locale que trabalha com arquivos Gettext, e está livre para usar e modificar para projetos comerciais e não-comerciais de qualquer tipo.

Não haverá quaisquer recursos adicionais no padrão C ++ 0x, tanto quanto eu posso dizer. Eu suspeito que o Comité considera este um assunto para bibliotecas de terceiros.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top