/// <summary>
        /// Game session monitor (worker thread)
        /// </summary>
        public void GameSessionsMonitorThreadFunc()
        {
            NetworkBackgammonEventQueueElement queueElement = null;

            while (gameSessionsMonitorKeepRunning)
            {
                gameSessionsSemaphore.WaitOne();

                lock (gameSessionsEventQueue)
                {
                    if (gameSessionsEventQueue.Count > 0)
                    {
                        queueElement = gameSessionsEventQueue.Dequeue();
                    }
                }

                if (queueElement != null)
                {
                    if (queueElement.Notifier is NetworkBackgammonGameSession &&
                        queueElement.Event is NetworkBackgammonGameSessionEvent)
                    {
                        NetworkBackgammonGameSession      gameSession      = (NetworkBackgammonGameSession)queueElement.Notifier;
                        NetworkBackgammonGameSessionEvent gameSessionEvent = (NetworkBackgammonGameSessionEvent)queueElement.Event;

                        if (gameSessionEvent.EventType == NetworkBackgammonGameSessionEvent.GameSessionEventType.GameFinished)
                        {
                            // Broadcast the game active event to all registered listeners
                            Broadcast(new NetworkBackgammonGameRoomEvent(NetworkBackgammonGameRoomEvent.GameRoomEventType.PlayerFinished));

                            gameSession.Stop();

                            gameSessions.Remove(gameSession);

                            gameSession = null;

                            GC.Collect();
                        }
                    }
                }

                queueElement = null;
            }
        }
        public void OnEventNotification(INetworkBackgammonNotifier sender, INetworkBackgammonEvent e)
        {
            if (sender is NetworkBackgammonPlayer)
            {
                NetworkBackgammonPlayer player = (NetworkBackgammonPlayer)sender;

                if (e is NetworkBackgammonChallengeResponseEvent)
                {
                    NetworkBackgammonChallengeResponseEvent challengeResponseEvent = (NetworkBackgammonChallengeResponseEvent)e;

                    if (challengeSyncList.Keys.Contains(player))
                    {
                        if (challengeSyncList[player] != null)
                        {
                            challengeSyncList[player].ChallengeAccepted = challengeResponseEvent.ChallengeAccepted;

                            try
                            {
                                challengeSyncList[player].ChallengeSemaphore.Release();
                            }
                            catch (SemaphoreFullException ex)
                            {
                                // TODO: If this exception occurs calling Release too many times...
                            }
                        }
                    }
                }
                else if (e is NetworkBackgammonChatEvent)
                {
                    // Pass the message through to the listeners
                    Broadcast((NetworkBackgammonChatEvent)e);
                }
            }
            else if (sender is NetworkBackgammonGameSession)
            {
                NetworkBackgammonGameSession gameSession = (NetworkBackgammonGameSession)sender;

                if (e is NetworkBackgammonGameSessionEvent)
                {
                    NetworkBackgammonGameSessionEvent gameSessionEvent = (NetworkBackgammonGameSessionEvent)e;

                    if (gameSessionEvent.EventType == NetworkBackgammonGameSessionEvent.GameSessionEventType.GameFinished)
                    {
                        bool newQueueItemAdd = true;

                        NetworkBackgammonEventQueueElement newQueueItem = new NetworkBackgammonEventQueueElement(e, sender);

                        lock (newQueueItem)
                        {
                            /*
                             * if (gameSessionsEventQueue.Count > 0)
                             * {
                             *  NetworkBackgammonEventQueueElement lastQueueItem = gameSessionsEventQueue.Last();
                             *  // Avoid adding the same event (from the same sender) twice
                             *  // Reason: Game Room listens to events from all players, i.e. also
                             *  // both players that are in one Game Session. Thus, all events broadcasted
                             *  // by the Game Session arrive here (at the Game Room) twice
                             *  if (gameSessionsEventQueue.Last().Notifier == sender &&
                             *      gameSessionsEventQueue.Last().Event == e)
                             *  {
                             *      newQueueItemAdd = false;
                             *  }
                             * }
                             */

                            if (newQueueItemAdd)
                            {
                                gameSessionsEventQueue.Enqueue(new NetworkBackgammonEventQueueElement(e, sender));

                                gameSessionsSemaphore.Release();
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 3
0
        public void OnEventNotification(INetworkBackgammonNotifier sender, INetworkBackgammonEvent e)
        {
            // Challegne event

            /*if (e is NetworkBackgammonChallengeResponseEvent)
             * {
             *  NetworkBackgammonChallengeResponseEvent challengeRespEvent = ((NetworkBackgammonChallengeResponseEvent)e);
             *
             *  bool challengeAccepted = challengeRespEvent.ChallengeAccepted;
             *
             *  if ( (NetworkBackgammonClient.Instance.Player.PlayerName.CompareTo(challengeRespEvent.ChallengingPlayer) == 0) ||
             *       (NetworkBackgammonClient.Instance.Player.PlayerName.CompareTo(challengeRespEvent.ChallengedPlayer) == 0)  )
             *  {
             *      if (InvokeRequired)
             *      {
             *          BeginInvoke(new OnChallengeResponseDelegate(ChallengeResponse), challengeAccepted);
             *      }
             *      else
             *      {
             *          ChallengeResponse(challengeAccepted);
             *      }
             *  }
             * }*/
            if (e is NetworkBackgammonGameRoomEvent)
            {
                switch (((NetworkBackgammonGameRoomEvent)e).EventType)
                {
                case NetworkBackgammonGameRoomEvent.GameRoomEventType.PlayerDisconnected:
                {
                    // TODO: Check if player that disconnected was the opposing player

                    if (InvokeRequired)
                    {
                        BeginInvoke(new OnGameRoomDelegate(ShowGameRoomScreen), true);
                        BeginInvoke(new OnShowBoardDelegate(ShowBoard), false);
                    }
                    else
                    {
                        ShowGameRoomScreen(true);
                        ShowBoard(false);
                    }
                }
                break;
                }
            }
            else if (e is NetworkBackgammonChallengeEvent)
            {
                string challengingPlayer = ((NetworkBackgammonChallengeEvent)e).ChallengingPlayer;
                string challengedPlayer  = ((NetworkBackgammonChallengeEvent)e).ChallengedPlayer;

                if (challengingPlayer.CompareTo(NetworkBackgammonClient.Instance.Player.PlayerName) != 0 &&
                    challengedPlayer.CompareTo(NetworkBackgammonClient.Instance.Player.PlayerName) == 0)
                {
                    if (InvokeRequired)
                    {
                        // In case the caller has called this routine on a different thread
                        BeginInvoke(new OnQueryChallengeDelegate(QueryChallenge), challengingPlayer);
                    }
                    else
                    {
                        QueryChallenge(challengingPlayer);
                    }
                }
            }
            else if (e is GameSessionInitialDiceRollEvent)
            {
                GameSessionInitialDiceRollEvent initialDiceRollEvent = (GameSessionInitialDiceRollEvent)e;
                if (InvokeRequired)
                {
                    BeginInvoke(new OnGameRoomDelegate(ShowGameRoomScreen), false);
                    BeginInvoke(new OnShowBoardWithInitialDiceDelegate(ShowBoard), new object[] { true, initialDiceRollEvent });
                }
                else
                {
                    ShowGameRoomScreen(false);
                    ShowBoard(true);
                }
            }
            else if (e is GameSessionPlayerResignationEvent)
            {
                if (InvokeRequired)
                {
                    BeginInvoke(new OnGameRoomDelegate(ShowGameRoomScreen), true);
                    // BeginInvoke(new OnShowBoardDelegate(ShowBoard), false);
                }
                else
                {
                    ShowGameRoomScreen(true);
                    // ShowBoard(false);
                }
            }
            else if (e is NetworkBackgammonGameSessionEvent)
            {
                NetworkBackgammonGameSessionEvent gameSessionEvt = (NetworkBackgammonGameSessionEvent)e;

                if (gameSessionEvt.EventType == NetworkBackgammonGameSessionEvent.GameSessionEventType.GameFinished)
                {
                    if (InvokeRequired)
                    {
                        BeginInvoke(new OnGameRoomDelegate(ShowGameRoomScreen), true);
                        // BeginInvoke(new OnShowBoardDelegate(ShowBoard), false);
                    }
                    else
                    {
                        ShowGameRoomScreen(true);
                        // ShowBoard(false);
                    }
                }
                if (gameSessionEvt.EventType == NetworkBackgammonGameSessionEvent.GameSessionEventType.Terminated)
                {
                    if (InvokeRequired)
                    {
                        BeginInvoke(new OnTerminateDelegate(OnTerminate));
                    }
                    else
                    {
                        OnTerminate();
                    }
                }
            }
        }
Ejemplo n.º 4
0
        public void OnEventNotification(INetworkBackgammonNotifier sender, INetworkBackgammonEvent e)
        {
            if (InvokeRequired)
            {
                Invoke(new NotifyDelegate(OnEventNotification), new object[] { sender, e });
            }
            else
            {
                buttonAction.Enabled = false;
                buttonAction.Text    = "[No Action]";

                #region Sender: Game Room

                if (sender is NetworkBackgammonRemoteGameRoom)
                {
                    try
                    {
                        if (e is NetworkBackgammonGameRoomEvent)
                        {
                            NetworkBackgammonGameRoomEvent gameRoomEvent = (NetworkBackgammonGameRoomEvent)e;

                            switch (gameRoomEvent.EventType)
                            {
                            case NetworkBackgammonGameRoomEvent.GameRoomEventType.PlayerConnected:
                                UpdateConnectedPlayersList();
                                break;

                            case NetworkBackgammonGameRoomEvent.GameRoomEventType.PlayerDisconnected:
                                UpdateConnectedPlayersList();
                                break;
                            }
                        }
                        else if (e is NetworkBackgammonChallengeEvent)
                        {
                            NetworkBackgammonChallengeEvent challengeEvent = (NetworkBackgammonChallengeEvent)e;

                            string challengingPlayer = challengeEvent.ChallengingPlayer;
                            string challengedPlayer  = challengeEvent.ChallengedPlayer;

                            if (challengingPlayer.CompareTo(player.PlayerName) != 0 &&
                                challengedPlayer.CompareTo(player.PlayerName) == 0)
                            {
                                bool challengeResponse = MessageBox.Show(
                                    "Accept game challenge from " + challengeEvent.ChallengingPlayer + "?",
                                    "Game Challenge",
                                    MessageBoxButtons.YesNo,
                                    MessageBoxIcon.Question,
                                    MessageBoxDefaultButton.Button1) == DialogResult.Yes;

                                player.RespondToChallenge(challengeResponse, challengeEvent.ChallengingPlayer);

                                groupBoxGameControls.Enabled = challengeResponse;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        listBoxLog.Items.Add(ex.Message);
                    }
                }

                #endregion

                #region Sender: Game Session

                else if (sender is NetworkBackgammonGameSession)
                {
                    // Filter out broadcasts from our own player
                    if (sender != player)
                    {
                        try
                        {
                            NetworkBackgammonGameSession gameSession = (NetworkBackgammonGameSession)sender;

                            if (e is NetworkBackgammonGameSessionEvent)
                            {
                                // Generate warning if last event has been overwritten
                                // (Currently every event received is supposed to be responded too by means of an
                                //  action (e.g. move, dice roll acknowledge, etc), which resets the last event type to invalid)
                                if (lastGameSessionEventType != null)
                                {
                                    listBoxLog.Items.Add("Warning: Overwriting last event (" + lastGameSessionEventType.ToString() + ") with new event " + e.GetType().ToString() + " (i.e. last event hasn't been responded to by means of an action)");
                                }

                                // Latch the event type
                                lastGameSessionEventType = e.GetType();
                            }

                            #region Actions for initial dice roll

                            if (e is GameSessionInitialDiceRollEvent)
                            {
                                listBoxCheckers.Items.Clear();
                                listBoxMoves.Items.Clear();

                                GameSessionInitialDiceRollEvent gameSessionInitialDiceRollEvent = (GameSessionInitialDiceRollEvent)e;

                                // if (player.InitialDice != null)
                                if (gameSessionInitialDiceRollEvent.GetDiceForPlayer(player.PlayerName) != null)
                                {
                                    listBoxLog.Items.Add("Initial dice rolled: " + gameSessionInitialDiceRollEvent.GetDiceForPlayer(player.PlayerName).CurrentValue);

                                    buttonAction.Enabled = true;

                                    buttonAction.Text = "Confirm initial dice roll";
                                }
                                else
                                {
                                    listBoxLog.Items.Add("Warning: Event received is " + e.GetType().ToString() + " but dice values are missing");
                                }
                            }

                            #endregion

                            #region Actions for checker update

                            else if (e is GameSessionCheckerUpdatedEvent)
                            {
                                listBoxCheckers.Items.Clear();
                                listBoxMoves.Items.Clear();

                                GameSessionCheckerUpdatedEvent gameSessionCheckerUpdateEvent = (GameSessionCheckerUpdatedEvent)e;

                                player = gameSessionCheckerUpdateEvent.GetPlayerByName(player.PlayerName);

                                string strDice = "";

                                foreach (NetworkBackgammonDice d in gameSessionCheckerUpdateEvent.DiceRolled)
                                {
                                    strDice += " " + d.CurrentValue;
                                }

                                listBoxLog.Items.Add("Dice: " + strDice);

                                foreach (NetworkBackgammonChecker checker in player.Checkers)
                                {
                                    listBoxCheckers.Items.Add(checker);
                                }
                            }

                            #endregion

                            #region Actions for move expected

                            else if (e is GameSessionMoveExpectedEvent)
                            {
                                GameSessionMoveExpectedEvent gameSessionMoveExpectedEvent = (GameSessionMoveExpectedEvent)e;

                                if (player.PlayerName == gameSessionMoveExpectedEvent.ActivePlayer)
                                {
                                    listBoxLog.Items.Add("I'm the active player, expected to make the next move ...");

                                    groupBoxGameControls.BackColor = Color.DarkGreen;

                                    buttonAction.Enabled = true;

                                    buttonAction.Text = "Make Move";
                                }
                                else
                                {
                                    groupBoxGameControls.BackColor = Color.DarkRed;
                                }
                            }

                            #endregion

                            #region Actions for no (valid) move

                            else if (e is GameSessionNoPossibleMovesEvent)
                            {
                                GameSessionNoPossibleMovesEvent gameSessionNoPossibleMovesEvent = (GameSessionNoPossibleMovesEvent)e;

                                if (player.PlayerName == gameSessionNoPossibleMovesEvent.PlayerName)
                                {
                                    listBoxLog.Items.Add("I'm the active player, but have no (valid) moves ...");

                                    groupBoxGameControls.BackColor = Color.DarkGreen;

                                    buttonAction.Enabled = true;

                                    buttonAction.Text = "Confirm";
                                }
                                else
                                {
                                    groupBoxGameControls.BackColor = Color.DarkRed;
                                }
                            }

                            #endregion

                            #region Actions for player resignation

                            else if (e is GameSessionPlayerResignationEvent)
                            {
                                listBoxCheckers.Items.Clear();
                                listBoxMoves.Items.Clear();

                                GameSessionPlayerResignationEvent gameSessionPlayerResignationEvent = (GameSessionPlayerResignationEvent)e;

                                listBoxLog.Items.Add("Player " + gameSessionPlayerResignationEvent.ResigningPlayer + " has resigned from current game");

                                listBoxCheckers.Items.Clear();

                                groupBoxGameControls.BackColor = SystemColors.Control;

                                groupBoxGameControls.Enabled = false;
                            }

                            #endregion

                            #region Actions for player won game

                            else if (e is GameSessionPlayerWonEvent)
                            {
                                listBoxCheckers.Items.Clear();
                                listBoxMoves.Items.Clear();

                                GameSessionPlayerWonEvent gameSessionPlayerWonEvent = (GameSessionPlayerWonEvent)e;

                                if (gameSessionPlayerWonEvent.WinningPlayer == player.PlayerName)
                                {
                                    listBoxLog.Items.Add("Yeah!!! I won the game!!!");
                                }
                                else
                                {
                                    listBoxLog.Items.Add("Player " + gameSessionPlayerWonEvent.WinningPlayer + " won the game");
                                }

                                listBoxCheckers.Items.Clear();

                                groupBoxGameControls.BackColor = SystemColors.Control;

                                groupBoxGameControls.Enabled = false;
                            }

                            #endregion

                            else if (e is NetworkBackgammonGameSessionEvent)
                            {
                                listBoxCheckers.Items.Clear();
                                listBoxMoves.Items.Clear();

                                NetworkBackgammonGameSessionEvent gameSessionEvent = (NetworkBackgammonGameSessionEvent)e;

                                switch (gameSessionEvent.EventType)
                                {
                                case NetworkBackgammonGameSessionEvent.GameSessionEventType.GameFinished:
                                {
                                    listBoxLog.Items.Add("Game finished");
                                }
                                break;
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            listBoxLog.Items.Add(ex.Message);
                        }
                    }
                }

                #endregion
            }
        }