initial commit

This commit is contained in:
chi
2025-01-07 16:08:02 +09:00
parent 9e657e2558
commit 0a93a54a6f
268 changed files with 50767 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{14E8C9A5-013E-49BA-B435-EFEFC77DD623}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>VarData</RootNamespace>
<AssemblyName>VarData</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Flag.cs" />
<Compile Include="RS232.cs" />
<Compile Include="Var.cs" />
<Compile Include="Enum.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -0,0 +1,196 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace COMM
{
public enum eVarInt32
{
PickOnCount = 0,
PickOfCount,
LPickOnCount,
SumQty,
ChargeWaitSec,
}
public enum eVarUInt32
{
Spare=0,
}
public enum eVarDBL
{
LeftJogSpeed,
RightJogSpeed,
CurrentLeftJogSpeed,
CurrentRightJogSpeed,
SpeedOffsetCW,
SpeedOffsetCCW,
MaxSpeedCW,
MaxSpeedCCW,
SQLConnection,
}
public enum eVarByte
{
None = 0,
/// <summary>
/// 충전명련전송횟수
/// </summary>
CHARGE_CMDCNT,
ButtonJog,
DataIndex ,
}
public enum eVarBool
{
//comm area start(0~31)
None = 0,
DebugMode,
SQLCONN,
//plc area start (32~63)
FLAG_STOPZ = 32,
FLAG_SETUP,
FLAG_SYNC,
FLAG_WAIT,
/// <summary>
/// 상태머신이 동작중인가
/// 장비동작은 AGV_RUN 플래그를 확인 하세요.
/// </summary>
FLAG_AUTORUN,
FLAG_MANUALRUN,
FLAG_LIMITHIGH,
FLAG_LIMITLOW,
FLAG_POWERLOSS,
/// <summary>
/// AGV 진행방향(UP = backward, DOWN = forward)
/// </summary>
AGVDIR_UP,
/// <summary>
/// 마크센서가 감지되면 활성화됨
/// (알림용으로도 쓰니 삭제 안됨)
/// </summary>
MARK_SENSOR,
MARK_SENSOROFF,
FLAG_LEFT_RUN,
FLAG_RIGHT_RUN,
FLAG_RUN_CMD,
FLAG_GO_CHAGER,
FLAG_NEXTSTOP_ALIGN,
NEXTSTOP_MARK,
/// <summary>
/// mark 1 혹은 2 의 값이 들어오면 설정됨
/// </summary>
//SENSOR_MARK,
CHG_POSERR,
FLAG_CHARGEONA,
FLAG_CHARGEONM,
OVERLOAD,
OVERLOADL,
OVERLOADR,
BATTERY_LOW,
BATTERY_HIGH,
MINSPACE,
CHARGE_CMDCNT,
CHARGE_READY,
CHARGE_WAIT,
AGV_ERROR,
WAIT_COVER_DOWN,
WAIT_COVER_UP,
EMERGENCY,
ITEMON,
/// <summary>
/// 충전시작명령을 전송했다
/// </summary>
WAIT_CHARGEACK,
//agv area start ( 64 ~ 95)
//area start (96~127)
}
public enum eVarString
{
MCStatus,
DataIndex,
StatusMessage,
JOBType,
JOBCustCode,
SWVersion,
ChargeCheckMsg,
}
public enum eVarTime
{
LastConnTry_PLC,
LastConn_PLC,
LastRecv_PLC,
LastConnTry_XBE,
LastConn_XBE,
LastRecv_XBE,
LastConnTry_BAT,
LastConn_BAT,
LastRecv_BAT,
LastSend_CMD,
LastSend_BAT,
LastConnTry_AGV,
LastConn_AGV,
LastRecv_AGV,
/// <summary>
/// 상태머신이 IDLE 전환시 설정
/// </summary>
IdleStart,
/// <summary>
/// 충전시도시 설정
/// </summary>
ChargeTry,
/// <summary>
/// 충전시작(확인)시 설정
/// </summary>
ChargeStart,
/// <summary>
/// 충전종료시점
/// </summary>
ChargeEnd,
/// <summary>
/// 장비가동중 READY상태 전환시 설정
/// </summary>
ReadyStart,
MarkSensorOff,
/// <summary>
/// 상태머신이 RUN되는 경우에 설정
/// 단 세부스텝이 READY 인 경우는 제외
/// </summary>
RunStart,
SendChargeOff,
ChargeSearch,
BatWarnTime,
IdleStopTime,
StatusReporttime,
}
}

