要求
简要模拟数字电路的运行过程,及电位(简化为L和H),用C# WinForm实现。
思路
逻辑部分
- 电路是一种图结构,基于C#的特性,设计Node类(结点)和Wire类(连线),且为泛型。
- 由于电路元件可以包含多个Node,故设计超类Unit(继承自Node,管理Node)。
- 电路器件的状态有L和H,故存在状态的变迁与计算,故设计Status类(状态)和Mutable类(原状态和新状态)。
- 每个电路对象(结点,单元,连线)拥有一个唯一编号,故设计Markable类(基于UUID)。
- 结点和单元可以处理事件(单击、绘图等),增加交互接口IInteractive和仿真接口ISimuate。
- 设计结点和单元的获得焦点和失去焦点事件,由OnStateUpdated和OnValueUpdated触发。
- 构造新元器件可通过派生Node并重载。
界面部分
- 采用DirectUI思想绘制,API采用Gdi+的Graphics,构造图元方法参考自@vczh的C++ GUI Library/GacLib。
- 构造渲染器工厂GraphicsRendererFactory和图元工厂GraphicsElementFactory,渲染器存放绘制句柄(对Gdi+而言不需要存放句柄,且Gdi+对象有缓存机制),图元存放图形的属性。
- 每个元器件拥有独立的IGraphicsElement图元绘制接口集合以绘制图像。
核心算法
采用状态更新机制,类似状态机,并行优化。(此算法仍存在缺陷,有循环刷新问题)
public virtual void Update() { _units.Values.Where(a => a.Active).AsParallel().ForAll(a => a.Activate(ActivateType.FilterUnit)); _nodes.Values.Where(a => a.Active).AsParallel().ForAll(a => a.Advance(AdvanceType.NodeToWire)); _wires.Values.Where(a => a.Active).AsParallel().ForAll(a => a.Advance(AdvanceType.NodeToWire)); _nodes.Values.Where(a => a.Active).AsParallel().ForAll(a => a.Advance(AdvanceType.WireToNode)); _wires.Values.Where(a => a.Active).AsParallel().ForAll(a => a.Advance(AdvanceType.WireToNode)); }
测试
源码
https://github.com/bajdcc/SimuCircult
类库:SimuCircult
界面:WinSC