Einfache Übersetzungen mit TTranslation

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

Kernle 32DLL

Betreff: Einfache Übersetzungen mit TTranslation

BeitragFr, Jul 17, 2009 2:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Für mein Spiel entwickelt, und fürs Codearchiv angepasst. Meine Übersetzungsklasse "TTranslation". Und was kann man damit nun machen? Man kann Übersetzungsteile definieren (Ein Code und dessen Übersetzung), und diese später Rück-Translaten lassen. Das wird dann interessant, wenn man während dem coding nur die Codes benutzt, weil der dann dort auftauchende Code immer davon abhängig ist was für eine "Translation" man gerade geladen hat.

Um Rechenzeit zu sparen, können Translationteile in sog. TranslationGroups eingeteilt werden. Das spart bei vielen Translations sehr viel Suchzeit. Außerdem kann man damit in Verbindung von Translations in Translations (Siehe Beispiel 2) allerlei interessantes Zeugs anstellen.

Die Befehle im Überblick:

BlitzMax: [AUSKLAPPEN]
'Muss ich neu machen, schreibe ich die Tage. Das beispiel sollte alles erklären.


Das eigentliche Include

BlitzMax: [AUSKLAPPEN]
'------------------------------------------
'
' TTRANSLATION
' EVERYTHING ABOUT TRANSLATION
'
'------------------------------------------

SuperStrict

'============================================================

Type TTranslation
'------------------------
' Globals
'------------------------

Global TranslationMap:TMap = CreateMap() 'Counting own instances
Global FileLoaderStream:TStream

'------------------------
' Fields
'------------------------

Field TranslationGroup:TTranslationGroup
Field Code:String
Field Content:String

'------------------------
' Constructors & Destructors
'------------------------

Function Create:TTranslation(_Code:String , _Content:String , _TranslationGroupObject:Object , Overwrite:Byte = False)
If String(_TranslationGroupObject) Or TTranslationGroup(_TranslationGroupObject) Or _TranslationGroupObject = Null
If String(_TranslationGroupObject) Then _TranslationGroupObject = TTranslationGroup.FindTranslationGroup(String(_TranslationGroupObject))
Else
Throw "Function call with INVALID parameter"
EndIf

If _Code = ""
DebugLog "ERROR: Function call with EMPTY parameter"
Return Null
EndIf

Local _Translation:TTranslation = TTranslation.FindTranslation(_Code , _TranslationGroupObject , True , True)

If Not _Translation
_Translation = New TTranslation
MapInsert(_Translation.TranslationMap , _Code , _Translation)

_Translation.Code = _Code
_Translation.Content = _Content
ElseIf Overwrite = True
_Translation.Code = _Code
_Translation.Content = _Content
EndIf

'Handles all the Map-Inserting
_Translation.ChangeTranslationGroup(_TranslationGroupObject)

Return _Translation
End Function

Method Remove()
MapRemove(Self.TranslationMap , Self.Code)

If Self.TranslationGroup
MapRemove(Self.TranslationGroup.TranslationMap , Self.Code)
EndIf
End Method

'------------------------
' Functions
'------------------------

Function FindTranslation:TTranslation(_Code:String , _TranslationGroupObject:Object = Null , SearchOverride:Byte = 1 , NoDebuglog:Byte = False)
'Search Override Params:
' 0 = Global Search
' 1 = Reduced Global Search (If _TranslationGroupObject is not given do Global Search)
' 2 = Disabled Global Search (NEVER do a Global Search)

If String(_TranslationGroupObject) Or TTranslationGroup(_TranslationGroupObject) Or _TranslationGroupObject = Null
If String(_TranslationGroupObject) Then _TranslationGroupObject = TTranslationGroup.FindTranslationGroup(String(_TranslationGroupObject))
Else
Throw "Function call with INVALID parameter"
EndIf

Local testvar:String = String(_TranslationGroupObject)
Local testvar2:TTranslationGroup = TTranslationGroup(_TranslationGroupObject)

Local _Translation:TTranslation

If TTranslationGroup(_TranslationGroupObject)
_Translation = TTranslation(MapValueForKey(TTranslationGroup(_TranslationGroupObject).TranslationMap , _Code))
If _Translation Then Return _Translation

