Table of Contents

Class ItemSlotPendingSet

Namespace
FishMMO.Client
Assembly
FishMMO.Client.dll

Tracks which slots of one item container have a request outstanding with the server.

public sealed class ItemSlotPendingSet
Inheritance
ItemSlotPendingSet
Inherited Members

Remarks

The item panels submit a request and then do nothing until the server's echo arrives. That leaves a window — one round trip, which on a bad connection is a long time — in which the slot still looks exactly as it did, so a second click submits the same operation again. Two equips of the same inventory slot, or two deposits of the same stack, is not a cosmetic problem: the server processes both, and what the second one does depends entirely on what the first one left behind.

Each outstanding slot gets its own PendingReplyGuard — the same watchdog the four login panels use — so a request whose reply never arrives hands the slot back instead of leaving it dead for the rest of the session. The reply can go missing for reasons the client cannot see: a handler that returned before broadcasting, a dropped packet on an unreliable path, a scene handover. The guard does not care which.

Guards are keyed by slot and kept after release rather than removed, because a player working out of one bag drags the same handful of slots over and over and re-allocating a guard per click would churn for no reason. Count therefore counts guards, not pending slots; HasAnyPending is the question worth asking.

Fields

ItemOperationTimeoutSeconds

How long an item operation may go unanswered before the slot is handed back.

public const float ItemOperationTimeoutSeconds = 8

Field Value

float

Remarks

Much shorter than DefaultTimeoutSeconds, and deliberately so. The login panels wait on a database round trip that a human has already been told to expect; an item click is a reflex, and a slot that stays locked for half a minute after a dropped reply reads as the game being broken. Still far longer than any healthy round trip, so a merely slow server is never mistaken for a silent one.

Properties

HasAnyPending

True while any slot in this container is waiting on the server.

public bool HasAnyPending { get; }

Property Value

bool

PendingCount

Number of slots that currently have a request outstanding.

public int PendingCount { get; }

Property Value

int

Methods

CollectExpired()

Collects the slots whose wait has just expired.

public List<int> CollectExpired()

Returns

List<int>

Slots released by timeout on this call. Empty when none expired.

Remarks

HasExpired() is self-clearing and reports true exactly once per wait, so this can be driven straight from a per-frame tick and each slot is handed back once. The returned list is reused; copy it if you need to keep it.

IsPending(int)

Reports whether a request is outstanding on slot.

public bool IsPending(int slot)

Parameters

slot int

Container slot index.

Returns

bool

True while the slot is waiting on a server reply.

Release(int)

Ends the wait on slot.

public bool Release(int slot)

Parameters

slot int

Container slot index.

Returns

bool

True when the slot had been waiting, so the caller knows to repaint it.

ReleaseAll(List<int>)

Ends every outstanding wait, reporting the slots that were released.

public void ReleaseAll(List<int> releasedInto = null)

Parameters

releasedInto List<int>

Receives the released slot indices. May be null.

Remarks

Used by every teardown path — panel close, character change, quit to login, destroy. A lock that outlives the panel it belongs to is worse than no lock at all: the slot is rebuilt from the container looking normal, but the set still refuses the next click.

TryBegin(int, float)

Claims slot for a request that is about to be sent.

public bool TryBegin(int slot, float timeoutSeconds = 8)

Parameters

slot int

Container slot index.

timeoutSeconds float

Seconds to wait for the reply.

Returns

bool

True when the slot was free and is now claimed.

Remarks

This is the double-submit guard itself: it returns false when the slot already has a request in flight, and the caller must then send nothing at all. Returning false rather than replacing the existing wait matters — replacing it would reset the watchdog on every click, so a player clicking a stuck slot repeatedly would never let it time out.