Class routine
Blitz3D Forums/Blitz3D Programming/Class routine
| ||
Here is a good method for storing and handling objects. Types have two fundamental problems. First, a variable can only be one type class, unless you use the clunky Object() command. Second, types cannot store a variable array of subobjects, like a vertex list. This lets you store any structure in a regular old four-byte integer variable. Here are the commands: item=CreateItem(class) "Class" is a constant, from 1 to infinity. Use CLASS_PLAYER, CLASS_MONSTER, etc. Setl(item,parameter,value) "parameter" is a constant, from 1 to infinity. Use PLAYER_HEALTH, MONSTER_LEVELOFSEETHINGRAGE, etc. Getl(item,parameter) returns integers. You can also use Setf(), Getf(), for floats. CountItems(class) How many items exist with that class. GetItem(class,index) Returns the item. Index is from 1 to CountItems(). This will probably be made into a lib. Include "classes.bb" Const CLASS_PLAYER=1 Const PLAYER_NAME=1 Const PLAYER_HEALTH=2 Const PLAYER_XPOSITION=3 Const PLAYER_YPOSITION=4 Const PLAYER_ZPOSITION=5 Const CLASS_MONSTER=2 Const MONSTER_HEALTH=1 Const MONSTER_XPOSITION=2 Const MONSTER_YPOSITION=3 Const MONSTER_ZPOSITION=4 Const CLASS_WEAPON=3 Const WEAPON_AMMO=1 Const WEAPON_RECOIL=2 For n=1 To 3 player=createitem(CLASS_PLAYER) setl player,PLAYER_HEALTH,n setf player,PLAYER_XPOSITION,Rnd(0,100) setf player,PLAYER_YPOSITION,Rnd(0,100) setf player,PLAYER_ZPOSITION,Rnd(0,100) Next player=GetItem(CLASS_PLAYER,2) FreeItem player sets GetItem(CLASS_PLAYER,1),PLAYER_NAME,"Adam" sets GetItem(CLASS_PLAYER,2),PLAYER_NAME,"Joe" For n=1 To CountItems(CLASS_PLAYER) player=getitem(CLASS_PLAYER,n) Print "Player "+n Print "Name: "+gets(player,PLAYER_NAME) Print "Health: "+getl(player,PLAYER_HEALTH) Print "X position: "+getf(player,PLAYER_XPOSITION) Print "Y position: "+getf(player,PLAYER_YPOSITION) Print "Z position: "+getf(player,PLAYER_ZPOSITION) Print "" Next For n=1 To 2 monster=createitem(CLASS_MONSTER) setl monster,MONSTER_HEALTH,Rnd(0,100) Next For n=1 To CountItems(CLASS_MONSTER) monster=getitem(CLASS_MONSTER,n) Print "Monster "+n Print "Health:"+getl(monster,MONSTER_HEALTH) Print "" Next WaitKey End classes.bb: Global masterclassbuffer=CreateBank() Const ITEM_HEADERLENGTH=4 Function CreateItem(class) If BankSize(masterclassbuffer)<class*4 ResizeBank masterclassbuffer,class*4 Else classbuffer=PeekInt(masterclassbuffer,(class-1)*4) EndIf If Not classbuffer classbuffer=CreateBank() PokeInt masterclassbuffer,(class-1)*4,classbuffer EndIf item=CreateBank(ITEM_HEADERLENGTH) PokeInt item,0,class size=BankSize(classbuffer) ResizeBank classbuffer,size+4 PokeInt classbuffer,size,item Return item End Function Function CountItems(class) If BankSize(masterclassbuffer)<class*4 Return 0 classbuffer=PeekInt(masterclassbuffer,(class-1)*4) If classbuffer Return BankSize(classbuffer)/4 Else Return 0 EndIf End Function Function GetItem(class,index) classbuffer=PeekInt(masterclassbuffer,(class-1)*4) Return PeekInt(classbuffer,(index-1)*4) End Function Function FreeItem(item) class=ItemClass(item) classbuffer=PeekInt(masterclassbuffer,(class-1)*4) For n=0 To (BankSize(classbuffer))/4-1 If PeekInt(classbuffer,n*4)=item For m=n To (BankSize(classbuffer))/4-1-1 PokeInt classbuffer,m*4,PeekInt(classbuffer,m*4+4) Next FreeBank item ResizeBank classbuffer,BankSize(classbuffer)-4 Exit EndIf Next End Function Function ItemClass(item) Return PeekInt(item,0) End Function Function Getl(item,parameter,defaultvalue=0) If BankSize(item)<parameter*4+ITEM_HEADERLENGTH Return defaultvalue Return PeekInt(item,(parameter-1)*4+ITEM_HEADERLENGTH) End Function Function Setl(item,parameter,value) If BankSize(item)<parameter*4+ITEM_HEADERLENGTH ResizeBank item,parameter*4+ITEM_HEADERLENGTH PokeInt item,(parameter-1)*4+ITEM_HEADERLENGTH,value End Function Function Getf#(item,parameter,defaultvalue#=0) If BankSize(item)<parameter*4+ITEM_HEADERLENGTH Return defaultvalue Return PeekFloat(item,(parameter-1)*4+ITEM_HEADERLENGTH) End Function Function Setf(item,parameter,value#) If BankSize(item)<parameter*4+ITEM_HEADERLENGTH ResizeBank item,parameter*4+ITEM_HEADERLENGTH PokeFloat item,(parameter-1)*4+ITEM_HEADERLENGTH,value End Function Function Gets$(item,parameter,defaultvalue$="") If BankSize(item)<parameter*4+ITEM_HEADERLENGTH Return defaultvalue sbank=PeekInt(item,(parameter-1)*4+ITEM_HEADERLENGTH) If Not sbank Return defaultvalue Return PeekString(sbank,0) End Function Function Sets(item,parameter,value$) If BankSize(item)<parameter*4+ITEM_HEADERLENGTH ResizeBank item,parameter*4+ITEM_HEADERLENGTH Else sbank=PeekInt(item,(parameter-1)*4+ITEM_HEADERLENGTH) EndIf If sbank ResizeBank sbank,Len(value)+1 Else sbank=CreateBank(Len(value)+1) PokeInt item,(parameter-1)*4+ITEM_HEADERLENGTH,sbank EndIf PokeString sbank,0,value End Function |
| ||
Fails here on: Return PeekString(sbank,0)" in your GetS function. Result: "Function PeekString not found." |
| ||
Oh, you need my poke/peek string lib: Global svar.s ProcedureDLL PokeString(*bank,offset,value.s) PokeS(*bank+offset,value) EndProcedure ProcedureDLL.l PeekString(*bank,offset) svar=PeekS(*bank+offset) ProcedureReturn @svar EndProcedure |
| ||
That looks a lot clunkier than Object() to me! |
| ||
What is the "Object()" command? There is no mention of it in any of the Language or Command help files, as far as I can see. Thank you. |
| ||
Types are better for a small program. This is good for when you have an engine with a lot of structures, and structures that reference other structures. I agree that typing out PLAYER_WHATEVER can get repetetive, but when you get to the point of a really massive engine, it's a tradeoff worth making. This is actually a LOT like how Blitz stores structures internally. This is the kind of code I am using it for. Organization is more important for this than easiness: Function LoadStaticMeshInstance(file$) file=Lower(file) For n=1 To countitems(CLASS_STATICMESHREFERENCE) staticmeshreference=getitem(CLASS_STATICMESHREFERENCE,n) If file=gets(staticmeshreference,STATICMESHREFERENCE_FILENAME) reference=staticmeshreference Exit EndIf Next If Not reference mesh=LoadStaticMesh(file) If mesh reference=createitem(CLASS_STATICMESHREFERENCE) setl reference,STATICMESHREFERENCE_MESH,mesh sets reference,STATICMESHREFERENCE_FILENAME,file EndIf EndIf If reference mesh=CopyEntity(gets(staticmeshreference,STATICMESHREFERENCE_MESH)) staticmesh=createitem(CLASS_STATICMESH) setl staticmesh,STATICMESH_MESH,mesh setl staticmesh,STATICMESH_VIEWDISTANCE,8000 Return staticmesh EndIf End Function |
| ||
Oh, you need my poke/peek string lib: Got an active link for that? Thanks, |
| ||
No, it's purebasic so he can't release it compiled. |
| ||
A lot of people seem to really like banks... I'm not one of them though. To each his own I guess. I wrote a real nice linked list lib that's really simple use even with Handle() and Object(). http://www.blitzbasic.com/codearcs/codearcs.php?code=1117 Halo, serious question, why would you use your system over mine? I ask just because I'm wondering if there is something wrong or not liked about what I did? |
| ||
Actually, that function is not a wrapper of a PB function, so someone could post the DLL without a problem. I don't know what yours does, and I hate types anyways. |
| ||
I don't know what yours does, and I hate types anyways. well, it's just a linked list but it does use types. although it does allow for lists within lists etc... Don't like types though, hmmm? you probably don't want to get into why? Well, I don't really like Mark's implementation here either. It was so much better in Blitz2 on the Amiga. As a matter of fact, my linked list lib was meant feel as close to that as possible. It's good to know that Mark will be going back to separate lists in BlitzMax, can't wait. |