'Didnt found Code in this group, so lets search Global
If SearchOverride = 0
If Not NoDebuglog Then DebugLog "WARNING: Cant find " + Chr(34) + _Code + Chr(34) + " in " + Chr(34) + TTranslationGroup(_TranslationGroupObject).Name + Chr(34) + "-Group -> Searching in Global-Group"
Return TTranslation.FindTranslation(_Code)
Else
If Not NoDebuglog Then DebugLog "WARNING: Cant find " + Chr(34) + _Code + Chr(34) + " in " + Chr(34) + TTranslationGroup(_TranslationGroupObject).Name + Chr(34) + "-Group -> Returning Null"
Return Null
EndIf
ElseIf SearchOverride <> 2
_Translation = TTranslation(MapValueForKey(TTranslation.TranslationMap , _Code))
If _Translation Then Return _Translation

If Not NoDebuglog Then DebugLog "WARNING: Cant find " + Chr(34) + _Code + Chr(34) + " in " + Chr(34) + "Global" + Chr(34) + "-Group -> Returning Null"

Return Null
Else
If Not NoDebuglog Then DebugLog "HINT: No _TranslationGroupObject given and Global-Search disabled (SearchOverride = 2) - Cant search! -> Returning Null"
Return Null
EndIf
End Function

Function CodeInUse:Byte(_Code:String , _TranslationGroup:TTranslationGroup = Null , SearchOverride:Byte = 1)
If TTranslation.FindTranslation(_Code , _TranslationGroup , SearchOverride , True) Then Return True Else Return False
End Function

Function CountTranslations:Int()
Local TranslationCount:Int

For Local count:Object = EachIn MapValues(TTranslation.TranslationMap)
TranslationCount:+1
Next

Return TranslationCount
End Function

Function DecodeTranslation:String(Translation:TTranslation)
Local TranslationString:String = Translation.GetContent()
Local _TranslationString:String

Repeat
Local pos:Int = Instr(TranslationString , "%" , 1)

If pos
Local pos2:Int = Instr(TranslationString , "%" , pos+1)

If pos2 = 0 Then pos2 = Len(TranslationString) + 1

_TranslationString:+ Left(TranslationString , pos - 1)
TranslationString = Mid(TranslationString , pos)

Select Mid(TranslationString , 2 , pos2 - pos - 1)
Case "" 'equals %%
_TranslationString:+ "%"
Case "groupname","Groupname","GroupName"
Local TranslationGroup:TTranslationGroup = Translation.GetTranslationGroup()
Local TranslationGroupName:String = "Global"

If TranslationGroup Then TranslationGroupName = TranslationGroup.GetName()

_TranslationString:+TranslationGroupName
Default
Local _Translation:TTranslation = TTranslation.FindTranslation(Mid(TranslationString , 2 , pos2 - pos - 1) )

If _Translation
_TranslationString:+ _Translation.Content
Else
_TranslationString:+ Mid(TranslationString , 1 , pos2 - pos + 1)
EndIf
End Select

TranslationString = Mid(TranslationString , pos2 - pos + 2)
Else
_TranslationString:+ TranslationString
Exit
EndIf
Forever

Return _TranslationString
End Function

'------------------------
' Methods
'------------------------

Method ChangeTranslationGroup(_TranslationGroupObject:Object = Null)
If String(_TranslationGroupObject) Or TTranslationGroup(_TranslationGroupObject) Or _TranslationGroupObject = Null
If String(_TranslationGroupObject) Then _TranslationGroupObject = TTranslationGroup.FindTranslationGroup(String(_TranslationGroupObject))
Else
Throw "Function call with INVALID parameter"
EndIf

If Self.TranslationGroup Then MapRemove(Self.TranslationGroup.TranslationMap , Self.Code)

Self.TranslationGroup = TTranslationGroup(_TranslationGroupObject)

If Self.TranslationGroup Then MapInsert(Self.TranslationGroup.TranslationMap , Self.Code , Self)
End Method

Method GetCode:String()
Return Self.Code
End Method

Method GetTranslationGroup:TTranslationGroup()
Return Self.TranslationGroup
End Method

Method GetContent:String()
Return Self.Content
End Method

Method SetContent(_Content:String)
Self.Content = _Content
End Method

'------------------------
' Loader
'------------------------

Function FileLoader_LoadFile:TMap(url:Object)
If TTranslation.FileLoaderStream Then CloseStream TTranslation.FileLoaderStream ; TTranslation.FileLoaderStream = Null
TTranslation.FileLoaderStream = OpenStream(url , True , False)

If TTranslation.FileLoaderStream
While Not Eof(TTranslation.FileLoaderStream)
TTranslation.FileLoader_Read()
Wend
Else
Throw "Tried to read translation, but stream isnt open"
EndIf

CloseStream TTranslation.FileLoaderStream ; TTranslation.FileLoaderStream = Null

