using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CapMachine.Wpf.CanDrive
{
///
/// Dbc 信息
///
public class CanDbcModel : BindableBase
{
///
/// 消息Id
///
public string? MsgId { get; set; }
///
/// 配置的中文名称:速度,转速限制,使能等常用的信息数据
/// 但不是所有的SignalName都会配置一个Name,只是需要时才会配置名称
/// 但是CanDbcModel集合会包括所有的SignalName名称的
///
public string? Name { get; set; }
///
/// 消息名称
///
public string? MsgName { get; set; }
///
/// 信号名称
///
public string? SignalName { get; set; }
///
/// 信号描述
///
public string? SignalDesc { get; set; }
///
/// 信号单位
///
public string? SignalUnit { get; set; }
private string? _SignalRtValue = "--";
///
/// 信号实时值(供 UI 绑定显示)。
///
///
/// - 仅当文本发生变化时才触发通知,避免无谓 UI 刷新。
/// - 若期望进一步降低分配开销,建议在调用方(接收循环)先做“数值层去重”,
/// 即:仅在数值变化(可设置容差)时才调用 ToString() 格式化并赋值到本属性。
/// 这样可以显著减少字符串分配与 GC 压力。
///
///
/// // 示例:数值层去重后再格式化(接收循环中使用)
/// // if (Math.Abs(newVal - lastVal) > 1e-3) { model.SignalRtValue = newVal.ToString("F3"); lastVal = newVal; }
///
public string? SignalRtValue
{
get { return _SignalRtValue; }
set
{
if (_SignalRtValue != value)
{
_SignalRtValue = value;
RaisePropertyChanged();
}
}
}
private StringBuilder _SignalRtValueSb = new StringBuilder(16);
///
/// 信号实时值的可变文本缓冲接口。
/// 设计目的:
/// - 避免外部传入的 StringBuilder 被直接保存(引用别名问题),统一复制文本到内部缓冲 _SignalRtValueSb;
/// - 仅当文本内容变化时才更新 SignalRtValue 并 RaisePropertyChanged,减少 UI 抖动与无谓刷新;
/// - 对 value == null 做防御:清空内部缓冲并置空显示文本(如需显示 “--” 可按需替换)。
/// 使用方式:
/// - 接收环路可重复复用同一个外部 StringBuilder 作为临时缓存,调用本属性进行更新不会产生实例共享风险。
///
///
/// 注意事项:
/// 1) 本属性会复制文本,不会保存外部 StringBuilder 引用;这可避免多个模型共享同一实例导致的数据串扰和并发问题。
/// 2) 若你的 UI 需要统一的“空值占位符”,可将 setter 中的空字符串替换为 "--",与字段初始值保持一致。
/// 3) 线程模型:建议仍在 UI 线程更新以避免跨线程通知问题;如需后台线程更新,请确保有合适的调度(Dispatcher/同步上下文)。
/// 4) 性能建议:结合 SignalRtValue 的备注,在进入本 setter 前尽量做数值层去重,进一步减少字符串分配。
///
///
/// // 示例:接收循环中复用临时缓存
/// // var tmp = new StringBuilder(32);
/// // ... 填充 tmp ...
/// // model.SignalRtValueSb = tmp; // 本属性会复制 tmp 的内容,安全且不会产生实例共享
///
public StringBuilder SignalRtValueSb
{
get { return _SignalRtValueSb; }
set
{
// 防御:若外部传入 null,清空内部状态并复位显示文本
// 注意:此处将显示文本设为空字符串 "",如果希望与初始占位符 "--" 一致,可改为 SignalRtValue = "--"。
if (value == null)
{
if (_SignalRtValue != string.Empty)
{
_SignalRtValueSb.Clear();
SignalRtValue = string.Empty;
}
return;
}
// 复制策略:不保存外部 StringBuilder 的引用,改为复制其当前文本内容
// 这样可避免多个模型共享同一 StringBuilder 实例导致的数据串扰与线程安全问题
var str = value.ToString();
// 仅当文本内容确实发生变化时,才更新内部缓冲与绑定属性,减少无谓的 UI 刷新与字符串分配
if (!string.Equals(_SignalRtValue, str, StringComparison.Ordinal))
{
_SignalRtValueSb.Clear();
_SignalRtValueSb.Append(str);
SignalRtValue = str;
}
}
}
private int _IsSeletedInfo;
///
/// 被选中的信息
/// 方便标注着色
///
public int IsSeletedInfo
{
get { return _IsSeletedInfo; }
set { _IsSeletedInfo = value;RaisePropertyChanged(); }
}
///
/// 发布者
///
public string? Publisher { get; set; }
}
}