taoye 2 years ago
parent
commit
b639b10053
34 changed files with 2326 additions and 1 deletions
  1. +14
    -0
      BPASmartClient.Bus/BPASmartClient.Bus.csproj
  2. +236
    -0
      BPASmartClient.Bus/DataBus/DataBus.cs
  3. +98
    -0
      BPASmartClient.Bus/DataBus/DataBus_Byte.cs
  4. +190
    -0
      BPASmartClient.Bus/DataBus/DataBus_Currency.cs
  5. +149
    -0
      BPASmartClient.Bus/DataBus/Executer.cs
  6. +54
    -0
      BPASmartClient.Bus/DataBus/IDataBus.cs
  7. +30
    -0
      BPASmartClient.Bus/DataBus/IGivenDataBus.cs
  8. +33
    -0
      BPASmartClient.Bus/DataBus/ISimpleDataBus.cs
  9. +32
    -0
      BPASmartClient.Bus/DataBus/SimpleDataType.cs
  10. +108
    -0
      BPASmartClient.Bus/EventBus/EventBus.cs
  11. +16
    -0
      BPASmartClient.Bus/EventBus/IEvent.cs
  12. +35
    -0
      BPASmartClient.Bus/EventBus/IEventExtends.cs
  13. +22
    -0
      BPASmartClient.Compiler/BPASmartClient.Compiler.csproj
  14. +89
    -0
      BPASmartClient.Compiler/Config.cs
  15. BIN
     
  16. BIN
     
  17. +9
    -0
      BPASmartClient.DATABUS/BPASmartClient.DATABUS.csproj
  18. +34
    -0
      BPASmartClient.DATABUS/Class_DataBus.cs
  19. +9
    -0
      BPASmartClient.MessageName/BPASmartClient.MessageName.csproj
  20. +25
    -0
      BPASmartClient.MessageName/DataName.cs
  21. +26
    -0
      BPASmartClient.MessageName/MessageName.cs
  22. +197
    -0
      BPASmartClient.SCADAControl/ArcGauge.cs
  23. +10
    -0
      BPASmartClient.SCADAControl/AssemblyInfo.cs
  24. +30
    -0
      BPASmartClient.SCADAControl/BPASmartClient.SCADAControl.csproj
  25. +28
    -0
      BPASmartClient.SCADAControl/Converters/HalfNumberConverter.cs
  26. +24
    -0
      BPASmartClient.SCADAControl/IExecutable.cs
  27. BIN
     
  28. +30
    -0
      BPASmartClient.SCADAControl/NewConveyorBelt.xaml
  29. +277
    -0
      BPASmartClient.SCADAControl/NewConveyorBelt.xaml.cs
  30. +42
    -0
      BPASmartClient.SCADAControl/Silos.xaml
  31. +96
    -0
      BPASmartClient.SCADAControl/Silos.xaml.cs
  32. +144
    -0
      BPASmartClient.SCADAControl/SwitchButton.cs
  33. +135
    -0
      BPASmartClient.SCADAControl/Themes/Generic.xaml
  34. +104
    -1
      SmartClient.sln

+ 14
- 0
BPASmartClient.Bus/BPASmartClient.Bus.csproj View File

@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\BPASmartClient.Helper\BPASmartClient.Helper.csproj" />
<ProjectReference Include="..\BPASmartClinet.DataBusName\BPASmartClinet.DataBusName.csproj" />
</ItemGroup>

</Project>

+ 236
- 0
BPASmartClient.Bus/DataBus/DataBus.cs View File

@@ -0,0 +1,236 @@

using BPASmartClient.Bus.DataBus;
using BPASmartClient.Helper;
using BPASmartClinet.DataBusName;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;


/* ***********************************************
 * subject 数据总线,总线入口,后续按类型分发
 * author 张原川
 * date   2019/6/3 9:49:03
 * ***********************************************/

namespace LandStation.Bus.DataBus
{
public class DataBus : Singleton<DataBus>, IDisposable
{
//原始数据总线
private IDataBus<byte> _dataBus_rawdata;
//MAVLINK消息总线
private IDataBus<object> _dataBus_mavMessage;
//参数总线
private IDataBus<object> _dataBus_parameter;
//调试消息总线
private IDataBus<string> _dataBus_message;

/// <summary>
/// 数据总线初始化
/// </summary>
public void Initialize()
{
_dataBus_rawdata = new DataBus_Byte();
_dataBus_mavMessage = new DataBus_Currency<object>();
_dataBus_parameter = new DataBus_Currency<object>();
_dataBus_message = new DataBus_Currency<string>();
}

/// <summary>
/// 总线开启
/// </summary>
public void Start()
{
Executer.GetInstance().Start(_dataBus_rawdata.StartBus, ActionKey.DataBus_Rawdata);
Executer.GetInstance().Start(_dataBus_mavMessage.StartBus, ActionKey.DataBus_MAVLinkMessage);
Executer.GetInstance().Start(_dataBus_message.StartBus, ActionKey.DataBus_MessageData);
Executer.GetInstance().Start(_dataBus_parameter.StartBus, ActionKey.DataBus_ParameterData);

//Executer.GetInstance().Start(delegate ()
//{
// while (true)
// {
// //Console.WriteLine("原始数据========>批量数据订阅数:{0},单数据订阅数:{1}", _dataBus_rawdata.MultSubscriberCount, _dataBus_rawdata.SingleSubscriberCount);
// //Console.WriteLine("MAVLink数据=====>批量数据订阅数:{0},单数据订阅数:{1}", _dataBus_mavMessage.MultSubscriberCount, _dataBus_mavMessage.SingleSubscriberCount);
// //Console.WriteLine("状态数据========>批量数据订阅数:{0},单数据订阅数:{1}", _dataBus_status.MultSubscriberCount, _dataBus_status.SingleSubscriberCount);
// //Console.WriteLine("参数数据========>批量数据订阅数:{0},单数据订阅数:{1}", _dataBus_parameter.MultSubscriberCount, _dataBus_parameter.SingleSubscriberCount);
// //Console.WriteLine("消息数据========>批量数据订阅数:{0},单数据订阅数:{1}", _dataBus_message.MultSubscriberCount, _dataBus_message.SingleSubscriberCount);
// //Console.WriteLine("===============================================================================================");
// Console.WriteLine("原始数据========>{0}", _dataBus_rawdata.DataCount);
// Console.WriteLine("MAVLink数据=====>{0}", _dataBus_mavMessage.DataCount);
// Console.WriteLine("状态数据========>{0}", _dataBus_status.DataCount);
// Console.WriteLine("参数数据========>{0}", _dataBus_parameter.DataCount);
// Console.WriteLine("消息数据========>{0}", _dataBus_message.DataCount);
// Console.WriteLine("===============================================================================================");
// Thread.Sleep(50);
// }
//}, ActionKey.DataBus_Monitor, "数据总线监控");
}

/// <summary>
/// 根据数据类型放入数据到对应总线
/// </summary>
/// <typeparam name="TData">数据实际类型</typeparam>
/// <param name="data">数据</param>
/// <param name="simpleData">数据业务类型</param>
public void Put<TData>(object data, SimpleDataType simpleData)
{
switch (simpleData)
{
case SimpleDataType.RAW_DATA:
if (data is byte)
_dataBus_rawdata.Put((byte)data);
if (data is byte[])
_dataBus_rawdata.Put((byte[])data);
break;
case SimpleDataType.MAV_MESSAGE_DATA:
_dataBus_mavMessage.Put((object)data);
break;
case SimpleDataType.PARAMETER:
_dataBus_parameter.Put((object)data);
break;
case SimpleDataType.MESSAGE_DATA:
_dataBus_message.Put((string)data);
break;
}
}

/// <summary>
/// 订阅数据
/// </summary>
/// <typeparam name="TData">数据实际类型</typeparam>
/// <param name="action">接收数据推送回调</param>
/// <param name="dataType">数据业务类型</param>
public void Subscribe<TData>(Action<TData> action, SimpleDataType dataType)
{
switch (dataType)
{
case SimpleDataType.RAW_DATA:
((ISimpleDataBus<TData>)_dataBus_rawdata).Subscribe(action);
break;
case SimpleDataType.MAV_MESSAGE_DATA:
((ISimpleDataBus<TData>)_dataBus_mavMessage).Subscribe(action);
break;
case SimpleDataType.PARAMETER:
((ISimpleDataBus<TData>)_dataBus_parameter).Subscribe(action);
break;
case SimpleDataType.MESSAGE_DATA:
((ISimpleDataBus<TData>)_dataBus_message).Subscribe(action);
break;
}
}

/// <summary>
/// 订阅数据
/// </summary>
/// <typeparam name="TData">数据实际类型</typeparam>
/// <param name="action">接收数据推送回调</param>
/// <param name="dataType">数据业务类型</param>
public void UnSubscribe<TData>(Action<TData> action, SimpleDataType dataType)
{
switch (dataType)
{
case SimpleDataType.RAW_DATA:
((ISimpleDataBus<TData>)_dataBus_rawdata).UnSubcribe(action);
break;
case SimpleDataType.MAV_MESSAGE_DATA:
((ISimpleDataBus<TData>)_dataBus_mavMessage).UnSubcribe(action);
break;
case SimpleDataType.PARAMETER:
((ISimpleDataBus<TData>)_dataBus_parameter).UnSubcribe(action);
break;
case SimpleDataType.MESSAGE_DATA:
((ISimpleDataBus<TData>)_dataBus_message).UnSubcribe(action);
break;
}
}

/// <summary>
/// 订阅数据
/// </summary>
/// <typeparam name="TData">数据实际类型</typeparam>
/// <param name="action">接收数据推送回调</param>
/// <param name="dataType">数据业务类型</param>
public void Subscribe<TData>(Action<TData[]> action, SimpleDataType dataType)
{
switch (dataType)
{
case SimpleDataType.RAW_DATA:
((ISimpleDataBus<TData>)_dataBus_rawdata).Subscribe(action);
break;
case SimpleDataType.MAV_MESSAGE_DATA:
((ISimpleDataBus<TData>)_dataBus_mavMessage).Subscribe(action);
break;
case SimpleDataType.PARAMETER:
((ISimpleDataBus<TData>)_dataBus_parameter).Subscribe(action);
break;
case SimpleDataType.MESSAGE_DATA:
((ISimpleDataBus<TData>)_dataBus_message).Subscribe(action);
break;
}
}

/// <summary>
/// 订阅数据
/// </summary>
/// <typeparam name="TData">数据实际类型</typeparam>
/// <param name="action">接收数据推送回调</param>
/// <param name="dataType">数据业务类型</param>
public void UnSubscribe<TData>(Action<TData[]> action, SimpleDataType dataType)
{
switch (dataType)
{
case SimpleDataType.RAW_DATA:
((ISimpleDataBus<TData>)_dataBus_rawdata).UnSubcribe(action);
break;
case SimpleDataType.MAV_MESSAGE_DATA:
((ISimpleDataBus<TData>)_dataBus_mavMessage).UnSubcribe(action);
break;
case SimpleDataType.PARAMETER:
((ISimpleDataBus<TData>)_dataBus_parameter).UnSubcribe(action);
break;
case SimpleDataType.MESSAGE_DATA:
((ISimpleDataBus<TData>)_dataBus_message).UnSubcribe(action);
break;
}
}

/// <summary>
/// 获取一个数据
/// </summary>
/// <typeparam name="TData">数据实际类型</typeparam>
/// <param name="dataType">数据业务类型</param>
/// <returns>一个数据</returns>
public byte GetRawdata()
{
return ((IGivenDataBus<byte>)_dataBus_rawdata).Get();
}

/// <summary>
/// 获取多个数据
/// </summary>
/// <typeparam name="TData">数据实际类型</typeparam>
/// <param name="dataType">数据业务类型</param>
/// <param name="length">获取数据长度</param>
/// <returns>一个数据</returns>
public byte[] GetRawdata(int length)
{
return ((IGivenDataBus<byte>)_dataBus_rawdata).Get(length);
}

/// <summary>
/// 释放数据总线
/// </summary>
public void Dispose()
{
_dataBus_rawdata.StopBus();
_dataBus_mavMessage.StopBus();
_dataBus_message.StopBus();
_dataBus_parameter.StopBus();
}
}
}

+ 98
- 0
BPASmartClient.Bus/DataBus/DataBus_Byte.cs View File

@@ -0,0 +1,98 @@

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;


/* ***********************************************
 * subject Byte类型数据总线,在订阅推送模式基础上
* 增加主动获取
 * author 张原川
 * date   2019/6/3 14:44:36
 * ***********************************************/

namespace BPASmartClient.Bus.DataBus
{
public class DataBus_Byte : DataBus_Currency<byte>, IGivenDataBus<byte>
{
//接收数据缓冲(用以Get)
//protected CircularBuffer<byte> _givenDataPool = new CircularBuffer<byte>(1 * 1024 * 1024);
protected ConcurrentQueue<byte> _givenDataPool = new ConcurrentQueue<byte>();

public new int DataCount { get { return _givenDataPool.Count; } }

/// <summary>
/// 重写Put方法,加入givenDataPool
/// </summary>
public new void Put(byte data)
{
if (!_running)
return;
if (_multDataHandlers.Count > 0 || _singleDataHandlers.Count > 0)
_dataPool.Enqueue(data);
_givenDataPool.Enqueue(data);
}

/// <summary>
/// 重写Put方法,加入givenDataPool
/// </summary>
public new void Put(byte[] data)
{
if (!_running)
return;
if (_multDataHandlers.Count > 0 || _singleDataHandlers.Count > 0)
foreach (var item in data)
_dataPool.Enqueue(item);
foreach (var item in data)
_givenDataPool.Enqueue(item);
}

/// <summary>
/// 数据取出
/// </summary>
public byte Get()
{
agin:
if (_givenDataPool.Count <= 0)
{
Thread.Sleep(5);
goto agin;
}
byte res;
while (!_givenDataPool.TryDequeue(out res)) ;
return res;
}

/// <summary>
/// 数据取出
/// </summary>
public byte[] Get(int count)
{
agin:
if (_givenDataPool.Count < count)
{
Thread.Sleep(5);
goto agin;
}
//Console.WriteLine(_givenDataPool.Size + "===========" + _dataPool.Size);
//for (int i = 0; i < count; i++) {
// _givenDataPool.TryDequeue
//}
int i = 0;
byte[] result = new byte[count];
while (i < count)
{
if (_givenDataPool.TryDequeue(out result[i]))
{
i++;
}
}

return result;// _givenDataPool.Get(count);
}
}
}

+ 190
- 0
BPASmartClient.Bus/DataBus/DataBus_Currency.cs View File

@@ -0,0 +1,190 @@

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;


/* ***********************************************
 * subject 通用数据总线,采取订阅推送模式
 * author 张原川
 * date   2019/6/3 15:03:10
 * ***********************************************/

namespace BPASmartClient.Bus.DataBus
{
public class DataBus_Currency<TData> : ISimpleDataBus<TData>
{
//接收数据缓冲
//protected CircularBuffer<TData> _dataPool = new CircularBuffer<TData>(1 * 1024 * 1024);
protected ConcurrentQueue<TData> _dataPool = new ConcurrentQueue<TData>();
//订阅数据回调集合
protected List<Action<TData[]>> _multDataHandlers = new List<Action<TData[]>>();
protected List<Action<TData>> _singleDataHandlers = new List<Action<TData>>();
//订阅与推送数据信号量
protected AutoResetEvent _are = new AutoResetEvent(false);
//运行标识
protected bool _running = false;

public int MultSubscriberCount { get { return _multDataHandlers.Count; } }

public int SingleSubscriberCount { get { return _singleDataHandlers.Count; } }

public int DataCount { get { return _dataPool.Count; } }

/// <summary>
/// 终止事件总线
/// </summary>
public void Dispose()
{
StopBus();
}

/// <summary>
/// 数据存入
/// </summary>
public void Put(TData data)
{
if (!_running)
return;
if (_multDataHandlers.Count > 0 || _singleDataHandlers.Count > 0)
_dataPool.Enqueue(data);
}

/// <summary>
/// 数据存入
/// </summary>
public void Put(TData[] data)
{
if (!_running)
return;
if (_multDataHandlers.Count > 0 || _singleDataHandlers.Count > 0)
foreach (var item in data)
_dataPool.Enqueue(item);
}

/// <summary>
/// 开启总线
/// </summary>
public void StartBus()
{
_running = true;
List<TData> items = new List<TData>();
_are.Set();
while (_running)
{
int count = _dataPool.Count;
items.Clear();
if (_singleDataHandlers.Count > 0)
{
_are.WaitOne(TimeSpan.FromMilliseconds(10));

for (int i = 0; i < count; i++)
{
TData data = default(TData);
while (!_dataPool.TryDequeue(out data)) ;
uint msgId = Convert.ToUInt32(data.GetType().GetProperty("msgid").GetValue(data));
if (msgId == 316)
{

}
//var item = _dataPool.Get();
//Parallel.ForEach(_singleDataHandlers, p => p.Invoke(items[items.Count - 1]));

for (int j = 0; j < _singleDataHandlers.Count; j++)
{
_singleDataHandlers[j].Invoke(data);
}
items.Add(data);
}
}
if (_multDataHandlers.Count > 0)
{
if (items.Count <= 0)
{
TData data = default(TData);
for (int i = 0; i < count; i++)
{
while (!_dataPool.TryDequeue(out data)) ;
items.Add(data);
}
//items.AddRange(_dataPool.Get(count));
}
_are.WaitOne(TimeSpan.FromMilliseconds(10));
//Parallel.For(0, _multDataHandlers.Count, (i) =>
//{
// _multDataHandlers[i].Invoke(items.ToArray());
//});
for (int i = _multDataHandlers.Count - 1; i >= 0; i--)
{
_multDataHandlers[i].Invoke(items.ToArray());
}
}
Thread.Sleep(10);
_are.Set();
}
}

public void StopBus()
{
_running = false;
}

/// <summary>
/// 数据订阅
/// </summary>
/// <param name="action">接收数据回调</param>
public void Subscribe(Action<TData> action)
{
if (_singleDataHandlers.Contains(action))
return;
_are.Reset();
_singleDataHandlers.Add(action);
_are.Set();
}

/// <summary>
/// 数据订阅
/// </summary>
/// <param name="action">接收数据回调</param>
public void Subscribe(Action<TData[]> action)
{
if (_multDataHandlers.Contains(action))
return;
_are.Reset();
_multDataHandlers.Add(action);
_are.Set();
}

/// <summary>
/// 取消数据订阅
/// </summary>
/// <param name="action">接收数据回调</param>
public void UnSubcribe(Action<TData> action)
{
if (!_singleDataHandlers.Contains(action))
return;
_are.Reset();
_singleDataHandlers.Remove(action);
_are.Set();
}

/// <summary>
/// 取消数据订阅
/// </summary>
/// <param name="action">接收数据回调</param>
public void UnSubcribe(Action<TData[]> action)
{
if (!_multDataHandlers.Contains(action))
return;
_are.Reset();
_multDataHandlers.Remove(action);
_are.Set();
}
}
}

+ 149
- 0
BPASmartClient.Bus/DataBus/Executer.cs View File

@@ -0,0 +1,149 @@
using BPASmartClient.Helper;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.Bus.DataBus
{
/// <summary>
/// 线程集中处理委托
/// </summary>
/// <param name="action"></param>
public delegate void ActionKeyHandle(string action);
public delegate void ThreadExceptionHandle(string action, Exception ex);
public delegate void ThreadExitHandle(string action);
/// <summary>
/// 执行器
/// </summary>
public class Executer : Singleton<Executer>
{
private System.Timers.Timer _timer4Monitor = new System.Timers.Timer(1000);
private ConcurrentDictionary<string, Thread> _actions = new ConcurrentDictionary<string, Thread>();
private object _async = new object();
public event ThreadExceptionHandle OnThreadException;
public event ThreadExitHandle ThreadExit;
/// <summary>
/// 构造器
/// </summary>
public Executer()
{
}

/// <summary>
///
/// </summary>
public void Dispose()
{
_timer4Monitor.Stop();
foreach (var th in _actions)
{
try { th.Value.Abort(); }
catch (ThreadAbortException) { }
}
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public List<Thread> GetActionInfos()
{
Monitor.TryEnter(_async, 200);
var actionInfos = _actions.Values.ToList();
Monitor.Exit(_async);
return actionInfos;
}


/// <summary>
///
/// </summary>
/// <param name="key"></param>
public void Abort(string key)
{
Monitor.TryEnter(_async, 200);
if (_actions.ContainsKey(key))
{
try { _actions[key].Abort(); }
catch (ThreadAbortException) { }
}
Monitor.Exit(_async);
}
/// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public bool ContainsKey(string key)
{
Monitor.TryEnter(_async, 200);
var item = _actions[key];
Monitor.Exit(_async);
if (null != item)
{
return true;
}
return false;
}
/// <summary>
///
/// </summary>
/// <param name="action"></param>
/// <param name="name"></param>
/// <param name="isBackground"></param>
/// <param name="priority"></param>
public void Start(Action action, string name, bool isBackground = false, ThreadPriority priority = ThreadPriority.Normal)
{
Thread thread = new Thread(() =>
{
try
{
action();
ThreadExit?.Invoke(name);
}
catch (Exception ex)
{
OnThreadException?.Invoke(name, ex);
}
});
thread.IsBackground = isBackground;
thread.Priority = priority;
thread.Name = name;
thread.Start();
Monitor.TryEnter(_async, 50);
if (_actions.ContainsKey(name))
{
try { _actions[name].Abort(); }
catch (ThreadAbortException) { }
}
_actions[name] = thread;
Monitor.Exit(_async);
}
/// <summary>
///
/// </summary>
/// <param name="action"></param>
/// <param name="timeout"></param>
/// <returns></returns>
public bool StartWhiteReturn(Func<bool> action, int timeout = 3)
{
DateTime beginTime = DateTime.Now;
bool doResult = false;
while (DateTime.Now.Subtract(beginTime).TotalSeconds <= 3 && !doResult)
{
doResult = action();
}
return doResult;
}
/// <summary>
///
/// </summary>
public event ActionKeyHandle ActionAbort;
/// <summary>
///
/// </summary>
public event ActionKeyHandle ActionStarted;
}
}

+ 54
- 0
BPASmartClient.Bus/DataBus/IDataBus.cs View File

@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


/* ***********************************************
 * subject 数据总线接口
 * author 张原川
 * date   2019/6/3 11:33:57
 * ***********************************************/

namespace BPASmartClient.Bus.DataBus
{
/// <summary>
/// 数据总线接口
/// </summary>
public interface IDataBus<TData>
{
/// <summary>
/// 多数据订阅数量
/// </summary>
int MultSubscriberCount { get; }
/// <summary>
/// 单数据订阅数量
/// </summary>
int SingleSubscriberCount { get; }
/// <summary>
/// 数据量
/// </summary>
int DataCount { get; }
/// <summary>
/// 开启总线
/// </summary>
void StartBus();

/// <summary>
/// 关闭总线
/// </summary>
void StopBus();

/// <summary>
/// 数据放入总线
/// </summary>
/// <param name="data">数据</param>
void Put(TData data);
/// <summary>
/// 数据放入总线
/// </summary>
/// <param name="data">数据</param>
void Put(TData[] data);
}
}

+ 30
- 0
BPASmartClient.Bus/DataBus/IGivenDataBus.cs View File

@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


/* ***********************************************
 * subject 数据总线接口,定义主动取得数据
 * author 张原川
 * date   2019/6/3 11:25:11
 * ***********************************************/

namespace BPASmartClient.Bus.DataBus
{
public interface IGivenDataBus<TData>: IDataBus<TData>
{
/// <summary>
/// 数据取出
/// </summary>
/// <returns></returns>
TData Get();

/// <summary>
/// 数据取出
/// </summary>
/// <returns></returns>
TData[] Get(int count);
}
}

+ 33
- 0
BPASmartClient.Bus/DataBus/ISimpleDataBus.cs View File

@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


/* ***********************************************
 * subject 数据总线接口,定义原始数据、MAVLINK消息、状态数据、消息数据标准
 * author 张原川
 * date   2019/6/3 9:50:01
 * ***********************************************/

namespace BPASmartClient.Bus.DataBus
{
interface ISimpleDataBus<TData>: IDataBus<TData>,IDisposable
{
/// <summary>
/// 订阅总线数据
/// </summary>
/// <param name="action">数据类型</param>
void Subscribe(Action<TData> action);
void Subscribe(Action<TData[]> action);

/// <summary>
/// 取消订阅数据
/// </summary>
/// <param name="action">数据类型</param>
void UnSubcribe(Action<TData> action);
void UnSubcribe(Action<TData[]> action);
}
}

+ 32
- 0
BPASmartClient.Bus/DataBus/SimpleDataType.cs View File

@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.Bus.DataBus
{
public enum SimpleDataType
{
/// <summary>
/// 原始数据总线
/// </summary>
RAW_DATA,
/// <summary>
/// MAVLINK消息总线
/// </summary>
MAV_MESSAGE_DATA,
/// <summary>
/// 全局状态数据总线
/// </summary>
STATUS_DATA,
/// <summary>
/// 参数总线
/// </summary>
PARAMETER,
/// <summary>
/// 调试消息总线
/// </summary>
MESSAGE_DATA
}
}

+ 108
- 0
BPASmartClient.Bus/EventBus/EventBus.cs View File

@@ -0,0 +1,108 @@

using BPASmartClient.Bus.EventBus;
using BPASmartClient.Helper;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

/* ***********************************************
 * subject 事件总线,总线入口,后续按类型分发
 * author 张原川
 * date   2019/6/3 15:49:03
 * ***********************************************/

namespace LandStation.Bus
{
public class EventBus : Singleton<EventBus>
{
//事件处理委托
public delegate void EventCallBackHandle(params object[] args);
//事件处理委托
public delegate void EventHandle(IEvent @event, EventCallBackHandle callBack = null);
//事件订阅者集合
private ConcurrentDictionary<Type, List<EventHandle>> _eventHandls = new ConcurrentDictionary<Type, List<EventHandle>>();

/// <summary>
/// 事件订阅
/// </summary>
public void Subscribe<TEvent>(EventHandle handle)
{
if (!_eventHandls.ContainsKey(typeof(TEvent)))
_eventHandls.TryAdd(typeof(TEvent), new List<EventHandle>());
lock (_eventHandls)
_eventHandls[typeof(TEvent)].Add(handle);
}

/// <summary>
/// 事件退订
/// </summary>
public void UnSubscribe<TEvent>(EventHandle handle)
{
if (_eventHandls.ContainsKey(typeof(TEvent)))
{
if (_eventHandls[typeof(TEvent)].Contains(handle))
{
lock (_eventHandls)
_eventHandls[typeof(TEvent)].Remove(handle);
}
}
}

/// <summary>
/// 事件发布,不带返回
/// </summary>
public void Publish<TEvent>(TEvent @event) where TEvent : IEvent
{
if (_eventHandls.ContainsKey(typeof(TEvent)))
{
for (int i = _eventHandls[typeof(TEvent)].Count - 1; i >= 0; i--)
_eventHandls[typeof(TEvent)][i](@event);

//_eventHandls[typeof(TEvent)].ForEach(p =>
//{
// p(@event);
//});
}
}

/// <summary>
/// 事件发布,带返回
/// </summary>
public void Publish<TEvent>(TEvent @event, EventCallBackHandle eventCallBack) where TEvent : IEvent
{
List<object> result = new List<object>();
if (_eventHandls.ContainsKey(typeof(TEvent)))
{
//_eventHandls[typeof(TEvent)].ForEach(p =>
//{
// p(@event, delegate (object[] args)
// {
// result.AddRange(args);
// });
//});

for (int i = _eventHandls[typeof(TEvent)].Count - 1; i >= 0; i--)
{
_eventHandls[typeof(TEvent)][i](@event, delegate (object[] args)
{
result.AddRange(args);
});
}

}
eventCallBack.Invoke(result.ToArray());
}

/// <summary>
/// 事件总线释放
/// </summary>
public void Dispose()
{
_eventHandls.Clear();
}
}
}

+ 16
- 0
BPASmartClient.Bus/EventBus/IEvent.cs View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.Bus.EventBus
{
/// <summary>
/// 事件接口
/// </summary>
public interface IEvent
{
int DeviceId { get; set; }
}
}

+ 35
- 0
BPASmartClient.Bus/EventBus/IEventExtends.cs View File

@@ -0,0 +1,35 @@
/* ==============================================================================
* 功能描述:
* 创 建 者:张原川
* 创建日期:2016/10/10 16:50:12
* ==============================================================================*/

using BPASmartClient.Bus.EventBus;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LandStation.Bus
{
/// <summary>
///
/// </summary>
public static class IEventExtends
{

#region Methods - Public

public static void Publish<TEvent>(this TEvent message) where TEvent : class, IEvent
{
EventBus.GetInstance().Publish<TEvent>(message);
}

public static void Publish<TEvent>(this TEvent message, EventBus.EventCallBackHandle eventCallBack) where TEvent : class, IEvent
{
EventBus.GetInstance().Publish<TEvent>(message, eventCallBack);
}

#endregion
}
}

+ 22
- 0
BPASmartClient.Compiler/BPASmartClient.Compiler.csproj View File

@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<Folder Include="Hepler\" />
</ItemGroup>

<ItemGroup>
<Reference Include="Antlr3.Runtime">
<HintPath>DLL\Antlr3.Runtime.dll</HintPath>
</Reference>
<Reference Include="Unvell.ReoScript">
<HintPath>DLL\Unvell.ReoScript.dll</HintPath>
</Reference>
</ItemGroup>

</Project>

+ 89
- 0
BPASmartClient.Compiler/Config.cs View File

@@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using Unvell.ReoScript;

namespace BPASmartClient.Compiler
{
public class Config
{
#region 单例模式
public static Config Instance = null;

public static Config GetInstance()
{
if (Instance == null)
{
Instance = new Config();
}
return Instance;
}
#endregion

public static ScriptRunningMachine srm { get; } = new ScriptRunningMachine();

public Config()
{
srm.WorkMode |=
// Enable DirectAccess
MachineWorkMode.AllowDirectAccess
// Ignore exceptions in CLR calling (by default)
| MachineWorkMode.IgnoreCLRExceptions
// Enable CLR Event Binding
| MachineWorkMode.AllowCLREventBind;

RegisterFunction();
}

/// <summary>
/// 运行脚本
/// </summary>
/// <param name="script"></param>
public void RunJsScipt(string script)
{
try
{
srm.Run(script);
}
catch (Exception e)
{
//MessageBox.Show(e.Message, "脚本错误");
}
}

/// <summary>
/// 注册对象到js
/// </summary>
public void SetVariable(string name, object obj)
{
srm.SetGlobalVariable(name, obj);
}

/// <summary>
/// 注册方法到Js
/// </summary>
private static void RegisterFunction()
{
srm["ShowMessage"] = new NativeFunctionObject("ShowMessage", (ctx, owner, args) =>
{
StringBuilder sb = new StringBuilder();
foreach (var item in args)
{
sb.Append(item.ToString());
}

//MessageBox.Show($"{sb}", "提示");
return null;
});

srm["SetICDValue"] = new NativeFunctionObject("SetICDValue", (ctx, owner, args) =>
{
//MessageBox.Show($"发送ICD数据", "提示");
return null;
});
}
}
}

BIN
View File


BIN
View File


+ 9
- 0
BPASmartClient.DATABUS/BPASmartClient.DATABUS.csproj View File

@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>

+ 34
- 0
BPASmartClient.DATABUS/Class_DataBus.cs View File

@@ -0,0 +1,34 @@
using System.Collections.Concurrent;

namespace BPASmartClient.DATABUS
{
/// <summary>
/// 数据总线
/// </summary>
public class Class_DataBus
{
#region 单例模式
public static Class_DataBus dataBus = null;

public static Class_DataBus GetInstance()
{
if (dataBus == null)
{
dataBus = new Class_DataBus();
}
return dataBus;
}
#endregion

#region 基础配置

#endregion

#region 实时数据->大数据量
/// <summary>
/// 设备数据
/// </summary>
public ConcurrentDictionary<string, object> Dic_DeviceData = new ConcurrentDictionary<string, object>(); //原始目标链表
#endregion
}
}

+ 9
- 0
BPASmartClient.MessageName/BPASmartClient.MessageName.csproj View File

@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>

+ 25
- 0
BPASmartClient.MessageName/DataName.cs View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.MessageName
{
/// <summary>
/// 数据订阅主题管理中心
/// </summary>
public class DataName
{
#region XX数据
/// <summary>
/// xxx消息
///
/// </summary>
[Description("消息备注"), Browsable(true)]
public static string xxx = "xxx";
#endregion

}
}

+ 26
- 0
BPASmartClient.MessageName/MessageName.cs View File

@@ -0,0 +1,26 @@
using System.ComponentModel;

namespace BPASmartClient.MessageName
{
/// <summary>
/// 消息名称管理中心
/// 特性:Description,消息备注
/// Browsable,是否使用
/// 消息发送案例:
/// Class_InnerMessageBus.GetInstance().PostMessage(this, MessageName.xxx, "12321");
/// 接收数据案例:
/// Class_InnerMessageBus.GetInstance().ListenMessage(this, MessageName.xxx, "xxnameHandler");
/// public void xxnameHandler(object sender, InnerMessageEventArgs e) { }
/// </summary>
public class MessageName
{
#region XX消息
/// <summary>
/// xxx消息
///
/// </summary>
[Description("消息备注"),Browsable(true)]
public static string xxx = "xxx";
#endregion
}
}

+ 197
- 0
BPASmartClient.SCADAControl/ArcGauge.cs View File

@@ -0,0 +1,197 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace BPASmartClient.SCADAControl
{
/// <summary>
/// 新测试仪表盘
/// </summary>
public class ArcGauge : Control, IExecutable
{
public ArcGauge()
{
Width = 300;
Height = 300;
SetCurrentValue(ValueProperty, 0d);
SetCurrentValue(MinValueProperty, 0d);
SetCurrentValue(MaxValueProperty, 100d);
}

private void InitTick()
{
// 画大刻度
for (int i = 0; i < 11; i++)
{
Line line = new Line();
line.X1 = 0;
line.Y1 = 0;
line.X2 = 0;
line.Y2 = 12;
line.Stroke = Brushes.White;
line.StrokeThickness = 2;
line.HorizontalAlignment = HorizontalAlignment.Center;
line.RenderTransformOrigin = new Point(0.5, 0.5);
line.RenderTransform = new RotateTransform() { Angle = -140 + i * 28 };
bdGrid.Children.Add(line);
DrawText();
}

// 画小刻度
for (int i = 0; i < 10; i++)
{
var start = -140 + 28 * i + 2.8;
for (int j = 0; j < 9; j++)
{
Line line = new Line();
line.X1 = 0;
line.Y1 = 0;
line.X2 = 0;
line.Y2 = 6;
line.Stroke = Brushes.White;
line.StrokeThickness = 1;
line.HorizontalAlignment = HorizontalAlignment.Center;
line.RenderTransformOrigin = new Point(0.5, 0.5);
line.RenderTransform = new RotateTransform() { Angle = start + j * 2.8 };
bdGrid.Children.Add(line);
}
}
}

List<TextBlock> textLabels = new List<TextBlock>();
private void DrawText()
{
foreach (var item in textLabels)
{
bdGrid.Children.Remove(item);
}
textLabels.Clear();

var per = MaxValue / 10;
for (int i = 0; i < 11; i++)
{
TextBlock textBlock = new TextBlock();
textBlock.Text = $"{MinValue + (per * i)}";
textBlock.HorizontalAlignment = HorizontalAlignment.Center;
textBlock.RenderTransformOrigin = new Point(0.5, 0.5);
textBlock.RenderTransform = new RotateTransform() { Angle = -140 + i * 28 };
textBlock.Margin = new Thickness(12);
textBlock.Foreground = Brushes.White;
bdGrid.Children.Add(textBlock);
textLabels.Add(textBlock);
}
}

static ArcGauge()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ArcGauge), new FrameworkPropertyMetadata(typeof(ArcGauge)));
}

