Commit 8ba0ce8b authored by 潘栩锋's avatar 潘栩锋 🚴

恢复删错的 Project.FLY.Thick.RemoteHistory

parent 82074f6b

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FLY.Thick.RemoteHistory", "FLY.Thick.RemoteHistory\FLY.Thick.RemoteHistory.csproj", "{7212BFCC-F0C4-4839-962E-31AA57324E42}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Misc", "..\Project.FLY.Misc\MISC\Misc.csproj", "{5EE61AC6-5269-4F0F-B8FA-4334FE4A678F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FObjBase", "..\Project.FLY.FObjSys\FObjSys\FObjBase.csproj", "{ABFE87D4-B692-4AE9-A8C0-1F470B8ACBB8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7212BFCC-F0C4-4839-962E-31AA57324E42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7212BFCC-F0C4-4839-962E-31AA57324E42}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7212BFCC-F0C4-4839-962E-31AA57324E42}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7212BFCC-F0C4-4839-962E-31AA57324E42}.Release|Any CPU.Build.0 = Release|Any CPU
{5EE61AC6-5269-4F0F-B8FA-4334FE4A678F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5EE61AC6-5269-4F0F-B8FA-4334FE4A678F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5EE61AC6-5269-4F0F-B8FA-4334FE4A678F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5EE61AC6-5269-4F0F-B8FA-4334FE4A678F}.Release|Any CPU.Build.0 = Release|Any CPU
{ABFE87D4-B692-4AE9-A8C0-1F470B8ACBB8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ABFE87D4-B692-4AE9-A8C0-1F470B8ACBB8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ABFE87D4-B692-4AE9-A8C0-1F470B8ACBB8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ABFE87D4-B692-4AE9-A8C0-1F470B8ACBB8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FObjBase;
namespace FLY.Thick.RemoteHistory
{
public class BUFFER_OBJ_INTERFACE
{
#region Pack
public class Pack_List<T> : IPack2
where T : IPack2, new()
{
public bool isAdd;//不是add,就是changed
public T[] list;
#region IPack2 成员
public byte[] ToBytes()
{
List<byte> buf = new List<byte>();
buf.AddRange(BitConverter.GetBytes(isAdd));
if (list == null)
{
buf.AddRange(BitConverter.GetBytes(0));
}
else
{
buf.AddRange(BitConverter.GetBytes(list.Count()));
for (int i = 0; i < list.Count(); i++)
{
buf.AddRange(list[i].ToBytes());
}
}
return buf.ToArray();
}
public bool TryParse(byte[] value)
{
int cnt;
return TryParse(value, 0, out cnt);
}
public bool TryParse(byte[] value, int index, out int cnt)
{
cnt = 1 + 4;
if (value.Length < (index + cnt))
return false;
int idx = index;
isAdd = BitConverter.ToBoolean(value, idx);
idx += 1;
int len = BitConverter.ToInt32(value, idx);
idx += 4;
if (len <= 0)
{
list = null;
return true;
}
list = new T[len];
for (int i = 0; i < len; i++)
{
int c;
list[i] = new T();
if (!list[i].TryParse(value, idx, out c))
return false;
idx += c;
cnt += c;
}
return true;
}
#endregion
}
public class Pack_Params
{
public int size;
#region IPack实现
public byte[] ToBytes()
{
List<byte> buf = new List<byte>();
buf.AddRange(BitConverter.GetBytes(size));
return buf.ToArray();
}
public bool TryParse(byte[] value)
{
int cnt = 4;
if (value.Length < cnt)
return false;
int idx = 0;
size = BitConverter.ToInt32(value, idx);
idx += 4;
return true;
}
#endregion
}
#endregion
#region GetValue
public const UInt16 GET_PARAMS = 0;
/// <summary>
/// Pack_List
/// </summary>
public const UInt16 GET_LIST = 1;
#endregion
#region SetValue
public const UInt16 SET_PARAMS = 0;
#endregion
#region PushMsg
public const UInt16 PUSH_PARAMS = 0;
/// <summary>
/// Pack_List
/// </summary>
public const UInt16 PUSH_LIST = 1;
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Threading;
using System.ComponentModel;
using System.IO;
namespace FLY.Thick.RemoteHistory
{
public class Buffer<T> : IBuffer<T>
where T : IFlyData, new()
{
DispatcherTimer timer;
private int SaveInterval = 1;
private bool hasnew = false;
public bool HasNew
{
get { return hasnew; }
set
{
if (hasnew != value)
{
hasnew = value;
NotifyPropertyChanged("HasNew");
}
}
}
private string FilePath;
#region IBuffer<T>
private int size = 400;
public int Size
{
get { return size; }
set
{
if (value < 100)
value = 100;
if (size != value)
{
size = value;
NotifyPropertyChanged("Size");
}
}
}
private List<T> record = new List<T>();
/// <summary>
/// 每次配料记录
/// </summary>
public List<T> Record
{
get
{
return record;
}
}
#endregion
public void Init(string filepath)
{
Init(filepath, false);
}
public void Init(string filepath, bool save_immediately)
{
FilePath = filepath;
Load();
if (save_immediately)
SaveInterval = 0;
if (SaveInterval > 0)
{
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMinutes(SaveInterval);
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}
this.PropertyChanged += Buffer_PropertyChanged;
}
public void Add(T t)
{
Record.Add(t);
while (Record.Count() > Size)
{
Record.RemoveAt(0);
}
HasNew = true;
NotifyRecordChanged(true, 1);
}
public void Remove(T t)
{
Record.Remove(t);
HasNew = true;
NotifyRecordChanged(false, Record.Count);
}
public void Clear()
{
Record.Clear();
HasNew = true;
NotifyRecordChanged(false, 0);
}
public void Flush()
{
Save();
}
void Buffer_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "HasNew")
{
if (HasNew)
{
if (SaveInterval <= 0)
{
Save();
}
}
}
}
/// <summary>
/// N分钟执行一次
/// </summary>
void timer_Tick(object sender, EventArgs e)
{
if (HasNew)
{
Save();
}
}
void Load()
{
if (string.IsNullOrEmpty(FilePath))
return;
Record.Clear();
HasNew = false;
try
{
using (StreamReader sr = new StreamReader(FilePath, Encoding.GetEncoding("GB2312")))
{
string header = sr.ReadLine();
if (string.IsNullOrEmpty(header))
return;
while (!sr.EndOfStream)
{
T t = new T();
if (t.TryParse(header, sr.ReadLine()))
{
Record.Add(t);
}
}
}
}
catch (Exception e)
{
}
}
void Save()
{
if (string.IsNullOrEmpty(FilePath))
return;
if (!HasNew)
return;
HasNew = false;
if (Record.Count() == 0)
{
//删除掉文件
File.Delete(FilePath);
return;
}
//以附加的方式打开只写文件。
//若文件不存在,则会建立该文件,
//如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。
using (StreamWriter sw = new StreamWriter(FilePath, false, Encoding.GetEncoding("GB2312")))
{
sw.WriteLine(Record[0].GetHeader());
for (int i = 0; i < Record.Count; i++)
sw.WriteLine(Record[i].ToString());
sw.Flush();
sw.Close();
}
}
#region IBuffer<T>
public event BufferChangedEventHandler RecordChanged;
#endregion
public void NotifyRecordChanged(bool isAdd, int cnt)
{
if (RecordChanged != null)
{
RecordChanged.Invoke(Record, new BufferChangedEventArgs(isAdd, cnt));
}
}
#region INotifyPropertyChanged 成员
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyname)
{
if (PropertyChanged != null)
{
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyname));
}
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLY.Thick.RemoteHistory
{
public class BufferChangedEventArgs : EventArgs
{
public bool IsAdd;//不是添加,就是改变
public int Cnt;//数量,当数据为0,就是清空列表
public BufferChangedEventArgs(bool isadd, int cnt)
{
IsAdd = isadd;
Cnt = cnt;
}
}
public delegate void BufferChangedEventHandler(object sender, BufferChangedEventArgs args);
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using FObjBase;
using System.Collections.ObjectModel;
namespace FLY.Thick.RemoteHistory
{
public class BufferServiceClient<T> : FObj, IBuffer<T>
where T : IPack2, new()
{
#region 延时推送 MARKNO
const int MARKNO_SET_PARAMS = 1;
#endregion
IFConn mConn;
UInt32 mServerID;
#region IBuffer<T>
private int size = 400;
public int Size
{
get { return size; }
set
{
if (value < 100)
value = 100;
if (size != value)
{
size = value;
NotifyPropertyChanged("Size");
}
}
}
private List<T> record = new List<T>();
/// <summary>
/// 每次配料记录
/// </summary>
public List<T> Record
{
get
{
return record;
}
}
public event BufferChangedEventHandler RecordChanged;
void NotifyRecordChanged(bool isAdd, int cnt)
{
if (RecordChanged != null)
{
RecordChanged.Invoke(Record, new BufferChangedEventArgs(isAdd, cnt));
}
}
#endregion
public BufferServiceClient(UInt32 serverid)
{
mServerID = serverid;
this.PropertyChanged += BufferServiceClient_PropertyChanged;
}
public ObservableCollection<T> GetObservableCollection()
{
ObservableCollection<T> datas = new ObservableCollection<T>(Record);
RecordChanged += (s, e) =>
{
if (e.IsAdd)
{
for (int i = 0; i < e.Cnt; i++)
{
int index = Record.Count - e.Cnt + i;
datas.Add(Record[index]);
}
while (datas.Count > Size)
datas.RemoveAt(0);
}
else
{
datas.Clear();
for (int i = 0; i < e.Cnt; i++)
{
datas.Add(Record[i]);
}
}
};
return datas;
}
private void BufferServiceClient_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (
(e.PropertyName == "Size"))
{
FObjBase.PollModule.Current.Poll_JustOnce(
new PollModule.PollHandler(delegate()
{
BUFFER_OBJ_INTERFACE.Pack_Params p = new BUFFER_OBJ_INTERFACE.Pack_Params();
p.size = Size;
CurrObjSys.PushObjInfoEx(
this, BUFFER_OBJ_INTERFACE.SET_PARAMS,
p.ToBytes());
}), this, MARKNO_SET_PARAMS);
}
}
public override void Dispose()
{
CurrObjSys.ObjRemove(
this, mConn);
}
public override void ConnectNotify(IFConn from)
{
mConn = from;
if (from.IsConnected)
{
//获取所有数据,设置推送
CurrObjSys.GetValueEx(
mConn, mServerID, ID,
BUFFER_OBJ_INTERFACE.GET_PARAMS);
CurrObjSys.GetValueEx(
mConn, mServerID, ID,
BUFFER_OBJ_INTERFACE.GET_LIST);
CurrObjSys.SenseConfigEx(
mConn, mServerID, ID,
0xffffffff,
SENSE_CONFIG.ADD);
}
}
public override void PushGetValue(IFConn from, uint srcid, ushort memid, byte[] infodata)
{
switch (memid)
{
case BUFFER_OBJ_INTERFACE.GET_LIST:
{
BUFFER_OBJ_INTERFACE.Pack_List<T> p = new BUFFER_OBJ_INTERFACE.Pack_List<T>();
if (!p.TryParse(infodata))
return;
int cnt = 0;
if (p.list != null)
{
cnt = p.list.Count();
if (cnt > Size)
cnt = Size;
}
if (!p.isAdd)//isChanged
Record.Clear();
if (cnt > 0)
{
Record.AddRange(p.list);
while (Record.Count() > Size)
{
Record.RemoveAt(0);
}
}
NotifyRecordChanged(p.isAdd, cnt);
}
break;
case BUFFER_OBJ_INTERFACE.GET_PARAMS:
{
BUFFER_OBJ_INTERFACE.Pack_Params p = new BUFFER_OBJ_INTERFACE.Pack_Params();
if (!p.TryParse(infodata))
return;
this.PropertyChanged -= BufferServiceClient_PropertyChanged;
Size = p.size;
this.PropertyChanged += BufferServiceClient_PropertyChanged;
}
break;
}
}
public override void PushInfo(IFConn from, uint srcid, ushort infoid, byte[] infodata)
{
PushGetValue(from, srcid, infoid, infodata);
}
#region INotifyPropertyChanged 成员
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyname)
{
if (PropertyChanged != null)
{
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyname));
}
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FObjBase;
namespace FLY.Thick.RemoteHistory
{
public class Buffer_OBJProxy<T> : FObj
where T : IFlyData, IPack2, new()
{
#region 延时推送 MARKNO
const int MARKNO_PUSH_PARAMS = 1;
#endregion
IBuffer<T> buffer;
public Buffer_OBJProxy(int objsys_idx, IBuffer<T> buffer, UInt32 id)
: base(objsys_idx)
{
ID = id;
this.buffer = buffer;
buffer.RecordChanged += Buffer_RecordChanged;
buffer.PropertyChanged += Buffer_PropertyChanged;
}
private void Buffer_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (
(e.PropertyName == "Size"))
{
FObjBase.PollModule.Current.Poll_JustOnce(
new PollModule.PollHandler(delegate()
{
byte[] buf;
GetValue(null, 0, BUFFER_OBJ_INTERFACE.GET_PARAMS, out buf);
CurrObjSys.PushObjInfoEx(
this, BUFFER_OBJ_INTERFACE.PUSH_PARAMS,
buf);
}), this, MARKNO_PUSH_PARAMS);
}
}
private void Buffer_RecordChanged(object sender, BufferChangedEventArgs e)
{
BUFFER_OBJ_INTERFACE.Pack_List<T> p = new BUFFER_OBJ_INTERFACE.Pack_List<T>();
p.isAdd = e.IsAdd;
if (e.Cnt > 0)
{
p.list = new T[e.Cnt];
for (int i = 0; i < p.list.Count(); i++)
{
int index = buffer.Record.Count() - p.list.Count() + i;
p.list[i] = buffer.Record[index];
}
}
CurrObjSys.PushObjInfoEx(
this, BUFFER_OBJ_INTERFACE.PUSH_LIST,
p.ToBytes());
}
public override void GetValue(IFConn from, uint srcid, ushort memid, out byte[] infodata)
{
switch (memid)
{
case BUFFER_OBJ_INTERFACE.GET_PARAMS:
{
BUFFER_OBJ_INTERFACE.Pack_Params p = new BUFFER_OBJ_INTERFACE.Pack_Params()
{
size = buffer.Size
};
infodata = p.ToBytes();
}
break;
case BUFFER_OBJ_INTERFACE.GET_LIST:
{
BUFFER_OBJ_INTERFACE.Pack_List<T> p = new BUFFER_OBJ_INTERFACE.Pack_List<T>()
{
isAdd = false,
list = buffer.Record.ToArray()
};
infodata = p.ToBytes();
}
break;
default:
infodata = null;
break;
}
}
public override void SetValue(IFConn from, uint srcid, ushort memid, byte[] infodata)
{
switch (memid)
{
case BUFFER_OBJ_INTERFACE.SET_PARAMS:
{
BUFFER_OBJ_INTERFACE.Pack_Params p = new BUFFER_OBJ_INTERFACE.Pack_Params();
if (!p.TryParse(infodata))
return;
buffer.Size = p.size;
return;
}
break;
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{7212BFCC-F0C4-4839-962E-31AA57324E42}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>FLY.Thick.RemoteHistory</RootNamespace>
<AssemblyName>FLY.Thick.RemoteHistory</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</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>
<DocumentationFile>bin\Debug\FLY.Thick.RemoteHistory.XML</DocumentationFile>
</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>
</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" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="Buffer.cs" />
<Compile Include="BufferChangedEventArgs.cs" />
<Compile Include="BufferServiceClient.cs" />
<Compile Include="Buffer_OBJProxy.cs" />
<Compile Include="BUFFER_OBJ_INTERFACE.cs" />
<Compile Include="History.cs" />
<Compile Include="IBuffer.cs" />
<Compile Include="IRemoteHistory.cs" />
<Compile Include="RemoteHistorySerivceClient.cs" />
<Compile Include="RemoteHistory_OBJProxy.cs" />
<Compile Include="REMOTEHISTORY_OBJ_INTERFACE.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Project.FLY.FObjSys\FObjSys\FObjBase.csproj">
<Project>{ABFE87D4-B692-4AE9-A8C0-1F470B8ACBB8}</Project>
<Name>FObjBase</Name>
</ProjectReference>
<ProjectReference Include="..\..\Project.FLY.Misc\MISC\Misc.csproj">
<Project>{5EE61AC6-5269-4F0F-B8FA-4334FE4A678F}</Project>
<Name>Misc</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace FLY.Thick.RemoteHistory
{
public interface IBuffer<T> : INotifyPropertyChanged
{
/// <summary>
/// 记录的大小
/// </summary>
int Size { get; set; }
/// <summary>
/// 每次配料记录
/// </summary>
List<T> Record { get; }
event BufferChangedEventHandler RecordChanged;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace FLY.Thick.RemoteHistory
{
public delegate void GetPathsReponseHandler(List<string> paths, object state);
public delegate void GetRootPathReponseHandler(string rootpath, object state);
public interface IRemoteHistory
: INotifyPropertyChanged
{
/// <summary>
/// 最小保存时间,当5分钟内都没新的数据产生,自动 Flush() 单位min
/// </summary>
int MinSaveInterval { get; set; }
/// <summary>
/// 数据能保存的天数
/// </summary>
int KeeyDay { get; set; }
/// <summary>
/// 多少行保存一次
/// </summary>
int SaveRows { get; set; }
/// <summary>
/// 当前总行数
/// </summary>
int CurrRows { get; }
/// <summary>
/// 当前保存的文件路径
/// </summary>
string CurrPath { get; }
/// <summary>
/// 当前保存的数据天数
/// </summary>
int CurrDays { get; }
/// <summary>
/// 参数应用
/// </summary>
void Apply();
/// <summary>
/// 全部保存
/// </summary>
void Flush();
//获取历史数据
void GetPaths(DateTime dt_begin, DateTime dt_end, string profilename, GetPathsReponseHandler return_func, object state);
/// <summary>
/// 获取根目录
/// </summary>
void GetRootPath(GetRootPathReponseHandler return_func, object state);
}
}
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的常规信息通过以下
// 特性集控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("FLY.Thick.RemoteHistory")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("佛山枫莱尔自动化技术有限公司")]
[assembly: AssemblyProduct("FLY.Thick.RemoteHistory")]
[assembly: AssemblyCopyright("Copyright © 2018 FLYAuotmation")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 使此程序集中的类型
// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
// 则将该类型上的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("c49e66cb-06fc-432a-90bd-8f3a1cda21ab")]
// 程序集的版本信息由下面四个值组成:
//
// 主版本
// 次版本
// 内部版本号
// 修订号
//
// 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值,
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.1.0.0")]
[assembly: AssemblyFileVersion("1.1.0.0")]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FObjBase;
namespace FLY.Thick.RemoteHistory
{
public class REMOTEHISTORY_OBJ_INTERFACE
{
#region Pack
public class Pack_Params : IPack
{
public int keeyday;
public int saverows;
public int minSaveInterval;
public byte[] ToBytes()
{
List<byte> buf = new List<byte>();
buf.AddRange(BitConverter.GetBytes(keeyday));
buf.AddRange(BitConverter.GetBytes(saverows));
buf.AddRange(BitConverter.GetBytes(minSaveInterval));
return buf.ToArray();
}
public bool TryParse(byte[] value)
{
if (value.Length < 12)
return false;
int idx = 0;
keeyday = BitConverter.ToInt32(value, idx);
idx += 4;
saverows = BitConverter.ToInt32(value, idx);
idx += 4;
minSaveInterval = BitConverter.ToInt32(value, idx);
idx += 4;
return true;
}
}
public class Pack_State : IPack
{
public int currrows;
public string currpath;
public int currdays;
public byte[] ToBytes()
{
List<byte> buf = new List<byte>();
buf.AddRange(BitConverter.GetBytes(currdays));
buf.AddRange(BitConverter.GetBytes(currrows));
if (currpath != null)
{
byte[] bs = Misc.Converter.StringToBytes(currpath);
int len = bs.Length;
buf.AddRange(BitConverter.GetBytes(len));
buf.AddRange(bs);
}
else
{
int len = 0;
buf.AddRange(BitConverter.GetBytes(len));
}
return buf.ToArray();
}
public bool TryParse(byte[] value)
{
int cnt = 12;
if (value.Length < cnt)
return false;
int idx = 0;
currdays = BitConverter.ToInt32(value, idx);
idx += 4;
currrows = BitConverter.ToInt32(value, idx);
idx += 4;
int len = BitConverter.ToInt32(value, idx);
idx += 4;
cnt += len;
if (value.Length < cnt)
return false;
if (len > 0)
{
currpath = Misc.Converter.BytesToString(value, idx, len);
}
else
{
currpath = null;
}
return true;
}
}
public class Pack_GetPathsResponse : IPack
{
public List<string> paths;
#region IPack 成员
public byte[] ToBytes()
{
List<byte> buf = new List<byte>();
byte[] bs;
buf.AddRange(BitConverter.GetBytes(paths.Count()));
for (int i = 0; i < paths.Count(); i++)
{
bs = Misc.Converter.StringToBytes(paths[i]);
buf.AddRange(BitConverter.GetBytes(bs.Count()));
buf.AddRange(bs);
}
return buf.ToArray();
}
/// <summary>
/// 返回由字节数组中指定位置的9个字节转换来的数据。
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public bool TryParse(byte[] value)
{
int cnt = 4;
if (value.Length < cnt)
return false;
int idx = 0;
int len = BitConverter.ToInt32(value, idx);
idx += 4;
cnt += len * 4;
if (value.Length < cnt)
return false;
if (paths == null)
paths = new List<string>();
paths.Clear();
for (int i = 0; i < len; i++)
{
int l = BitConverter.ToInt32(value, idx);
idx += 4;
cnt += l;
if (value.Length < cnt)
return false;
string s = Misc.Converter.BytesToString(value, idx, l);
idx += l;
paths.Add(s);
}
return true;
}
#endregion
}
public class Pack_GetPathsRequest : IPack
{
public DateTime dt_begin;
public DateTime dt_end;
public string profilename;
public byte[] ToBytes()
{
List<byte> buf = new List<byte>();
buf.AddRange(BitConverter.GetBytes(dt_begin.Ticks));
buf.AddRange(BitConverter.GetBytes(dt_end.Ticks));
if (!string.IsNullOrEmpty(profilename))
{
byte[] bs = Misc.Converter.StringToBytes(profilename);
int len = bs.Count();
buf.AddRange(BitConverter.GetBytes(len));
buf.AddRange(bs);
}
else
{
int len = 0;
buf.AddRange(BitConverter.GetBytes(len));
}
return buf.ToArray();
}
public bool TryParse(byte[] value)
{
int cnt = 8+8+4;
if (value.Length < cnt)
return false;
int idx = 0;
dt_begin = new DateTime(BitConverter.ToInt64(value, idx));
idx += 8;
dt_end = new DateTime(BitConverter.ToInt64(value, idx));
idx += 8;
int len = BitConverter.ToInt32(value, idx);
idx += 4;
cnt += len;
if (value.Length < cnt)
return false;
if (len > 0)
{
profilename = Misc.Converter.BytesToString(value, idx, len);
idx += len;
}
return true;
}
}
public class Pack_GetRootPathResponse : IPack
{
public string rootpath;
#region IPack 成员
public byte[] ToBytes()
{
List<byte> buf = new List<byte>();
byte[] bs= Misc.Converter.StringToBytes(rootpath);
buf.AddRange(BitConverter.GetBytes(bs.Count()));
buf.AddRange(bs);
return buf.ToArray();
}
/// <summary>
/// 返回由字节数组中指定位置的9个字节转换来的数据。
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public bool TryParse(byte[] value)
{
int cnt = 4;
if (value.Length < cnt)
return false;
int idx = 0;
int l = BitConverter.ToInt32(value, idx);
idx += 4;
cnt += l;
if (value.Length < cnt)
return false;
rootpath = Misc.Converter.BytesToString(value, idx, l);
idx += l;
return true;
}
#endregion
}
#endregion
#region GetValue
/// <summary>
/// Pack_Params
/// </summary>
public const UInt16 GET_PARAMS = 0;
/// <summary>
/// Pack_State
/// </summary>
public const UInt16 GET_STATE = 1;
#endregion
#region SetValue
/// <summary>
/// Pack_Params
/// </summary>
public const UInt16 SET_PARAMS = 0;
#endregion
#region PushMsg
/// <summary>
/// Pack_Params
/// </summary>
public const UInt16 PUSH_PARAMS = 0;
/// <summary>
/// Pack_State
/// </summary>
public const UInt16 PUSH_STATE = 1;
#endregion
#region CALL
/// <summary>
/// null
/// </summary>
public const UInt16 CALL_FLUSH = 1;
/// <summary>
/// Pack_GetPathsRequest
/// Pack_GetPathsResponse
/// </summary>
public const UInt16 CALL_GETPATHS = 2;
/// <summary>
/// null
/// Pack_GetRootPathResponse
/// </summary>
public const UInt16 CALL_GETROOTPATH = 3;
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Misc;
using System.ComponentModel;
using FObjBase;
namespace FLY.Thick.RemoteHistory
{
public class RemoteHistorySerivceClient : FObj, IRemoteHistory
{
IFConn mConn = null;
UInt32 mServerID;
public bool IsConnected;
#region IHistory<T> 成员
private int currdays = 0;
/// <summary>
/// 当前保存的数据天数
/// </summary>
public int CurrDays
{
get { return currdays; }
protected set
{
if (currdays != value)
{
currdays = value;
NotifyPropertyChanged("CurrDays");
}
}
}
private int keeyday;
/// <summary>
/// 数据能保存的天数
/// </summary>
public int KeeyDay
{
get
{
return keeyday;
}
set
{
if (value <= 0)
value = 1;
if (keeyday != value)
{
keeyday = value;
NotifyPropertyChanged("KeeyDay");
}
}
}
private int minSaveInterval = 5;
/// <summary>
/// 最小保存时间,当5分钟内都没新的数据产生,自动 Flush() 单位min
/// </summary>
public int MinSaveInterval
{
get { return minSaveInterval; }
set
{
if (minSaveInterval != value)
{
minSaveInterval = value;
NotifyPropertyChanged("MinSaveInterval");
}
}
}
private int saverows;
/// <summary>
/// 多少行保存一次
/// </summary>
public int SaveRows
{
get
{
return saverows;
}
set
{
if (saverows != value)
{
saverows = value;
NotifyPropertyChanged("SaveRows");
}
}
}
private int currrows;
/// <summary>
/// 当前总行数
/// </summary>
public int CurrRows
{
get
{
return currrows;
}
protected set
{
if (currrows != value)
{
currrows = value;
NotifyPropertyChanged("CurrRows");
}
}
}
private string currpath = null;
public string CurrPath
{
get
{
return currpath;
}
protected set
{
if (currpath != value)
{
currpath = value;
NotifyPropertyChanged("CurrPath");
}
}
}
#endregion
public RemoteHistorySerivceClient(UInt32 serverid)
{
mServerID = serverid;
}
public void Apply()
{
REMOTEHISTORY_OBJ_INTERFACE.Pack_Params p
= new REMOTEHISTORY_OBJ_INTERFACE.Pack_Params()
{
keeyday = KeeyDay,
saverows = SaveRows,
minSaveInterval = MinSaveInterval
};
CurrObjSys.SetValueEx(
mConn, mServerID, ID,
REMOTEHISTORY_OBJ_INTERFACE.SET_PARAMS, p.ToBytes());
}
public void Flush()
{
CurrObjSys.CallFunctionEx(
mConn, mServerID, ID,
REMOTEHISTORY_OBJ_INTERFACE.CALL_FLUSH, null);
}
public void GetPaths(DateTime dt_begin, DateTime dt_end, string profilename, GetPathsReponseHandler return_func, object state)
{
REMOTEHISTORY_OBJ_INTERFACE.Pack_GetPathsRequest p = new REMOTEHISTORY_OBJ_INTERFACE.Pack_GetPathsRequest()
{
dt_begin = dt_begin,
dt_end = dt_end,
profilename = profilename
};
CurrObjSys.CallFunctionEx(
mConn, mServerID, ID,
REMOTEHISTORY_OBJ_INTERFACE.CALL_GETPATHS, p.ToBytes(), return_func, state);
}
/// <summary>
/// 获取根目录
/// </summary>
public void GetRootPath(GetRootPathReponseHandler return_func, object state)
{
CurrObjSys.CallFunctionEx(
mConn, mServerID, ID,
REMOTEHISTORY_OBJ_INTERFACE.CALL_GETROOTPATH, null, return_func, state);
}
#region INotifyPropertyChanged 成员
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyname)
{
if (PropertyChanged != null)
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyname));
}
#endregion
public override void Dispose()
{
//获取所有数据,设置推送
CurrObjSys.ObjRemove(this, mConn);
}
public override void ConnectNotify(IFConn from)
{
mConn = from;
IsConnected = from.IsConnected;
if (from.IsConnected)
{
//获取所有数据,设置推送
CurrObjSys.GetValueEx(
mConn, mServerID, ID,
REMOTEHISTORY_OBJ_INTERFACE.GET_PARAMS);
CurrObjSys.GetValueEx(
mConn, mServerID, ID,
REMOTEHISTORY_OBJ_INTERFACE.GET_STATE);
CurrObjSys.SenseConfigEx(
mConn, mServerID, ID, 0xffffffff,
SENSE_CONFIG.ADD);
}
}
public override void PushGetValue(IFConn from, uint srcid, ushort memid, byte[] infodata)
{
switch (memid)
{
case REMOTEHISTORY_OBJ_INTERFACE.GET_PARAMS:
{
REMOTEHISTORY_OBJ_INTERFACE.Pack_Params p = new REMOTEHISTORY_OBJ_INTERFACE.Pack_Params();
if (p.TryParse(infodata))
{
KeeyDay = p.keeyday;
SaveRows = p.saverows;
MinSaveInterval = p.minSaveInterval;
}
} break;
case REMOTEHISTORY_OBJ_INTERFACE.GET_STATE:
{
REMOTEHISTORY_OBJ_INTERFACE.Pack_State p = new REMOTEHISTORY_OBJ_INTERFACE.Pack_State();
if (p.TryParse(infodata))
{
CurrRows = p.currrows;
CurrPath = p.currpath;
CurrDays = p.currdays;
}
} break;
}
}
public override void PushInfo(IFConn from, uint srcid, ushort infoid, byte[] infodata)
{
PushGetValue(from, srcid, infoid, infodata);
}
public override void PushCallFunction(IFConn from, uint srcid, UInt32 magic, ushort funcid, byte[] retdata, object AsyncDelegate, object AsyncState)
{
switch (funcid)
{
case REMOTEHISTORY_OBJ_INTERFACE.CALL_GETPATHS:
{
REMOTEHISTORY_OBJ_INTERFACE.Pack_GetPathsResponse p = new REMOTEHISTORY_OBJ_INTERFACE.Pack_GetPathsResponse();
if (!p.TryParse(retdata))
return;
GetPathsReponseHandler func = (GetPathsReponseHandler)AsyncDelegate;
func(p.paths, AsyncState);
}break;
case REMOTEHISTORY_OBJ_INTERFACE.CALL_GETROOTPATH:
{
REMOTEHISTORY_OBJ_INTERFACE.Pack_GetRootPathResponse p = new REMOTEHISTORY_OBJ_INTERFACE.Pack_GetRootPathResponse();
if (!p.TryParse(retdata))
return;
GetRootPathReponseHandler func = (GetRootPathReponseHandler)AsyncDelegate;
func(p.rootpath, AsyncState);
}break;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FObjBase;
using Misc;
using System.ComponentModel;
namespace FLY.Thick.RemoteHistory
{
public class RemoteHistory_OBJProxy: FObj
{
#region 延时推送 MARKNO
const int MARKNO_PUSH_PARAMS = 1;
const int MARKNO_PUSH_STATE = 2;
#endregion
IRemoteHistory mRemoteHistory;
public RemoteHistory_OBJProxy(int objsys_idx, UInt32 objid, IRemoteHistory remotehistory)
: base(objsys_idx)
{
mRemoteHistory = remotehistory;
ID = objid;
mRemoteHistory.PropertyChanged += new PropertyChangedEventHandler(mRemoteHistory_PropertyChanged);
}
void mRemoteHistory_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if ((e.PropertyName == "KeeyDay") ||
(e.PropertyName == "SaveRows") ||
(e.PropertyName == "MinSaveInterval"))
{
FObjBase.PollModule.Current.Poll_JustOnce(
new PollModule.PollHandler(delegate()
{
byte[] buf;
GetValue(null, 0, REMOTEHISTORY_OBJ_INTERFACE.GET_PARAMS, out buf);
CurrObjSys.PushObjInfoEx(
this, REMOTEHISTORY_OBJ_INTERFACE.PUSH_PARAMS,
buf);
}), this, MARKNO_PUSH_PARAMS);
}
else if (
(e.PropertyName == "CurrDays")||
(e.PropertyName == "CurrRows") ||
(e.PropertyName == "CurrPath"))
{
FObjBase.PollModule.Current.Poll_JustOnce(
new PollModule.PollHandler(delegate()
{
byte[] buf;
GetValue(null, 0, REMOTEHISTORY_OBJ_INTERFACE.GET_STATE, out buf);
CurrObjSys.PushObjInfoEx(
this, REMOTEHISTORY_OBJ_INTERFACE.PUSH_STATE,
buf);
}), this, MARKNO_PUSH_STATE);
}
}
public override void CallFunction(IFConn from, UInt32 srcid, UInt32 magic, UInt16 funcid, byte[] infodata)
{
switch (funcid)
{
case REMOTEHISTORY_OBJ_INTERFACE.CALL_FLUSH:
{
mRemoteHistory.Flush();
return;
}
break;
case REMOTEHISTORY_OBJ_INTERFACE.CALL_GETPATHS:
{
REMOTEHISTORY_OBJ_INTERFACE.Pack_GetPathsRequest p = new REMOTEHISTORY_OBJ_INTERFACE.Pack_GetPathsRequest();
if (!p.TryParse(infodata))
return;
mRemoteHistory.GetPaths(p.dt_begin, p.dt_end, p.profilename,
new GetPathsReponseHandler(delegate(List<string> paths, object state)
{
ConnContext c = (ConnContext)state;
CurrObjSys.PushCallFunctionEx(c.from, c.srcid, ID, c.magic,
REMOTEHISTORY_OBJ_INTERFACE.CALL_GETPATHS,
new REMOTEHISTORY_OBJ_INTERFACE.Pack_GetPathsResponse() { paths = paths }.ToBytes());
}),
new ConnContext(from, srcid, magic));
return;
}break;
case REMOTEHISTORY_OBJ_INTERFACE.CALL_GETROOTPATH:
{
mRemoteHistory.GetRootPath(
new GetRootPathReponseHandler(delegate(string path, object state)
{
ConnContext c = (ConnContext)state;
CurrObjSys.PushCallFunctionEx(c.from, c.srcid, ID, c.magic,
REMOTEHISTORY_OBJ_INTERFACE.CALL_GETROOTPATH,
new REMOTEHISTORY_OBJ_INTERFACE.Pack_GetRootPathResponse() { rootpath = path }.ToBytes());
}),
new ConnContext(from, srcid, magic));
return;
}break;
}
return;
}
public override void GetValue(IFConn from, uint srcid, ushort memid, out byte[] infodata)
{
switch (memid)
{
case REMOTEHISTORY_OBJ_INTERFACE.GET_PARAMS:
{
REMOTEHISTORY_OBJ_INTERFACE.Pack_Params p = new REMOTEHISTORY_OBJ_INTERFACE.Pack_Params()
{
keeyday = mRemoteHistory.KeeyDay,
saverows = mRemoteHistory.SaveRows,
minSaveInterval = mRemoteHistory.MinSaveInterval
};
infodata = p.ToBytes();
} break;
case REMOTEHISTORY_OBJ_INTERFACE.GET_STATE:
{
REMOTEHISTORY_OBJ_INTERFACE.Pack_State p = new REMOTEHISTORY_OBJ_INTERFACE.Pack_State()
{
currdays = mRemoteHistory.CurrDays,
currrows = mRemoteHistory.CurrRows,
currpath = mRemoteHistory.CurrPath
};
infodata = p.ToBytes();
}break;
default:
infodata = null;
break;
}
}
public override void SetValue(IFConn from, uint srcid, ushort memid, byte[] infodata)
{
switch (memid)
{
case REMOTEHISTORY_OBJ_INTERFACE.SET_PARAMS:
{
REMOTEHISTORY_OBJ_INTERFACE.Pack_Params p = new REMOTEHISTORY_OBJ_INTERFACE.Pack_Params();
if (p.TryParse(infodata))
{
mRemoteHistory.KeeyDay = p.keeyday;
mRemoteHistory.SaveRows = p.saverows;
mRemoteHistory.MinSaveInterval = p.minSaveInterval;
}
} break;
}
}
}
}
****************************************************************************************************
产品版本:Project.FLY.Thick.RemoteHistory_v2.0.0_20180526
****************************************************************************************************
1.新增 Buffer<T> 及Buffer_OBJProxy,BufferServiceClient 用于列表类的obj通讯 (05-26)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment