CHandle: Difference between revisions
Jump to navigation
Jump to search
Tip:CHandles are slower to access than pointers. If you create pointers for access purposes and are supporting saved games, remember to repopulate them in
Note:CHandles are only designed to work with fully fledged entities (as opposed to temporary particle effects and the like) which inherit from IHandleEntity. Attempting to assign an incompatible entity can result in ambiguous/technical runtime errors.
TomEdwards (talk | contribs) (this just in: apparently not actually that slow) |
SirYodaJedi (talk | contribs) (I understood the edit comment on the ai_hint page better than this page) |
||
(7 intermediate revisions by 6 users not shown) | |||
Line 1: | Line 1: | ||
{{lang|CHandle}} | |||
{{toc-right}} | {{toc-right}} | ||
'''CHandle''' is a C++ class that represents a 32-bit ID (entindex + serial number) unique to every past and present entity in a game. It is used to refer to entities where [[pointer]]s and [[entity index]]es are unsafe; mainly across the client/server divide and after restoring a saved game. | '''CHandle''' is a C++ class that represents a 32-bit ID (entindex + serial number) unique to every past and present entity in a game. It is used to refer to entities where [[pointer]]s and [[entity index]]es are unsafe; mainly across the client/server divide and after restoring a saved game. | ||
{{tip|CHandles are slower to access than pointers. If you | {{tip|CHandles are slower to access than pointers. If you create pointers for access purposes and are supporting saved games, remember to repopulate them in <code>[[Restore()]]</code>!}} | ||
{{note|CHandles are only designed to work with fully fledged entities (as opposed to temporary particle effects and the like) which inherit from IHandleEntity. Attempting to assign an incompatible entity can result in ambiguous/technical runtime errors.}} | |||
{{todo|Layman's explanation of "ehandle" as an [[I/O]] parameter, as the explanation here is more programmer-focused. This is used on a few pages, such as {{ent|ai_hint}} and {{ent|env_projectedtexture}}.}} | |||
== Usage == | == Usage == | ||
Line 9: | Line 13: | ||
CHandle<YourStoredClass> hMyHandle; | CHandle<YourStoredClass> hMyHandle; | ||
A CHandle is broadly similar to a pointer, but as it is a | A CHandle is broadly similar to a pointer, but as it is a custom C++ class, and not a built-in feature, extra syntax is needed in some places: | ||
* You must assign a pointer to | * You must assign a pointer to the object, not the object itself. | ||
* <code>Get()</code> or a cast is required access the class it is storing | * The <code>CHandle</code>'s <code>Get()</code> function, or a cast, is required access the class it is storing. | ||
* <code>IsValid()</code> is | * <code>IsValid()</code> is used to check whether a value is stored. | ||
* To invalidate, call <code>Term()</code> or assign <code>INVALID_EHANDLE_INDEX</code>. | * To invalidate, call <code>Term()</code> or assign <code>INVALID_EHANDLE_INDEX</code>. | ||
== EHANDLE == | == EHANDLE == | ||
CHandle is often used through the <code>EHANDLE</code> typedef, which is shorthand for <code>CHandle<C_BaseEntity></code>. If you want to store a particular class it's better to declare a more specific CHandle manually (see previous section). | CHandle is often used through the <code>EHANDLE</code> typedef, which is shorthand for <code>CHandle<C_BaseEntity></code>. If you want to store a particular class it's better to declare a more specific CHandle manually (see previous section). | ||
Line 32: | Line 35: | ||
pPlayer = dynamic_cast<CBasePlayer*>( hPlayer.Get() );</source> | pPlayer = dynamic_cast<CBasePlayer*>( hPlayer.Get() );</source> | ||
== See | == See also == | ||
* [[Accessing other entities]] | |||
* [[Entity index]] | |||
* [[Networking Entities#Networking_entities|Networking Entities]] | |||
[[Category:Source class]] | |||
[[Category:Variables]] | [[Category:Variables]]<!--Why?--> |
Latest revision as of 01:51, 5 May 2025
CHandle is a C++ class that represents a 32-bit ID (entindex + serial number) unique to every past and present entity in a game. It is used to refer to entities where pointers and entity indexes are unsafe; mainly across the client/server divide and after restoring a saved game.

Restore()
!
Todo: Layman's explanation of "ehandle" as an I/O parameter, as the explanation here is more programmer-focused. This is used on a few pages, such as ai_hint and env_projectedtexture.
Usage
CHandle<YourStoredClass> hMyHandle;
A CHandle is broadly similar to a pointer, but as it is a custom C++ class, and not a built-in feature, extra syntax is needed in some places:
- You must assign a pointer to the object, not the object itself.
- The
CHandle
'sGet()
function, or a cast, is required access the class it is storing. IsValid()
is used to check whether a value is stored.- To invalidate, call
Term()
or assignINVALID_EHANDLE_INDEX
.
EHANDLE
CHandle is often used through the EHANDLE
typedef, which is shorthand for CHandle<C_BaseEntity>
. If you want to store a particular class it's better to declare a more specific CHandle manually (see previous section).
Example
// Create a pointer to an entity
CBasePlayer* pPlayer = gEntList.FindEntityByClassname( NULL, "player" );
// Store it (twice, for demonstration purposes)
EHANDLE hPlayer = pPlayer;
CHandle<CBasePlayer> hPlayer_ = pPlayer;
// Convert the EHANDLE back to a CBasePlayer pointer
pPlayer = dynamic_cast<CBasePlayer*>( hPlayer.Get() );