RotateTransform rotateTransform;
Grid bdGrid;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
rotateTransform = GetTemplateChild("PointRotate") as RotateTransform;
bdGrid = GetTemplateChild("bdGrid") as Grid;
Refresh();
InitTick();
}

private bool isExecuteState;
public bool IsExecuteState
{
get { return isExecuteState; }
set
{
isExecuteState = value;
if (IsExecuteState)
{
Register();
}
}
}

[Category("值设定")]
public double Value
{
get { return (double)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(double), typeof(ArcGauge), new PropertyMetadata(0d, OnValueChanged));

private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => (d as ArcGauge)?.Refresh();

[Category("值设定")]
public double MinValue
{
get { return (double)GetValue(MinValueProperty); }
set { SetValue(MinValueProperty, value); }
}
public static readonly DependencyProperty MinValueProperty =
DependencyProperty.Register("MinValue", typeof(double), typeof(ArcGauge), new PropertyMetadata(0d, OnValueChanged));

[Category("值设定")]
public double MaxValue
{
get { return (double)GetValue(MaxValueProperty); }
set { SetValue(MaxValueProperty, value); }
}

public string ControlType => "控件";

public static readonly DependencyProperty MaxValueProperty =
DependencyProperty.Register("MaxValue", typeof(double), typeof(ArcGauge), new PropertyMetadata(0d, OnValueChanged));


private void Refresh()
{
if (rotateTransform == null)
return;
DrawText();
DoubleAnimation da = new DoubleAnimation();
da.Duration = new Duration(TimeSpan.FromMilliseconds(350));
da.EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseOut };

if (Value > MaxValue)
{
rotateTransform.Angle = 140;
da.To = 140;
}
else if (Value < MinValue)
{
rotateTransform.Angle = -140;
da.To = -140;
}
else
{
var range = MaxValue - MinValue;
var process = Value / range;
var tAngle = process * 280 - 140;
rotateTransform.Angle = tAngle;
da.To = tAngle;
}

rotateTransform.BeginAnimation(RotateTransform.AngleProperty, da);
}

