namespace ChivaXR.Op { using System.Collections; using System.Collections.Generic; using UnityEngine; using Sirenix.OdinInspector; using System; using ChivaXR; using QFramework.TimeExtend; public enum DeductionRules { //操作错误持续扣分, 操作错误单扣操作点分 } public class ExamManager : SerializedMonoSingleton { [ReadOnly] [LabelText("总分数")] public int totalScore; [LabelText("考试时长(分钟)")] public int examTime; [ReadOnly] [LabelText("剩余时长")] public string remainingDuration; [LabelText("扣分规则")] public DeductionRules deductionRules; [LabelText("课程名称")] public string courseName; //用于保存考试所有步骤 [TableList(AlwaysExpanded = true, MaxScrollViewHeight = 300,NumberOfItemsPerPage = 10)] public List examDataContainers = new List(); //计分池(用于保存本次考试选择错误工具或者目标后扣分项) private List ScoringPool = new List(); //计时回调/1s一次(boo:是否完成、 string:解析后的时间(格式:00:00:00)) public event Action timeHandle; //每次扣分的回调 public event Action deductionScoreHandle; private void Start() { StartExam(); } /// /// 开始一个场考试 /// public void StartExam() { OperateSetting.Instance.ToolPackUILogic.SetHintButtonActive(false); OperateSetting.Instance.ToolPackUILogic.SetHint(false); StartCoroutine(StartTime(examTime * 60, (finish, time) => { remainingDuration = time; timeHandle?.Invoke(finish, time); if (finish) StopAllCoroutines(); })); ScoringPool.Clear(); } /// /// 得到当前减了多少分 /// public int GetCurrentScoreReportScore() { int tmpReportScore = 0; foreach (var item in ScoringPool) tmpReportScore += item.score; return tmpReportScore; } /// /// 扣除分数 /// public void DeductionScore() { ExamDataContainer examDataContainer = examDataContainers.Find(t => t.processElement.active); switch (deductionRules) { case DeductionRules.操作错误单扣操作点分: if (!ScoringPool.Contains(examDataContainer)) { ScoringPool.Add(examDataContainer); deductionScoreHandle?.Invoke(examDataContainer); } break; default: break; } } /// /// 分数结算 /// public int ScoreSettlement() { int tmpTotalScore = totalScore; foreach (var item in GetExamDataContainers()) tmpTotalScore -= item.score; StopAllCoroutines(); return tmpTotalScore; } /// /// 计时器 /// /// private IEnumerator StartTime(int Seconds,System.Action callBack) { while (Seconds > 0) { yield return new WaitForSeconds(1); Seconds--; //为完成 callBack(false,SerialiTime(Seconds)); } //完成 callBack(true, SerialiTime(Seconds)); } /// /// 序列化时间 /// /// private string SerialiTime(int time) { TimeSpan ts = new TimeSpan(0, 0, Convert.ToInt32(time)); string str = ""; if (ts.Hours > 0) { str = String.Format("{0:00}", ts.Hours) + ":" + String.Format("{0:00}", ts.Minutes) + ":" + String.Format("{0:00}", ts.Seconds); } if (ts.Hours == 0 && ts.Minutes > 0) { str = "00:" + String.Format("{0:00}", ts.Minutes) + ":" + String.Format("{0:00}", ts.Seconds); } if (ts.Hours == 0 && ts.Minutes == 0) { str = "00:00:" + String.Format("{0:00}", ts.Seconds); } return str; } #region Editor [Button("刷新")] public void RefreshDataInfo() { List processElements = ProcessManagement.Instance.processes; for (int i = 0; i < examDataContainers.Count; i++) if (examDataContainers[i].processElement == null) examDataContainers.Remove(examDataContainers[i]); StepListProxy stepListProxy = DAL.Instance.Get(); List operationStepDataInfo = stepListProxy.ReadStepMsgInfoFromTable(courseName); for (int i = 0; i < processElements.Count; i++) { ExamDataContainer tmpExamDataContainers = examDataContainers.Find(t => t.processElement == processElements[i]); if (tmpExamDataContainers == null) tmpExamDataContainers = new ExamDataContainer(processElements[i], operationStepDataInfo[i].stepName); else { tmpExamDataContainers.Refresh(operationStepDataInfo[i].stepName); continue; } tmpExamDataContainers.id = processElements[i].stepID; examDataContainers.Add(tmpExamDataContainers); } //重新排序 ExamDataContainersShort(); totalScore = 0; foreach (var item in examDataContainers) totalScore += item.score; } /// /// 获取扣分以及没有完成的列表 /// /// public List GetExamDataContainers() { List tmpExamDataContainers = new List(); foreach (var item in ScoringPool) tmpExamDataContainers.Add(item); foreach (var item in examDataContainers) { if (!tmpExamDataContainers.Contains(item) && !item.processElement.finished) tmpExamDataContainers.Add(item); } return tmpExamDataContainers; } private void ExamDataContainersShort() { for (int i = 0; i < examDataContainers.Count - 1; i++) { for (int j = 0; j < examDataContainers.Count - i - 1; j++) { if (examDataContainers[j].id > examDataContainers[j + 1].id) { ExamDataContainer temp = examDataContainers[j]; examDataContainers[j] = examDataContainers[j + 1]; examDataContainers[j + 1] = temp; } } } } #endregion } [Serializable] public class ExamDataContainer { [HideInInspector] public int id; [ReadOnly] public string OpDataName; [ReadOnly] public string OpDataDescription; [ReadOnly] public ProcessElement processElement; public int score; public ExamDataContainer(ProcessElement _processElement, string opDataName) { OpDataName = opDataName; processElement = _processElement; PB_OpData pbOpData = (PB_OpData)_processElement.processBase; OpDataDescription = pbOpData.GetPBDescribe(); } public void Refresh(string opDataName) { OpDataName = opDataName; PB_OpData pbOpData = (PB_OpData)processElement.processBase; OpDataDescription = pbOpData.GetPBDescribe(); } } }