An Old Topic Revisited

Blitz3D Forums/Blitz3D Beginners Area/An Old Topic Revisited

Gauge(Posted 2004) [#1]
In a previous post someone said when you need to store a pointer in another variable type you use


p\a%=handle(new player)

p2.player=object.player(p\a%)

I don't know how Handle or Object actually work as commands.
But how can you acces this type:

name$="John"
p\name$=Handle(new player)

*is lost*

can someone either gimme a working example of how to do this, or at least explain handle and object?
thanks for any help


soja(Posted 2004) [#2]
More precisely, you use Handle when you want to store a *custom type pointer* as an *int*. It doesn't have anything to do with strings. It's just like the first two lines.

In the first line, a new Player is created, and the memory address of the instance (normally stored as a Player type) is converted to an Int type and stored in p\a (whatever p is).

In the second line, you take the player type pointer that was "casted" into an int (p\a), and you convert in back into a Player type pointer (specified by the .player suffix of Object) and then assign it to another player type pointer p2.

Using Object and Handle is is useful for (among other things) allowing you to pass in multiple different custom types into a function that does similar things to each type. Normally you would have to create multiple functions for each specific type, with the same code in each function, becuase the function declaration would have to specify what type is expected, but if you pass in the Handle of the type pointer, then you just have to specify an Int, and return an Int, then convert it back to the type pointer afterwards.

The last part is just putting the new Player pointer, converted to an int, then converted to a string (i.e. "14586547") into p\Name$ (whatever p is, again). Name$ is still "John".

To sum up, unless you have a specific reason (like above) to use object and handle, I wouldn't. It generally obfuscates things, and it's still leaves you with just a custom type pointer (just as a different type).


eBusiness(Posted 2004) [#3]
Try using arrays (as a member of the "arrays > types" religious movement it is my duty to try to convert you), then handles will never be anywhere, but where you stored them. You can acces everything using a strictly logical system. By the way, I can't find any documentation on the handle command, what does it do?


big10p(Posted 2004) [#4]
Actually, Handle() does NOT convert a type pointer to an integer - it simply returns a unique number ID for the specified type instance.

i.e. the first time you call Handle() it returns 1, the second time it returns 2, the third time 3, etc. You can then later use these unique ID numbers with the Object() command to retrieve the pointer to the actual type instance.


soja(Posted 2004) [#5]
Ah, thanks for the clarification. That's what I get for assuming.

In other words, it DOES return an int, but not an int representation of the type address. That's good to know.


bobbo(Posted 2004) [#6]
Do you know why there is no documentation for these two commands? I have the latest version of BlitzPlus.


Gauge(Posted 2004) [#7]
well though i'm sure these commands are nice to have, it doesn't work the way i'd hoped. If I do:
Type playerlist
Field player$
End Type

Type player
Field name$
End Type

p.playerlist=New playerlist
player$="jack"
p\player$=Handle(New player)
pl.player=Object.player(p\player$)
pl\name$="Jack"
Print pl\name$
player$="john"
p\player$=Handle(New player)
pl.player=Object.player(p\player$)
pl\name$="john"
Print pl\name$

For pl.player=Each player
Print pl\name$
Next

player$="jack"
pl.player=Object.player(p\player$)
Print pl\name$
WaitKey()


It makes two players, but It only saves one player$, which means i'd still have to revert to use arrays so it doesn't help any. The thing i was trying to avoid was for next loops, and redimming an array(well sorta), so i could have some type of pointer to that player. Right now what i'm doing is dimming p.player by 1000. And keeping a continous usercount, so each player increments ucount by 1 so i can have a pointer?(if this is the right word) to it. But when a player hangs, it resaves information to each player, well heres what i'm using right now:

Function Logoff(p.player)
If Not Eof(p\stream)
	Print p\name$+" has logged off!"
	WriteLine p\stream, "GOODBYE!...come back soon!"
	CloseTCPStream(p\stream)
	EndIf
	jhk=p\playerID
	;Print "player id deleteing: "+jhk
	Select True
	Case jhk=1 And ucount#=1
		ucount#=oucount#-1
		Delete pl(1)
	Case jhk=ucount#
		Delete pl(ucount#)
		ucount#=ucount#-1
	Case jhk<>ucount#
	jhk=jhk+1
	For x=jhk To ucount# Step 1
	Print "Redimming player #"+x
	k=x-1
	stream=pl(x)\stream
	pl (k)\stream=stream
	;Print "player_id"+pl(x)\playerID+" larger Then A!="+a
	pl(k)\playerid=pl(x)\PlayerId-1
	pl(k)\status=pl(x)\status
	pl(k)\level=pl(x)\level
	pl(k)\name$=pl(x)\name$
	pl(k)\password$=pl(x)\password$
	pl(k)\password$=pl(x)\Curr_Area
	pl(k)\curr_room=pl(x)\curr_room
	pl(k)\title$=pl(x)\title$
	pl(k)\pclass$=pl(x)\pclass$
	pl(k)\prace$=pl(x)\prace$
	pl(k)\pracenumber=pl(x)\pracenumber ;?
	pl(k)\pclassnumber=pl(x)\pclassnumber;?
	pl(k)\sex$=pl(x)\sex$
	pl(k)\comm=pl(x)\comm
	pl(k)\experience#=pl(x)\experience#
	pl(k)\baseexp#=pl(x)\baseexp#
	pl(k)\exptnl#=pl(x)\exptnl#	
	Next
	Print "Deleting player#"+ucount#
	Delete pl(ucount#)
	ucount#=ucount#-1
	End Select
	Print "End Logoff"
End Function


What would be nice if i could input a name, or string to use as a variable or in an array so that i could input the players name from readstream, which would be from a string. Right now I have to use numbers. Using a string$ as a pointer to that variable would be very nice. for example:

Currently it works like this:
command="kill" target="Dave"
finds him on room\alsohere ; x
grabs his playersid;which looks like this:
y=a(curr_area)\ro[curr_room]\al[x]\Alsoid
then check p(y)(player) for all the other game crap

The only other way to do this would be to run a bunch of for next loop, which would be horrible for time/effiency,etc, considering i'd have to loop several times for each player. Wether it be writing to the player, the players in the rooms, adjancent rooms, etc.

it'd be nice if i could use there name, unless theres some other way, if there is, lemme know.


Curtastic(Posted 2004) [#8]
why do you think you 'have to' use arrays?
If I were making the program, the areas would be a linked list, they would each have a linked list of rooms, and a list of players. and they would not have a field for 'ID'. well, usually I dont.

if you are using a name to find a player, then youre going to have to search all of the players to find it, whether you use arrays or types. or use a hash table, that should be quick


Curtastic(Posted 2004) [#9]
instead of moving all of the fields, you can just change the pointers in the array

Function Logoff(p.player)
If Not Eof(p\stream)
	Print p\name$+" has logged off!"
	WriteLine p\stream, "GOODBYE!...come back soon!"
	CloseTCPStream(p\stream)
	EndIf
	jhk=p\playerID
	;Print "player id deleteing: "+jhk
	Select True
	Case jhk=1 And ucount#=1
		ucount#=oucount#-1
		Delete pl(1)
	Case jhk=ucount#
		Delete pl(ucount#)
		ucount#=ucount#-1
	Case jhk<>ucount#
	jhk=jhk+1
	For x=jhk To ucount# Step 1
	Print "Redimming player #"+x
		pl(x-1)=pl(x)
	Next
	Print "Deleting player#"+ucount#
	Delete pl(ucount#)
	ucount#=ucount#-1
	End Select
	Print "End Logoff"
End Function


you should probably learn everything there is to know about blitz types before doing a large program like this


Gauge(Posted 2004) [#10]
thanks, thats cool i didn't know you could do that, i appreciate it *smile*