public void Register()
{
Refresh();
}
}
}

+ 10
- 0
BPASmartClient.SCADAControl/AssemblyInfo.cs View File

@@ -0,0 +1,10 @@
using System.Windows;

[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]

+ 30
- 0
BPASmartClient.SCADAControl/BPASmartClient.SCADAControl.csproj View File

@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
</PropertyGroup>

<ItemGroup>
<None Remove="Images\光柱.png" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\BPASmartClient.Compiler\BPASmartClient.Compiler.csproj" />
</ItemGroup>

<ItemGroup>
<Reference Include="Antlr3.Runtime">
<HintPath>DLL\Antlr3.Runtime.dll</HintPath>
</Reference>
<Reference Include="Unvell.ReoScript">
<HintPath>DLL\Unvell.ReoScript.dll</HintPath>
</Reference>
</ItemGroup>

<ItemGroup>
<Resource Include="Images\光柱.png" />
</ItemGroup>

</Project>

+ 28
- 0
BPASmartClient.SCADAControl/Converters/HalfNumberConverter.cs View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;

namespace BPASmartClient.SCADAControl.Converters
{
public class HalfNumberConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (double.TryParse(value.ToString(), out double val))
{
return val / 2;
}

return 0;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
}

+ 24
- 0
BPASmartClient.SCADAControl/IExecutable.cs View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.SCADAControl
{
public interface IExecutable
{
/// <summary>
/// 是否执行
/// </summary>
bool IsExecuteState { get; set; }
/// <summary>
/// 运行程序 注册事件
/// </summary>
void Register();
/// <summary>
/// 控件类型
/// </summary>
string ControlType { get; }
}
}

BIN
View File


+ 30
- 0
BPASmartClient.SCADAControl/NewConveyorBelt.xaml View File

@@ -0,0 +1,30 @@
<UserControl x:Class="BPASmartClient.SCADAControl.NewConveyorBelt"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:BPASmartClient.SCADAControl"
mc:Ignorable="d"
x:Name="gr"
Margin="0,0,0,0"
d:DesignHeight="400" d:DesignWidth="1200">
<Grid >
<Viewbox Width="auto" Height="auto">
<Canvas Width="{Binding ElementName=gr, Path=ActualWidth}" Height="{Binding ElementName=gr, Path=ActualHeight}">
<Path
Tag="mp"
Margin="0"
Stroke="{Binding StrokeFillBrush, RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}}"
StrokeDashArray="{Binding StrokeDashArray, RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}}"
StrokeThickness="{Binding ConveyorBeltWidth, RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}}" />

<Path
Tag="cb"
Fill="Transparent"
Stroke="{Binding StrokeBrush, RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}}"
StrokeThickness="{Binding StrokeThickness, RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}}" />

</Canvas>
</Viewbox>
</Grid>
</UserControl>

+ 277
- 0
BPASmartClient.SCADAControl/NewConveyorBelt.xaml.cs View File

