Пример #1
0
        public void showPostRacePanel(RacerDetails racer, Action <TrackRecords.TrackRecordList, int> postRaceDoneHandler)
        {
            prepareForPanelChange(false);

            Grid_Content.Children.Add(new TrackRecords.PostRacePanel(postRaceDoneHandler, racer));
            PanelState = panelState.PostRaceDisplay;
        }
Пример #2
0
        void dataSourceUpdating(int racerIndex, DataSourcePacket data)
        {
            RacerDetails racer = racerDetails[racerIndex];

            //Handle targets if this is a distance race
            if (target_type == targetType.Meters)
            {
                if (data.distance >= racer.targetValue)
                {
                    double finishTime = raceTimer.Elapsed.TotalMilliseconds / 1000;

                    //Since the finish distance is usually a little past the target when we get it, we need to interpolate to get an accurate value for the actual finish
                    //TODO qc Another issue with accuracy is that depending on the timing of the first update packets between racers, one racer can have up to one packet period advantage.
                    racer.finish(++finishOrder, targetType.Seconds, finishTime - ((data.distance - racer.targetValue) / data.speed_ms));

                    //If everyone is done, stop the timer, don't wait for simulator results
                    if (racer.dataSource.isHuman)
                    {
                        if (--notFinishedHumanRacers == 0)
                        {
                            //Make sure all non-humans are closed too
                            foreach (RacerDetails i in racerDetails)
                            {
                                i.dataSource.stop();
                                i.dataSource.isInUse = false;
                            }

                            startAsync(finishRaceAsync);
                        }
                    }
                }
                else
                {
                    if (data.speed_ms != 0)
                    {
                        racer.racePanel.updateProgressDisplay(data.distance, (int)(1000 * (racer.targetValue - data.distance) / data.speed_ms));
                    }
                    else
                    {
                        racer.racePanel.updateProgressDisplay(data.distance, 0);
                    }
                }
            }

            racer.racePanel.updateStats(data);
        }
Пример #3
0
        private void populateDistanceBox(racerSportType sport)
        {
            ComboBox_RaceLength.Items.Clear();

            RacerDetails selectedRacer = null;

            if (racerIndexUnderConfig >= 0)
            {
                selectedRacer = configuredRacers[racerIndexUnderConfig];
                ComboBox_RaceLength.Items.Add(new Label()
                {
                    Content = selectedRacer.targetValue.ToString() + "m track"
                });
            }

            //Add all available values
            foreach (AntPlusRacerConfig.RaceTrack i in AntPlusRacerConfig.getInstance().enabledRaceTracks)
            {
                if (i.sportType == sport)
                {
                    //Skip the current value because we already added it
                    if (selectedRacer != null && selectedRacer.targetValue == i.distance)
                    {
                        continue;
                    }

                    ComboBox_RaceLength.Items.Add(new Label()
                    {
                        Content = i.distance.ToString() + "m track"
                    });
                }
            }

            if (ComboBox_RaceLength.Items.Count == 0)
            {
                ComboBox_RaceLength.Items.Add(new Label()
                {
                    Content = "499m track"
                });
            }

            ComboBox_RaceLength.SelectedIndex = 0;
            comboBoxAutoLblFontSize(ComboBox_RaceLength);
        }