Return TTranslation.TranslationMap
End Function

Function FileLoader_SaveFile(url:Object)
If TTranslation.FileLoaderStream Then CloseStream TTranslation.FileLoaderStream ; TTranslation.FileLoaderStream = Null

TTranslation.FileLoaderStream = OpenStream(url , False , True)

If TTranslation.FileLoaderStream
For Local _Translation:TTranslation = EachIn MapValues(TTranslation.TranslationMap)'TTranslation.TranslationList
TTranslation.FileLoader_Save(_Translation)
Next
Else
Throw "Tried to save translation, but stream isnt open"
EndIf

CloseStream TTranslation.FileLoaderStream ; TTranslation.FileLoaderStream = Null
End Function

Function FileLoader_Read:TTranslation()
If TTranslation.FileLoaderStream
Local ReadArray:String[3]

For Local I:Int = 0 To 2
ReadArray[I] = ReadLine(TTranslation.FileLoaderStream)
Next

If ReadArray[2] <> "" Then CreateTranslationGroup(ReadArray[2])

Return CreateTranslation(ReadArray[0] , ReadArray[1] , ReadArray[2])
Else
Throw "Tried to read translation, but stream isnt open"
EndIf
End Function

Function FileLoader_Save(_Translation:TTranslation)
If TTranslation.FileLoaderStream And _Translation
WriteLine(TTranslation.FileLoaderStream , _Translation.Code)
WriteLine(TTranslation.FileLoaderStream , _Translation.Content)

Local TranslationGroupName:String = ""

If _Translation.TranslationGroup
TranslationGroupName = _Translation.TranslationGroup.Name
Else
TranslationGroupName = ""
EndIf

WriteLine(TTranslation.FileLoaderStream , TranslationGroupName)
Else
Throw "Tried to save translation, but stream isnt open"
EndIf
End Function
End Type

'============================================================

'------------------------
' General Wrapper
'------------------------

Function CreateTranslation:TTranslation(_Code:String , _Content:String , _TranslationGroupObject:Object)
Return TTranslation.Create(_Code, _Content , _TranslationGroupObject)
End Function

Function FindTranslation:TTranslation(_Code:String , _TranslationGroupObject:Object = Null , SearchOverride:Byte = 1 , NoDebuglog:Byte = False)
Return TTranslation.FindTranslation(_Code , _TranslationGroupObject , SearchOverride , NoDebuglog)
End Function

Function TranslateCode:String(_Code:String , _TranslationGroupObject:Object = Null , SearchOverride:Byte = 1)
Local Translation:TTranslation = TTranslation.FindTranslation(_Code , _TranslationGroupObject , SearchOverride)

If Translation Then Return TTranslation.DecodeTranslation(Translation)

Return _Code
End Function

Function LoadTranslationsFromFile:TMap(url:Object)
Return TTranslation.FileLoader_LoadFile(url)
End Function

Function SaveTranslationsToFile(url:Object)
TTranslation.FileLoader_SaveFile(url)
End Function

'------------------------
' New Functions
'------------------------

Function RemoveAllTranslations()
For Local Translation:TTranslation = EachIn MapValues(TTranslation.TranslationMap)
Translation.Remove()
Next
End Function

'============================================================

Type TTranslationGroup
'------------------------
' Globals
'------------------------

Global TranslationGroupList:TList = CreateList() 'Counting own instances

'------------------------
' Fields
'------------------------

Field Name:String
'Field TranslationList:TList = CreateList()
Field TranslationMap:TMap = CreateMap()

'------------------------
' Constructors & Destructors
'------------------------

Method New()
TranslationGroupList.AddLast(Self)
End Method

Function Create:TTranslationGroup(_Name:String)
If _Name = "" Then Return Null
If TTranslationGroup.NameInUse(_Name) Then Return Null

Local _TranslationGroup:TTranslationGroup = New TTranslationGroup

_TranslationGroup.Name = _Name

Return _TranslationGroup
End Function

Method Remove()
Self.TranslationGroupList.Remove(Self)

For Local Translation:TTranslation = EachIn MapValues(Self.TranslationMap)
Translation.Remove()
Next
End Method

'------------------------
' Functions
'------------------------

Function NameInUse:Byte(_Name:String)
If TTranslationGroup.FindTranslationGroup(_Name) Then Return True Else Return False
End Function

Function FindTranslationGroup:TTranslationGroup(_Name:String)
For Local _TranslationGroup:TTranslationGroup = EachIn TTranslationGroup.TranslationGroupList
If _TranslationGroup.Name = _Name Then Return _TranslationGroup
Next
Return Null
End Function