@@ -0,0 +1,277 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace BPASmartClient.SCADAControl
{
/// <summary>
/// NewConveyorBelt.xaml 的交互逻辑
/// </summary>
public partial class NewConveyorBelt : UserControl, IExecutable
{
Path Path_mp = null;
Path Path_cb = null;
Storyboard storyboard = new Storyboard();
Storyboard storyboard1 = new Storyboard();
public NewConveyorBelt()
{
InitializeComponent();
Width = 1200;
Height = 400;
this.SizeChanged += ConveyorBelt_SizeChanged;
ConveyorBeltWidth = 70;
Direction = 0;
StrokeBrush = new SolidColorBrush((System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#00BEFA"));
StrokeDashArray = new DoubleCollection { 1.5, 1.5 };
StrokeFillBrush = new SolidColorBrush((System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#00BEFA"));
StrokeThickness = 2;
}

public string ControlType => "滚动线";

private bool isExecuteState;
public bool IsExecuteState
{
get { return isExecuteState; }
set
{
isExecuteState = value;
if (IsExecuteState)
{
IsEnabled = true;
Register();
Style = null;
}
}
}

public void Register()
{
}

public void VisualStateManagerData()
{
storyboard.RepeatBehavior = RepeatBehavior.Forever;
DoubleAnimation dbAscending = new DoubleAnimation
{
From = 0,
To = 100,
Duration = new Duration(new TimeSpan(0, 0, 20)),

};
storyboard.Children.Add(dbAscending);
Storyboard.SetTarget(dbAscending, Path_mp);
Storyboard.SetTargetProperty(dbAscending, new PropertyPath("StrokeDashOffset"));

storyboard1.RepeatBehavior = RepeatBehavior.Forever;
DoubleAnimation dbAscending1 = new DoubleAnimation
{
From = 0,
To = -100,
Duration = new Duration(new TimeSpan(0, 0, 20)),
};
storyboard1.Children.Add(dbAscending1);
Storyboard.SetTarget(dbAscending1, Path_mp);
Storyboard.SetTargetProperty(dbAscending1, new PropertyPath("StrokeDashOffset"));
Refursh();
}

private void ConveyorBelt_SizeChanged(object sender, SizeChangedEventArgs e)
{
//查找
if (!(Path_cb != null && Path_mp != null))
{
foreach (Path tb in FindVisualChildren<Path>(this))
{
// do something with tb here
if (tb.Tag != null)
{
if (tb.Tag.ToString() == "cb")
{
Path_cb = tb;
}
else if (tb.Tag.ToString() == "mp")
{
Path_mp = tb;
}
}
}
VisualStateManagerData();
}


//传送带外边框绘制
PathGeometry geometry = new PathGeometry();
PathFigure pathFigure = new PathFigure();
pathFigure.StartPoint = new Point(this.Height / 2, 0);
pathFigure.Segments.Add(new ArcSegment(new Point(this.Height / 2, this.Height), new Size(this.Height / 2, this.Height / 2), 0, false, SweepDirection.Counterclockwise, true));
pathFigure.Segments.Add(new LineSegment(new Point(this.Width, this.Height), true));
pathFigure.Segments.Add(new LineSegment(new Point(this.Width, this.Height - ConveyorBeltWidth), true));
double innerCircle = (this.Height - (ConveyorBeltWidth * 2)) / 2;//内圆半径
pathFigure.Segments.Add(new LineSegment(new Point(ConveyorBeltWidth + innerCircle, this.Height - ConveyorBeltWidth), true));
pathFigure.Segments.Add(new ArcSegment(new Point(ConveyorBeltWidth + innerCircle, ConveyorBeltWidth), new Size(innerCircle, innerCircle), 0, false, SweepDirection.Clockwise, true));
pathFigure.Segments.Add(new LineSegment(new Point(this.Width, ConveyorBeltWidth), true));
pathFigure.Segments.Add(new LineSegment(new Point(this.Width, 0), true));
pathFigure.Segments.Add(new LineSegment(new Point(this.Height / 2, 0), true));
geometry.Figures.Add(pathFigure);
Path_cb.Data = geometry;

//传送带内部皮带绘制
PathGeometry geometry1 = new PathGeometry();
PathFigure pathFigure1 = new PathFigure();
pathFigure1.StartPoint = new Point(this.Width, ConveyorBeltWidth / 2);
double innerCircle1 = (this.Height - ConveyorBeltWidth) / 2;//内圆半径
pathFigure1.Segments.Add(new LineSegment(new Point(innerCircle1 + ConveyorBeltWidth / 2, ConveyorBeltWidth / 2), true));
pathFigure1.Segments.Add(new ArcSegment(new Point(innerCircle1 + ConveyorBeltWidth / 2, this.Height - ConveyorBeltWidth / 2), new Size(innerCircle1, innerCircle1), 0, false, SweepDirection.Counterclockwise, true));
pathFigure1.Segments.Add(new LineSegment(new Point(this.Width, this.Height - ConveyorBeltWidth / 2), true));
geometry1.Figures.Add(pathFigure1);
Path_mp.Data = geometry1;
}
/// <summary>
/// 搜索指定名称的子元素
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <param name="name"></param>
/// <returns></returns>
public static T FindChild<T>(DependencyObject obj, string name) where T : FrameworkElement
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is T && (child as T).Name.Equals(name))
return (T)child;
else
{
T childOfChild = FindChild<T>(child, name);
if (childOfChild != null)
return childOfChild;
}
}
return null;
}

public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
{
yield return (T)child;
}

foreach (T childOfChild in FindVisualChildren<T>(child))
{
yield return childOfChild;
}
}
}
}

private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as NewConveyorBelt)?.Refursh();
}

private void Refursh()
{
if (Direction == 1)
{
storyboard.Begin();
storyboard1.Stop();
// VisualStateManager.GoToState(this, "Left", false);
}
else if (Direction == 2)
{
storyboard.Stop();
storyboard1.Begin();
//VisualStateManager.GoToState(this, "Right", false);
}
else
{
storyboard.Stop();
storyboard1.Stop();
//VisualStateManager.GoToState(this, "Stop", false);
}
}


public DoubleCollection StrokeDashArray
{
get { return (DoubleCollection)GetValue(StrokeDashArrayProperty); }
set { SetValue(StrokeDashArrayProperty, value); }
}
public static readonly DependencyProperty StrokeDashArrayProperty =
DependencyProperty.Register("StrokeDashArray", typeof(DoubleCollection), typeof(NewConveyorBelt),
new PropertyMetadata(default, new PropertyChangedCallback(OnPropertyChanged)));


public double ConveyorBeltWidth
{
get { return (double)GetValue(ConveyorBeltWidthProperty); }
set { SetValue(ConveyorBeltWidthProperty, value); }
}
public static readonly DependencyProperty ConveyorBeltWidthProperty =
DependencyProperty.Register("ConveyorBeltWidth", typeof(double), typeof(NewConveyorBelt),
new PropertyMetadata(50.0, new PropertyChangedCallback(OnPropertyChanged)));


public Brush StrokeFillBrush
{
get { return (Brush)GetValue(StrokeFillBrushProperty); }
set { SetValue(StrokeFillBrushProperty, value); }
}
public static readonly DependencyProperty StrokeFillBrushProperty =
DependencyProperty.Register("StrokeFillBrush", typeof(Brush), typeof(NewConveyorBelt),
new PropertyMetadata(Brushes.LightBlue, new PropertyChangedCallback(OnPropertyChanged)));



public Brush StrokeBrush
{
get { return (Brush)GetValue(StrokeBrushProperty); }
set { SetValue(StrokeBrushProperty, value); }
}
public static readonly DependencyProperty StrokeBrushProperty =
DependencyProperty.Register("StrokeBrush", typeof(Brush), typeof(NewConveyorBelt),
new PropertyMetadata(Brushes.LightBlue, new PropertyChangedCallback(OnPropertyChanged)));


public double StrokeThickness
{
get { return (double)GetValue(StrokeThicknessProperty); }
set { SetValue(StrokeThicknessProperty, value); }
}
public static readonly DependencyProperty StrokeThicknessProperty =
DependencyProperty.Register("StrokeThickness", typeof(double), typeof(NewConveyorBelt),
new PropertyMetadata(1.0, new PropertyChangedCallback(OnPropertyChanged)));

[Category("值设定")]
public int Direction
{
get { return (int)GetValue(DirectionProperty); }
set { SetValue(DirectionProperty, value); }
}
public static readonly DependencyProperty DirectionProperty =
DependencyProperty.Register("Direction", typeof(int), typeof(NewConveyorBelt),
new PropertyMetadata(0, new PropertyChangedCallback(OnPropertyChanged)));


}
}

+ 42
- 0
BPASmartClient.SCADAControl/Silos.xaml View File

@@ -0,0 +1,42 @@
<UserControl x:Class="BPASmartClient.SCADAControl.Silos"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:BPASmartClient.SCADAControl"
mc:Ignorable="d"
d:DesignHeight="270" d:DesignWidth="180" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
Margin="0 0 0 35"
FontSize="25"
Foreground="#FFCCD61F"
Text="{Binding Title,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
<TextBlock
Grid.Row="1"
Margin="0,25,0,0"
HorizontalAlignment="Center"
FontSize="20"
Foreground="#FF0084FF"
Text="{Binding Value,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />

<TextBlock
Grid.Row="1"
Margin="0,70,0,0"
HorizontalAlignment="Center"
FontSize="20"
Foreground="#FF0084FF"
Text="{Binding Text,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
<Image
Grid.RowSpan="2"
Source="/BPASmartClient.SCADAControl;component/Images/光柱.png"
Stretch="Fill" />

</Grid>
</UserControl>

+ 96
- 0
BPASmartClient.SCADAControl/Silos.xaml.cs View File

@@ -0,0 +1,96 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace BPASmartClient.SCADAControl
{
/// <summary>
/// Silos.xaml 的交互逻辑
/// 物料仓
/// </summary>
public partial class Silos : UserControl, IExecutable
{
public Silos()
{
InitializeComponent();
this.DataContext = this;
Width = 180;
Height = 270;
Value = 25.23;
Title = "香料";
Text = "1 号仓";
}

public string ControlType => "物料仓";

private bool isExecuteState;
public bool IsExecuteState
{
get { return isExecuteState; }
set
{
isExecuteState = value;
if (IsExecuteState)
{
IsEnabled = true;
Register();
Style = null;
}
}
}

#region 属性
[Category("值设定")]
public double Value
{
get { return (double)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(double), typeof(Silos), new PropertyMetadata(0d, OnValueChanged));

private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => (d as Silos)?.Refresh();

[Category("值设定")]
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(Silos), new PropertyMetadata(string.Empty));

[Category("值设定")]
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(string), typeof(Silos), new PropertyMetadata(string.Empty));
#endregion

#region 函数
public void Refresh()
{
}
#endregion

public void Register()
{
}
}
}