Пример #4
0
        private void updateRaceAnimations()
        {
            RacerDetails        leadingRacer        = racerDetails[0];
            double              leadingRaceProgress = leadingRacer.dataSource.getCurrentDistance() / leadingRacer.targetValue;
            List <RacerDetails> trailingRacers      = new List <RacerDetails>();
            List <double>       trailerRaceProgress = new List <double>();

            for (int i = 1; i < racerDetails.Count; ++i)
            {
                double currentRacePosition = racerDetails[i].dataSource.getCurrentDistance() / racerDetails[i].targetValue;
                if (currentRacePosition > leadingRaceProgress)
                {
                    //Push the old highest into the trailing list
                    trailingRacers.Add(leadingRacer);
                    trailerRaceProgress.Add(leadingRaceProgress);
                    //Save the new highest
                    leadingRacer        = racerDetails[i];
                    leadingRaceProgress = currentRacePosition;
                }
                else
                {
                    trailingRacers.Add(racerDetails[i]);
                    trailerRaceProgress.Add(currentRacePosition);
                }
            }

            if (leadingRaceProgress == 0)   //Updating when the leading racer is 0 causes divide by 0 errors
            {
                return;
            }

            //Take care of leader's positioning first
            double leadingDisplayPosition;

            if (leadingRacer.dataSource.isRunning())
            {
                if (leadingRaceProgress < 0.2)
                {
                    leadingDisplayPosition = leadingRaceProgress * 2; // ~ pos/0.2 * 0.4
                }
                else if (leadingRaceProgress < 0.8)
                {
                    leadingDisplayPosition = (((leadingRaceProgress - 0.2) / 0.6) * 0.4) + 0.4;
                }
                else
                {
                    leadingDisplayPosition = leadingRaceProgress;
                }
                //System.Console.Write("f-{0}, {1:0.00}, ", leadingRacer.dataSource.getSourceName(), leadingRaceProgress);
                leadingRacer.racePanel.moveDistance(leadingDisplayPosition, 1);
            }
            else
            {
                leadingRaceProgress    = 1;
                leadingDisplayPosition = 1;
                //System.Console.WriteLine("f-{0}, {1:0.00}, Finished.", leadingRacer.dataSource.getSourceName(), leadingRaceProgress);
            }


            //Now take care of trailers
            for (int i = 0; i < trailingRacers.Count; ++i)
            {
                if (trailingRacers[i].dataSource.isRunning())
                {
                    double fractionOfLead  = trailerRaceProgress[i] / leadingRaceProgress;
                    double displayPosition = 0;
                    double trailingScale   = 1;
                    if (fractionOfLead > 0.5)
                    {
                        displayPosition = (fractionOfLead - 0.5) * 2;
                    }
                    // if (fractionOfLead > 0.7)
                    //     displayPosition = fractionOfLead / 0.6; // ~ 1 - ((x / 0.3) * 0.5)
                    // else if (fractionOfLead > 0.5)
                    //     displayPosition = (fractionOfLead - 0.3) / 0.4; // ~((x - 0.3) / 0.2) * 0.5
                    else
                    if (raceTimer.Elapsed.TotalSeconds > 1)                  //Don't start scaling at very start of race or it swings back and forth a bunch
                    {
                        trailingScale = Math.Max(fractionOfLead / 0.5, 0.2); //Max at 20%, we don't want racer to get too small to see
                    }
                    //System.Console.Write("t-{0}, {1:0.00}, ", trailingRacers[i].dataSource.getSourceName(), trailerRaceProgress[i]);
                    trailingRacers[i].racePanel.moveDistance(displayPosition * leadingDisplayPosition, trailingScale);
                }
            }
        }
