How does Handle() work exactly? + linklist stuff

Blitz3D Forums/Blitz3D Programming/How does Handle() work exactly? + linklist stuff

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

Does Handle() record the object's location in an internal array?

What happens to the Handle() index 3? What is I now create another cat? Does it fill the hole or get tagged on the end?


Yeah, Blitz keeps track of handles in its own array or something. The holes don't seem to get filled.

But all of this is academic: it shouldn't matter to you, since you can't do anything with Handles except pass them to Object() and test them for equality. Handle() might as well be returning you a real pointer... as long as you don't want to do pointer arithmetic.

For me to construct a linked list of, given the above example, cats, I would have to use Handle() on every cat object I create. I could point each cat object to others using a .cat field and object.xxx().


If your next_node field is of type cat, you wouldn't need Handle() at all. You can construct a fully featured linked list without using Handle(). Here's the basic idea:
Type foo
	Field next_node.foo
End Type

f1.foo = New foo
f2.foo = New foo
f1\next_node = f2
The only reason you should need Handle() is if you want to keep references to objects of different types.
Type ferret
	Field colour$
End Type

Type emu
	Field bites
End Type

Type person
	Field pet
	Field pet_class$
End Type

p.person = New person
e.emu = New emu
e\bites = True
p\pet = Handle(e)
p\pet_class$ = "EMU"
go_for_a_walk(p)

Function go_for_a_walk(this_person.person)
	If this_person\pet_class$ = "FERRET" Then
		this_ferret.ferret = Object.ferret(this_person\pet)
		Print "Your "+this_ferret\colour$+" ferret escapes!"
		Delete this_ferret
		this_person\pet = 0
		this_person\pet_class$ = ""
	ElseIf this_person\pet_class$ = "EMU" Then
		this_emu.emu = Object.emu(this_person\pet)
		If this_emu\bites Then
			Print "Your emu bites you!"
		Else
			Print "Everything is swell."
		EndIf
	ElseIf this_person\pet_class$ = "" Then
		Print "Your loneliness causes you to sink deeper into depression"
	Else
		RuntimeError "invalid this_person\pet_class$ = " + this_person\pet_class$
	EndIf
End Function
This example may seem trivial (why not just use a field for each pet type - emu.emu and ferret.ferret) but consider this:

The problem with designing a linked list which manages objects of type foo is that you'll be hard-coding all your functions to deal with type foo. If you wind up needing a second linked list for objects of type bar later on, (or worse, a second linked list of objects of type foo!) you'd need to copy all your functions. Handle() to the rescue! If you write all your linked list code to manage a list of integers instead of type objects, then you can store Handles in there and turn them back into Objects when you retrieve the values.

This example uses my double linked list library.

include "listType.bb"

; create some objects
type fooType
	field value$
end type
x.fooType = new fooType : x\value$ = "bar"
y.fooType = new fooType : y\value$ = "baaz"
z.fooType = new fooType : z\value$ = "quux"

; push them into a new list
list.listType = new listType
list_push(list, handle(x))
list_push(list, handle(y))
list_push(list, handle(z))

; iterate over our list
list_iterator_begin(list)
while list_iterator_next(list)
	this_element.fooType = object.fooType(list_iterator_get(list))
	print this_element\value$
wend
You use Handle() when you put things into the list, and Object() when you take them out. The linked list only has to worry about integers, and you get to store whatever you want in there. The only drawback is that it's up to you to make sure that you don't mix types.