+ 144
- 0
BPASmartClient.SCADAControl/SwitchButton.cs View File

@@ -0,0 +1,144 @@
using BPASmartClient.Compiler;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace BPASmartClient.SCADAControl
{
[TemplatePart(Name = ELLIPSE, Type = typeof(FrameworkElement))]
[TemplatePart(Name = TranslateX, Type = typeof(TranslateTransform))]
public class SwitchButton : ToggleButton, IExecutable
{
public SwitchButton()
{
SetCurrentValue(WidthProperty, 120d);
SetCurrentValue(HeightProperty, 40d);
}

public const string ELLIPSE = "ELLIPSE";
public const string TranslateX = "TranslateX";
static SwitchButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(SwitchButton), new FrameworkPropertyMetadata(typeof(SwitchButton)));
}

/// <summary>
/// 不勾选时执行代码
/// </summary>
[Category("事件")]
public string UnCheckedExec
{
get { return (string)GetValue(UnCheckedExecProperty); }
set { SetValue(UnCheckedExecProperty, value); }
}
public static readonly DependencyProperty UnCheckedExecProperty =
DependencyProperty.Register("UnCheckedExec", typeof(string), typeof(SwitchButton), new PropertyMetadata(string.Empty));

/// <summary>
/// 勾选时执行代码
/// </summary>
[Category("事件")]
public string CheckedExec
{
get { return (string)GetValue(CheckedExecProperty); }
set { SetValue(CheckedExecProperty, value); }
}
public static readonly DependencyProperty CheckedExecProperty =
DependencyProperty.Register("CheckedExec", typeof(string), typeof(SwitchButton), new PropertyMetadata(string.Empty));

protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
ellipse.Width = Height - 8;
ellipse.Height = Height - 8;
Refresh();
}

TranslateTransform transX;
Ellipse ellipse;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
ellipse = GetTemplateChild(ELLIPSE) as Ellipse;
transX = GetTemplateChild(TranslateX) as TranslateTransform;
}
protected override void OnChecked(RoutedEventArgs e)
{
base.OnChecked(e);
Refresh();
}
protected override void OnUnchecked(RoutedEventArgs e)
{
base.OnUnchecked(e);
Refresh();
}

void Refresh()
{
if (ellipse == null)
{
return;
}
DoubleAnimation da = new DoubleAnimation();
da.Duration = new Duration(TimeSpan.FromMilliseconds(250));
da.EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseOut };
if (IsChecked == true)
{
da.To = ActualWidth - ellipse.ActualWidth - 5;
ellipse.SetCurrentValue(Ellipse.FillProperty, Background);
}
else
{
da.To = 3;
ellipse.SetCurrentValue(Ellipse.FillProperty, Brushes.Gray);
}

transX.BeginAnimation(TranslateTransform.XProperty, da);
}

private bool isExecuteState;
public bool IsExecuteState
{
get { return isExecuteState; }
set
{
isExecuteState = value;
if (IsExecuteState)
{
Register();
}
}
}

public void Register()
{
Checked += TheCheckBox_Checked;
Unchecked += TheCheckBox_Unchecked;
}
private void TheCheckBox_Unchecked(object sender, RoutedEventArgs e)
{
Config.GetInstance().RunJsScipt(UnCheckedExec);
}

private void TheCheckBox_Checked(object sender, RoutedEventArgs e)
{
Config.GetInstance().RunJsScipt(CheckedExec);
}
public string ControlType => "控件";

}
}

+ 135
- 0
BPASmartClient.SCADAControl/Themes/Generic.xaml View File

@@ -0,0 +1,135 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:BPASmartClient.SCADAControl"
xmlns:ctrl="clr-namespace:BPASmartClient.SCADAControl"
xmlns:con="clr-namespace:BPASmartClient.SCADAControl.Converters">
<!--<Style TargetType="{x:Type local:CustomControl1}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomControl1}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>-->

<Style TargetType="{x:Type ctrl:ArcGauge}">
<Setter Property="Background" Value="#646464"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ctrl:ArcGauge}">
<Border Margin="10">
<Grid Width="{Binding RelativeSource={RelativeSource Self},Path=ActualHeight}">
<Ellipse Fill="#FF3B3B3B"/>
<Grid RenderTransformOrigin="0.5,0.5" Margin="2">
<Grid.RenderTransform>
<TransformGroup>
<RotateTransform Angle="{Binding Path=Angle,ElementName=PointRotate}"/>
</TransformGroup>
</Grid.RenderTransform>
<Ellipse Width="16" Height="14" Fill="Orange" VerticalAlignment="Top" >
<Ellipse.Effect>
<BlurEffect Radius="12"/>
</Ellipse.Effect>
</Ellipse>
</Grid>

<Grid x:Name="bdGrid" Margin="12" UseLayoutRounding="True" ClipToBounds="True">
<Ellipse>
<Ellipse.Fill>
<RadialGradientBrush>
<GradientStop Color="#4D000000"/>
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>

<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="2*"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Ellipse Stroke="#464646" StrokeThickness="1" Grid.Column="1" Grid.Row="1"/>
<Ellipse Stroke="#959595" Margin="4" StrokeThickness="6" Grid.Column="1" Grid.Row="1"/>
<Ellipse Stroke="#464646" Margin="14" StrokeThickness="1" Grid.Column="1" Grid.Row="1"/>
</Grid>

<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Path Data="M5,0 5,0 10,120 0,120z" Fill="#0FA9CE" Stretch="Uniform" Margin="0 30 0 0" RenderTransformOrigin="0.5,1" HorizontalAlignment="Center">
<Path.RenderTransform>
<TransformGroup>
<RotateTransform x:Name="PointRotate"/>
</TransformGroup>
</Path.RenderTransform>
</Path>
</Grid>

<Ellipse Width="28" Height="28" Fill="Black">
<Ellipse.Effect>
<DropShadowEffect Color="#0FA9CE" ShadowDepth="0" Direction="0" BlurRadius="16"/>
</Ellipse.Effect>
</Ellipse>

<Border VerticalAlignment="Bottom" BorderBrush="#10ABD1" BorderThickness="2" Margin="0 0 0 12" Background="Black" Padding="4 2" HorizontalAlignment="Center">
<TextBlock Text="{Binding Value,RelativeSource={RelativeSource Mode=TemplatedParent},StringFormat={}{0:f1}}" FontSize="16" Width="46" TextAlignment="Center" Foreground="White"/>
</Border>
</Grid>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

<LinearGradientBrush x:Key="NormalBackground" StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStopCollection>
<GradientStop Color="White" />
<GradientStop Color="#D0D0D0" Offset="0.5"/>
<GradientStop Color="#E3E3E3" Offset="1"/>
</GradientStopCollection>
</LinearGradientBrush>

<SolidColorBrush x:Key="AccentBrush" Color="#2B79E2"/>
<SolidColorBrush x:Key="ControlBorderBrush" Color="LightGray"/>
<SolidColorBrush x:Key="ControlBackground" Color="White"/>
<SolidColorBrush x:Key="ControlForeground" Color="Black"/>
<con:HalfNumberConverter x:Key="HalfNumber"/>
<Style TargetType="{x:Type ctrl:SwitchButton}">
<Setter Property="Background" Value="#00F4D5"/>
<Setter Property="BorderBrush" Value="LightGray"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ctrl:SwitchButton">
<Border CornerRadius="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=ActualHeight,Converter={StaticResource HalfNumber}}"
BorderThickness="1" Background="{StaticResource ControlBackground}" BorderBrush="{TemplateBinding BorderBrush}">
<Grid>
<Ellipse x:Name="ELLIPSE" HorizontalAlignment="Left" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5"
Fill="Gray" Stroke="{StaticResource ControlBorderBrush}" StrokeThickness="1">
<Ellipse.RenderTransform>
<TransformGroup>
<TranslateTransform x:Name="TranslateX" X="2"/>
</TransformGroup>
</Ellipse.RenderTransform>
</Ellipse>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

</ResourceDictionary>

+ 104
- 1
SmartClient.sln View File