Пример #5
0
        private void decodeRaceControlCmd(RacePanel selectedPanel, byte[] lastMsgBytes)
        {
            switch (lastMsgBytes[3])
            {
            case 0:     //start
            {
                if (selectedPanel.PanelState != RacePanel.panelState.RaceFactory)
                {
                    sendResponse(RemoteControlReturnCodes.Error_PanelInWrongState, lastMsgBytes);
                    return;
                }

                RaceFactoryPanel factoryPanel = selectedPanel.Grid_Content.Children[0] as RaceFactoryPanel;
                if (!factoryPanel.startRace())
                {
                    sendResponse(RemoteControlReturnCodes.Error_RacersNotConfigured, lastMsgBytes);
                    return;
                }
                sendResponse(RemoteControlReturnCodes.Success, lastMsgBytes);
                return;
            }

            case 1:     //restart
            {
                if (selectedPanel.PanelState != RacePanel.panelState.Racing)
                {
                    sendResponse(RemoteControlReturnCodes.Error_PanelInWrongState, lastMsgBytes);
                    return;
                }

                selectedPanel.raceConfig.disposeRace();
                selectedPanel.raceConfig = new RaceDetails(selectedPanel.raceConfig.racerDetails, selectedPanel.raceConfig.target_type);
                selectedPanel.raceConfig.startRace(selectedPanel);
                sendResponse(RemoteControlReturnCodes.Success, lastMsgBytes);
                return;
            }

            case 2:     //cancel race
            {
                if (selectedPanel.PanelState != RacePanel.panelState.RaceFactory &&
                    selectedPanel.PanelState != RacePanel.panelState.Racing &&
                    selectedPanel.PanelState != RacePanel.panelState.PostRaceDisplay &&
                    selectedPanel.PanelState != RacePanel.panelState.PostRaceResults)
                {
                    sendResponse(RemoteControlReturnCodes.Error_PanelInWrongState, lastMsgBytes);
                    return;
                }

                selectedPanel.showRaceFactory();
                sendResponse(RemoteControlReturnCodes.Success, lastMsgBytes);
                return;
            }

            case 3:     //get current racer list
            {
                if (selectedPanel.PanelState != RacePanel.panelState.RaceFactory &&
                    selectedPanel.PanelState != RacePanel.panelState.Racing &&
                    selectedPanel.PanelState != RacePanel.panelState.PostRaceDisplay &&
                    selectedPanel.PanelState != RacePanel.panelState.PostRaceResults)
                {
                    sendResponse(RemoteControlReturnCodes.Error_PanelInWrongState, lastMsgBytes);
                    return;
                }


                List <RacerDetails> racerList;
                if (selectedPanel.PanelState == RacePanel.panelState.RaceFactory)
                {
                    racerList = ((RaceFactoryPanel)selectedPanel.Grid_Content.Children[0]).configuredRacers;
                }
                else
                {
                    racerList = selectedPanel.raceConfig.racerDetails;
                }


                List <byte> retMsg = new List <byte> {
                    (byte)racerList.Count
                };
                for (byte i = 0; i < racerList.Count; ++i)
                {
                    RacerDetails racer = racerList[i];
                    retMsg.Add(i);
                    retMsg.Add(racer.dataSource.uid);
                    retMsg.Add((byte)((ushort)racer.targetValue & 0xFF));
                    retMsg.Add((byte)(((ushort)racer.targetValue & 0xFF00) >> 8));
                    ushort curDistance = (ushort)racer.dataSource.getCurrentDistance();
                    retMsg.Add((byte)((ushort)curDistance & 0xFF));
                    retMsg.Add((byte)(((ushort)curDistance & 0xFF00) >> 8));
                    if (racer.racerRecordInfo != null)
                    {
                        if (!String.IsNullOrWhiteSpace(racer.racerRecordInfo.FirstName))
                        {
                            retMsg.Add(1);
                            retMsg.Add((byte)racer.racerRecordInfo.FirstName.Length);
                            retMsg.AddRange(UTF8Encoding.ASCII.GetBytes(racer.racerRecordInfo.FirstName));
                        }
                        if (!String.IsNullOrWhiteSpace(racer.racerRecordInfo.LastName))
                        {
                            retMsg.Add(2);
                            retMsg.Add((byte)racer.racerRecordInfo.LastName.Length);
                            retMsg.AddRange(UTF8Encoding.ASCII.GetBytes(racer.racerRecordInfo.LastName));
                        }
                        if (!String.IsNullOrWhiteSpace(racer.racerRecordInfo.PhoneNumber))
                        {
                            retMsg.Add(3);
                            retMsg.Add((byte)racer.racerRecordInfo.PhoneNumber.Length);
                            retMsg.AddRange(UTF8Encoding.ASCII.GetBytes(racer.racerRecordInfo.PhoneNumber));
                        }
                        if (!String.IsNullOrWhiteSpace(racer.racerRecordInfo.Email))
                        {
                            retMsg.Add(4);
                            retMsg.Add((byte)racer.racerRecordInfo.Email.Length);
                            retMsg.AddRange(UTF8Encoding.ASCII.GetBytes(racer.racerRecordInfo.Email));
                        }
                    }
                    retMsg.Add(0);          //Null term options list
                }
                sendResponse(RemoteControlReturnCodes.Success, lastMsgBytes, retMsg);
                return;
            }

            case 4:     //Config race
            {
                if (selectedPanel.PanelState != RacePanel.panelState.RaceFactory)
                {
                    if (selectedPanel.PanelState == RacePanel.panelState.ScreenSaverRecordDisplay)
                    {
                        selectedPanel.Dispatcher.Invoke((Action)selectedPanel.showRaceFactory);
                    }
                    else
                    {
                        sendResponse(RemoteControlReturnCodes.Error_PanelInWrongState, lastMsgBytes);
                        return;
                    }
                }

                selectedPanel.ss_lastActivity = DateTime.Now.Add(new TimeSpan(0, 0, 5));            //Give ourselves 5 seconds of extra time before screensaver to process ant messages
                RaceFactoryPanel factoryPanel = selectedPanel.Grid_Content.Children[0] as RaceFactoryPanel;

                if (lastMsgBytes[5] == 0xFF)
                {
                    if (factoryPanel.removeRacer(lastMsgBytes[4]))
                    {
                        sendResponse(RemoteControlReturnCodes.Success, lastMsgBytes);
                        return;
                    }
                    else
                    {
                        sendResponse(RemoteControlReturnCodes.Error_RacerDoesntExist, lastMsgBytes);
                        return;
                    }
                }

                byte sourceID = lastMsgBytes[5];

                DataSources.DataSourceBase dataSrc = null;
                foreach (AntPlusDevMgr.AntPlus_Connection i in AntConfigPanel.accessInstance().antMgr.deviceList)
                {
                    if (i.dataSource.uid == sourceID)
                    {
                        dataSrc = i.dataSource;
                        if (i.getConnStatus() != AntPlusDevMgr.AntPlus_Connection.ConnState.Connected)
                        {
                            sendResponse(RemoteControlReturnCodes.Error_DataSourceNotConnected, lastMsgBytes);
                            return;
                        }
                        break;
                    }
                }
                if (dataSrc == null)
                {
                    sendResponse(RemoteControlReturnCodes.Error_DataSourceDoesntExist, lastMsgBytes);
                    return;
                }

                double trackDist = 0;
                //Get the default (first) track for the given sport type
                foreach (AntPlusRacerConfig.RaceTrack i in AntPlusRacerConfig.getInstance().enabledRaceTracks)
                {
                    if (i.sportType == dataSrc.getSportType())
                    {
                        trackDist = i.distance;
                        break;
                    }
                }

                //decode options
                string firstName = null;
                string lastName  = null;
                string phoneNum  = null;
                string emailAdr  = null;
                int    curPos    = 6;
                while (curPos < lastMsgBytes.Length && lastMsgBytes[curPos] != 0)         //0 is the end of list marker
                {
                    int option = lastMsgBytes[curPos];
                    switch (option)
                    {
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                        int    strLength = lastMsgBytes[curPos + 1];
                        string str       = UTF8Encoding.ASCII.GetString(lastMsgBytes.Skip(curPos + 2).Take(strLength).ToArray());
                        switch (option)
                        {
                        case 1:
                            firstName = str;
                            break;

                        case 2:
                            lastName = str;
                            break;

                        case 3:
                            phoneNum = str;
                            break;

                        case 4:
                            emailAdr = str;
                            break;
                        }
                        curPos += 2 + strLength;
                        break;

                    default:
                        sendResponse(RemoteControlReturnCodes.Error_CmdFormatWrong, lastMsgBytes);
                        return;
                    }
                }

                if (curPos >= lastMsgBytes.Length)          //If we ended without hitting the end of the list
                {
                    sendResponse(RemoteControlReturnCodes.Error_CmdFormatWrong, lastMsgBytes);
                    return;
                }

                //Finally create/change the racer
                int ret = factoryPanel.configureRacer(lastMsgBytes[4], dataSrc, trackDist, firstName, lastName, phoneNum, emailAdr);

                if (ret == 0)
                {
                    sendResponse(RemoteControlReturnCodes.Success, lastMsgBytes);
                }
                else if (ret == -1)
                {
                    sendResponse(RemoteControlReturnCodes.Error_DataSourceInUse, lastMsgBytes);
                }
                else if (ret == -2)
                {
                    sendResponse(RemoteControlReturnCodes.Error_RacerDoesntExist, lastMsgBytes);
                }
                return;
            }

            default:
                sendResponse(RemoteControlReturnCodes.Error_CmdFormatWrong, lastMsgBytes);
                return;
            }
        }