Struct SessionId
One connected client's identity: a 16-bit table slot and a 16-bit generation packed into a 32-bit value.
public readonly struct SessionId : IEquatable<SessionId>
- Implements
- Inherited Members
Remarks
It fits in a component. That is the whole reason for the packing: an application that possesses an avatar stores the session on the entity, and a 32-bit field costs nothing beside the entity's own data. It is also why the session table's hard maximum is 65 535 rather than a number somebody chose — a slot wider than a ushort does not exist.
The generation is what makes a recycled slot safe. Slots are reused, so a bare slot number would let a stale reference — a component written three ticks ago, a command that arrived late — address whichever client now occupies it. The generation rises every time a slot is handed out again, so a stale id fails its lookup instead of quietly naming a stranger. A generation of zero is never issued, which makes default mean "no session" and costs one value out of 65 536.
The generation wraps after 65 535 reuses of one slot and skips zero as it goes. Wrapping is not a correctness hole here: it would take a stale reference surviving 65 536 connections on the same slot to collide, which is a lifetime no engine structure has.
Constructors
SessionId(ushort, ushort)
Creates an identity from a slot and a generation.
public SessionId(ushort slot, ushort generation)
Parameters
slotushortThe session table row.
generationushortHow many times that row has been handed out. Zero means "no session".
Properties
Generation
How many times that row had been handed out when this identity was issued.
public ushort Generation { get; }
Property Value
IsValid
Whether this names a session at all. A zero generation is never issued, so it is the one value that cannot.
public bool IsValid { get; }
Property Value
None
The absent session. Its generation is zero, which is never issued.
public static SessionId None { get; }
Property Value
Slot
The session table row this identity names.
public ushort Slot { get; }
Property Value
Value
The packed value, as it travels in WELCOME and as a component field stores it.
public uint Value { get; }
Property Value
Methods
Equals(object)
public override bool Equals(object obj)
Parameters
objobject
Returns
Equals(SessionId)
public bool Equals(SessionId other)
Parameters
otherSessionId
Returns
FromValue(uint)
Rebuilds an identity from its packed value — from the wire, or from a component field.
public static SessionId FromValue(uint value)
Parameters
Returns
- SessionId
The identity. It is not validated against the table; a lookup is what decides whether it still names a live session.
GetHashCode()
public override int GetHashCode()
Returns
ToString()
public override string ToString()
Returns
Remarks
Both halves are printed, because a log that shows only the slot cannot distinguish the client that just left from the one that took its row — which is exactly the confusion the generation exists to prevent.
Operators
operator ==(SessionId, SessionId)
Compares two identities.
public static bool operator ==(SessionId left, SessionId right)
Parameters
Returns
operator !=(SessionId, SessionId)
Compares two identities.
public static bool operator !=(SessionId left, SessionId right)