@@ -132,7 +132,23 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.JXJFoodBigSt
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.JXJFoodSmallStation", "BPASmartClient.JXJFoodSmallStation\BPASmartClient.JXJFoodSmallStation.csproj", "{D609C4CF-FA5C-4D39-B12F-07A60FFE5E40}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WPFDemo", "WPFDemo\WPFDemo.csproj", "{A456D582-D910-4CA2-8620-6D8F63344B47}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WPFDemo", "WPFDemo\WPFDemo.csproj", "{A456D582-D910-4CA2-8620-6D8F63344B47}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "0.SCADA", "0.SCADA", "{7B0175AD-BB74-4A98-B9A7-1E289032485E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.MessageName", "BPASmartClient.MessageName\BPASmartClient.MessageName.csproj", "{0D769B3B-0332-4DB9-A657-B739EDB28567}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.DATABUS", "BPASmartClient.DATABUS\BPASmartClient.DATABUS.csproj", "{7C1AF86E-867C-427E-90DB-6473D88F51EB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.SCADAControl", "BPASmartClient.SCADAControl\BPASmartClient.SCADAControl.csproj", "{6A3FC66D-0B89-45E8-B39B-9D81538002D1}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "1.数据中心", "1.数据中心", "{7BED8969-7EA7-409C-8BBC-D2777ECDA2F1}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2.消息名称管理", "2.消息名称管理", "{28BE5235-2399-4EBA-B1F0-88E0F32AC869}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3.组态控件集", "3.组态控件集", "{5300552F-560D-474A-8D96-0A2747D08F64}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Compiler", "BPASmartClient.Compiler\BPASmartClient.Compiler.csproj", "{B6213013-2A0E-41DD-BA9F-775D53C19374}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -1288,6 +1304,86 @@ Global
{A456D582-D910-4CA2-8620-6D8F63344B47}.Release|x64.Build.0 = Release|Any CPU
{A456D582-D910-4CA2-8620-6D8F63344B47}.Release|x86.ActiveCfg = Release|Any CPU
{A456D582-D910-4CA2-8620-6D8F63344B47}.Release|x86.Build.0 = Release|Any CPU
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Debug|ARM.ActiveCfg = Debug|Any CPU
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Debug|ARM.Build.0 = Debug|Any CPU
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Debug|ARM64.Build.0 = Debug|Any CPU
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Debug|x64.ActiveCfg = Debug|Any CPU
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Debug|x64.Build.0 = Debug|Any CPU
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Debug|x86.ActiveCfg = Debug|Any CPU
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Debug|x86.Build.0 = Debug|Any CPU
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Release|Any CPU.Build.0 = Release|Any CPU
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Release|ARM.ActiveCfg = Release|Any CPU
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Release|ARM.Build.0 = Release|Any CPU
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Release|ARM64.ActiveCfg = Release|Any CPU
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Release|ARM64.Build.0 = Release|Any CPU
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Release|x64.ActiveCfg = Release|Any CPU
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Release|x64.Build.0 = Release|Any CPU
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Release|x86.ActiveCfg = Release|Any CPU
{0D769B3B-0332-4DB9-A657-B739EDB28567}.Release|x86.Build.0 = Release|Any CPU
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Debug|ARM.ActiveCfg = Debug|Any CPU
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Debug|ARM.Build.0 = Debug|Any CPU
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Debug|ARM64.Build.0 = Debug|Any CPU
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Debug|x64.ActiveCfg = Debug|Any CPU
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Debug|x64.Build.0 = Debug|Any CPU
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Debug|x86.ActiveCfg = Debug|Any CPU
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Debug|x86.Build.0 = Debug|Any CPU
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Release|Any CPU.Build.0 = Release|Any CPU
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Release|ARM.ActiveCfg = Release|Any CPU
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Release|ARM.Build.0 = Release|Any CPU
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Release|ARM64.ActiveCfg = Release|Any CPU
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Release|ARM64.Build.0 = Release|Any CPU
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Release|x64.ActiveCfg = Release|Any CPU
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Release|x64.Build.0 = Release|Any CPU
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Release|x86.ActiveCfg = Release|Any CPU
{7C1AF86E-867C-427E-90DB-6473D88F51EB}.Release|x86.Build.0 = Release|Any CPU
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Debug|ARM.ActiveCfg = Debug|Any CPU
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Debug|ARM.Build.0 = Debug|Any CPU
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Debug|ARM64.Build.0 = Debug|Any CPU
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Debug|x64.ActiveCfg = Debug|Any CPU
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Debug|x64.Build.0 = Debug|Any CPU
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Debug|x86.ActiveCfg = Debug|Any CPU
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Debug|x86.Build.0 = Debug|Any CPU
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Release|Any CPU.Build.0 = Release|Any CPU
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Release|ARM.ActiveCfg = Release|Any CPU
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Release|ARM.Build.0 = Release|Any CPU
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Release|ARM64.ActiveCfg = Release|Any CPU
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Release|ARM64.Build.0 = Release|Any CPU
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Release|x64.ActiveCfg = Release|Any CPU
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Release|x64.Build.0 = Release|Any CPU
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Release|x86.ActiveCfg = Release|Any CPU
{6A3FC66D-0B89-45E8-B39B-9D81538002D1}.Release|x86.Build.0 = Release|Any CPU
{B6213013-2A0E-41DD-BA9F-775D53C19374}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B6213013-2A0E-41DD-BA9F-775D53C19374}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B6213013-2A0E-41DD-BA9F-775D53C19374}.Debug|ARM.ActiveCfg = Debug|Any CPU
{B6213013-2A0E-41DD-BA9F-775D53C19374}.Debug|ARM.Build.0 = Debug|Any CPU
{B6213013-2A0E-41DD-BA9F-775D53C19374}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{B6213013-2A0E-41DD-BA9F-775D53C19374}.Debug|ARM64.Build.0 = Debug|Any CPU
{B6213013-2A0E-41DD-BA9F-775D53C19374}.Debug|x64.ActiveCfg = Debug|Any CPU
{B6213013-2A0E-41DD-BA9F-775D53C19374}.Debug|x64.Build.0 = Debug|Any CPU
{B6213013-2A0E-41DD-BA9F-775D53C19374}.Debug|x86.ActiveCfg = Debug|Any CPU
{B6213013-2A0E-41DD-BA9F-775D53C19374}.Debug|x86.Build.0 = Debug|Any CPU
{B6213013-2A0E-41DD-BA9F-775D53C19374}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B6213013-2A0E-41DD-BA9F-775D53C19374}.Release|Any CPU.Build.0 = Release|Any CPU
{B6213013-2A0E-41DD-BA9F-775D53C19374}.Release|ARM.ActiveCfg = Release|Any CPU
{B6213013-2A0E-41DD-BA9F-775D53C19374}.Release|ARM.Build.0 = Release|Any CPU
{B6213013-2A0E-41DD-BA9F-775D53C19374}.Release|ARM64.ActiveCfg = Release|Any CPU
{B6213013-2A0E-41DD-BA9F-775D53C19374}.Release|ARM64.Build.0 = Release|Any CPU
{B6213013-2A0E-41DD-BA9F-775D53C19374}.Release|x64.ActiveCfg = Release|Any CPU
{B6213013-2A0E-41DD-BA9F-775D53C19374}.Release|x64.Build.0 = Release|Any CPU
{B6213013-2A0E-41DD-BA9F-775D53C19374}.Release|x86.ActiveCfg = Release|Any CPU
{B6213013-2A0E-41DD-BA9F-775D53C19374}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1350,6 +1446,13 @@ Global
{FA695D7E-6F12-4483-A16D-8494609FAE68} = {8712125E-14CD-4E1B-A1CE-4BDE03805942}
{D609C4CF-FA5C-4D39-B12F-07A60FFE5E40} = {8712125E-14CD-4E1B-A1CE-4BDE03805942}
{A456D582-D910-4CA2-8620-6D8F63344B47} = {8712125E-14CD-4E1B-A1CE-4BDE03805942}
{0D769B3B-0332-4DB9-A657-B739EDB28567} = {28BE5235-2399-4EBA-B1F0-88E0F32AC869}
{7C1AF86E-867C-427E-90DB-6473D88F51EB} = {7BED8969-7EA7-409C-8BBC-D2777ECDA2F1}
{6A3FC66D-0B89-45E8-B39B-9D81538002D1} = {5300552F-560D-474A-8D96-0A2747D08F64}
{7BED8969-7EA7-409C-8BBC-D2777ECDA2F1} = {7B0175AD-BB74-4A98-B9A7-1E289032485E}
{28BE5235-2399-4EBA-B1F0-88E0F32AC869} = {7B0175AD-BB74-4A98-B9A7-1E289032485E}
{5300552F-560D-474A-8D96-0A2747D08F64} = {7B0175AD-BB74-4A98-B9A7-1E289032485E}
{B6213013-2A0E-41DD-BA9F-775D53C19374} = {5300552F-560D-474A-8D96-0A2747D08F64}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9AEC9B81-0222-4DE9-B642-D915C29222AC}


Loading…
Cancel
Save