View File

@@ -0,0 +1,108 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace COMM
{
public class Flag
{
public Boolean IsInit; //H/W설정이 안된경우에만 FALSE로 한다
public string errorMessage;
public int PortCount;
private UInt64 _value;
private UInt64 _changed;
public string[] Name;
public UInt64 Value { get { return _value; } }
public event EventHandler<ValueEventArgs> ValueChanged;
public class ValueEventArgs : EventArgs
{
private int _arridx;
private Boolean _oldvalue;
private Boolean _newvalue;
public int ArrIDX { get { return _arridx; } }
public Boolean OldValue { get { return _oldvalue; } }
public Boolean NewValue { get { return _newvalue; } }
public ValueEventArgs(int arridx, Boolean oldvalue, Boolean newvalue)
{
_arridx = arridx;
_oldvalue = oldvalue;
_newvalue = newvalue;
}
}
public Flag(int pcnt)
{
if (pcnt > 64) throw new Exception("Max count is 64");
PortCount = pcnt;
IsInit = true;
errorMessage = string.Empty;
_value = 0;
_changed = 0;
Name = new string[PortCount];
for (int i = 0; i < Name.Length; i++)
{
Name[i] = string.Empty;
}
}
public void writeValue(Int16 val)
{
var NewValue = (ulong)val;
_changed = this._value ^ NewValue;
this._value = NewValue;
}
//private Boolean readValue(ref UInt64 value, int idx)
//{
// var offset = (UInt64)(1 << idx);
// return ((value & offset) != 0);
//}
public Boolean Get(int idx)
{
var offset = (UInt64)(1 << idx);
return (_value & offset) != 0;
}
/// <summary>
/// 변경여부를 확인 합니다
/// </summary>
/// <param name="idx"></param>
/// <returns></returns>
public Boolean GetChanged(int idx)
{
var offset = (UInt64)(1 << idx);
return (this._changed & offset) != 0;
}
public void Set(int idx, Boolean value)
{
var oldvalue = Get(idx);
if (value)
{
var offset = (UInt64)(1 << idx);
_value = _value | offset;
}
else
{
var offset = (UInt64)(~(1 << idx));
_value = _value & offset;
}
if (oldvalue != value)
{
if (ValueChanged != null)
ValueChanged(this, new ValueEventArgs(idx, oldvalue, value));
}
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 어셈블리에 대한 일반 정보는 다음 특성 집합을 통해
// 제어됩니다. 어셈블리와 관련된 정보를 수정하려면
// 이러한 특성 값을 변경하세요.
[assembly: AssemblyTitle("VarData")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("VarData")]
[assembly: AssemblyCopyright("Copyright © 2022")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// ComVisible을 false로 설정하면 이 어셈블리의 형식이 COM 구성 요소에
// 표시되지 않습니다. COM에서 이 어셈블리의 형식에 액세스하려면
// 해당 형식에 대해 ComVisible 특성을 true로 설정하세요.
[assembly: ComVisible(false)]
// 이 프로젝트가 COM에 노출되는 경우 다음 GUID는 typelib의 ID를 나타냅니다.
[assembly: Guid("14e8c9a5-013e-49ba-b435-efefc77dd623")]
// 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다.
//
// 주 버전
// 부 버전
// 빌드 번호
// 수정 버전
//
// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를
// 기본값으로 할 수 있습니다.
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,487 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
namespace arDev
{
public abstract partial class arRS232 : IDisposable
{
protected System.IO.Ports.SerialPort _device;
protected ManualResetEvent _mre;
protected byte[] LastReceiveBuffer = new byte[] { };
/// <summary>
/// 최종 전송 메세지
/// </summary>
public byte[] lastSendBuffer = new byte[] { };
protected List<byte> tempBuffer = new List<byte>();
protected Boolean findSTX = false;
public string errorMessage { get; set; }
public DateTime LastConnTime { get; set; }
public DateTime LastConnTryTime { get; set; }
public DateTime lastSendTime;
/// <summary>
/// 메세지 수신시 사용하는 내부버퍼
/// </summary>
protected List<byte> _buffer = new List<byte>();
// public byte[] LastRecvData;
public string LastRecvString
{
get
{
if (LastReceiveBuffer == null) return String.Empty;
else return System.Text.Encoding.Default.GetString(LastReceiveBuffer);
}
}
/// <summary>
/// 마지막으로 데이터를 받은 시간
/// </summary>
public DateTime lastRecvTime;
public int WriteError = 0;
public string WriteErrorMessage = string.Empty;
public int WaitTimeout { get; set; } = 1000;
public int MinRecvLength { get; set; } = 1;
/// <summary>
/// 포트이름
/// </summary>
[Description("시리얼 포트 이름")]
[Category("설정"), DisplayName("Port Name")]
public string PortName
{
get
{
if (_device == null) return string.Empty;
else return _device.PortName;
}
set
{
if (this.IsOpen)
{
Message?.Invoke(this, new MessageEventArgs("포트가 열려있어 포트이름을 변경할 수 없습니다", true));
}
else if (String.IsNullOrEmpty(value) == false)
_device.PortName = value;
else
{
Message?.Invoke(this, new MessageEventArgs("No PortName", true));
}
}
}
public int BaudRate
{
get
{
if (_device == null) return 0;
else return _device.BaudRate;
}
set
{
if (this.IsOpen)
{
Message?.Invoke(this, new MessageEventArgs("포트가 열려있어 BaudRate(를) 변경할 수 없습니다", true));
}
else if (value != 0)
_device.BaudRate = value;
else Message?.Invoke(this, new MessageEventArgs("No baud rate", true));
}
}
public arRS232()
{
_device = new System.IO.Ports.SerialPort();
this.BaudRate = 9600;
_device.DataReceived += barcode_DataReceived;
_device.ErrorReceived += this.barcode_ErrorReceived;
_device.WriteTimeout = 5000;
_device.ReadTimeout = 5000;
// _device.DtrEnable = false;
_device.ReadBufferSize = 8192;
_device.WriteBufferSize = 8192;
errorMessage = string.Empty;
lastRecvTime = DateTime.Parse("1982-11-23");
LastConnTime = DateTime.Parse("1982-11-23");
LastConnTryTime = DateTime.Parse("1982-11-23");
lastRecvTime = DateTime.Parse("1982-11-23");
this._mre = new ManualResetEvent(true);
}
~arRS232()
{
Dispose(false);
}
// Flag: Has Dispose already been called?
bool disposed = false;
// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing)
{
// Free any other managed objects here.
//
}
_device.DataReceived -= barcode_DataReceived;
_device.ErrorReceived -= this.barcode_ErrorReceived;
// Free any unmanaged objects here.
//
disposed = true;
}
public Boolean Open()
{
try
{
_device.Open();
return IsOpen;
}
catch (Exception ex)
{
errorMessage = ex.Message;
Message.Invoke(this, new MessageEventArgs(ex.Message, true));
return false;
}
}
public string GetHexString(Byte[] input)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
foreach (byte b in input)
sb.Append(" " + b.ToString("X2"));
return sb.ToString();
}
/// <summary>
/// 포트가 열려있는지 확인
/// </summary>
[Description("현재 시리얼포트가 열려있는지 확인합니다")]
[Category("정보"), DisplayName("Port Open")]
public Boolean IsOpen
{
get
{
if (_device == null) return false;
return _device.IsOpen;
}
}
public virtual void Close(Boolean PortClose = true)
{
if (_device != null && _device.IsOpen)
{
_device.DiscardInBuffer();
_device.DiscardOutBuffer();
if (PortClose) _device.Close(); //dispose에서는 포트를 직접 클리어하지 않게 해뒀다.
}
}
protected Boolean RaiseRecvData()
{
return RaiseRecvData(LastReceiveBuffer.ToArray(), false);
}
/// <summary>
/// 수신받은 메세지를 발생 시킵니다
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public virtual Boolean RaiseRecvData(byte[] Data, bool udpatelastbuffer)
{
//181206 - 최종수신 메세지 기록
lastRecvTime = DateTime.Now;
if (udpatelastbuffer && Data != null)
{
if (LastReceiveBuffer == null || LastReceiveBuffer.Length != Data.Length)
{
LastReceiveBuffer = new byte[Data.Length];
Array.Copy(Data, LastReceiveBuffer, Data.Length);
}
}
try
{
Message?.Invoke(this, new MessageEventArgs(Data, true)); //recvmessage
if (ProcessRecvData(Data) == false)
{
//Message?.Invoke(this, new MessageEventArgs(Data, true)); //recvmessage
Message?.Invoke(this, new MessageEventArgs(this.errorMessage, true)); //errormessage
return false;
}
else
{
return true;
}
}
catch (Exception ex)
{
this.errorMessage = ex.Message;
this.Message?.Invoke(this, new MessageEventArgs(ex.Message, true));
return false;
}
}
/// <summary>
/// 수신받은 자료를 처리한다
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public abstract bool ProcessRecvData(byte[] data);
#region "Internal Events"
void barcode_ErrorReceived(object sender, System.IO.Ports.SerialErrorReceivedEventArgs e)
{
Message?.Invoke(this, new MessageEventArgs(e.ToString(), true));
}
byte[] buffer = new byte[] { };
void barcode_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
try
{
int ReadCount = _device.BytesToRead;
buffer = new byte[ReadCount];
_device.Read(buffer, 0, buffer.Length);
System.Text.StringBuilder LogMsg = new StringBuilder();
byte[] remainBuffer;
Repeat:
if (CustomParser(buffer, out remainBuffer))
{
//분석완료이므로 받은 데이터를 버퍼에 기록한다
if (LastReceiveBuffer == null || (LastReceiveBuffer.Length != tempBuffer.Count))
Array.Resize(ref LastReceiveBuffer, tempBuffer.Count);
Array.Copy(tempBuffer.ToArray(), LastReceiveBuffer, tempBuffer.Count);
tempBuffer.Clear();
//수신메세지발생
RaiseRecvData();
if (remainBuffer != null && remainBuffer.Length > 0)
{
//버퍼를 변경해서 다시 전송을 해준다.
Array.Resize(ref buffer, remainBuffer.Length);
Array.Copy(remainBuffer, buffer, remainBuffer.Length);
goto Repeat; //남은 버퍼가 있다면 진행을 해준다.
}
}
}
catch (Exception ex)
{
if (IsOpen)
{
//_device.DiscardInBuffer();
//_device.DiscardOutBuffer();
}
errorMessage = ex.Message;
this.Message?.Invoke(this, new MessageEventArgs(ex.Message, true));
}
}
#endregion
#region "External Events"
/// <summary>
/// 오류 및 기타 일반 메세지
/// </summary>
public event EventHandler<MessageEventArgs> Message;
#endregion
#region "Event Args"
/// <summary>
/// 데이터를 수신할떄 사용함(RAW 포함)
/// </summary>
public class ReceiveDataEventArgs : EventArgs
{
private byte[] _buffer = null;
/// <summary>
/// 바이트배열의 버퍼값
/// </summary>
public byte[] Value { get { return _buffer; } }
/// <summary>
/// 버퍼(바이트배열)의 데이터를 문자로 반환합니다.
/// </summary>
public string StrValue
{
get
{
//return string.Empty;
if (_buffer == null || _buffer.Length < 1) return string.Empty;
else return System.Text.Encoding.Default.GetString(_buffer);
}
}
public ReceiveDataEventArgs(byte[] buffer)
{
_buffer = buffer;
}
}
/// <summary>
/// 메세지를 강제 발생
/// </summary>
/// <param name="mt"></param>
/// <param name="message"></param>
protected virtual void RaiseMessage(MessageType mt, string message)
{
this.Message?.Invoke(this, new MessageEventArgs(mt, message));
}
public enum MessageType
{
Normal,
Error,
Send,
Recv,
}
public class MessageEventArgs : EventArgs
{
public MessageType MsgType { get; set; }
private string _message = string.Empty;
/// <summary>
/// Recv,Send,Normal,Error 모두 지원
/// </summary>
public string Message { get { return _message; } }
private byte[] _data = null;
/// <summary>
/// Recv,Send에서만 값이 존재 합니다
/// </summary>
public byte[] Data { get { return _data; } }
public MessageEventArgs(string Message, bool isError = false)
{
if (isError) MsgType = MessageType.Error;
else MsgType = MessageType.Normal;
_message = Message;
}
public MessageEventArgs(MessageType msgtype, string Message)
{
MsgType = msgtype;
_message = Message;
_data = System.Text.Encoding.Default.GetBytes(Message);
}
public MessageEventArgs(byte[] buffer, bool isRecv = true)
{
if (isRecv) MsgType = MessageType.Recv;
else MsgType = MessageType.Send;
_data = new byte[buffer.Length];
Array.Copy(buffer, _data, Data.Length);
_message = System.Text.Encoding.Default.GetString(_data);
}
}
#endregion
protected abstract bool CustomParser(byte[] buf, out byte[] remainBuffer);
/// <summary>
/// 데이터수신시간이 설정값보다 x 2.5를 초과하면 false 가 반환됨
/// </summary>
public Boolean IsValid
{
get
{
if (IsOpen == false) return false;
if (lastRecvTime.Year == 1982) return false;
var ts = DateTime.Now - lastRecvTime;
if (ts.TotalSeconds > 5) return false;
return true;
}
}
protected bool WriteData(string cmd)
{
return WriteData(System.Text.Encoding.Default.GetBytes(cmd));
}
/// <summary>
/// 포트에 쓰기(barcode_DataReceived 이벤트로 메세지수신)
/// </summary>
protected Boolean WriteData(byte[] data)
{
Boolean bRet = false;
//171205 : 타임아웃시간추가
if (!_mre.WaitOne(WaitTimeout))
{
errorMessage = $"WriteData:MRE:WaitOne:TimeOut {WaitTimeout}ms";
this.Message?.Invoke(this, new MessageEventArgs(errorMessage, true));
return false;
}
_mre.Reset();
//Array.Resize(ref data, data.Length + 2);
try
{
lastSendTime = DateTime.Now;
if (lastSendBuffer == null) lastSendBuffer = new byte[data.Length]; //171113
else Array.Resize(ref lastSendBuffer, data.Length);
Array.Copy(data, lastSendBuffer, data.Length);
for (int i = 0; i < data.Length; i++)
_device.Write(data, i, 1);
//_device.Write(data, 0, data.Length);
//171113
this.Message?.Invoke(this, new MessageEventArgs(data, false));
bRet = true;
WriteError = 0;
WriteErrorMessage = string.Empty;
}
catch (Exception ex)
{
// this.isinit = false;
this.Message?.Invoke(this, new MessageEventArgs(ex.Message, true));
bRet = false;
WriteError += 1; //연속쓰기오류횟수
WriteErrorMessage = ex.Message;
}
finally
{
_mre.Set();
}
return bRet;
}
}
}

View File

@@ -0,0 +1,340 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace COMM
{
public abstract class VarData<T> : INotifyPropertyChanged
{
protected T[] _values;
protected T defaultvalue;
protected string[] _code;
protected string[] _desc;
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public T this[int idx]
{
get { return Get(idx); }
set { Set(idx, value); }
}
public string StrType
{
get
{
return typeof(T).ToString();
}
}
public VarData(int capa, T defvalue = default(T))
{
_values = new T[capa];
_code = new string[capa];
_desc = new string[capa];
defaultvalue = defvalue;
Clear();
if (typeof(T) == typeof(UInt16)) SupportAdd = true;
else if (typeof(T) == typeof(UInt32)) SupportAdd = true;
else if (typeof(T) == typeof(Int16)) SupportAdd = true;
else if (typeof(T) == typeof(Int32)) SupportAdd = true;
else if (typeof(T) == typeof(Int64)) SupportAdd = true;
else if (typeof(T) == typeof(UInt64)) SupportAdd = true;
else if (typeof(T) == typeof(byte)) SupportAdd = true;
else if (typeof(T) == typeof(double)) SupportAdd = true;
else if (typeof(T) == typeof(Single)) SupportAdd = true;
else if (typeof(T) == typeof(string)) SupportAdd = false;
else if (typeof(T) == typeof(bool)) SupportAdd = false;
else if (typeof(T) == typeof(DateTime)) SupportAdd = false;
else throw new Exception($"Support Data Type : {typeof(T)}");
}
public virtual void Set(int idx, T value)
{
var changed = _values[idx].Equals(value);
_values[idx] = value;
if (changed) OnPropertyChanged($"{idx}|{value}"); //idx값을 알림한다
}
public virtual T Get(int idx)
{
return _values[idx];
}
public virtual void Clear(T value)
{
for (int i = 0; i < _values.Length; i++)
_values[i] = value;
}
public virtual void Clear()
{
Clear(defaultvalue);
}
public void Clear(int idx)
{
_values[idx] = defaultvalue;
}
public Tuple<string, string> GetCodeDesc(int idx)
{
return new Tuple<string, string>(_code[idx], _desc[idx]);
}
public virtual bool SupportAdd { get; private set; }
}
public abstract class VarDataNumber<T> : VarData<T>
{
public VarDataNumber(int capa) : base(capa) { }
public abstract void Add(T value);
public abstract void Add(int idx, T value);
}
public class VarDataI32 : VarDataNumber<Int32>
{
public VarDataI32(int capa) : base(capa) { }
public override void Add(Int32 value)
{
for (int i = 0; i < _values.Length; i++)
_values[i] += value;
}
public override void Add(int idx, Int32 value)
{
_values[idx] += value;
}
public void Add(eVarInt32 idx, Int32 value = 1)
{
Add((int)idx, value);
}
public void Clear(eVarInt32 idx)
{
Clear((int)idx);
}
public Int32 this[eVarInt32 idx]
{
get { return Get((int)idx); }
set { Set((int)idx, value); }
}
}
public class VarDataDBL : VarDataNumber<double>
{
public VarDataDBL(int capa) : base(capa) { }
public override void Add(double value)
{
for (int i = 0; i < _values.Length; i++)
_values[i] += value;
}
public override void Add(int idx, double value)
{
_values[idx] += value;
}
public void Add(eVarDBL idx, double value = 1)
{
Add((int)idx, value);
}
public void Clear(eVarDBL idx)
{
Clear((int)idx);
}
public double this[eVarDBL idx]
{
get { return Get((int)idx); }
set { Set((int)idx, value); }
}
}
public class VarDataUI32 : VarDataNumber<UInt32>
{
public VarDataUI32(int capa) : base(capa) { }
public override void Add(UInt32 value)
{
for (int i = 0; i < _values.Length; i++)
_values[i] += value;
}
public override void Add(int idx, UInt32 value)
{
_values[idx] += value;
}
public void Add(eVarUInt32 idx, UInt32 value = 1)
{
Add((int)idx, value);
}
public void Clear(eVarUInt32 idx)
{
Clear((int)idx);
}
public UInt32 this[eVarUInt32 idx]
{
get { return Get((int)idx); }
set { Set((int)idx, value); }
}
}
public class VarDataByte : VarDataNumber<byte>
{
public VarDataByte(int capa) : base(capa) { }
public override void Add(byte value)
{
for (int i = 0; i < _values.Length; i++)
_values[i] += value;
}
public override void Add(int idx, byte value)
{
_values[idx] += value;
}
public void Add(eVarByte idx, byte value)
{
Add((int)idx, value);
}
public byte this[eVarByte idx]
{
get
{
return Get((int)idx);
}
set
{
Set((int)idx, value);
}
}
}
public class VarDataBool : VarData<bool>
{
public VarDataBool(int capa) : base(capa) { }
public bool this[eVarBool idx]
{
get
{
return Get(idx);
}
set
{
Set(idx, value);
}
}
public bool Get(eVarBool idx)
{
return Get((int)idx);
}
public void Set(eVarBool idx, bool value)
{
Set((int)idx, value);
}
}
public class VarDataStr : VarData<string>
{
public VarDataStr(int capa) : base(capa, string.Empty) { }
public string Get(eVarString idx)
{
return Get((int)idx);
}
public void Set(eVarString idx, string value)
{
Set((int)idx, value);
}
public string this[eVarString idx]
{
get { return Get(idx); }
set { Set(idx, value); }
}
}
public class VarDataDateTime : VarData<DateTime>
{
public VarDataDateTime(int capa) : base(capa, new DateTime(1982, 11, 23)) { }
public DateTime this[eVarTime idx]
{
get
{
return Get((int)idx);
}
set
{
Set(idx, value);
}
}
public TimeSpan RUN(int idx)
{
return DateTime.Now - _values[idx];
}
public TimeSpan RUN(eVarTime idx)
{
return RUN((int)idx);
}
[Browsable(false)]
public void Add(int idx, TimeSpan value)
{
_values[idx] += value;
}
public void Add(eVarTime idx, TimeSpan value)
{
Add((int)idx, value);
}
/// <summary>
/// 지정된 시간으로 업데이트 합니다
/// </summary>
/// <param name="idx"></param>
/// <param name="value"></param>
public void Set(eVarTime idx, DateTime value)
{
Set((int)idx, value);
}
/// <summary>
/// 현재시간으로 업데이트 합니다
/// </summary>
/// <param name="idx"></param>
public void Set(eVarTime idx)
{
Set(idx, DateTime.Now);
}
public bool IsSet(eVarTime idx)
{
return this[idx].Year != 1982;
}
}
//공용변수(시간)
public static class VAR
{
public static VarDataBool BOOL;
public static VarDataByte BYTE;
public static VarDataStr STR;
public static VarDataDateTime TIME;
public static VarDataI32 I32;
public static VarDataUI32 U32;
public static VarDataDBL DBL;
public static bool isInit { get; private set; } = false;
public static void Init(int varlen)
{
if (isInit) return; //already init
//가변 데이트타임변수
BOOL = new VarDataBool(varlen);
BYTE = new VarDataByte(varlen);
STR = new VarDataStr(varlen);
TIME = new VarDataDateTime(varlen);
I32 = new VarDataI32(varlen);
U32 = new VarDataUI32(varlen);
DBL = new VarDataDBL(varlen);
isInit = true;
}
}
}