'------------------------
' Methods
'------------------------

Method GetName:String()
Return Self.Name
End Method

Method GetTranslationMap:TMap()
Return Self.TranslationMap
End Method
End Type

'============================================================

'------------------------
' General Wrapper
'------------------------

Function CreateTranslationGroup:TTranslationGroup(_Name:String)
Return TTranslationGroup.Create(_Name)
End Function

Function FindTranslationGroup:TTranslationGroup(_Name:String)
Return TTranslationGroup.FindTranslationGroup(_Name)
End Function

'------------------------
' New Functions
'------------------------

Function RemoveAllTranslationGroups()
RemoveAllTranslations()
For Local TranslationGroup:TTranslationGroup = EachIn TTranslationGroup.TranslationGroupList
TranslationGroup.Remove()
Next
End Function

'============================================================


Beispiel1:

BlitzMax: [AUSKLAPPEN]
Rem
Dieses Beispiel zeigt allgemein was man mit Translations so machen kann,
und wie man sie shcließlich ausgibt. Außerdem wird gezeigt wie man Translations
in Translations benutzen kann.
End Rem


'------------------------
' Game Strings
'------------------------

CreateTranslationGroup("GUI")
CreateTranslation("#GUI_YES" , "Ja" , "GUI")
CreateTranslation("#GUI_NO" , "Nein" , "GUI")
CreateTranslation("#GUI_OK" , "Okay" , "GUI")
CreateTranslation("#GUI_ABORT" , "Abbrechen" , "GUI")
CreateTranslation("#GUI_NEXT" , "Weiter" , "GUI")
CreateTranslation("#GUI_BACK" , "Zurück" , "GUI")

CreateTranslationGroup("Game")
'Freie Translation zum späteren auffüllen
CreateTranslation("#GAME_PLAYERNAME" , "" , "Game")

'Eine einfache Translation...
CreateTranslation("#GAME_WELCOME1" , "Wilkommen zum Translations Test" , "Game")

'Eine Translation einfügen
CreateTranslation("#GAME_WELCOME2" , "Hallo %#GAME_PLAYERNAME%" , "Game")

'Mehrere Translations einfügen
CreateTranslation("#GAME_CHOOSE" , "Wählen sie zum Fortfahren %#GUI_YES% oder %#GUI_NO%" , "Game")

'% mit %% erzeugen
CreateTranslation("#GAME_PERCENT" , "Ladevorgang zu 100%% abgeschlossen" , "Game")

'Beispiel für Gruppenbildung
CreateTranslationGroup("PLAYER1")
CreateTranslation("#PLAYER_LOWHP" , "Player1 hat wenig HP" , "PLAYER1")

CreateTranslationGroup("PLAYER2")
CreateTranslation("#PLAYER_LOWHP" , "Player2 hat wenig HP" , "PLAYER2")

'------------------------

Global PlayerName:String = "Kernle 32DLL"

'Den Spielernamen einfüllen
FindTranslation("#GAME_PLAYERNAME").SetContent(PlayerName)

'Alles ausgeben
Print TranslateCode("#GAME_WELCOME1")
Print TranslateCode("#GAME_WELCOME2")
Print TranslateCode("#GAME_CHOOSE")
Print TranslateCode("#GAME_PERCENT")

Print TranslateCode("#PLAYER_LOWHP" , "PLAYER1")
Print TranslateCode("#PLAYER_LOWHP" , "PLAYER2")


Beispiel2:

BlitzMax: [AUSKLAPPEN]
Rem
Dieses Beispiel ist etwas Komplex. Aber im Grunde erstellen wir für jeden
Spieler eine TranslationGroup, die wiederrum ihre Translations mit Einfügungen
hat. Somit kann man für jeden Spieler einen eigenen Übersetzungssatz haben.
Sehr praktisch, aber auch nicht leicht zu verstehen.
End Rem


'Eine Liste mit Spielernamen
Global PlayerList:TList = CreateList()
'Ein paar spieler hinzufügen
PlayerList.AddLast("Herbert")
PlayerList.AddLast("Hans")
PlayerList.AddLast("Hubert")
PlayerList.AddLast("Peter")

For Local Name:String = EachIn PlayerList
CreateTranslationGroup(Name) 'Eine Gruppe mit dem Spielernamen erstellen
'Die Translations einfügen
CreateTranslation("#PLAYER_SAYYES" , Name+" sagt %#GUI_YES%!" , Name)
CreateTranslation("#PLAYER_SAYNO" , Name+" sagt %#GUI_NO%!" , Name)
CreateTranslation("#PLAYER_LOWHP" , Name+ " hat wenig HP!" , Name)

