Localization (Lokalisierung bzw. Übersetzung)
Übersicht

![]() |
JolinahBetreff: Localization (Lokalisierung bzw. Übersetzung) |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich habe ein kleines Modul zur Lokalisierung programmiert. Damit ist es ziemlich einfach ein Programm in mehreren Sprachen anzubieten. Angenommen man will eine Deutsche und eine Englische Version erstellen, dann macht man zunächst 2 Resource-Files mit folgendem Format:
example_de.txt Code: [AUSKLAPPEN] HELLO_WORLD = Hallo Welt!
example_en.txt Code: [AUSKLAPPEN] HELLO_WORLD = Hello world!
Diese kann man nun mit dem Modul auf unterschiedliche Art laden: Beispiel Code: [AUSKLAPPEN] SuperStrict
Import "Localization.bmx" 'Sprachen hinzufügen Localization.AddLanguages("de, en") 'Aktuelle Sprache wählen Localization.SetLanguage("de") 'Einzelne Resource-Datei öffnen (Nichts wird in den Speicher geladen) 'Bei jedem GetString wird direkt in der Datei gesucht 'Localization.OpenResource("Resources/example_de.txt") 'Einzelne Resource-Datei laden (Wird in Speicher geladen) 'GetString holt die Daten aus dem Speicher, es ist keine Datei geöffnet 'Localization.LoadResource("Resources/example_en.txt") 'Mehrere Resource-Dateien öffnen anhand eines Filters (Dateizugriff) 'Localization.OpenResources("Resources/example*.txt") 'Mehrere Resource-Dateien laden anhand eines Filters (Speicherzugriff) Localization.LoadResources("Resources/example*.txt") Graphics 800, 600, 0 Repeat Cls If KeyHit(KEY_SPACE) Then 'Sprache abfragen If Localization.Language() = "de" Localization.SetLanguage("en") Else Localization.SetLanguage("de") EndIf EndIf 'Wert für den Key HELLO_WORLD in der aktuellen Sprache abfragen DrawText Localization.GetString("HELLO_WORLD"), 10, 10 'Wert für den Key HELLO_WORLD in der Gruppe Version2 in der aktuellen Sprache abfragen DrawText Localization.GetString("HELLO_WORLD", "Version2"), 10, 50 Flip Until KeyHit(KEY_ESCAPE) 'Dateien schliessen und Speicher freigeben Localization.Dispose() EndGraphics GCCollect() End Ein Resource-File kann auch Gruppen beinhalten, diese sind gleich wie bei INI-Dateien definiert: Code: [AUSKLAPPEN] [Version1]
HELLO_WORLD = Hallo Welt! [Version2] HELLO_WORLD = Gugu! Nun kann man mit Localization.GetString("HELLO_WORLD", "Version2") die zweite Version abfragen, in dem Fall "Gugu!". Gibt man keine Gruppe an so wird der erste gefundene Wert verwendet, egal in welcher Gruppe. Noch ein Hinweis zum Laden einer Resource-File: Die Sprache wird anhand des Dateinamens automatisch erkannt, jedoch nur diese beiden Formate: name_de.extension (hier alles was zwischen _ und . ist) name_de_zusatz.extension (alles was zwischen _ und _ ist) Wenn die Datei ein anderes Format benutzt kann man die Sprache manuell angeben, als zweiten Parameter der Load-Funktionen. Z.Bsp.: Localization.LoadResource("meineDatei.txt", "de") Bei den Load-Funktionen mit dem Filter geht das jedoch nicht, der Filter sorgt nur dafür dass die entsprechenden Dateien zurückgegeben werden, geladen werden sie jeweils mit den normalen Funktionen (kann ich vielleicht irgendwann noch anpassen) Für GUI-Anwendungen wo die Labels etc. nur am Anfang geladen werden empfiehlt sich OpenResource(). Bei Spielen etc. wo die Texte vielleicht mehrmals abgefragt werden, oder noch schlimmer in jedem Hauptschleifendurchlauf, empfehle ich LoadResource(), sonst kommt die Harddisk nicht mehr nach ![]() Hier noch das Modul bzw. die Include-File selbst ![]() Code: [AUSKLAPPEN] SuperStrict
Type Localization Global currentLanguage:String Global supportedLanguages:TList Global Resources:TList 'Set the current language Function SetLanguage:Int(language:String) For Local lang:String = EachIn supportedLanguages If language = lang Then currentLanguage = language Return True EndIf Next Return False End Function 'Returns the current language Function Language:String() Return currentLanguage End Function 'Adds a comma separated list of languages to the supported languages list Function AddLanguages(languages:String) Local pos:Int = Instr(languages, ",") If pos = 0 Then supportedLanguages.AddLast(languages.Trim()) Return EndIf Local lang:String While pos > 0 supportedLanguages.AddLast(Left(languages, pos - 1).Trim()) languages = Mid(languages, pos + 1) pos = Instr(languages, ",") Wend supportedLanguages.AddLast(languages.Trim()) End Function 'Opens a resource file (no memory used) Function OpenResource(filename:String) LocalizationStreamingResource.Open(filename) End Function 'Loads the specified resource file into memory (faster, memory used) Function LoadResource(filename:String) LocalizationMemoryResource.Open(filename) End Function 'Opens all resource files according to the filter (for example: myfile*.txt will open myfile_en.txt, myfile_de.txt etc.) Function OpenResources(filter:String) For Local file:String = EachIn GetResourceFiles(filter) OpenResource(file) Next End Function 'Loads all resource files according to the filter (for example: myfile*.txt will load myfile_en.txt, myfile_de.txt etc.) Function LoadResources(filter:String) For Local file:String = EachIn GetResourceFiles(filter) LoadResource(file) Next End Function 'Returns the value for the specified key, or an empty string if the key was not found Function GetString:String(key:String, group:String = Null) Local ret:String = "" For Local r:LocalizationResource = EachIn resources If r.language <> currentLanguage Then Continue ret = r.GetString(key, group) If ret <> Null Then Return ret Next Return ret End Function 'Detects the language of a resource file Function GetLanguageFromFilename:String(filename:String) Local lastpos:Int = 0 Local pos:Int = Instr(filename, "_") 'Look for the last occurence of "_" While pos > 0 lastpos = pos pos = Instr(filename, "_", lastpos + 1) Wend If lastpos > 0 pos = Instr(filename, "_", lastpos + 1) If pos > 0 Return Mid(filename, lastpos + 1, pos - lastpos - 1) EndIf pos = Instr(filename, ".", lastpos + 1) If pos > 0 Return Mid(filename, lastpos + 1, pos - lastpos - 1) EndIf Return Mid(filename, lastpos + 1) EndIf Return Null End Function 'Returns all resource files according to the filter Function GetResourceFiles:TList(filter:String) Local ret:TList = New TList Local pos:Int = Instr(filter, "*") If pos > 0 Local prefix:String = Left(filter, pos - 1) Local suffix:String = Mid(filter, pos + 1) Local dir:String = ExtractDir(filter) Local dir_content:String[] = LoadDir(dir) prefix = Mid(prefix, dir.Length + 1) If Left(prefix, 1) = "/" Or Left(prefix, 1) = "\" Then prefix = Mid(prefix, 2) For Local file:String = EachIn dir_content If file.Length >= prefix.Length And Left(file, prefix.Length) = prefix If file.Length >= prefix.Length + suffix.Length And Right(file, suffix.Length) = suffix ret.AddLast(dir + "/" + file) EndIf EndIf Next EndIf Return ret End Function 'Releases all resources used by the Localization Module Function Dispose() For Local r:LocalizationResource = EachIn Resources r.Close() Next Resources.Clear() Resources = Null supportedLanguages = Null End Function End Type 'Initialize Localization.Resources = New TList Localization.supportedLanguages = New TList 'resource file base type ----------------------------------------------------- Type LocalizationResource Abstract Field language:String Field _link:TLink Method GetString:String(key:String, group:String = Null) Abstract Method Close() Abstract End Type 'resource type (uses a stream to read on demand, lower access, no memory used) ------------------ Type LocalizationStreamingResource Extends LocalizationResource Field stream:TStream 'Opens a resource file Function Open:LocalizationStreamingResource(filename:String, language:String = Null) If language = Null Then language = Localization.GetLanguageFromFilename(filename) If language = Null Then Throw "No language was specified for loading the resource file and the language could not be detected from the filename itself.~r~nPlease specify the language or use the format ~qname_language.extension~q for the resource files." EndIf Local file:TStream = ReadFile(filename) If file = Null Then Throw "The resource file ~q" + filename + "~q was not found or could not be opened for reading." Local r:LocalizationStreamingResource = New LocalizationStreamingResource r.language = language r.stream = file r._link = Localization.resources.AddLast(r) End Function 'Gets the value for the specified key Method GetString:String(key:String, group:String = Null) If stream = Null Then Return Null stream.Seek(0) Local line:String Local _key:String Local value:String Local skip:Int = False Local pos:Int = 0 While Not Eof(stream) line = ReadLine(stream).Trim() 'If a group was specified, look for the group and skip lines (faster) If group <> Null If skip And Left(line, 1) <> "[" Then Continue If Left(line, 1) = "[" And Right(line, 1) = "]" If Mid(line, 2, line.Length - 2) <> group Then skip = True Else skip = False EndIf EndIf EndIf 'Look for the key pos = Instr(line, "=") If pos > 0 Then _key = Left(line, pos - 1).Trim() value = Mid(line, pos + 1).Trim() EndIf If _key = key Then Return value Wend 'Not found, or maybe the wrong group was specified Return Null End Method 'Close the resource file manually Method Close() If _link <> Null Then _link.Remove() If stream <> Null Then stream.Close() End Method 'If there are no references to this resource, the object will be deleted automatically Method Delete() Close() End Method End Type 'resource type (loads the resource file in the memory, faster access, increased memory usage) ---------------- Type LocalizationMemoryResource Extends LocalizationResource Field map:TMap 'Opens a resource file and loads the content into memory Function Open:LocalizationMemoryResource(filename:String, language:String = Null) If language = Null Then language = Localization.GetLanguageFromFilename(filename) If language = Null Then Throw "No language was specified for loading the resource file and the language could not be detected from the filename itself.~r~nPlease specify the language or use the format ~qname_language.extension~q for the resource files." EndIf Local file:TStream = ReadFile(filename) If file = Null Then Throw "The resource file ~q" + filename + "~q was not found or could not be opened for reading." Local r:LocalizationMemoryResource = New LocalizationMemoryResource r.language = language r.map = New TMap r._link = Localization.resources.AddLast(r) Local line:String Local key:String Local value:String Local pos:Int = 0 Local group:String = "" While Not Eof(file) line = ReadLine(file) If Left(line, 1) = "[" And Right(line, 1) = "]" group = Mid(line, 2, line.Length - 2).Trim() EndIf pos = Instr(line, "=") If pos > 0 Then key = Left(line, pos - 1).Trim() value = Mid(line, pos + 1).Trim() EndIf If key <> Null And key <> "" Then If group <> Null And group <> "" r.map.Insert(group + "::" + key, value) If r.map.ValueForKey(key) = Null Then r.map.Insert(key, value) Else r.map.Insert(key, value) EndIf EndIf Wend file.Close() Return r End Function 'Gets the value for the specified key Method GetString:String(key:String, group:String = Null) Local ret:Object If group <> Null Then ret = map.ValueForKey(group + "::" + key) Else ret = map.ValueForKey(key) EndIf If ret = Null Then Return Null Return String(ret) End Method 'Releases the used memory Method Close() If _link <> Null Then _link.Remove() If map <> Null Then map.Clear() End Method 'If there are no references to this resource, the object will be deleted automatically Method Delete() Close() End Method End Type |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group