using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Project { public partial class StateMachine { public DateTime UpdateTime; private Boolean bLoop = true; private DateTime StepStartTime; private byte _messageOption; private Boolean _isRun; private System.Threading.Thread worker; private Boolean firstRun = false; public Boolean isRun { get { return _isRun; } } public double Loop_ms { get; set; } // private IMCResult MCResult = null; public StateMachine() { UpdateTime = DateTime.Now; _messageOption = 0xFF; //모든메세지가 오도록 한다. worker = new System.Threading.Thread(new System.Threading.ThreadStart(Loop)); worker.IsBackground = false; StepStartTime = DateTime.Parse("1982-11-23"); Loop_ms = 0; } //public void attachMCResult(IMCResult item) //{ // MCResult = item; // if (GetMsgOpt(eMsgOpt.NORMAL)) // RaiseMessage("ATTACH", string.Format("MCResult")); //} public void Stop() { bLoop = false; worker.Abort(); } public void Start() { worker.Start(); } void Loop() { _isRun = true; RaiseMessage("SM", "Start"); while (bLoop) { //Console.WriteLine("LOOP-START => 11111111111 " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")); //이전업데이트타임과의 시간차를 기록한다 Loop_ms = (DateTime.Now - UpdateTime).TotalMilliseconds; UpdateTime = DateTime.Now; //항상 작동하는 경우 if (SPS != null) { //try //{ SPS(this,new EventArgs()); //} //catch (Exception ex) //{ // Console.WriteLine("ERROR:SM:SPS:" + ex.Message); //} } // Console.WriteLine("LOOP-START => 2222222222 " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")); //작동스텝이 변경되었다면 그것을 알림 처리한다. if (getNewStep != Step) { if (GetMsgOpt(eMsgOpt.STEPCHANGE)) RaiseMessage("SM-STEP", string.Format("Step Changed {0} >> {1}", Step, getNewStep)); StepApply(); firstRun = true; StepStartTime = DateTime.Now; } else firstRun = false; // Console.WriteLine("LOOP-START => 3333333333 " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")); //동작중에 발생하는 이벤트 if (Running != null) { //try //{ Running(this,new RunningEventArgs(Step, firstRun, StepRunTime)); //} //catch (Exception ex) //{ // //오류보고는 3초에 한번씩 동작한다 // if(Pub.GetVarRunTime(eVarTime.SMRUNERROR).TotalSeconds > 3) // { // Pub.SetVarTime(eVarTime.SMRUNERROR, DateTime.Now); // Pub.log.AddE("상태머신 RUN 오류:" + ex.Message); // } //} } System.Threading.Thread.Sleep(1); // Console.WriteLine("LOOP-END => 4444444444444 " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")); } _isRun = false; if (GetMsgOpt(eMsgOpt.NORMAL)) RaiseMessage("SM", "Stop"); } eSMStep prebackupstepo = eSMStep.NOTSET; eSMStep prebackupstepn = eSMStep.NOTSET; public void PushStep() { prebackupstepo = OldStep; prebackupstepn = _step; } public void PopStep() { if (prebackupstepn != eSMStep.NOTSET) { _step = prebackupstepn; OldStep = prebackupstepo; prebackupstepn = eSMStep.NOTSET; } } /// /// 상태머신의 작동상태 /// public eSMStep Step { get { return _step; } } /// /// 상태머신값을 숫자로 반환 합니다. (20이하는 시스템상태이고 그 이상은 사용자 상태) /// public byte StepValue { get { return (byte)this._step; } } public void setNewStep(eSMStep newstep_, Boolean force = false) { if (Step != newstep_) //현재스텝과 새로운 스텝이 다른경우 { if (NewStep != newstep_) { if (force == false && NewStep == eSMStep.EMERGENCY && newstep_ != eSMStep.RESET) { //스텝을 변경해야하는데. 예약된 스텝이 비상정지라면 처리하지 않는다 RaiseMessage("SM-STEP", string.Format("비상정지가 예약되어 있으므로 이 스텝({0})은 취소 됩니다", newstep_)); } else { //바뀌도록 예약을 한다. NewStep = newstep_; if (GetMsgOpt(eMsgOpt.STEPCHANGE)) RaiseMessage("SM-STEP", string.Format("Step Reserve {0} -> {1}", Step, NewStep)); } } else { //예약은 되어있는데 아직 바뀐것은 아니다. if (GetMsgOpt(eMsgOpt.STEPCHANGE)) RaiseMessage("SM-STEP", string.Format("Step Already Reserve {0} -> {1}", Step, NewStep)); } } } public eSMStep getNewStep { get { return NewStep; } } private eSMStep NewStep = eSMStep.NOTSET; public eSMStep OldStep = eSMStep.NOTSET; //171214 private eSMStep _step; /// /// newstep 의 값을 step 에 적용합니다. /// private void StepApply() { var ostep = _step; OldStep = _step; _step = NewStep; if (StepChanged != null) StepChanged(this, new StepChangeEventArgs(ostep, _step)); } //171214 /// /// 메세지 출력옵션을 변경 합니다. /// /// /// public void SetMsgOpt(eMsgOpt opt, Boolean value) { byte pos = (byte)opt; if (value) _messageOption = (byte)(_messageOption | (1 << pos)); else _messageOption = (byte)(_messageOption & ~(1 << pos)); } public void SetMegOptOn() { _messageOption = 0xFF; } public void SetMsgOptOff() { _messageOption = 0; } public Boolean GetMsgOpt(eMsgOpt opt) { byte pos = (byte)opt; return (_messageOption & (1 << pos)) > 0; } public TimeSpan StepRunTime { get { if (StepStartTime.Year == 1982) return new TimeSpan(0); else return DateTime.Now - StepStartTime; } } } }