Wrapper around a bank
BlitzMax Forums/BlitzMax Programming/Wrapper around a bank
| ||
Hi, I'm writing a small wrapper around a bank to make it a bit easier to use it. When my wrapper is used, the programmer creates a layout of how the information in the bank is stored. Here is some code to show how: (In a RPG looking way) Local save:TGameSave = TGameSave.create() ' Format the layout ' name (string), hp, hpmax, mana, manamax, gold Local layout:Int[] = [ 8, GSL_INT, GSL_INT, GSL_INT, GSL_INT, GSL_INT ] save.create_layout( layout ) GSL_INT is equal to 4, since an Int uses 4 bytes. I also have GSL_BYTE, GSL_SHORT, GSL_FLOAT and so on... I don't have one for strings, so the 8 in the array means 8 bytes (chars) is used for the name. Everything works just fine. I also have a method in the type that returns the offset in bytes: Method get_offset( fs_index ) Local off = 0 If fs_index < 0 Or fs_index >= Len( bank_layout ) Then Return -1 ' error For Local i = 0 Until fs_index off:+bank_layout[i] Next Return off EndMethod Using that method I can get the offset i should peek/poke in the bank. But my "problem" comes when I want to use all this: Print "Pokes some stuff into the savefile..." save.bank.PokeInt( save.get_offset(1), 73 ) save.bank.PokeInt( save.get_offset(2), 100 ) save.bank.PokeInt( save.get_offset(3), 20 ) save.bank.PokeInt( save.get_offset(4), 20 ) save.bank.PokeInt( save.get_offset(5), 143 ) Print "Peeks some stuff from the savefile:" Print "HP : "+save.bank.PeekInt( save.get_offset(1) )+"/"+save.bank.PeekInt( save.get_offset(2) ) Print "MANA: "+save.bank.PeekInt( save.get_offset(3) )+"/"+save.bank.PeekInt( save.get_offset(4) ) Print "GOLD: "+save.bank.PeekInt( save.get_offset(5) ) This is not a pretty sight. This is what I want some help with. How should I do to simplify it? I could creade peekint/pokeint, peekbyte/pokebyte and so on in my type but I am looking for something better. If at all possible. What I want is something like this: local hero_hp = save.get( 1 ) local hero_mana = save.get( 3 ) But the "get" method needs to be able to return bytes,ints,floats,etc and that isn't possible, afaik. Anyone got any idea? |
| ||
greetings deps :) this is just one way to do it but you could use a map to create a readable index system (this is untested and will need your Type functionality added in).Import BRL.Map Type BankWrap Field index:TMap Field bank:TBank Method create_layout(layout:Int[],keys:String[]) ' do your layout creation stuff here ' create the index map If Not index Then index=New TMap Else index.clear() ' map each key to an index in your layout array Local layout_idx:Int=0 ' this is the index into your layout array For Local key:String=EachIn keys index.Insert(key,String.FromInt(layout_idx)) layout_idx:+1 Next EndMethod Method getByte:Byte(key:String) Local idx:String=String(index.ValueForKey(key)) If Not idx Then RuntimeError "Invalid Key" Return bank.PeekByte(get_offset(Int(idx))) EndMethod Method getDouble:Double(key:String) Local idx:String=String(index.ValueForKey(key)) If Not idx Then RuntimeError "Invalid Key" Return bank.PeekDouble(get_offset(Int(idx))) EndMethod Method getFloat:Float(key:String) Local idx:String=String(index.ValueForKey(key)) If Not idx Then RuntimeError "Invalid Key" Return bank.PeekFloat(get_offset(Int(idx))) EndMethod Method getInt:Int(key:String) Local idx:String=String(index.ValueForKey(key)) If Not idx Then RuntimeError "Invalid Key" Return bank.PeekInt(get_offset(Int(idx))) EndMethod Method getLong:Long(key:String) Local idx:String=String(index.ValueForKey(key)) If Not idx Then RuntimeError "Invalid Key" Return bank.PeekLong(get_offset(Int(idx))) EndMethod Method getShort:Short(key:String) Local idx:String=String(index.ValueForKey(key)) If Not idx Then RuntimeError "Invalid Key" Return bank.PeekShort(get_offset(Int(idx))) EndMethod Method setByte(key:String,val:Byte) Local idx:String=String(index.ValueForKey(key)) If Not idx Then RuntimeError "Invalid Key" bank.PokeByte(get_offset(Int(idx)),val) EndMethod Method setDouble(key:String,val:Double) Local idx:String=String(index.ValueForKey(key)) If Not idx Then RuntimeError "Invalid Key" bank.PokeDouble(get_offset(Int(idx)),val) EndMethod Method setFloat(key:String,val:Float) Local idx:String=String(index.ValueForKey(key)) If Not idx Then RuntimeError "Invalid Key" bank.PokeFloat(get_offset(Int(idx)),val) EndMethod Method setInt(key:String,val:Int) Local idx:String=String(index.ValueForKey(key)) If Not idx Then RuntimeError "Invalid Key" bank.PokeInt(get_offset(Int(idx)),val) EndMethod Method setLong(key:String,val:Long) Local idx:String=String(index.ValueForKey(key)) If Not idx Then RuntimeError "Invalid Key" bank.PokeLong(get_offset(Int(idx)),val) EndMethod Method setShort(key:String,val:Short) Local idx:String=String(index.ValueForKey(key)) If Not idx Then RuntimeError "Invalid Key" bank.PokeShort(get_offset(Int(idx)),val) EndMethod EndType it then reduces your gets and sets to something like: save.setInt("HP",23) save.setInt("MANA",150) ... Local hero_hp:Int=save.getInt("HP") Local hero_mana:Int=save.getInt("MANA") HTH. |
| ||
an alternative would be to extend your wrapper type and define Type constants (or global if you want):Type herobank Extends BankWrap Const HP:Int=0 Const MANA:Int=1 Method getByte:Byte(idx:Int) If idx>=layout_arr.length Then RuntimeError "Invalid Index" Return bank.PeekByte(get_offset(idx)) EndMethod Method getDouble:Double(idx:Int) If idx>=layout_arr.length Then RuntimeError "Invalid Index" Return bank.PeekDouble(get_offset(idx)) EndMethod Method getFloat:Float(idx:Int) If idx>=layout_arr.length Then RuntimeError "Invalid Index" Return bank.PeekFloat(get_offset(idx)) EndMethod Method getInt:Int(idx:Int) If idx>=layout_arr.length Then RuntimeError "Invalid Index" Return bank.PeekInt(get_offset(idx)) EndMethod Method getLong:Long(idx:Int) If idx>=layout_arr.length Then RuntimeError "Invalid Index" Return bank.PeekLong(get_offset(idx)) EndMethod Method getShort:Short(idx:Int) If idx>=layout_arr.length Then RuntimeError "Invalid Index" Return bank.PeekShort(get_offset(idx)) EndMethod Method setByte(idx:Int,val:Byte) If idx>=layout_arr.length Then RuntimeError "Invalid Index" bank.PokeByte(get_offset(idx),val) EndMethod Method setDouble(idx:Int,val:Double) If idx>=layout_arr.length Then RuntimeError "Invalid Index" bank.PokeDouble(get_offset(idx),val) EndMethod Method setFloat(idx:Int,val:Float) If idx>=layout_arr.length Then RuntimeError "Invalid Index" bank.PokeFloat(get_offset(idx),val) EndMethod Method setInt(idx:Int,val:Int) If idx>=layout_arr.length Then RuntimeError "Invalid Index" bank.PokeInt(get_offset(idx),val) EndMethod Method setLong(idx:Int,val:Long) If idx>=layout_arr.length Then RuntimeError "Invalid Index" bank.PokeLong(get_offset(idx),val) EndMethod Method setShort(idx:Int,val:Short) If idx>=layout_arr.length Then RuntimeError "Invalid Index" bank.PokeShort(get_offset(idx),val) EndMethod EndType your calls then look something like: save.setInt(herobank.HP,23) save.setInt(herobank.MANA,150) ... Local hero_hp:Int=save.getInt(herobank.HP) Local hero_mana:Int=save.getInt(herobank.MANA) |
| ||
you could use a map to create a readable index system This sounds interesting. Looks like I'm stuck with get<type>/set<type> methods but at least it looks a bit cooler. :) Thanks. |