fyi
Quote:
But it surprises me, that it doesn't matter if I use ((TEXT*)Object).pos_x = PositionX; or ((PANEL*)Object).pos_x = PositionX; in my code above. Both works independet from which type is passed... (?)


After the typecasting the compiler knows the type, which is in the first example "TEXT*". It doesn't really matter which object "Object" really is. The compiler thinks it's type is "TEXT*". The "." is reinterpreteted as "->". The "->" leads to a resolving of the pointer (so access the memory area behind the pointer). The "pos_x" tells the compiler the offset to the value of the pointer "Object". The type of "pos_x" tells the compiler how many bytes he has to erase / overwrite with PositionX.

If now PANEL* and TEXT* "pos_x/y" parameters have the same offset, and the parameters have the same type, the code will work identically for the compiler.

That's by the way, the way handle works. Handle() just reads out the index in the C_LINK structure in the engine object. As you see in ANY engine object, the C_LINK structure is the FIRST parameter (offset 0).
So actually handle does nothing but:

ENTITY* obj = ...;
int handle_of = ((int)*((void*)obj)));

This code just interpretes the first 4 bytes of the ENTITY object as integer. As you can see in the struct the first 4 bytes of any engine-object (STRING,PANEL etc.) is filled with the C_LINK struct. The first 4 Bytes of the C_LINK struct is filled with the index of an object.

That's why: handle is extremly fast (ptr_for_handle is not that fast as it has to iterate over a linked list, with a complexity of O(N), which is never that fast - though as you know, the index of an object also contains the type, which makes things a little bit slower).