'Das hätte auch funktioniert:
'CreateTranslation("#PLAYER_SAYYES" , "%groupname% sagt %#GUI_YES%!" , Name)
'CreateTranslation("#PLAYER_SAYNO" , "%groupname% sagt %#GUI_NO%!" , Name)
'CreateTranslation("#PLAYER_LOWHP" , "%groupname% hat wenig HP!" , Name)
Next

'Peter soll Ja sagen...
Print TranslateCode("#PLAYER_SAYYES" , "Peter")

'Hans soll Nein sagen...
Print TranslateCode("#PLAYER_SAYNO" , "Hans")


Update 26 Juli 2009: Ich habe das ganze Translations Paket nach meinen neusten Anpassungen hier komplett neu eingefügt. Neues und Änderungen betreffen:

- Debug Befehle entfernt
- Translations in Translations hinzugefügt (mithilfe von %Translation%)
- Verschiedene Optimierungen am Code
- "" als TranslationGroupObject wird jetzt richtig als INVALID Parameter erkannt (benutzt stattdessen NULL)

Der Befehl DecodeTranslation enthält eine provisorische Select Case Gabelung, an der man bestimmten Schlüsselwörtern (wie z.b. groupname) eine anderen Einfügung geben kann. So wird %groupname% also mit dem Name der Gruppe ersetzt. Vielleicht ersetze ich das später mal durch eine Externe Liste...

Die Dokumentation mit Befehlsübersicht werde ich die Tage neu einfügen.


So long,
Kernle
Mein PC: "Bluelight" - Xtreme Gamer PC [Video]
Meine Projekte: Cube-Wars 2010 [Worklog]
Anerkennungen: 1. Platz BCC #7 , 1. Platz BCC #22 , 3. Platz BAC #89
Ich war dabei: NRW Treff III, IV ; Frankfurter BB Treffen 2009
  • Zuletzt bearbeitet von Kernle 32DLL am So, Jul 26, 2009 16:34, insgesamt 6-mal bearbeitet

Nova

BeitragFr, Jul 17, 2009 3:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Und was machst das ganze jetzt? Bei deiner Erklärung verstehe ich nur Bahnhof.
"Man kann Übersetzungsteile definieren" - ???
AMD Athlon II 4x3,1GHz, 8GB Ram DDR3, ATI Radeon HD 6870, Win 7 64bit

Kernle 32DLL

BeitragFr, Jul 17, 2009 3:14
Antworten mit Zitat
Benutzer-Profile anzeigen
Du definierst einen Code (z.b. "#TYPE_TANK"), und weist ihm eine Übersetzung zu. Wenn du jetzt programmierst, dann fügst du per TranslateCode() immer die Übersetzung dieses Codes ein. Und wenn du jetzt "#TYPE_TANK" eine andere Übersetzung zuordnest (z.b. durch einen anderer Languagefile), dann steht im Code immer noch das gleiche, aber die Aussgabe ist eine andere.

Hoffe das hilft?

So long,
Kernle
Mein PC: "Bluelight" - Xtreme Gamer PC [Video]
Meine Projekte: Cube-Wars 2010 [Worklog]
Anerkennungen: 1. Platz BCC #7 , 1. Platz BCC #22 , 3. Platz BAC #89
Ich war dabei: NRW Treff III, IV ; Frankfurter BB Treffen 2009

Jolinah

BeitragFr, Jul 17, 2009 13:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Find ich gut Smile

Nur so als kleine Anmerkung: Hab sowas auch schonmal gemacht, basierend auf INI-Files, nur hat das damals wohl auch keiner richtig verstanden ^^ (https://www.blitzforum.de/foru...hp?t=19413)

Kernle 32DLL

BeitragFr, Jul 17, 2009 15:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Ach du warst das Very Happy Ich wusste das doch jemand hier schonmal was ähnliches gepostet hatte ^^ Ich wollte deins eigentlich auch benutzen, aber dann habe ich es doch selber programmiert für den Lerneffekt Razz

So long,
Kernle
Mein PC: "Bluelight" - Xtreme Gamer PC [Video]
Meine Projekte: Cube-Wars 2010 [Worklog]
Anerkennungen: 1. Platz BCC #7 , 1. Platz BCC #22 , 3. Platz BAC #89
Ich war dabei: NRW Treff III, IV ; Frankfurter BB Treffen 2009

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group