Are Entities and Handle()s unique?

Blitz3D Forums/Blitz3D Programming/Are Entities and Handle()s unique?

octothorpe(Posted 2005) [#1]
type foo
	field bar
end type
o.foo = new foo
h = handle(o)
e = createcube()
if h = e then octothorpe$ = "sad"
Can I safely expect that entities and handles will never share the same value?


Curtastic(Posted 2005) [#2]
handle()s always start at 1 and go up to TheAmountOfObjectsYouHaveCalledHandleWith

entities always seem to be big numbers like 4033962


Shifty Geezer(Posted 2005) [#3]
Entity and object variable values are pointers to memory addresses where the created objects exist. The show where in your computers memory these objects are. No objects get created in the same space as existing objects. If the did you get disappearing objects and all sorts of trouble.

The 'Handle' command isn't documented on my version of Blitz. I think it returns a counter of which object out of all created objects the object your referencing is. I can't see any use for this myself. I guess that's why it's not documented?


octothorpe(Posted 2005) [#4]
Thanks for your help!

Blast. I had hoped Handle() was returning pointers addressing the same memory that Entity values do. Since it's returning an element index for some internal Blitz array, it can't be guaranteed that a Handle() will never equal an Entity value.

Handles are useful for encapsulation. You can store references to objects within objects that don't need to know what class of object they're referencing. I find this extremely useful for (a) polymorphism (e.g. my list and hash container classes), and (b) storing references to objects in entities (by setting EntityName(e, "unit"+Handle(u))).


Techlord(Posted 2005) [#5]
I'm not a big fan of the Handle/Object commands myself which is why I use a Array of Types and home-brewed ID management scheme.


Shifty Geezer(Posted 2005) [#6]
octothorpe : An entity value will always be a very large value as the OS chugs up the first umpteen megs of RAM. Handle() should never equal an Entity value unless you have several million entities. A quick test shows a sprite created at 10615232 and a sphere created at 21826408. That's 10 million entities before Handle starts to encroach! It also looks like different entity types are stored in different locations, as the mesh was stored much deeper in the memory than the sprite.

Regards using Handle(), looking at your List code I see the entity can be retrieved through Object(). So Blitz is storing the pointers to entities and types in it's own array, and Handle() returns which array index a given entity is, and Object() returns the pointer held at that index? I've just tried...

c.cat=New cat
h=Handle(c)
p=Object(h)
Text 320,250,"Handle "+p

...and I get a compilation error 'Expecting Identifier'. Can you explain a bit more about Object()? A linked list might be an excellent addition to my current program. I currently use an array of types but deleting entities leaves holes in my array that it'd be awkward to manage. A linked list a much more sensible solution to the problem I think.


RGR(Posted 2005) [#7]
Shifty Geezer
Try it that way:




Techlord(Posted 2005) [#8]
Shifty Geezer

I use a FILO stack to manage the IDs. Its a ideal way to recycle IDs if you create/delete objects often. You can use either array or bank.

You load the stack with IDs then pop IDs off when creating objects and push IDs back on when deleting them.

There are 100 ways one could implement ID management. Heres one using a single index array:



octothorpe(Posted 2005) [#9]
The syntax for Object() is obj.type = Object.type(hnd). Handle() and Object() are extremely useful and shouldn't be undoumented. :(

<Shifty Geezer> A linked list might be an excellent addition to my current program.


Check out my double-linked list library in the Code Archives. Let me know if you have any problems or if there are missing features you need.

<Frank Taylor> Heres one using a single index array


Interesting. You're using a container (a FILO stack) to manage another container (an array.) If you're removing elements, it might be simpler to replace these two containers with a single linked-list. While you don't get IDs with linked lists (unless you create another container for doing lookups,) I find it's usually easy to avoid IDs and lookups, instead storing references to the objects themselves. When I do need IDs, I generally want them to be strings, and so I use a hash container (aka maps, dictionaries).

Linked lists and hashes are slower than vectors (a vector is an idealized one-dimensional arrays) for most list operations, but unless you're in a tight loop the difference is negligible. Vectors are great if you need speed, arbitrary numeric lookups, and won't be removing elements often.

Blitz arrays serve as vectors, but have additional drawbacks: they must be global and you cannot reference them. This means a function will only be able to operate on the arrays that have been hard-coded into it - you can't encapsulate anything to do with arrays. You can't have a function RemoveBadOnes() which will operate on either your winkies or sprockets arrays. One day I'll write a Vector Container library using banks, so I'll be able to have the advantages of vectors without the disadvantages of Blitz arrays.


Techlord(Posted 2005) [#10]
octothorpe,

I use IDs because I find it to be a easier way to link diffent types to different types compared to using types within types. The methodoloy is similar to using relational ID keys in Database tables.

A stack provides a easy way for recycling IDs. Its for objects that created and deleted frequently. Some objects are created once and never deleted. Simply incrementing the IDs by 1 upon the creation of a object is all thats needed.

I have also can found it easier to operate on the data with Editors at design-time and reference one object to another by ID. Object/Handle are assigned by Blitz the ID at run-time in a sequential order. This can really complicated ID assignment at design time. Interestingly, you may have a need to recycle IDs at design time but, not at runtime.


octothorpe(Posted 2005) [#11]
I use IDs because I find it to be a easier way to link diffent types to different types compared to using types within types.


Funny, I thought the easiest way to link objects (types) to different objects was to have your objects have references to each other (types within types). foo\bar seems much simpler to me than bar[foo\bar_id].

Yes, if you need keys (IDs) (and since you're talking about dealing with externally-derived data, you probably do,) you have the choice of either a vector (array) or a hash. They each have their advantages and disadvantages.

Object/Handle are assigned by Blitz the ID at run-time in a sequential order. This can really complicated ID assignment at design time.


Whoa. That's a whole different bag of worms. Handle() essentially returns pointers, which are useful for when you want to store a reference to an object somewhere that's not type-qualified. Although it's feasible that you might use Handle() to generate unique IDs for serializing a bunch of objects without their own IDs, you certainly wouldn't want to use those IDs as vector keys!


Ross C(Posted 2005) [#12]
Remember the number returned using handle command will increase then wrap round to a - number as it's a 32 bit number. Then it will eventually go back to 0. The likely hood of you overwriting a previous handle are quite small though. Morduun once run a test of creating a handle every loop and took about an hour and a half i think. But, it's just a warning :o)