diff --git a/appveyor.yml b/appveyor.yml
index 2581592a..a5b77c6c 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -19,7 +19,7 @@ before_build:
choco install codecov
build:
project: ./src/
- parallel: true
+ parallel: false
verbosity: minimal
test_script:
- ps: >-
diff --git a/src/MineCase.Engine/AsyncEventHandler.cs b/src/Common/Engine/AsyncEventHandler.cs
similarity index 100%
rename from src/MineCase.Engine/AsyncEventHandler.cs
rename to src/Common/Engine/AsyncEventHandler.cs
diff --git a/src/Common/Engine/Component.cs b/src/Common/Engine/Component.cs
new file mode 100644
index 00000000..b7efd868
--- /dev/null
+++ b/src/Common/Engine/Component.cs
@@ -0,0 +1,150 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+#if ECS_SERVER
+using ServiceProviderType = System.IServiceProvider;
+#else
+using ServiceProviderType = Autofac.ILifetimeScope;
+#endif
+
+namespace MineCase.Engine
+{
+ internal interface IComponentIntern
+ {
+#if ECS_SERVER
+ Task
+#else
+ void
+#endif
+ Attach(DependencyObject dependencyObject, ServiceProviderType serviceProvider);
+
+#if ECS_SERVER
+ Task
+#else
+ void
+#endif
+ Detach();
+
+ int GetMessageOrder(object message);
+ }
+
+ ///
+ /// 组件基类
+ ///
+ public abstract partial class Component : IComponentIntern
+ {
+ ///
+ /// 获取名称
+ ///
+ public string Name { get; }
+
+ ///
+ /// 获取附加到的实体
+ ///
+ protected DependencyObject AttachedObject { get; private set; }
+
+ ///
+ /// 获取服务提供程序
+ ///
+ protected ServiceProviderType ServiceProvider { get; private set; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// 名称
+ public Component(string name)
+ {
+ Name = name;
+ }
+
+#if ECS_SERVER
+ Task
+#else
+ void
+#endif
+ IComponentIntern.Attach(DependencyObject dependencyObject, ServiceProviderType serviceProvider)
+ {
+ AttachedObject = dependencyObject;
+ ServiceProvider = serviceProvider;
+ AttatchPartial(dependencyObject, serviceProvider);
+#if ECS_SERVER
+ return
+#endif
+ OnAttached();
+ }
+
+ partial void AttatchPartial(DependencyObject dependencyObject, ServiceProviderType serviceProvider);
+
+#if ECS_SERVER
+ Task
+#else
+ void
+#endif
+ IComponentIntern.Detach()
+ {
+ AttachedObject = null;
+#if ECS_SERVER
+ return
+#endif
+ OnDetached();
+ }
+
+ ///
+ /// 组件被附加到实体时
+ ///
+ protected virtual
+
+#if ECS_SERVER
+ Task
+#else
+ void
+#endif
+ OnAttached()
+ {
+#if ECS_SERVER
+ return Task.CompletedTask;
+#endif
+ }
+
+ ///
+ /// 组件从实体卸载时
+ ///
+ protected virtual Task OnDetached()
+ {
+ return Task.CompletedTask;
+ }
+
+ ///
+ /// 获取消息处理顺序
+ ///
+ /// 消息
+ /// 处理顺序(数字越小越靠前)
+ public virtual int GetMessageOrder(object message)
+ {
+ return 0;
+ }
+ }
+
+ ///
+ /// 组件基类
+ ///
+ /// 实体类型
+ public abstract class Component : Component
+ where T : DependencyObject
+ {
+ ///
+ /// 获取附加到的实体
+ ///
+ public new T AttachedObject => (T)base.AttachedObject;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// 名称
+ public Component(string name)
+ : base(name)
+ {
+ }
+ }
+}
diff --git a/src/MineCase.Engine/Data/DependencyValueStorage.cs b/src/Common/Engine/Data/DependencyValueStorage.cs
similarity index 62%
rename from src/MineCase.Engine/Data/DependencyValueStorage.cs
rename to src/Common/Engine/Data/DependencyValueStorage.cs
index 44e4cbf1..a0694f8e 100644
--- a/src/MineCase.Engine/Data/DependencyValueStorage.cs
+++ b/src/Common/Engine/Data/DependencyValueStorage.cs
@@ -22,13 +22,24 @@ public IEnumerable Keys
}
}
- public event AsyncEventHandler CurrentValueChanged;
+ public event
+#if ECS_SERVER
+ AsyncEventHandler
+#else
+ EventHandler
+#endif
+ CurrentValueChanged;
public DependencyValueStorage()
{
}
- public async Task AddOrUpdate(IDependencyValueProvider provider, DependencyProperty key, Func> addValueFactory, Func, Task>> updateValueFactory)
+ public
+#if ECS_SERVER
+ async Task AddOrUpdate(IDependencyValueProvider provider, DependencyProperty key, Func> addValueFactory, Func, Task>> updateValueFactory)
+#else
+ IEffectiveValue AddOrUpdate(IDependencyValueProvider provider, DependencyProperty key, Func> addValueFactory, Func, IEffectiveValue> updateValueFactory)
+#endif
{
var storage = GetStorage(provider, key);
var priority = provider.Priority;
@@ -42,12 +53,21 @@ public async Task AddOrUpdate(IDependencyValueProvider provi
result = value;
var raiseChanged = storage.IndexOfKey(priority) == 0;
if (raiseChanged)
- await OnCurrentValueChanged(key, false, null, true, value.Value);
+ {
+#if ECS_SERVER
+ await
+#endif
+ OnCurrentValueChanged(key, false, null, true, value.Value);
+ }
}
else
{
var oldValue = (IEffectiveValue)storage.Values[oldIdx];
- var newValue = await updateValueFactory(key, oldValue);
+ var newValue =
+#if ECS_SERVER
+ await
+#endif
+ updateValueFactory(key, oldValue);
if (oldValue != newValue)
{
oldValue.ValueChanged = null;
@@ -55,7 +75,12 @@ public async Task AddOrUpdate(IDependencyValueProvider provi
storage[priority] = newValue;
var raiseChanged = oldIdx == 0;
if (raiseChanged)
- await OnCurrentValueChanged(key, true, oldValue.Value, true, newValue.Value);
+ {
+#if ECS_SERVER
+ await
+#endif
+ OnCurrentValueChanged(key, true, oldValue.Value, true, newValue.Value);
+ }
}
result = newValue;
@@ -103,12 +128,27 @@ public bool TryGetCurrentEffectiveValue(DependencyProperty key, out IEffectiveVa
return false;
}
- private Task OnCurrentValueChanged(DependencyProperty key, bool hasOldValue, object oldValue, bool hasNewValue, object newValue)
+ private
+#if ECS_SERVER
+ Task
+#else
+ void
+#endif
+ OnCurrentValueChanged(DependencyProperty key, bool hasOldValue, object oldValue, bool hasNewValue, object newValue)
{
- return CurrentValueChanged.InvokeSerial(this, new CurrentValueChangedEventArgs(key, hasOldValue, oldValue, hasNewValue, newValue));
+#if ECS_SERVER
+ return
+#endif
+ CurrentValueChanged.InvokeSerial(this, new CurrentValueChangedEventArgs(key, hasOldValue, oldValue, hasNewValue, newValue));
}
- private Task OnEffectiveValueCleared(int index, DependencyProperty key, object oldValue)
+ private
+#if ECS_SERVER
+ Task
+#else
+ void
+#endif
+ OnEffectiveValueCleared(int index, DependencyProperty key, object oldValue)
{
if (index == 0)
{
@@ -121,17 +161,36 @@ private Task OnEffectiveValueCleared(int index, DependencyProperty key, object o
newValue = ((dynamic)list.Values[0]).Value;
}
- return OnCurrentValueChanged(key, true, oldValue, hasNewValue, newValue);
+#if ECS_SERVER
+ return
+#endif
+ OnCurrentValueChanged(key, true, oldValue, hasNewValue, newValue);
}
+#if ECS_SERVER
return Task.CompletedTask;
+#endif
}
- private async Task OnEffectiveValueChanged(float priority, DependencyProperty key, object oldValue, object newValue)
+ private
+#if ECS_SERVER
+ Task
+#else
+ void
+#endif
+ OnEffectiveValueChanged(float priority, DependencyProperty key, object oldValue, object newValue)
{
SortedList list;
if (_dict.TryGetValue(key, out list) && list.IndexOfKey(priority) == 0)
- await OnCurrentValueChanged(key, true, oldValue, true, newValue);
+ {
+#if ECS_SERVER
+ return
+#endif
+ OnCurrentValueChanged(key, true, oldValue, true, newValue);
+ }
+#if ECS_SERVER
+ return Task.CompletedTask;
+#endif
}
public bool TryGetValue(IDependencyValueProvider provider, DependencyProperty key, out IEffectiveValue value)
@@ -148,7 +207,13 @@ public bool TryGetValue(IDependencyValueProvider provider, DependencyProperty
return false;
}
- public Task TryRemove(IDependencyValueProvider provider, DependencyProperty key, out IEffectiveValue value)
+ public
+#if ECS_SERVER
+ Task
+#else
+ bool
+#endif
+ TryRemove(IDependencyValueProvider provider, DependencyProperty key, out IEffectiveValue value)
{
var storage = GetStorage(provider, key);
var priority = provider.Priority;
@@ -158,12 +223,21 @@ public Task TryRemove(IDependencyValueProvider provider, DependencyProp
value = (IEffectiveValue)eValue;
var index = storage.IndexOfKey(priority);
storage.RemoveAt(index);
+#if ECS_SERVER
return OnEffectiveValueCleared(index, key, value.Value)
.ContinueWith(t => true);
+#else
+ OnEffectiveValueCleared(index, key, value.Value);
+ return true;
+#endif
}
value = null;
+#if ECS_SERVER
return Task.FromResult(false);
+#else
+ return false;
+#endif
}
private SortedList GetStorage(IDependencyValueProvider provider, DependencyProperty key)
@@ -175,18 +249,44 @@ private SortedList GetStorage(IDependencyValueProvider p
}
}
+ ///
+ /// 当前值变更
+ ///
public class CurrentValueChangedEventArgs : EventArgs
{
+ ///
+ /// 获取依赖属性
+ ///
public DependencyProperty Property { get; }
+ ///
+ /// 获取原始值
+ ///
public object OldValue { get; }
+ ///
+ /// 获取新值
+ ///
public object NewValue { get; }
+ ///
+ /// 获取是否有原始值
+ ///
public bool HasOldValue { get; }
+ ///
+ /// 获取是否有新值
+ ///
public bool HasNewValue { get; }
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// 依赖属性
+ /// 是否有原始值
+ /// 原始值
+ /// 是否有新值
+ /// 新值
public CurrentValueChangedEventArgs(DependencyProperty property, bool hasOldValue, object oldValue, bool hasNewValue, object newValue)
{
Property = property;
diff --git a/src/Common/Engine/Data/IDependencyValueProvider.cs b/src/Common/Engine/Data/IDependencyValueProvider.cs
new file mode 100644
index 00000000..a4003c4d
--- /dev/null
+++ b/src/Common/Engine/Data/IDependencyValueProvider.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MineCase.Engine.Data
+{
+ ///
+ /// 依赖值提供程序接口
+ ///
+ public interface IDependencyValueProvider
+ {
+ ///
+ /// 获取优先级
+ ///
+ float Priority { get; }
+ }
+
+ ///
+ /// EffectiveValue 提供程序接口
+ ///
+ public interface IEffectiveValueProvider
+ {
+ ///
+ /// 提供值
+ ///
+ /// 依赖对象
+ /// EffectiveValue
+ IEffectiveValue ProviderValue(DependencyObject d);
+ }
+
+ ///
+ /// EffectiveValue 提供程序接口
+ ///
+ /// 值类型
+ public interface IEffectiveValueProvider : IEffectiveValueProvider
+ {
+ }
+}
diff --git a/src/Common/Engine/Data/IDependencyValueStorage.cs b/src/Common/Engine/Data/IDependencyValueStorage.cs
new file mode 100644
index 00000000..d2246221
--- /dev/null
+++ b/src/Common/Engine/Data/IDependencyValueStorage.cs
@@ -0,0 +1,95 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MineCase.Engine.Data
+{
+ ///
+ /// 依赖值存储接口
+ ///
+ public interface IDependencyValueStorage
+ {
+ ///
+ /// 当前值变更事件
+ ///
+ event
+#if ECS_SERVER
+ AsyncEventHandler
+#else
+ EventHandler
+#endif
+ CurrentValueChanged;
+
+ ///
+ /// 添加或更新
+ ///
+ /// 值类型
+ /// 依赖值提供程序
+ /// 依赖属性
+ /// 添加工厂
+ /// 更新工厂
+ /// 新的值
+#if ECS_SERVER
+ Task AddOrUpdate(IDependencyValueProvider provider, DependencyProperty key, Func> addValueFactory, Func, Task>> updateValueFactory);
+#else
+ IEffectiveValue AddOrUpdate(IDependencyValueProvider provider, DependencyProperty key, Func> addValueFactory, Func, IEffectiveValue> updateValueFactory);
+#endif
+
+ ///
+ /// 尝试获取值
+ ///
+ /// 值类型
+ /// 依赖值提供程序
+ /// 依赖属性
+ /// 值
+ /// 是否成功获取
+ bool TryGetValue(IDependencyValueProvider provider, DependencyProperty key, out IEffectiveValue value);
+
+ ///
+ /// 尝试删除值
+ ///
+ /// 值类型
+ /// 依赖值提供程序
+ /// 依赖属性
+ /// 值
+ /// 是否成功删除
+#if ECS_SERVER
+ Task
+#else
+ bool
+#endif
+ TryRemove(IDependencyValueProvider provider, DependencyProperty key, out IEffectiveValue value);
+
+ ///
+ /// 尝试获取当前值
+ ///
+ /// 值类型
+ /// 依赖属性
+ /// 值
+ /// 是否成功获取
+ bool TryGetCurrentValue(DependencyProperty key, out T value);
+
+ ///
+ /// 尝试获取当前 EffectiveValue
+ ///
+ /// 值类型
+ /// 依赖属性
+ /// EffectiveValue
+ /// 是否成功获取
+ bool TryGetCurrentEffectiveValue(DependencyProperty key, out IEffectiveValue value);
+
+ ///
+ /// 尝试获取当前 EffectiveValue
+ ///
+ /// 依赖属性
+ /// EffectiveValue
+ /// 是否成功获取
+ bool TryGetCurrentEffectiveValue(DependencyProperty key, out IEffectiveValue value);
+
+ ///
+ /// 获取包含的依赖属性
+ ///
+ IEnumerable Keys { get; }
+ }
+}
diff --git a/src/Common/Engine/Data/IEffectiveValue.cs b/src/Common/Engine/Data/IEffectiveValue.cs
new file mode 100644
index 00000000..57a5886f
--- /dev/null
+++ b/src/Common/Engine/Data/IEffectiveValue.cs
@@ -0,0 +1,99 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MineCase.Engine.Data
+{
+ ///
+ /// EffectiveValue 接口
+ ///
+ public interface IEffectiveValue
+ {
+ ///
+ /// 获取值改变处理器
+ ///
+#if ECS_SERVER
+ AsyncEventHandler
+#else
+ EventHandler
+#endif
+ ValueChanged { set; }
+ }
+
+ ///
+ /// EffectiveValue 接口
+ ///
+ /// 值类型
+ public interface IEffectiveValue : IEffectiveValue
+ {
+ ///
+ /// 获取可否设置值
+ ///
+ bool CanSetValue { get; }
+
+ ///
+ /// 获取值
+ ///
+ T Value { get; }
+
+ ///
+ /// 设置值
+ ///
+ /// 值
+#if ECS_SERVER
+ Task
+#else
+ void
+#endif
+ SetValue(T value);
+ }
+
+ ///
+ /// 接口
+ ///
+ public interface IEffectiveValueChangedEventArgs
+ {
+ ///
+ /// 获取原始值
+ ///
+ object OldValue { get; }
+
+ ///
+ /// 获取新值
+ ///
+ object NewValue { get; }
+ }
+
+ ///
+ /// EffectiveValue 变更事件参数
+ ///
+ /// 值类型
+ public class EffectiveValueChangedEventArgs : EventArgs, IEffectiveValueChangedEventArgs
+ {
+ ///
+ /// 获取原始值
+ ///
+ public T OldValue { get; }
+
+ ///
+ /// 获取新值
+ ///
+ public T NewValue { get; }
+
+ object IEffectiveValueChangedEventArgs.OldValue => OldValue;
+
+ object IEffectiveValueChangedEventArgs.NewValue => NewValue;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// 原始值
+ /// 新值
+ public EffectiveValueChangedEventArgs(T oldValue, T newValue)
+ {
+ OldValue = oldValue;
+ NewValue = newValue;
+ }
+ }
+}
diff --git a/src/Common/Engine/Data/LocalDependencyValueExtensions.cs b/src/Common/Engine/Data/LocalDependencyValueExtensions.cs
new file mode 100644
index 00000000..995bd5c7
--- /dev/null
+++ b/src/Common/Engine/Data/LocalDependencyValueExtensions.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using MineCase.Engine.Data;
+
+namespace MineCase.Engine
+{
+ ///
+ /// 本地依赖值扩展
+ ///
+ public static class LocalDependencyValueExtensions
+ {
+ ///
+ /// 尝试获取本地值
+ ///
+ /// 值类型
+ /// 依赖对象
+ /// 依赖属性
+ /// 值
+ /// 是否获取成功
+ public static bool TryGetLocalValue(this DependencyObject d, DependencyProperty property, out T value)
+ {
+ return LocalDependencyValueProvider.Current.TryGetValue(property, d.ValueStorage, out value);
+ }
+
+ ///
+ /// 设置本地值
+ ///
+ /// 值类型
+ /// 依赖对象
+ /// 依赖属性
+ /// 值
+ public static
+#if ECS_SERVER
+ Task
+#else
+ void
+#endif
+ SetLocalValue(this DependencyObject d, DependencyProperty property, T value)
+ {
+#if ECS_SERVER
+ return
+#endif
+ LocalDependencyValueProvider.Current.SetValue(property, d.ValueStorage, value);
+ }
+
+ ///
+ /// 清除本地值
+ ///
+ /// 值类型
+ /// 依赖对象
+ /// 依赖属性
+ public static
+#if ECS_SERVER
+ Task
+#else
+ void
+#endif
+ ClearLocalValue(this DependencyObject d, DependencyProperty property)
+ {
+#if ECS_SERVER
+ return
+#endif
+ LocalDependencyValueProvider.Current.ClearValue(property, d.ValueStorage);
+ }
+ }
+}
diff --git a/src/Common/Engine/Data/LocalDependencyValueProvider.cs b/src/Common/Engine/Data/LocalDependencyValueProvider.cs
new file mode 100644
index 00000000..f433b897
--- /dev/null
+++ b/src/Common/Engine/Data/LocalDependencyValueProvider.cs
@@ -0,0 +1,133 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MineCase.Engine.Data
+{
+ ///
+ /// 本地依赖值提供程序
+ ///
+ public class LocalDependencyValueProvider : IDependencyValueProvider
+ {
+ ///
+ /// 获取当前提供程序
+ ///
+ public static LocalDependencyValueProvider Current { get; } = new LocalDependencyValueProvider();
+
+ ///
+ public float Priority => 1.0f;
+
+ ///
+ /// 设置值
+ ///
+ /// 值类型
+ /// 依赖属性
+ /// 值存储
+ /// 值
+#if ECS_SERVER
+ public Task SetValue(DependencyProperty property, IDependencyValueStorage storage, T value)
+ {
+ return storage.AddOrUpdate(this, property, o => new LocalEffectiveValue(value), async (k, o) =>
+ {
+ await ((LocalEffectiveValue)o).SetValue(value);
+ return o;
+ });
+ }
+#else
+ public void SetValue(DependencyProperty property, IDependencyValueStorage storage, T value)
+ {
+ storage.AddOrUpdate(this, property, o => new LocalEffectiveValue(value), (k, o) =>
+ {
+ ((LocalEffectiveValue)o).SetValue(value);
+ return o;
+ });
+ }
+#endif
+
+ ///
+ /// 尝试获取值
+ ///
+ /// 值类型
+ /// 依赖属性
+ /// 值存储
+ /// 值
+ /// 是否获取成功
+ public bool TryGetValue(DependencyProperty property, IDependencyValueStorage storage, out T value)
+ {
+ IEffectiveValue eValue;
+ if (storage.TryGetValue(this, property, out eValue))
+ {
+ value = eValue.Value;
+ return true;
+ }
+
+ value = default(T);
+ return false;
+ }
+
+ ///
+ /// 清除值
+ ///
+ /// 值类型
+ /// 依赖属性
+ /// 值存储
+ public
+#if ECS_SERVER
+ Task
+#else
+ void
+#endif
+ ClearValue(DependencyProperty property, IDependencyValueStorage storage)
+ {
+ IEffectiveValue eValue;
+#if ECS_SERVER
+ return
+#endif
+ storage.TryRemove(this, property, out eValue);
+ }
+
+ internal class LocalEffectiveValue : IEffectiveValue
+ {
+ ///
+ public
+#if ECS_SERVER
+ AsyncEventHandler
+#else
+ EventHandler
+#endif
+ ValueChanged { get; set; }
+
+ ///
+ public bool CanSetValue => true;
+
+ private T _value;
+
+ ///
+ public T Value => _value;
+
+ public LocalEffectiveValue(T value)
+ {
+ _value = value;
+ }
+
+ ///
+#if ECS_SERVER
+ public async Task SetValue(T value)
+#else
+ public void SetValue(T value)
+#endif
+ {
+ if (!EqualityComparer.Default.Equals(_value, value))
+ {
+ var oldValue = _value;
+ _value = value;
+#if ECS_SERVER
+ await
+#endif
+ ValueChanged.InvokeSerial(this, new EffectiveValueChangedEventArgs(oldValue, value));
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/MineCase.Engine/DependencyObject.cs b/src/Common/Engine/DependencyObject.cs
similarity index 53%
rename from src/MineCase.Engine/DependencyObject.cs
rename to src/Common/Engine/DependencyObject.cs
index 0392fe6e..b996bc8c 100644
--- a/src/MineCase.Engine/DependencyObject.cs
+++ b/src/Common/Engine/DependencyObject.cs
@@ -7,27 +7,48 @@
using System.Text;
using System.Threading.Tasks;
using MineCase.Engine.Data;
+#if ECS_SERVER
using Orleans;
+#endif
namespace MineCase.Engine
{
- public abstract class DependencyObject : Grain, IDependencyObject
+ ///
+ /// 依赖对象
+ ///
+ public abstract partial class DependencyObject
+ :
+#if ECS_SERVER
+ Grain,
+#else
+ SmartBehaviour,
+#endif
+ IDependencyObject
{
private Dictionary _components;
private Dictionary _indexes;
private int _index = 0;
+ ///
+ /// Initializes a new instance of the class.
+ ///
public DependencyObject()
{
_realType = this.GetType();
_valueStorage.CurrentValueChanged += ValueStorage_CurrentValueChanged;
}
- public override async Task OnActivateAsync()
+ private void LoadState()
{
_components = new Dictionary();
_indexes = new Dictionary();
_messageHandlers = new MultiValueDictionary();
+ }
+
+#if ECS_SERVER
+ public override async Task OnActivateAsync()
+ {
+ LoadState();
await InitializeComponents();
}
@@ -35,8 +56,34 @@ protected virtual Task InitializeComponents()
{
return Task.CompletedTask;
}
+#else
+ ///
+ protected override void Awake()
+ {
+ base.Awake();
+ LoadState();
+ InitializeComponents();
+ }
- public T GetComponent()
+ ///
+ /// 初始化组件
+ ///
+ protected virtual void InitializeComponents()
+ {
+ }
+#endif
+
+ ///
+ /// 获取组件
+ ///
+ /// 组件类型
+ /// 组件
+#if ECS_SERVER
+ public
+#else
+ public new
+#endif
+ T GetComponent()
where T : Component
{
foreach (var component in _components)
@@ -48,32 +95,72 @@ public T GetComponent()
return null;
}
- public async Task SetComponent(Component component)
+#if !ECS_SERVER
+ ///
+ /// 获取 Unity 组件
+ ///
+ /// 组件类型
+ /// 组件
+ public T GetUnityComponent()
+ where T : UnityEngine.Component =>
+ base.GetComponent();
+#endif
+
+ ///
+ /// 设置组件
+ ///
+ /// 组件
+ public
+#if ECS_SERVER
+ async Task
+#else
+ void
+#endif
+ SetComponent(Component component)
{
var name = component.Name;
if (_components.TryGetValue(name, out var old))
{
if (old == component) return;
Unsubscribe(old);
- await old.Detach();
+#if ECS_SERVER
+ await
+#endif
+ old.Detach();
_indexes.Remove(old);
_components.Remove(name);
}
_components.Add(name, component);
_indexes.Add(component, _index++);
- await ((IComponentIntern)component).Attach(this, ServiceProvider);
+#if ECS_SERVER
+ await
+#endif
+ ((IComponentIntern)component).Attach(this, ServiceProvider);
Subscribe(component);
}
- public async Task ClearComponent()
+ ///
+ /// 清除组件
+ ///
+ /// 组件类型
+ public
+#if ECS_SERVER
+ async Task
+#else
+ void
+#endif
+ ClearComponent()
where T : Component
{
var components = _components.Where(o => o.Value is T);
foreach (var component in components)
{
Unsubscribe(component.Value);
- await component.Value.Detach();
+#if ECS_SERVER
+ await
+#endif
+ component.Value.Detach();
_indexes.Remove(component.Value);
_components.Remove(component.Key);
}
@@ -89,6 +176,12 @@ public async Task ClearComponent()
private readonly ConcurrentDictionary _propertyChangedHandlersGen = new ConcurrentDictionary();
private Delegate _anyPropertyChangedHandler;
+ ///
+ /// 获取值
+ ///
+ /// 值类型
+ /// 依赖属性
+ /// 值
public T GetValue(DependencyProperty property)
{
T value;
@@ -98,28 +191,86 @@ public T GetValue(DependencyProperty property)
return value;
}
- public Task SetCurrentValue(DependencyProperty property, T value)
+ ///
+ /// 设置当前值
+ ///
+ /// 值类型
+ /// 依赖属性
+ /// 值
+ public
+#if ECS_SERVER
+ Task
+#else
+ void
+#endif
+ SetCurrentValue(DependencyProperty property, T value)
{
IEffectiveValue eValue;
if (_valueStorage.TryGetCurrentEffectiveValue(property, out eValue) && eValue.CanSetValue)
- return eValue.SetValue(value);
+ {
+#if ECS_SERVER
+ return
+#endif
+ eValue.SetValue(value);
+ }
else
- return this.SetLocalValue(property, value);
+ {
+#if ECS_SERVER
+ return
+#endif
+ this.SetLocalValue(property, value);
+ }
}
private static readonly MethodInfo _raisePropertyChangedHelper = typeof(DependencyObject).GetRuntimeMethods().Single(o => o.Name == nameof(RaisePropertyChangedHelper));
- private Task ValueStorage_CurrentValueChanged(object sender, CurrentValueChangedEventArgs e)
+ private
+#if ECS_SERVER
+ Task
+#else
+ void
+#endif
+ ValueStorage_CurrentValueChanged(object sender, CurrentValueChangedEventArgs e)
{
+#if ECS_SERVER
return (Task)_raisePropertyChangedHelper.MakeGenericMethod(e.Property.PropertyType).Invoke(this, new object[] { e.Property, e });
+#else
+ _raisePropertyChangedHelper.MakeGenericMethod(e.Property.PropertyType).Invoke(this, new object[] { e.Property, e });
+#endif
}
- public void RegisterPropertyChangedHandler(DependencyProperty property, AsyncEventHandler> handler)
+ ///
+ /// 注册属性变更处理器
+ ///
+ /// 值类型
+ /// 依赖属性
+ /// 处理器
+ public void RegisterPropertyChangedHandler(
+ DependencyProperty property,
+#if ECS_SERVER
+ AsyncEventHandler>
+#else
+ EventHandler>
+#endif
+ handler)
{
_propertyChangedHandlers.AddOrUpdate(property, handler, (k, old) => Delegate.Combine(old, handler));
}
- public void RemovePropertyChangedHandler(DependencyProperty property, AsyncEventHandler> handler)
+ ///
+ /// 删除属性变更处理器
+ ///
+ /// 值类型
+ /// 依赖属性
+ /// 处理器
+ public void RemovePropertyChangedHandler(
+ DependencyProperty property,
+#if ECS_SERVER
+ AsyncEventHandler>
+#else
+ EventHandler>
+#endif
+ handler)
{
Delegate d = null;
_propertyChangedHandlers.TryRemove(property, out d);
@@ -127,12 +278,36 @@ public void RemovePropertyChangedHandler(DependencyProperty property, Asyn
_propertyChangedHandlers.AddOrUpdate(property, k => Delegate.Remove(d, handler), (k, old) => Delegate.Combine(old, Delegate.Remove(d, handler)));
}
- public void RegisterPropertyChangedHandler(DependencyProperty property, AsyncEventHandler handler)
+ ///
+ /// 注册属性变更处理器
+ ///
+ /// 依赖属性
+ /// 处理器
+ public void RegisterPropertyChangedHandler(
+ DependencyProperty property,
+#if ECS_SERVER
+ AsyncEventHandler
+#else
+ EventHandler
+#endif
+ handler)
{
_propertyChangedHandlersGen.AddOrUpdate(property, handler, (k, old) => Delegate.Combine(old, handler));
}
- public void RemovePropertyChangedHandler(DependencyProperty property, AsyncEventHandler handler)
+ ///
+ /// 删除属性变更处理器
+ ///
+ /// 依赖属性
+ /// 处理器
+ public void RemovePropertyChangedHandler(
+ DependencyProperty property,
+#if ECS_SERVER
+ AsyncEventHandler
+#else
+ EventHandler
+#endif
+ handler)
{
Delegate d = null;
_propertyChangedHandlersGen.TryRemove(property, out d);
@@ -140,17 +315,43 @@ public void RemovePropertyChangedHandler(DependencyProperty property, AsyncEvent
_propertyChangedHandlersGen.AddOrUpdate(property, k => Delegate.Remove(d, handler), (k, old) => Delegate.Combine(old, Delegate.Remove(d, handler)));
}
- public void RegisterAnyPropertyChangedHandler(AsyncEventHandler handler)
+ ///
+ /// 注册任意属性变更处理器
+ ///
+ /// 处理器
+ public void RegisterAnyPropertyChangedHandler(
+#if ECS_SERVER
+ AsyncEventHandler
+#else
+ EventHandler
+#endif
+ handler)
{
_anyPropertyChangedHandler = Delegate.Combine(_anyPropertyChangedHandler, handler);
}
- public void RemoveAnyPropertyChangedHandler(AsyncEventHandler handler)
+ ///
+ /// 删除任意属性变更处理器
+ ///
+ /// 处理器
+ public void RemoveAnyPropertyChangedHandler(
+#if ECS_SERVER
+ AsyncEventHandler
+#else
+ EventHandler
+#endif
+ handler)
{
_anyPropertyChangedHandler = Delegate.Remove(_anyPropertyChangedHandler, handler);
}
- internal async Task RaisePropertyChangedHelper(DependencyProperty property, CurrentValueChangedEventArgs e)
+ internal
+#if ECS_SERVER
+ async Task
+#else
+ void
+#endif
+ RaisePropertyChangedHelper(DependencyProperty property, CurrentValueChangedEventArgs e)
{
var oldValue = e.HasOldValue ? (T)e.OldValue : GetDefaultValue(property);
var newValue = e.HasNewValue ? (T)e.NewValue : GetDefaultValue(property);
@@ -158,16 +359,38 @@ internal async Task RaisePropertyChangedHelper(DependencyProperty property
if (e.HasOldValue && e.HasNewValue && EqualityComparer.Default.Equals((T)e.OldValue, (T)e.NewValue))
return;
var args = new PropertyChangedEventArgs(property, oldValue, newValue);
- await property.RaisePropertyChanged(_realType, this, args);
- await InvokeLocalPropertyChangedHandlers(args);
- await OnDependencyPropertyChanged(args);
+
+#if ECS_SERVER
+ await
+#endif
+ property.RaisePropertyChanged(_realType, this, args);
+#if ECS_SERVER
+ await
+#endif
+ InvokeLocalPropertyChangedHandlers(args);
+#if ECS_SERVER
+ await
+#endif
+ OnDependencyPropertyChanged(args);
}
+ ///
+ /// 依赖属性发生变更时
+ ///
+ /// 值类型
+ /// 参数
+#if ECS_SERVER
public virtual Task OnDependencyPropertyChanged(PropertyChangedEventArgs args)
{
return Task.CompletedTask;
}
+#else
+ public virtual void OnDependencyPropertyChanged(PropertyChangedEventArgs args)
+ {
+ }
+#endif
+#if ECS_SERVER
private async Task InvokeLocalPropertyChangedHandlers(PropertyChangedEventArgs e)
{
Delegate d;
@@ -178,6 +401,18 @@ private async Task InvokeLocalPropertyChangedHandlers(PropertyChangedEventArg
await ((AsyncEventHandler)d).InvokeSerial(this, e);
await ((AsyncEventHandler)_anyPropertyChangedHandler).InvokeSerial(this, e);
}
+#else
+ private void InvokeLocalPropertyChangedHandlers(PropertyChangedEventArgs e)
+ {
+ Delegate d;
+ if (_propertyChangedHandlers.TryGetValue(e.Property, out d))
+ ((EventHandler>)d).InvokeSerial(this, e);
+
+ if (_propertyChangedHandlersGen.TryGetValue(e.Property, out d))
+ ((EventHandler)d).InvokeSerial(this, e);
+ ((EventHandler)_anyPropertyChangedHandler).InvokeSerial(this, e);
+ }
+#endif
private T GetDefaultValue(DependencyProperty property)
{
@@ -256,55 +491,129 @@ private void Unsubscribe(IComponentIntern component)
_messageHandlers.Remove(type, component);
}
- public Task Tell(IEntityMessage message)
+ ///
+ public
+#if ECS_SERVER
+ Task
+#else
+ void
+#endif
+ Tell(IEntityMessage message)
{
- return Tell(message, message.GetType());
+#if ECS_SERVER
+ return
+#endif
+ Tell(message, message.GetType());
}
- public Task Tell(T message)
+ ///
+ /// 告知
+ ///
+ /// 消息类型
+ /// 消息
+ public
+#if ECS_SERVER
+ Task
+#else
+ void
+#endif
+ Tell(T message)
where T : IEntityMessage
{
- return Tell(message, typeof(T));
+#if ECS_SERVER
+ return
+#endif
+ Tell(message, typeof(T));
}
- private async Task Tell(IEntityMessage message, Type messageType)
+ private
+#if ECS_SERVER
+ async Task
+#else
+ void
+#endif
+ Tell(IEntityMessage message, Type messageType)
{
- var invoker = (Func)GetOrAddMessageCaller(messageType);
+ var invoker =
+#if ECS_SERVER
+ (Func
+#else
+ (Action
+#endif
+)GetOrAddMessageCaller(messageType);
if (_messageHandlers.TryGetValue(messageType, out var handlers))
{
foreach (var handler in from h in handlers
orderby h.GetMessageOrder(message), _indexes[h]
select h)
- await invoker(handler, message);
+ {
+#if ECS_SERVER
+ await
+#endif
+ invoker(handler, message);
+ }
}
}
- public async Task Ask(IEntityMessage message)
+ ///
+ public
+#if ECS_SERVER
+ async Task
+#else
+ TResponse
+#endif
+ Ask(IEntityMessage message)
{
- var response = await TryAsk(message);
+ var response =
+#if ECS_SERVER
+ await
+#endif
+ TryAsk(message);
if (!response.Succeeded)
throw new ReceiverNotFoundException();
return response.Response;
}
- public async Task> TryAsk(IEntityMessage message)
+ ///
+ public
+#if ECS_SERVER
+ async Task>
+#else
+ AskResult
+#endif
+ TryAsk(IEntityMessage message)
{
var messageType = message.GetType();
- var invoker = (Func, Task>)GetOrAddMessageCaller(messageType);
+ var invoker =
+#if ECS_SERVER
+ (Func, Task>
+#else
+ (Func, TResponse>
+#endif
+)GetOrAddMessageCaller(messageType);
if (_messageHandlers.TryGetValue(messageType, out var handlers))
{
foreach (var handler in from h in handlers
orderby h.GetMessageOrder(message), _indexes[h]
select h)
- return new AskResult { Succeeded = true, Response = await invoker(handler, message) };
+ {
+ var response =
+#if ECS_SERVER
+ await
+#endif
+ invoker(handler, message);
+ return new AskResult { Succeeded = true, Response = response };
+ }
}
return AskResult.Failed;
}
+#if ECS_SERVER
public virtual void Destroy()
{
DeactivateOnIdle();
}
+#endif
}
}
diff --git a/src/MineCase.Engine/DependencyProperty.cs b/src/Common/Engine/DependencyProperty.cs
similarity index 71%
rename from src/MineCase.Engine/DependencyProperty.cs
rename to src/Common/Engine/DependencyProperty.cs
index 279f637d..ead8bd55 100644
--- a/src/MineCase.Engine/DependencyProperty.cs
+++ b/src/Common/Engine/DependencyProperty.cs
@@ -11,24 +11,53 @@ namespace MineCase.Engine
[Flags]
internal enum DependencyPropertyFlags
{
+ ///
+ /// 无
+ ///
None = 0,
+
+ ///
+ /// 附加属性
+ ///
Attached = 1,
+
+ ///
+ /// 只读属性
+ ///
ReadOnly = 2
}
+ ///
+ /// 依赖属性
+ ///
public abstract class DependencyProperty : IEquatable
{
private static int _nextAvailableGlobalId = 0;
private static readonly ConcurrentDictionary _fromNameMaps = new ConcurrentDictionary();
+ ///
+ /// 获取名称
+ ///
public string Name { get; }
+ ///
+ /// 获取所有者类型
+ ///
public Type OwnerType { get; }
+ ///
+ /// 获取属性类型
+ ///
public abstract Type PropertyType { get; }
+ ///
+ /// 获取是否附加属性
+ ///
public bool IsAttached => Flags.HasFlag(DependencyPropertyFlags.Attached);
+ ///
+ /// 获取是否只读属性
+ ///
public bool IsReadOnly => Flags.HasFlag(DependencyPropertyFlags.ReadOnly);
internal DependencyPropertyFlags Flags { get; }
@@ -44,6 +73,7 @@ internal DependencyProperty(string name, Type ownerType, DependencyPropertyFlags
_globalId = Interlocked.Increment(ref _nextAvailableGlobalId);
}
+ ///
public override bool Equals(object obj)
{
if (obj is DependencyProperty)
@@ -51,22 +81,40 @@ public override bool Equals(object obj)
return false;
}
+ ///
public bool Equals(DependencyProperty other)
{
if (other != null) return _globalId == other._globalId;
return false;
}
+ ///
public override int GetHashCode()
{
return _globalId.GetHashCode();
}
+ ///
+ /// 注册
+ ///
+ /// 属性类型
+ /// 名称
+ /// 所有者类型
+ /// 元数据
+ /// 依赖属性
public static DependencyProperty Register(string name, Type ownerType, PropertyMetadata metadata = null)
{
return RegisterIntern(name, ownerType, DependencyPropertyFlags.None, metadata ?? new PropertyMetadata(UnsetValue));
}
+ ///
+ /// 注册附加属性
+ ///
+ /// 属性类型
+ /// 名称
+ /// 所有者类型
+ /// 元数据
+ /// 依赖属性
public static DependencyProperty RegisterAttached(string name, Type ownerType, PropertyMetadata metadata = null)
{
return RegisterIntern(name, ownerType, DependencyPropertyFlags.Attached, metadata ?? new PropertyMetadata(UnsetValue));
@@ -82,6 +130,12 @@ private static DependencyProperty RegisterIntern(string name, Type ownerTy
return new DependencyProperty(name, ownerType, flag, metadata ?? new PropertyMetadata(UnsetValue));
}
+ ///
+ /// 从名称获取依赖属性
+ ///
+ /// 名称
+ /// 所有者类型
+ /// 依赖属性
public static DependencyProperty FromName(string name, Type ownerType)
{
if (name == null)
@@ -99,14 +153,25 @@ public static DependencyProperty FromName(string name, Type ownerType)
return property != null ? property : throw new InvalidOperationException($"Property {ownerType.Name}.{name} not found.");
}
+ ///
+ /// 添加从名称获取
+ ///
+ /// 名称
+ /// 所有者类型
protected void AddFromeNameKey(string name, Type ownerType)
{
if (!_fromNameMaps.TryAdd(new FromNameKey(name, ownerType), this))
throw new ArgumentException($"Property {ownerType.Name}.{name} is already registered.");
}
+ ///
+ /// 未设置值
+ ///
public static readonly UnsetValueType UnsetValue = default(UnsetValueType);
+ ///
+ /// 未设置值类型
+ ///
public struct UnsetValueType
{
}
@@ -145,11 +210,16 @@ public override bool Equals(object obj)
}
}
+ ///
+ /// 依赖属性
+ ///
+ /// 属性类型
public sealed class DependencyProperty : DependencyProperty
{
private PropertyMetadata _baseMetadata;
private readonly ConcurrentDictionary> _metadatas = new ConcurrentDictionary>();
+ ///
public override Type PropertyType => typeof(T);
internal DependencyProperty(string name, Type ownerType, DependencyPropertyFlags flags, PropertyMetadata metadata)
@@ -160,6 +230,11 @@ internal DependencyProperty(string name, Type ownerType, DependencyPropertyFlags
_baseMetadata = metadata;
}
+ ///
+ /// 重写元数据
+ ///
+ /// 要重写的目标类型
+ /// 元数据
public void OverrideMetadata(Type type, PropertyMetadata metadata)
{
if (type == null)
@@ -184,6 +259,12 @@ public void OverrideMetadata(Type type, PropertyMetadata metadata)
}
}
+ ///
+ /// 添加所有者
+ ///
+ /// 所有者类型
+ /// 元数据
+ /// 依赖属性
public DependencyProperty AddOwner(Type ownerType, PropertyMetadata metadata = null)
{
if (ownerType == null)
@@ -196,16 +277,37 @@ public DependencyProperty AddOwner(Type ownerType, PropertyMetadata metada
return this;
}
+ ///
+ /// 尝试获取默认值
+ ///
+ /// 依赖对象
+ /// 类型
+ /// 值
+ /// 是否获取成功
public bool TryGetDefaultValue(DependencyObject d, Type type, out T value)
{
return GetMetadata(type).TryGetDefaultValue(d, this, out value);
}
- internal Task RaisePropertyChanged(Type type, object sender, PropertyChangedEventArgs e)
+ internal
+#if ECS_SERVER
+ Task
+#else
+ void
+#endif
+ RaisePropertyChanged(Type type, object sender, PropertyChangedEventArgs e)
{
- return GetMetadata(type).RaisePropertyChanged(sender, e);
+#if ECS_SERVER
+ return
+#endif
+ GetMetadata(type).RaisePropertyChanged(sender, e);
}
+ ///
+ /// 获取元数据
+ ///
+ /// 类型
+ /// 元数据
public PropertyMetadata GetMetadata(Type type)
{
bool metadataIsDervied;
@@ -245,6 +347,13 @@ private PropertyMetadata MergeMetadata(bool ownerIsDerived, PropertyMetadata<
return newMetadata;
}
+ ///
+ /// 尝试获取非默认值
+ ///
+ /// 依赖对象
+ /// 类型
+ /// 值
+ /// 是否具有非默认值
public bool TryGetNonDefaultValue(DependencyObject d, Type type, out T value)
{
return GetMetadata(type).TryGetNonDefaultValue(d, this, out value);
diff --git a/src/MineCase.Engine/EngineAssemblyExtensions.cs b/src/Common/Engine/EngineAssemblyExtensions.cs
similarity index 61%
rename from src/MineCase.Engine/EngineAssemblyExtensions.cs
rename to src/Common/Engine/EngineAssemblyExtensions.cs
index ac7a5d9b..6fe2d5f0 100644
--- a/src/MineCase.Engine/EngineAssemblyExtensions.cs
+++ b/src/Common/Engine/EngineAssemblyExtensions.cs
@@ -5,8 +5,16 @@
namespace MineCase
{
+ ///
+ /// Engine 程序集扩展
+ ///
public static class EngineAssemblyExtensions
{
+ ///
+ /// 添加 Engine
+ ///
+ /// 程序集集合
+ /// 程序集集合
public static ICollection AddEngine(this ICollection assemblies)
{
assemblies.Add(typeof(EngineAssemblyExtensions).Assembly);
diff --git a/src/Common/Engine/IDependencyObject.cs b/src/Common/Engine/IDependencyObject.cs
new file mode 100644
index 00000000..8a1f4ac5
--- /dev/null
+++ b/src/Common/Engine/IDependencyObject.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+#if ECS_SERVER
+using Orleans;
+using Orleans.Concurrency;
+#endif
+
+namespace MineCase.Engine
+{
+ ///
+ /// 询问结果
+ ///
+ /// 回复类型
+#if ECS_SERVER
+ [Immutable]
+#endif
+ public sealed class AskResult
+ {
+ ///
+ /// 询问失败
+ ///
+ public static readonly AskResult Failed = new AskResult { Succeeded = false };
+
+ ///
+ /// 是否成功
+ ///
+ public bool Succeeded;
+
+ ///
+ /// 回复
+ ///
+ public TResponse Response;
+ }
+
+ ///
+ /// 依赖对象接口
+ ///
+ public interface IDependencyObject
+#if ECS_SERVER
+ : IGrain
+#endif
+ {
+ ///
+ /// 通知
+ ///
+ /// 消息
+#if ECS_SERVER
+ Task
+#else
+ void
+#endif
+ Tell(IEntityMessage message);
+
+ ///
+ /// 询问
+ ///
+ /// 消息
+ /// 回复
+#if ECS_SERVER
+ Task
+#else
+ TResponse
+#endif
+ Ask(IEntityMessage message);
+
+ ///
+ /// 尝试询问
+ ///
+ /// 消息
+ /// 询问结果
+#if ECS_SERVER
+ Task>
+#else
+ AskResult
+#endif
+ TryAsk(IEntityMessage message);
+ }
+}
diff --git a/src/MineCase.Engine/IEntityMessage.cs b/src/Common/Engine/IEntityMessage.cs
similarity index 51%
rename from src/MineCase.Engine/IEntityMessage.cs
rename to src/Common/Engine/IEntityMessage.cs
index 1b5d1e51..5b104431 100644
--- a/src/MineCase.Engine/IEntityMessage.cs
+++ b/src/Common/Engine/IEntityMessage.cs
@@ -4,14 +4,24 @@
namespace MineCase.Engine
{
+ ///
+ /// 是实体消息
+ ///
public interface IEntityMessage
{
}
+ ///
+ /// 具有回复的实体消息
+ ///
+ /// 回复类型
public interface IEntityMessage
{
}
+ ///
+ /// 找不到接收者异常
+ ///
public class ReceiverNotFoundException : Exception
{
}
diff --git a/src/Common/Engine/IHandle.cs b/src/Common/Engine/IHandle.cs
new file mode 100644
index 00000000..a484a098
--- /dev/null
+++ b/src/Common/Engine/IHandle.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MineCase.Engine
+{
+ ///
+ /// 实体消息处理接口
+ ///
+ /// 消息类型
+ public interface IHandle
+ where TMessage : IEntityMessage
+ {
+ ///
+ /// 处理消息
+ ///
+ /// 消息
+#if ECS_SERVER
+ Task
+#else
+ void
+#endif
+ Handle(TMessage message);
+ }
+
+ ///
+ /// 实体消息处理接口
+ ///
+ /// 消息类型
+ /// 返回类型
+ public interface IHandle
+ where TMessage : IEntityMessage
+ {
+ ///
+ /// 处理消息
+ ///
+ /// 消息
+ /// 回复
+#if ECS_SERVER
+ Task
+#else
+ TResponse
+#endif
+ Handle(TMessage message);
+ }
+}
diff --git a/src/Common/Engine/PropertyChangedEventArgs.cs b/src/Common/Engine/PropertyChangedEventArgs.cs
new file mode 100644
index 00000000..842d634b
--- /dev/null
+++ b/src/Common/Engine/PropertyChangedEventArgs.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MineCase.Engine
+{
+ ///
+ /// 属性变更事件参数
+ ///
+ public class PropertyChangedEventArgs : EventArgs
+ {
+ ///
+ /// 依赖属性
+ ///
+ public DependencyProperty Property { get; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// 依赖属性
+ public PropertyChangedEventArgs(DependencyProperty property)
+ {
+ Property = property;
+ }
+ }
+
+ ///
+ /// 属性变更事件参数
+ ///
+ /// 值类型
+ public class PropertyChangedEventArgs : PropertyChangedEventArgs
+ {
+ ///
+ /// 依赖属性
+ ///
+ public new DependencyProperty Property => (DependencyProperty)base.Property;
+
+ ///