public bool TryGet(int slot, out UserReady userReady) { if (unchecked ((uint)slot < (uint)SlotCount)) { userReady = slots[slot]; return(true); } userReady = default; return(false); }
public Error GetPlayerReady(string gameId, int slot, out UserReady userReady) { userReady = default; var game = Games.TryGet(Id.Partial(gameId)); if (game == null) { return(Error.Codes.E01GameNotFound); } var sed = game.Phase.Setup.Data; if (sed == null) { return(Error.Codes.E03NotInSetupPhase); } return(sed.TryGet(slot, out userReady) ? Error.Codes.E00NoError : Error.Codes.E10InvalidSlotIndex); }
public Error SetSlotReady(string gameId, int slot, UserReady userReady) { if (!Users.ContainsId(Id.Partial(userReady.UserId))) { return(Error.Codes.E02UserNotFound); } var game = Games.TryGet(Id.Partial(gameId)); if (game == null) { return(Error.Codes.E01GameNotFound); } var setup = game.Phase.Setup; if (setup == null) { return(Error.Codes.E03NotInSetupPhase); } return(setup.TrySetSlotReady(slot, userReady)); }
// WARNING: does NOT check that the user exists! internal Error TrySetSlotReady(int slot, UserReady ur) { PhaseData @new, old; do { old = data; if (old.IsFinalLocked) { // final locked: game is being transitioned to the next phase. return(Error.Codes.E03NotInSetupPhase); } if (unchecked ((uint)slot >= (uint)old.SlotCount)) { return(Error.Codes.E10InvalidSlotIndex); } @new = old.TrySetSlotReady(slot, ur); if (@new == old) // no change { return(Error.Codes.E00NoError); } if (@new == null) { if (old.IsEmpty) { // game is in the process of being removed, hence "not found". return(Error.Codes.E01GameNotFound); } else { return(Error.Codes.E12UserIdMismatch); } } }while (Interlocked.CompareExchange(ref data, @new, old) != old); return(Error.Codes.E00NoError); }
: null; // userId mismatch // WARNING: does NOT check slot index range! // WARNING: does NOT check for duplicates! // WARNING: does NOT check MaxUsers! private PhaseData SetSlot(int slot, UserReady ur) => new PhaseData(slots.Copy().Modify(slot, ur), others);
// WARNING: does NOT check slot index range! // WARNING: does NOT check that user exists! internal PhaseData TrySetSlotReady(int slot, UserReady ur) => slots[slot].UserId == ur.UserId ? slots[slot].IsReady == ur.IsReady ? this // no change : SetSlot(slot, ur) : null; // userId mismatch
// WARNING: does NOT check slot index range! // WARNING: does NOT check that slot is vacant! private PhaseData TryMoveFromOthersToSlot(int slot, UserReady ur) => TryFindOther(ur.UserId, out int otherIndex) ? new PhaseData(slots.Copy().Modify(slot, ur), others.CopyRemoveAt(otherIndex)) : null;
public static PlayerReady ToModel(UserReady ur) // static for elegant use with Linq => new PlayerReady { UserId = ur.UserId, Ready = ur.IsReady };