Files
ATV_STDLabelAttach/Handler/Project_form2/Don't change it/StateMachine/StateMachine.cs
2025-07-17 16:11:46 +09:00

234 lines
7.7 KiB
C#

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;
}
}
/// <summary>
/// 상태머신의 작동상태
/// </summary>
public eSMStep Step { get { return _step; } }
/// <summary>
/// 상태머신값을 숫자로 반환 합니다. (20이하는 시스템상태이고 그 이상은 사용자 상태)
/// </summary>
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;
/// <summary>
/// newstep 의 값을 step 에 적용합니다.
/// </summary>
private void StepApply()
{
var ostep = _step;
OldStep = _step; _step = NewStep;
if (StepChanged != null) StepChanged(this, new StepChangeEventArgs(ostep, _step));
} //171214
/// <summary>
/// 메세지 출력옵션을 변경 합니다.
/// </summary>
/// <param name="opt"></param>
/// <param name="value"></param>
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;
}
}
}
}