Skip to content

Instantly share code, notes, and snippets.

@polerin
Created January 30, 2020 18:59
Show Gist options
  • Save polerin/990d968cf583324fcf16cfb998c81e5e to your computer and use it in GitHub Desktop.
Save polerin/990d968cf583324fcf16cfb998c81e5e to your computer and use it in GitHub Desktop.
lolAbstract
using System.Collections.Generic;
using Zenject;
using SMG.EventBus.Interfaces;
using SMG.Proximity.Players;
namespace SMG.Proximity.GameFlow
{
public abstract class AbstractContest<StatusType> : IContest
where StatusType : IPlayerContestStatus
{
public ContestState State { get; protected set; }
public bool IsReady { get; protected set; }
public int OpenSpots { get { return settings.maxParticipants - participants.Count; } }
public Dictionary<int, IPlayerContestStatus> participantStatus { get; protected set; }
protected Dictionary<int, IPlayer> participants;
protected IContestSettings settings;
protected IEventBus<IEvent> eventBus;
protected PlaceholderFactory<IPlayer, IContestSettings, StatusType> playerContestStatusFactory;
#region Lifecycle
public AbstractContest(
IEventBus<IEvent> eventBus,
PlaceholderFactory<IPlayer, IContestSettings, StatusType> playerContestStatusFactory)
{
this.eventBus = eventBus;
this.participants = new Dictionary<int, IPlayer>();
this.participantStatus = new Dictionary<int, IPlayerContestStatus>();
this.playerContestStatusFactory = playerContestStatusFactory;
}
~AbstractContest()
{
// probably already cleaned up, but doesn't hurt to double check
UnregisterListeners();
}
protected virtual void UnregisterListeners()
{
// intentional no-op
}
#endregion lifecycle
#region progress control
public virtual void Start()
{
State = ContestState.inProgress;
}
public virtual void End()
{
if (State == ContestState.won) {
State = ContestState.completed;
}
UnregisterListeners();
}
#endregion progress control
#region participant management
public void RegisterParticipants(IEnumerable<IPlayer> newParticipants)
{
foreach (IPlayer participant in newParticipants) {
RegisterParticipant(participant);
}
}
public virtual void RegisterParticipant(IPlayer participant)
{
if (participants.Count >= settings.maxParticipants) {
// @todo Does this really need to be an exception, and if so, where do we need to catch
throw new EventFullException("Attempting to add more than the maximum players to the Race");
}
// @todo this needs to be in a factory, can't be arsed to figure it out right now
participantStatus.Add(participant.id, playerContestStatusFactory.Create(participant, settings));
eventBus.Publish<ParticipantJoined>(new ParticipantJoined(participant));
}
public void RemoveParticipants(IEnumerable<IPlayer> participants)
{
foreach (IPlayer participant in participants) {
RemoveParticipant(participant);
}
}
public virtual void RemoveParticipant(IPlayer participant)
{
if (participants.ContainsKey(participant.id)) {
participants.Remove(participant.id);
}
if (participantStatus.ContainsKey(participant.id)) {
participantStatus.Remove(participant.id);
}
}
public IPlayerContestStatus GetParticipantStatus(IPlayer participant)
{
return GetParticipantStatus(participant.id);
}
public IPlayerContestStatus GetParticipantStatus(int participantId)
{
if (participantStatus.ContainsKey(participantId)) {
return participantStatus[participantId];
}
throw new PlayerNotParticipantException("Unable to locate participant with id: " + participantId);
}
public PlayerContestState GetParticipantContestState(int playerId)
{
return GetParticipantStatus(playerId).playerState;
}
public PlayerContestState GetParticipantContestState(IPlayer player)
{
return GetParticipantStatus(player.id).playerState;
}
public bool IsParticipantReady(IPlayer participant)
{
return IsParticipantReady(participant.id);
}
public bool IsParticipantReady(int playerId)
{
if (participantStatus.ContainsKey(playerId)) {
return (participantStatus[playerId].playerState == PlayerContestState.ready);
}
throw new PlayerNotParticipantException("Attempting to check player readiness when they are not an event participant");
}
#endregion participant management
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment