using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; using FObjBase; using static FLY.Thick.BulkDataModule.BulkDataService; using System.Collections.Specialized; namespace FLY.Thick.BulkDataModule { /// <summary> /// 推送服务,(AsyncState,param) 作为一个对,不能存在 两个一样的(AsyncState,param)。 它只会推送一次 /// </summary> public interface IBulkDataService : INotifyPropertyChanged { /// <summary> /// 获取一幅数据, 默认带推送 /// 参数 Pack_CallGetFrameDataParam /// 回复 Pack_CallGetFrameDataReturn /// </summary> /// <param name="param"></param> /// <param name="AsyncDelegate"></param> /// <param name="AsyncState"></param> void GetFrameData( BULKDATA_OBJ_INTERFACE.Pack_CallGetFrameDataParam param, AsyncCBHandler AsyncDelegate, object AsyncState); /// <summary> /// 关闭 扫描图 推送 /// </summary> /// <param name="param"></param> /// <param name="AsyncState"></param> void ClosePushFrameData( BULKDATA_OBJ_INTERFACE.Pack_CallClosePushFrameData param, object AsyncState); /// <summary> /// 获取纵向趋势图,默认带推送 /// </summary> /// <param name="param"></param> /// <param name="AsyncDelegate"></param> /// <param name="AsyncState"></param> void GetTrendData( BULKDATA_OBJ_INTERFACE.Pack_CallGetTrendDataParam param, AsyncCBHandler AsyncDelegate, object AsyncState); /// <summary> /// 关闭 纵向趋势图 推送 /// </summary> /// <param name="param"></param> /// <param name="AsyncState"></param> void ClosePushTrendData( BULKDATA_OBJ_INTERFACE.Pack_CallClosePushTrendData param, object AsyncState); /// <summary> /// 注册新数据推送 /// </summary> /// <param name="param"></param> /// <param name="AsyncDelegate"></param> /// <param name="AsyncState"></param> void PushNewFrameData( BULKDATA_OBJ_INTERFACE.Pack_CallPushNewFrameDataParam param, AsyncCBHandler AsyncDelegate, object AsyncState); /// <summary> /// 关闭 新数据推送 /// </summary> /// <param name="param"></param> /// <param name="AsyncState"></param> void ClosePushNewFrameData( BULKDATA_OBJ_INTERFACE.Pack_CallClosePushNewFrameData param, object AsyncState); /// <summary> /// 获取一幅数据, 默认带推送 /// 参数 Pack_CallGetFrameDataMixRequest /// 回复 Pack_CallGetFrameDataMixReponse /// </summary> /// <param name="param"></param> /// <param name="AsyncDelegate"></param> /// <param name="AsyncState"></param> void GetFrameDataMix( Pack_CallGetFrameDataMixRequest param, AsyncCBHandler AsyncDelegate, object AsyncState); /// <summary> /// 关闭 扫描图 推送 /// </summary> /// <param name="param"></param> /// <param name="AsyncState"></param> void ClosePushFrameDataMix( Pack_CallClosePushFrameDataMixRequest param, object AsyncState); /// <summary> /// 清空缓存区 /// </summary> void Clear(); /// <summary> /// 只要 AsyncState 满足 match 的都要删除 /// </summary> /// <param name="match">AsyncState 规则</param> void ClosePush(Predicate<object> match); /// <summary> /// 准备好,只有在 IsReady=true ,发送的命令才能执行,才能推送 /// </summary> bool IsConnected { get; } /// <summary> /// 缓冲区数据 /// </summary> List<FR_DATA> Datas { get; } /// <summary> /// 数量 /// </summary> int Count { get; } /// <summary> /// 分区数 /// </summary> int NBolts { get; } /// <summary> /// 第1分区号 /// </summary> int BoltNo1st { get; } /// <summary> /// 最新的bookmark /// </summary> int CurrentBookmark { get; } // // 摘要: // 在添加、移除、更改或者在刷新整个列表时发生。 event NotifyDatasChangedEventHandler DatasChanged; } public class NotifyDatasChangedEventArgs : EventArgs { public NotifyDatasChangedAction Action; public int NewStartingIndex; public List<FR_DATA> Items; } public enum NotifyDatasChangedAction { Add, Replace, Reset } public delegate void NotifyDatasChangedEventHandler(object sender, NotifyDatasChangedEventArgs e); /// <summary> /// 作为服务器端 添加,改变 数据 /// </summary> public interface IBulkDataServiceAdd { /// <summary> /// 分区数 /// </summary> int NBolts { get; set; } /// <summary> /// 第1分区号 /// </summary> int BoltNo1st { get; set; } /// <summary> /// 初始化推送 /// </summary> void InitPush(); /// <summary> /// 添加空数据 /// </summary> /// <returns></returns> int AddEmply(); /// <summary> /// 添加数据 /// </summary> /// <param name="buf"></param> /// <param name="type"></param> /// <param name="dt"></param> /// <returns></returns> int Add(int[] buf, FR_DATA_TYPE type, DateTime dt); /// <summary> /// 添加数据 /// </summary> /// <param name="buf"></param> /// <param name="type"></param> /// <returns></returns> int Add(int[] buf, FR_DATA_TYPE type); /// <summary> /// 改变数据 /// </summary> /// <param name="bm"></param> /// <param name="start_boltIndex"></param> /// <param name="buf"></param> /// <param name="type"></param> /// <param name="time"></param> /// <returns></returns> bool Change(int bm, int start_boltIndex, int[] buf, FR_DATA_TYPE type, DateTime time); /// <summary> /// 改变数据 /// </summary> /// <param name="bm"></param> /// <param name="start_boltIndex"></param> /// <param name="buf"></param> /// <param name="type"></param> /// <returns></returns> bool Change(int bm, int start_boltIndex, int[] buf, FR_DATA_TYPE type); /// <summary> /// 改变数据为空 /// </summary> /// <param name="bm"></param> /// <returns></returns> bool ChangeEmply(int bm); /// <summary> /// 改变最新幅数据为空 /// </summary> /// <returns></returns> bool ChangeEmply(); /// <summary> /// 保存 /// </summary> void Save(); } /// <summary> /// /// </summary> public class Pack_CallGetFrameDataMixRequest : Pack_CallClosePushFrameDataMixRequest { /// <summary> /// 当数据变化时,是否需要推送 /// </summary> public bool NeedPush; #region IPack 成员 /// <summary> /// 转换为 17个字节 /// </summary> /// <returns></returns> public override byte[] ToBytes() { List<byte> buf = new List<byte>(); buf.AddRange(base.ToBytes()); buf.AddRange(BitConverter.GetBytes(NeedPush)); return buf.ToArray(); } /// <summary> /// 17个字节 类型转换 /// </summary> /// <param name="value"></param> /// <returns></returns> public override bool TryParse(byte[] value) { if (!base.TryParse(value)) return false; int index = 16; int cnt = 1; int idx = index; if (value.Length < cnt+index) return false; NeedPush = BitConverter.ToBoolean(value, idx); idx += 1; return true; } #endregion } /// <summary> /// /// </summary> public class Pack_CallGetFrameDataMixReponse : Pack_CallGetFrameDataMixRequest { /// <summary> /// 结果对应的 bookmark /// </summary> public int bookmark = -1; /// <summary> /// 结果对应的 实际结束时间 /// </summary> public DateTime dt = DateTime.MinValue; /// <summary> /// 结果对应的 实际开始时间 /// </summary> public DateTime act_startDt = DateTime.MinValue; /// <summary> /// 开始分区index /// </summary> public int fromBoltIndex = 0; /// <summary> /// 结束分区index /// </summary> public int toBoltIndex = 0; /// <summary> /// 结果.数据是否有效 /// </summary> public FR_DATA_TYPE type = FR_DATA_TYPE.INVALID; /// <summary> /// 结果, 当needPush=true, 以后推送时,只发送变化了的数据 /// </summary> public FrameDataCell[] result = null; #region IPack 成员 /// <summary> /// /// </summary> /// <returns></returns> public override byte[] ToBytes() { List<byte> buf = new List<byte>(); buf.AddRange(base.ToBytes());//17 buf.AddRange(BitConverter.GetBytes(bookmark));//4 buf.AddRange(BitConverter.GetBytes(dt.Ticks));//8 buf.AddRange(BitConverter.GetBytes(act_startDt.Ticks));//8 buf.AddRange(BitConverter.GetBytes(fromBoltIndex));//4 buf.AddRange(BitConverter.GetBytes(toBoltIndex));//4 buf.Add((byte)type);//1 if (result != null) { buf.AddRange(BitConverter.GetBytes((int)result.Length));//4 foreach (FrameDataCell dat in result) buf.AddRange(dat.ToBytes()); } else { buf.AddRange(BitConverter.GetBytes((int)0));//4 } return buf.ToArray(); } /// <summary> /// /// </summary> /// <param name="value"></param> /// <returns></returns> public override bool TryParse(byte[] value) { if (!base.TryParse(value)) return false; int index = 17; int cnt = 4 + 8 + 8 + 4 + 4 + 1 + 4; if (value.Length < cnt+index) return false; int idx = index; bookmark = BitConverter.ToInt32(value, idx); idx += 4; try { dt = new DateTime(BitConverter.ToInt64(value, idx)); } catch { return false; } idx += 8; try { act_startDt = new DateTime(BitConverter.ToInt64(value, idx)); } catch { return false; } idx += 8; fromBoltIndex = BitConverter.ToInt32(value, idx); idx += 4; toBoltIndex = BitConverter.ToInt32(value, idx); idx += 4; type = (FR_DATA_TYPE)value[idx]; idx += 1; int length = BitConverter.ToInt32(value, idx); idx += 4; if (length > 0) { cnt += length * 4; if (value.Length < cnt + index) return false; result = new FrameDataCell[length]; for (int i = 0; i < length; i++) { result[i] = new FrameDataCell(); result[i].TryParse(value, idx); idx += 8; } } else { result = null; } return true; } #endregion } /// <summary> /// /// </summary> public class Pack_CallClosePushFrameDataMixRequest : IPack { /// <summary> /// 标记, 当bm>0 为bookmark,当bm <=0 为往前面数 /// </summary> public int bm; /// <summary> /// 混合数 /// </summary> public int mix; /// <summary> /// 混合数据,只能从 start_dt 开始 /// </summary> public DateTime start_dt; #region IPack 成员 /// <summary> /// 转换为 16个字节 /// </summary> /// <returns></returns> public virtual byte[] ToBytes() { List<byte> buf = new List<byte>(); buf.AddRange(BitConverter.GetBytes(bm)); buf.AddRange(BitConverter.GetBytes(mix)); buf.AddRange(BitConverter.GetBytes(start_dt.Ticks)); return buf.ToArray(); } /// <summary> /// 16个字节 类型转换 /// </summary> /// <returns></returns> public virtual bool TryParse(byte[] value) { int count = 4+4+8; if (value.Length < count) return false; int idx = 0; bm = BitConverter.ToInt32(value, idx); idx += 4; mix = BitConverter.ToInt32(value, idx); idx += 4; try { start_dt = new DateTime(BitConverter.ToInt64(value, idx)); } catch { start_dt = DateTime.MinValue; } idx += 8; return true; } #endregion /// <summary> /// 参数是否一样 /// </summary> /// <param name="dest"></param> /// <returns></returns> public bool IsSame(Pack_CallClosePushFrameDataMixRequest dest) { if ((bm == dest.bm) && (mix == dest.mix) && (start_dt == dest.start_dt)) { return true; } else { return false; } } } }