Orbiter-Forum  

Go Back   Orbiter-Forum > Orbiter Space Flight Simulator > Orbiter SDK
Register Blogs Orbinauts List Social Groups FAQ Projects Mark Forums Read

Orbiter SDK Orbiter software developers post your questions and answers about the SDK, the API interface, LUA, meshing, etc.

Reply
 
Thread Tools
Old 11-05-2018, 09:00 PM   #1
fred18
Addon Developer

Default Handles, void* and casting

Hi guys,

I've been working a bit in these days and I have the following doubt.

Let's say that I am making a project and that I also make the relevant APIs and SDK for others to use it.

Let's also say that I want to put Handles made by myself in it. Actually it is not the case but I am in the exact position of implementing this and I am willing to learn how to properly do it.

The thing I am working on is a linking system between vessels which will behave phisically like docking but with the commands and hierarchy of attachments.

So I have a std::vector holding the list of all the links in the sim which are processed at every frame.

The links are identified by a unique index, which never changes during runtime and that never duplicates.

So if I want to identify the link I can refer to its index, which means (to my eyes) that the index is the best candidate for a linkhandle here.

So I made the linkAPI.h which basically just contains
Code:
typedef void* LINKHANDLE;
and then when I pass the linkhandle in the process the handle gets casted back to integer to get the index.

The issue I am encountering is relevant to the void* pointer and to pointers in general... for example in a function if I try to use the static_cast it doesn't work:

Code:
bool LinkManager::ActivateLink(LINKHANDLE lh) {
	int index = static_cast <int>(lh);
...
...
return FALSE;
}
the compiler says that this conversion of type is not valid and my guess is that because void* is a pointer while int is not.

if I change it to
Code:
int* index = static_cast <int*>(lh);
then the conversion works, but I don't want a pointer to an integer, I want an integer to use so it seems not useful to me (even if I realize that pointers can work also this way if only I could get it...)

but to my surprise this works fine even though my feel is that it's not right:

Code:
bool LinkManager::ActivateLink(LINKHANDLE lh) {
	int index = (int)lh;
...
... 
return FALSE;
}
So... what's the proper way to do it?

thanks in advance to anyone!
fred18 is online now   Reply With Quote
Old 11-05-2018, 09:05 PM   #2
Face
Beta Tester
 
Face's Avatar

Default

Why is the handle of type void pointer to start with? Just define it as integer and be done with it.

Besides this, there is nothing bad about using a C-style cast. It just tells the compiler to use the value as a different type.
Face is offline   Reply With Quote
Thanked by:
Old 11-05-2018, 09:13 PM   #3
Urwumpe
Certain Super User
 
Urwumpe's Avatar

Default

The proper way is the way that it works without bugs. I would also recommend using an long or another value and not a pointer.

Especially because pointers are not type-safe as I had to experience a few weeks ago: sizeof(void*) is 4 on a 32-bit system, but 8 on a 64-bit system. It could really drive you mad, if you are expecting a 32 bit value there.
Urwumpe is online now   Reply With Quote
Thanked by:
Old 11-05-2018, 09:24 PM   #4
fred18
Addon Developer

Default

Quote:
Originally Posted by Face View Post
 Why is the handle of type void pointer to start with? Just define it as integer and be done with it.
to be honest I gave a look at orbiterAPI.h and all the handles there are defined as typedef void*, so I used the same to see how it worked... I don't know if that is because the scope of the handle is to "hide" the real implementation behind a certain process.

Quote:
Originally Posted by Face View Post
 Besides this, there is nothing bad about using a C-style cast. It just tells the compiler to use the value as a different type.
Quote:
Originally Posted by Urwumpe View Post
 The proper way is the way that it works without bugs. I would also recommend using an long or another value and not a pointer.
"Safety" is the reason why I tried only with static_cast (AFAIK it's the safest way to cast). I'll define the handle as an integer anyway and I will sleep better because it's surely much safer

One question though: if I use something like "typdef int LINKHANDLE" then can I use the handle as an integer itself or shall I cast to an integer when I use it ?
fred18 is online now   Reply With Quote
Old 11-05-2018, 09:53 PM   #5
Urwumpe
Certain Super User
 
Urwumpe's Avatar

Default

Quote:
Originally Posted by fred18 View Post
 One question though: if I use something like "typdef int LINKHANDLE" then can I use the handle as an integer itself or shall I cast to an integer when I use it ?

I would cast once at the beginning of a function and never use a LINKHANDLE then in any code where you are doing integer operations.


Simply for avoiding any possible mistake that might arise from assuming a LINKHANDLE is always an integer. Of course, it must be so, because otherwise, the initial cast will fail.



But more so, you can assert automatically if the initial cast is valid, while this would be impossible if you assume that the LINKHANDLE is an integer. For example, you could start counting your LINKHANDLE with 10000, so any integer case from it with less than 10000 would be invalid. Same with using prime number steps there other than 2. For example, if you use LINKHANDLE = 100000 + 7 * index - you can quickly check with a modulus, if the handle is not result of an illegal operation.
Urwumpe is online now   Reply With Quote
Thanked by:
Old 11-06-2018, 07:18 AM   #6
jedidia
shoemaker without legs
 
jedidia's Avatar
Default

Honestly, if your object is already hidden inside a vector, and all you expose is its index, I don't quite see the point of using a handle architecture in the first place. The whole point of a handle is to pass objects around without granting access to them (well, not too obvious access, anyways), a goal that you can easily achieve safer by proper access methods.
The advantage of using handles is that code that receives a handle doesn't need to have access to the data structure containing the object, because it already has the object, but if your handle is an index used to retrieve the object, that advantage is gone and it must be assumed that providing proper access to everybody who needs it isn't a problem. So... just use the index. You can still typedef an int if you think that leads to clearer code, but passing an index as a handle has no benefit and unnecessarily makes your code more obtuse and unsafe.
jedidia is offline   Reply With Quote
Thanked by:
Reply

  Orbiter-Forum > Orbiter Space Flight Simulator > Orbiter SDK


Thread Tools

Posting Rules
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
Forum Jump


All times are GMT. The time now is 11:23 AM.

Quick Links Need Help?


About Us | Rules & Guidelines | TOS Policy | Privacy Policy

Orbiter-Forum is hosted at Orbithangar.com
Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Copyright 2007 - 2017, Orbiter-Forum.com. All rights reserved.