From e2e94c947c3e731e580b2e7f6d86fc8946f80463 Mon Sep 17 00:00:00 2001 From: SunnyCase Date: Mon, 27 Nov 2017 17:37:50 +0800 Subject: [PATCH 1/7] Remove asyncs on dp --- src/Common/Engine/Component.cs | 51 +---- .../Engine/Data/DependencyValueStorage.cs | 92 +-------- .../Engine/Data/IDependencyValueStorage.cs | 19 +- src/Common/Engine/Data/IEffectiveValue.cs | 14 +- .../Data/LocalDependencyValueExtensions.cs | 22 +-- .../Data/LocalDependencyValueProvider.cs | 37 +--- src/Common/Engine/DependencyObject.cs | 178 ++++-------------- src/Common/Engine/DependencyProperty.cs | 11 +- src/Common/Engine/PropertyMetadata.cs | 49 +---- .../Game/Entity/Ai/MobAi/CreatureAi.cs | 4 +- .../DependencyObject.Server.cs | 10 +- src/MineCase.Gateway/Program.cs | 2 + .../AddressByPartitionKeyComponent.cs | 18 +- .../Components/BlockWorldPositionComponent.cs | 2 +- .../Components/EntityIdComponent.cs | 3 +- .../Components/EntityLookComponent.cs | 6 +- .../Components/EntityOnGroundComponent.cs | 2 +- .../EntityWorldPositionComponent.cs | 2 +- .../Components/GameTickComponent.cs | 24 +-- .../Components/IsEnabledComponent.cs | 6 +- .../Components/NameComponent.cs | 2 +- .../Components/WorldComponent.cs | 2 +- .../Game/BlockEntities/BlockEntityGrain.cs | 18 +- .../BlockEntities/ChestBlockEntityGrain.cs | 8 +- .../BlockEntityLiftTimeComponent.cs | 7 +- .../Components/ChestComponent.cs | 23 ++- .../Components/FurnaceComponent.cs | 15 +- .../Game/BlockEntities/FurnaceBlockEntity.cs | 8 +- .../ActiveWorldPartitionComponent.cs | 19 +- .../Components/ChunkLoaderComponent.cs | 7 +- .../Entities/Components/ColliderComponent.cs | 38 ++-- .../Components/DiscoveryRegisterComponent.cs | 24 +-- .../Components/DraggedSlotComponent.cs | 5 +- .../Entities/Components/EntityAiComponent.cs | 26 ++- .../EntityDiscoveryComponentBase.cs | 5 - .../Components/EntityLifeTimeComponent.cs | 11 +- .../Components/EntityLookComponentBase.cs | 5 - .../Components/EntityMoveComponent.cs | 5 - .../Game/Entities/Components/FoodComponent.cs | 6 +- .../Entities/Components/HealthComponent.cs | 4 +- .../Entities/Components/HeldItemComponent.cs | 7 +- .../Components/MobDiscoveryComponent.cs | 7 +- .../Components/MobSpawnerComponent.cs | 6 +- .../Entities/Components/MobTypeComponent.cs | 2 +- .../Components/PickupDiscoveryComponent.cs | 6 +- .../Components/PickupMetadataComponent.cs | 5 +- .../Components/SlotContainerComponent.cs | 24 +-- .../Components/StandaloneHeldItemComponent.cs | 5 +- .../Components/SyncMobStateComponent.cs | 18 +- .../Components/SyncPlayerStateComponent.cs | 18 +- .../Components/WindowManagerComponent.cs | 3 +- .../Game/Entities/EntityGrain.cs | 22 +-- .../Game/Entities/MobGrain.cs | 30 +-- .../Game/Entities/MonsterGrain.cs | 28 +-- .../Game/Entities/PassiveMobGrain.cs | 26 +-- .../Game/Entities/PickupGrain.cs | 16 +- .../Game/Entities/PlayerGrain.cs | 68 +++---- .../Play/ServerboundPacketComponent.cs | 46 ++--- .../Components/AutoSaveStateComponent.cs | 3 +- .../Persistence/Components/StateComponent.cs | 14 +- .../User/NonAuthenticatedUserGrain.cs | 4 +- src/MineCase.Server.Grains/User/UserGrain.cs | 17 +- .../World/ChunkColumnGrain.cs | 8 +- .../World/CollectableFinder.cs | 8 +- .../World/TickEmitterGrain.cs | 8 +- .../World/WorldGrain.cs | 21 ++- .../World/WorldPartitionGrain.cs | 8 +- tests/UnitTest/SerializationTest.cs | 14 +- 68 files changed, 452 insertions(+), 780 deletions(-) diff --git a/src/Common/Engine/Component.cs b/src/Common/Engine/Component.cs index b7efd868..8c467fe8 100644 --- a/src/Common/Engine/Component.cs +++ b/src/Common/Engine/Component.cs @@ -12,19 +12,9 @@ namespace MineCase.Engine { internal interface IComponentIntern { -#if ECS_SERVER - Task -#else - void -#endif - Attach(DependencyObject dependencyObject, ServiceProviderType serviceProvider); + void Attach(DependencyObject dependencyObject, ServiceProviderType serviceProvider); -#if ECS_SERVER - Task -#else - void -#endif - Detach(); + void Detach(); int GetMessageOrder(object message); } @@ -58,61 +48,34 @@ public Component(string name) Name = name; } -#if ECS_SERVER - Task -#else - void -#endif - IComponentIntern.Attach(DependencyObject dependencyObject, ServiceProviderType serviceProvider) + void 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() + void IComponentIntern.Detach() { - AttachedObject = null; -#if ECS_SERVER - return -#endif OnDetached(); + AttachedObject = null; } /// /// 组件被附加到实体时 /// - protected virtual - -#if ECS_SERVER - Task -#else - void -#endif - OnAttached() + protected virtual void OnAttached() { -#if ECS_SERVER - return Task.CompletedTask; -#endif } /// /// 组件从实体卸载时 /// - protected virtual Task OnDetached() + protected virtual void OnDetached() { - return Task.CompletedTask; } /// diff --git a/src/Common/Engine/Data/DependencyValueStorage.cs b/src/Common/Engine/Data/DependencyValueStorage.cs index e0c96203..6188bfb5 100644 --- a/src/Common/Engine/Data/DependencyValueStorage.cs +++ b/src/Common/Engine/Data/DependencyValueStorage.cs @@ -27,13 +27,7 @@ public IEnumerable Keys public bool IsDirty { get; set; } - public event -#if ECS_SERVER - AsyncEventHandler -#else - EventHandler -#endif - CurrentValueChanged; + public event EventHandler CurrentValueChanged; public DependencyValueStorage() { @@ -54,12 +48,7 @@ public DependencyValueStorage(Dictionary AddOrUpdate(IDependencyValueProvider provider, DependencyProperty key, Func> addValueFactory, Func, Task>> updateValueFactory) -#else - IEffectiveValue AddOrUpdate(IDependencyValueProvider provider, DependencyProperty key, Func> addValueFactory, Func, IEffectiveValue> updateValueFactory) -#endif + public IEffectiveValue AddOrUpdate(IDependencyValueProvider provider, DependencyProperty key, Func> addValueFactory, Func, IEffectiveValue> updateValueFactory) { var storage = GetStorage(provider, key); var priority = provider.Priority; @@ -70,43 +59,30 @@ IEffectiveValue AddOrUpdate(IDependencyValueProvider provider, DependencyProp var value = addValueFactory(key); storage.Add(priority, value); value.ValueChanged = (s, e) => OnEffectiveValueChanged(priority, key, e.OldValue, e.NewValue); + IsDirty = true; result = value; var raiseChanged = storage.IndexOfKey(priority) == 0; if (raiseChanged) - { -#if ECS_SERVER - await -#endif OnCurrentValueChanged(key, false, null, true, value.Value); - } } else { var oldValue = (IEffectiveValue)storage.Values[oldIdx]; - var newValue = -#if ECS_SERVER - await -#endif - updateValueFactory(key, oldValue); + var newValue = updateValueFactory(key, oldValue); if (oldValue != newValue) { oldValue.ValueChanged = null; newValue.ValueChanged = (s, e) => OnEffectiveValueChanged(priority, key, e.OldValue, e.NewValue); storage[priority] = newValue; + IsDirty = true; var raiseChanged = oldIdx == 0; if (raiseChanged) - { -#if ECS_SERVER - await -#endif OnCurrentValueChanged(key, true, oldValue.Value, true, newValue.Value); - } } result = newValue; } - IsDirty = true; return result; } @@ -149,28 +125,12 @@ public bool TryGetCurrentEffectiveValue(DependencyProperty key, out IEffectiveVa return false; } - private -#if ECS_SERVER - Task -#else - void -#endif - OnCurrentValueChanged(DependencyProperty key, bool hasOldValue, object oldValue, bool hasNewValue, object newValue) + private void OnCurrentValueChanged(DependencyProperty key, bool hasOldValue, object oldValue, bool hasNewValue, object newValue) { - IsDirty = true; -#if ECS_SERVER - return -#endif CurrentValueChanged.InvokeSerial(this, new CurrentValueChangedEventArgs(key, hasOldValue, oldValue, hasNewValue, newValue)); } - private -#if ECS_SERVER - Task -#else - void -#endif - OnEffectiveValueCleared(int index, DependencyProperty key, object oldValue) + private void OnEffectiveValueCleared(int index, DependencyProperty key, object oldValue) { IsDirty = true; if (index == 0) @@ -184,37 +144,18 @@ public bool TryGetCurrentEffectiveValue(DependencyProperty key, out IEffectiveVa newValue = ((dynamic)list.Values[0]).Value; } -#if ECS_SERVER - return -#endif OnCurrentValueChanged(key, true, oldValue, hasNewValue, newValue); } - -#if ECS_SERVER - return Task.CompletedTask; -#endif } - private -#if ECS_SERVER - Task -#else - void -#endif - OnEffectiveValueChanged(float priority, DependencyProperty key, object oldValue, object newValue) + private void OnEffectiveValueChanged(float priority, DependencyProperty key, object oldValue, object newValue) { IsDirty = true; SortedList list; if (_dict.TryGetValue(key, out list) && list.IndexOfKey(priority) == 0) { -#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) @@ -231,13 +172,7 @@ public bool TryGetValue(IDependencyValueProvider provider, DependencyProperty return false; } - public -#if ECS_SERVER - Task -#else - bool -#endif - TryRemove(IDependencyValueProvider provider, DependencyProperty key, out IEffectiveValue value) + public bool TryRemove(IDependencyValueProvider provider, DependencyProperty key, out IEffectiveValue value) { var storage = GetStorage(provider, key); var priority = provider.Priority; @@ -247,21 +182,12 @@ public bool TryGetValue(IDependencyValueProvider provider, DependencyProperty 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) diff --git a/src/Common/Engine/Data/IDependencyValueStorage.cs b/src/Common/Engine/Data/IDependencyValueStorage.cs index 26e1f72f..39dafae7 100644 --- a/src/Common/Engine/Data/IDependencyValueStorage.cs +++ b/src/Common/Engine/Data/IDependencyValueStorage.cs @@ -18,13 +18,7 @@ public interface IDependencyValueStorage /// /// 当前值变更事件 /// - event -#if ECS_SERVER - AsyncEventHandler -#else - EventHandler -#endif - CurrentValueChanged; + event EventHandler CurrentValueChanged; /// /// 添加或更新 @@ -35,11 +29,7 @@ public interface IDependencyValueStorage /// 添加工厂 /// 更新工厂 /// 新的值 -#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 /// /// 尝试获取值 @@ -59,12 +49,7 @@ public interface IDependencyValueStorage /// 依赖属性 /// 值 /// 是否成功删除 -#if ECS_SERVER - Task -#else - bool -#endif - TryRemove(IDependencyValueProvider provider, DependencyProperty key, out IEffectiveValue value); + bool TryRemove(IDependencyValueProvider provider, DependencyProperty key, out IEffectiveValue value); /// /// 尝试获取当前值 diff --git a/src/Common/Engine/Data/IEffectiveValue.cs b/src/Common/Engine/Data/IEffectiveValue.cs index 00e534d3..ecf3a8c7 100644 --- a/src/Common/Engine/Data/IEffectiveValue.cs +++ b/src/Common/Engine/Data/IEffectiveValue.cs @@ -18,12 +18,7 @@ public interface IEffectiveValue /// /// 获取值改变处理器 /// -#if ECS_SERVER - AsyncEventHandler -#else - EventHandler -#endif - ValueChanged { set; } + EventHandler ValueChanged { set; } } /// @@ -46,12 +41,7 @@ public interface IEffectiveValue : IEffectiveValue /// 设置值 /// /// 值 -#if ECS_SERVER - Task -#else - void -#endif - SetValue(T value); + void SetValue(T value); } /// diff --git a/src/Common/Engine/Data/LocalDependencyValueExtensions.cs b/src/Common/Engine/Data/LocalDependencyValueExtensions.cs index 995bd5c7..9ff92c19 100644 --- a/src/Common/Engine/Data/LocalDependencyValueExtensions.cs +++ b/src/Common/Engine/Data/LocalDependencyValueExtensions.cs @@ -31,17 +31,8 @@ public static bool TryGetLocalValue(this DependencyObject d, DependencyProper /// 依赖对象 /// 依赖属性 /// 值 - public static -#if ECS_SERVER - Task -#else - void -#endif - SetLocalValue(this DependencyObject d, DependencyProperty property, T value) + public static void SetLocalValue(this DependencyObject d, DependencyProperty property, T value) { -#if ECS_SERVER - return -#endif LocalDependencyValueProvider.Current.SetValue(property, d.ValueStorage, value); } @@ -51,17 +42,8 @@ public static /// 值类型 /// 依赖对象 /// 依赖属性 - public static -#if ECS_SERVER - Task -#else - void -#endif - ClearLocalValue(this DependencyObject d, DependencyProperty property) + public static void 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 index f1c3652a..1bf81471 100644 --- a/src/Common/Engine/Data/LocalDependencyValueProvider.cs +++ b/src/Common/Engine/Data/LocalDependencyValueProvider.cs @@ -25,16 +25,6 @@ public class LocalDependencyValueProvider : IDependencyValueProvider /// 依赖属性 /// 值存储 /// 值 -#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) => @@ -43,7 +33,6 @@ public void SetValue(DependencyProperty property, IDependencyValueStorage return o; }); } -#endif /// /// 尝试获取值 @@ -72,18 +61,9 @@ public bool TryGetValue(DependencyProperty property, IDependencyValueStora /// 值类型 /// 依赖属性 /// 值存储 - public -#if ECS_SERVER - Task -#else - void -#endif - ClearValue(DependencyProperty property, IDependencyValueStorage storage) + public void ClearValue(DependencyProperty property, IDependencyValueStorage storage) { IEffectiveValue eValue; -#if ECS_SERVER - return -#endif storage.TryRemove(this, property, out eValue); } @@ -95,13 +75,7 @@ internal static IEffectiveValue FromValue(T value) internal class LocalEffectiveValue : IEffectiveValue { /// - public -#if ECS_SERVER - AsyncEventHandler -#else - EventHandler -#endif - ValueChanged { get; set; } + public EventHandler ValueChanged { get; set; } /// public bool CanSetValue => true; @@ -119,19 +93,12 @@ public LocalEffectiveValue(T 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)); } } diff --git a/src/Common/Engine/DependencyObject.cs b/src/Common/Engine/DependencyObject.cs index 526646bd..1af69290 100644 --- a/src/Common/Engine/DependencyObject.cs +++ b/src/Common/Engine/DependencyObject.cs @@ -77,22 +77,13 @@ public T GetUnityComponent() /// 设置组件 /// /// 组件 - public -#if ECS_SERVER - async Task -#else - void -#endif - SetComponent(Component component) + public void SetComponent(Component component) { var name = component.Name; if (_components.TryGetValue(name, out var old)) { if (old == component) return; Unsubscribe(old); -#if ECS_SERVER - await -#endif old.Detach(); _indexes.Remove(old); _components.Remove(name); @@ -100,9 +91,6 @@ async Task _components.Add(name, component); _indexes.Add(component, _index++); -#if ECS_SERVER - await -#endif ((IComponentIntern)component).Attach(this, ServiceProvider); Subscribe(component); } @@ -111,22 +99,13 @@ async Task /// 清除组件 /// /// 组件类型 - public -#if ECS_SERVER - async Task -#else - void -#endif - ClearComponent() + public void ClearComponent() where T : Component { var components = _components.Where(o => o.Value is T); foreach (var component in components) { Unsubscribe(component.Value); -#if ECS_SERVER - await -#endif component.Value.Detach(); _indexes.Remove(component.Value); _components.Remove(component.Key); @@ -142,8 +121,8 @@ async Task /// public IDependencyValueStorage ValueStorage => _valueStorage; - private readonly ConcurrentDictionary _propertyChangedHandlers = new ConcurrentDictionary(); - private readonly ConcurrentDictionary _propertyChangedHandlersGen = new ConcurrentDictionary(); + private readonly Dictionary _propertyChangedHandlers = new Dictionary(); + private readonly Dictionary _propertyChangedHandlersGen = new Dictionary(); private Delegate _anyPropertyChangedHandler; /// @@ -167,46 +146,24 @@ public T GetValue(DependencyProperty property) /// 值类型 /// 依赖属性 /// 值 - public -#if ECS_SERVER - Task -#else - void -#endif - SetCurrentValue(DependencyProperty property, T value) + public void SetCurrentValue(DependencyProperty property, T value) { IEffectiveValue eValue; if (_valueStorage.TryGetCurrentEffectiveValue(property, out eValue) && eValue.CanSetValue) { -#if ECS_SERVER - return -#endif eValue.SetValue(value); } else { -#if ECS_SERVER - return -#endif this.SetLocalValue(property, value); } } private static readonly MethodInfo _raisePropertyChangedHelper = typeof(DependencyObject).GetRuntimeMethods().Single(o => o.Name == nameof(RaisePropertyChangedHelper)); - private -#if ECS_SERVER - Task -#else - void -#endif - ValueStorage_CurrentValueChanged(object sender, CurrentValueChangedEventArgs e) + private void 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 } /// @@ -215,16 +172,13 @@ public T GetValue(DependencyProperty property) /// 值类型 /// 依赖属性 /// 处理器 - public void RegisterPropertyChangedHandler( - DependencyProperty property, -#if ECS_SERVER - AsyncEventHandler> -#else - EventHandler> -#endif - handler) + public void RegisterPropertyChangedHandler(DependencyProperty property, EventHandler> handler) { - _propertyChangedHandlers.AddOrUpdate(property, handler, (k, old) => Delegate.Combine(old, handler)); + if (_propertyChangedHandlers.TryGetValue(property, out var newHandler)) + newHandler = Delegate.Combine(newHandler, handler); + else + newHandler = handler; + _propertyChangedHandlers[property] = newHandler; } /// @@ -233,19 +187,15 @@ public void RegisterPropertyChangedHandler( /// 值类型 /// 依赖属性 /// 处理器 - public void RemovePropertyChangedHandler( - DependencyProperty property, -#if ECS_SERVER - AsyncEventHandler> -#else - EventHandler> -#endif - handler) + public void RemovePropertyChangedHandler(DependencyProperty property, EventHandler> handler) { - Delegate d = null; - _propertyChangedHandlers.TryRemove(property, out d); - if (d != (Delegate)handler) - _propertyChangedHandlers.AddOrUpdate(property, k => Delegate.Remove(d, handler), (k, old) => Delegate.Combine(old, Delegate.Remove(d, handler))); + if (_propertyChangedHandlers.TryGetValue(property, out var newHandler)) + newHandler = Delegate.Remove(newHandler, handler); + + if (newHandler == null) + _propertyChangedHandlers.Remove(property); + else + _propertyChangedHandlers[property] = newHandler; } /// @@ -253,16 +203,13 @@ public void RemovePropertyChangedHandler( /// /// 依赖属性 /// 处理器 - public void RegisterPropertyChangedHandler( - DependencyProperty property, -#if ECS_SERVER - AsyncEventHandler -#else - EventHandler -#endif - handler) + public void RegisterPropertyChangedHandler(DependencyProperty property, EventHandler handler) { - _propertyChangedHandlersGen.AddOrUpdate(property, handler, (k, old) => Delegate.Combine(old, handler)); + if (_propertyChangedHandlersGen.TryGetValue(property, out var newHandler)) + newHandler = Delegate.Combine(newHandler, handler); + else + newHandler = handler; + _propertyChangedHandlersGen[property] = newHandler; } /// @@ -270,32 +217,22 @@ public void RegisterPropertyChangedHandler( /// /// 依赖属性 /// 处理器 - public void RemovePropertyChangedHandler( - DependencyProperty property, -#if ECS_SERVER - AsyncEventHandler -#else - EventHandler -#endif - handler) + public void RemovePropertyChangedHandler(DependencyProperty property, EventHandler handler) { - Delegate d = null; - _propertyChangedHandlersGen.TryRemove(property, out d); - if (d != (Delegate)handler) - _propertyChangedHandlersGen.AddOrUpdate(property, k => Delegate.Remove(d, handler), (k, old) => Delegate.Combine(old, Delegate.Remove(d, handler))); + if (_propertyChangedHandlersGen.TryGetValue(property, out var newHandler)) + newHandler = Delegate.Remove(newHandler, handler); + + if (newHandler == null) + _propertyChangedHandlersGen.Remove(property); + else + _propertyChangedHandlersGen[property] = newHandler; } /// /// 注册任意属性变更处理器 /// /// 处理器 - public void RegisterAnyPropertyChangedHandler( -#if ECS_SERVER - AsyncEventHandler -#else - EventHandler -#endif - handler) + public void RegisterAnyPropertyChangedHandler(EventHandler handler) { _anyPropertyChangedHandler = Delegate.Combine(_anyPropertyChangedHandler, handler); } @@ -304,24 +241,12 @@ public void RegisterAnyPropertyChangedHandler( /// 删除任意属性变更处理器 /// /// 处理器 - public void RemoveAnyPropertyChangedHandler( -#if ECS_SERVER - AsyncEventHandler -#else - EventHandler -#endif - handler) + public void RemoveAnyPropertyChangedHandler(EventHandler handler) { _anyPropertyChangedHandler = Delegate.Remove(_anyPropertyChangedHandler, handler); } - internal -#if ECS_SERVER - async Task -#else - void -#endif - RaisePropertyChangedHelper(DependencyProperty property, CurrentValueChangedEventArgs e) + internal void RaisePropertyChangedHelper(DependencyProperty property, CurrentValueChangedEventArgs e) { var oldValue = e.HasOldValue ? (T)e.OldValue : GetDefaultValue(property); var newValue = e.HasNewValue ? (T)e.NewValue : GetDefaultValue(property); @@ -330,17 +255,8 @@ async Task return; var args = new PropertyChangedEventArgs(property, oldValue, newValue); -#if ECS_SERVER - await -#endif property.RaisePropertyChanged(_realType, this, args); -#if ECS_SERVER - await -#endif InvokeLocalPropertyChangedHandlers(args); -#if ECS_SERVER - await -#endif OnDependencyPropertyChanged(args); } @@ -349,29 +265,10 @@ async Task /// /// 值类型 /// 参数 -#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; - if (_propertyChangedHandlers.TryGetValue(e.Property, out d)) - await ((AsyncEventHandler>)d).InvokeSerial(this, e); - - if (_propertyChangedHandlersGen.TryGetValue(e.Property, out d)) - await ((AsyncEventHandler)d).InvokeSerial(this, e); - await ((AsyncEventHandler)_anyPropertyChangedHandler).InvokeSerial(this, e); - } -#else private void InvokeLocalPropertyChangedHandlers(PropertyChangedEventArgs e) { Delegate d; @@ -382,7 +279,6 @@ private void InvokeLocalPropertyChangedHandlers(PropertyChangedEventArgs e ((EventHandler)d).InvokeSerial(this, e); ((EventHandler)_anyPropertyChangedHandler).InvokeSerial(this, e); } -#endif private T GetDefaultValue(DependencyProperty property) { diff --git a/src/Common/Engine/DependencyProperty.cs b/src/Common/Engine/DependencyProperty.cs index 7bfc92a3..ab48c475 100644 --- a/src/Common/Engine/DependencyProperty.cs +++ b/src/Common/Engine/DependencyProperty.cs @@ -334,17 +334,8 @@ public bool TryGetDefaultValue(DependencyObject d, Type type, out T value) return GetMetadata(type).TryGetDefaultValue(d, this, out value); } - internal -#if ECS_SERVER - Task -#else - void -#endif - RaisePropertyChanged(Type type, object sender, PropertyChangedEventArgs e) + internal void RaisePropertyChanged(Type type, object sender, PropertyChangedEventArgs e) { -#if ECS_SERVER - return -#endif GetMetadata(type).RaisePropertyChanged(sender, e); } diff --git a/src/Common/Engine/PropertyMetadata.cs b/src/Common/Engine/PropertyMetadata.cs index af198c94..7ff68ca1 100644 --- a/src/Common/Engine/PropertyMetadata.cs +++ b/src/Common/Engine/PropertyMetadata.cs @@ -27,27 +27,14 @@ public class PropertyMetadata /// /// 属性更改事件 /// - public event -#if ECS_SERVER - AsyncEventHandler> -#else - EventHandler> -#endif - PropertyChanged; + public event EventHandler> PropertyChanged; /// /// Initializes a new instance of the class. /// /// 默认值 /// 属性更改处理器 - public PropertyMetadata( - T defaultValue, -#if ECS_SERVER - AsyncEventHandler> -#else - EventHandler> -#endif - propertyChangedHandler = null) + public PropertyMetadata(T defaultValue, EventHandler> propertyChangedHandler = null) { _defaultValue = defaultValue; _defaultValueSet = true; @@ -60,14 +47,7 @@ public PropertyMetadata( /// /// 未设置默认值 /// 属性更改处理器 - public PropertyMetadata( - DependencyProperty.UnsetValueType unsetValue, -#if ECS_SERVER - AsyncEventHandler> -#else - EventHandler> -#endif - propertyChangedHandler = null) + public PropertyMetadata(DependencyProperty.UnsetValueType unsetValue, EventHandler> propertyChangedHandler = null) { _defaultValueSet = false; if (propertyChangedHandler != null) @@ -107,35 +87,20 @@ protected virtual bool TryGetDefaultValueOverride(DependencyObject d, Dependency return false; } -#if ECS_SERVER - internal async Task RaisePropertyChanged(object sender, PropertyChangedEventArgs e) - { - await OnPropertyChanged(sender, e); - await PropertyChanged.InvokeSerial(sender, e); - } -#else internal void RaisePropertyChanged(object sender, PropertyChangedEventArgs e) { OnPropertyChanged(sender, e); PropertyChanged.InvokeSerial(sender, e); } -#endif /// /// 当属性修改时 /// /// 发送方 /// 参数 -#if ECS_SERVER - protected virtual Task OnPropertyChanged(object sender, PropertyChangedEventArgs e) - { - return Task.CompletedTask; - } -#else protected virtual void OnPropertyChanged(object sender, PropertyChangedEventArgs e) { } -#endif /// /// 合并属性元数据 @@ -155,13 +120,7 @@ internal void Merge(PropertyMetadata old, bool ownerIsDerived) if (ownerIsDerived) { - PropertyChanged = -#if ECS_SERVER - (AsyncEventHandler> -#else - (EventHandler> -#endif -)Delegate.Combine(old.PropertyChanged, PropertyChanged); + PropertyChanged = (EventHandler>)Delegate.Combine(old.PropertyChanged, PropertyChanged); } MergeOverride(old); diff --git a/src/MineCase.Algorithm/Game/Entity/Ai/MobAi/CreatureAi.cs b/src/MineCase.Algorithm/Game/Entity/Ai/MobAi/CreatureAi.cs index b8b342ae..7d401edc 100644 --- a/src/MineCase.Algorithm/Game/Entity/Ai/MobAi/CreatureAi.cs +++ b/src/MineCase.Algorithm/Game/Entity/Ai/MobAi/CreatureAi.cs @@ -22,8 +22,8 @@ public CreatureAi(Func getter, Action setter) _stateMachine = stateMachine; } - public Task FireAsync(CreatureEvent @event) => - _stateMachine.FireAsync(@event); + public void Fire(CreatureEvent @event) => + _stateMachine.Fire(@event); protected abstract void Configure(StateMachine stateMachine); } diff --git a/src/MineCase.Engine/DependencyObject.Server.cs b/src/MineCase.Engine/DependencyObject.Server.cs index b2616488..2c8b3502 100644 --- a/src/MineCase.Engine/DependencyObject.Server.cs +++ b/src/MineCase.Engine/DependencyObject.Server.cs @@ -18,9 +18,9 @@ public partial class DependencyObject public override async Task OnActivateAsync() { Logger = ServiceProvider.GetRequiredService().CreateLogger(GetType()); - await InitializePreLoadComponent(); + InitializePreLoadComponent(); await ReadStateAsync(); - await InitializeComponents(); + InitializeComponents(); } public override async Task OnDeactivateAsync() @@ -35,14 +35,12 @@ public void Destroy() DeactivateOnIdle(); } - protected virtual Task InitializeComponents() + protected virtual void InitializeComponents() { - return Task.CompletedTask; } - protected virtual Task InitializePreLoadComponent() + protected virtual void InitializePreLoadComponent() { - return Task.CompletedTask; } public async Task ReadStateAsync() diff --git a/src/MineCase.Gateway/Program.cs b/src/MineCase.Gateway/Program.cs index 842cf499..7d1ce730 100644 --- a/src/MineCase.Gateway/Program.cs +++ b/src/MineCase.Gateway/Program.cs @@ -26,6 +26,7 @@ static void Main(string[] args) Configuration = LoadConfiguration(); Startup(); _exitEvent.WaitOne(); + _clusterClient?.Dispose(); } private static void ConfigureApplicationParts(IClientBuilder builder) @@ -44,6 +45,7 @@ private static async void Startup() (ex, timeSpan) => logger?.LogError($"Cluster connection failed. Next retry: {timeSpan.TotalSeconds} secs later.")); await retryPolicy.ExecuteAsync(async () => { + _clusterClient?.Dispose(); var builder = new ClientBuilder() .LoadConfiguration("OrleansConfiguration.dev.xml") .ConfigureServices(ConfigureServices) diff --git a/src/MineCase.Server.Grains/Components/AddressByPartitionKeyComponent.cs b/src/MineCase.Server.Grains/Components/AddressByPartitionKeyComponent.cs index d89b1afc..7f94d0e0 100644 --- a/src/MineCase.Server.Grains/Components/AddressByPartitionKeyComponent.cs +++ b/src/MineCase.Server.Grains/Components/AddressByPartitionKeyComponent.cs @@ -14,37 +14,33 @@ internal class AddressByPartitionKeyComponent : Component public static readonly DependencyProperty AddressByPartitionKeyProperty = DependencyProperty.Register("AddressByPartitionKey", typeof(AddressByPartitionKeyComponent), new PropertyMetadata(string.Empty, OnAddressByPartitionKeyChanged)); - public event AsyncEventHandler<(string oldKey, string newKey)> KeyChanged; + public event EventHandler<(string oldKey, string newKey)> KeyChanged; public AddressByPartitionKeyComponent(string name = "addressByPartitionKey") : base(name) { } - protected override Task OnAttached() + protected override void OnAttached() { AttachedObject.RegisterPropertyChangedHandler(WorldComponent.WorldProperty, OnWorldChanged); AttachedObject.RegisterPropertyChangedHandler(EntityWorldPositionComponent.EntityWorldPositionProperty, OnEntityWorldPositionChanged); AttachedObject.RegisterPropertyChangedHandler(BlockWorldPositionComponent.BlockWorldPositionProperty, OnBlockWorldPositionChanged); - return Task.CompletedTask; } - private Task OnBlockWorldPositionChanged(object sender, PropertyChangedEventArgs e) + private void OnBlockWorldPositionChanged(object sender, PropertyChangedEventArgs e) { UpdateKey(); - return Task.CompletedTask; } - private Task OnWorldChanged(object sender, PropertyChangedEventArgs e) + private void OnWorldChanged(object sender, PropertyChangedEventArgs e) { UpdateKey(); - return Task.CompletedTask; } - private Task OnEntityWorldPositionChanged(object sender, PropertyChangedEventArgs e) + private void OnEntityWorldPositionChanged(object sender, PropertyChangedEventArgs e) { UpdateKey(); - return Task.CompletedTask; } private void UpdateKey() @@ -65,11 +61,11 @@ private void UpdateKey() } } - private static async Task OnAddressByPartitionKeyChanged(object sender, PropertyChangedEventArgs e) + private static void OnAddressByPartitionKeyChanged(object sender, PropertyChangedEventArgs e) { var component = ((DependencyObject)sender).GetComponent(); if (component != null) - await component.KeyChanged.InvokeSerial(sender, (e.OldValue, e.NewValue)); + component.KeyChanged?.Invoke(sender, (e.OldValue, e.NewValue)); } } diff --git a/src/MineCase.Server.Grains/Components/BlockWorldPositionComponent.cs b/src/MineCase.Server.Grains/Components/BlockWorldPositionComponent.cs index 30d0bb15..c8fdd694 100644 --- a/src/MineCase.Server.Grains/Components/BlockWorldPositionComponent.cs +++ b/src/MineCase.Server.Grains/Components/BlockWorldPositionComponent.cs @@ -19,7 +19,7 @@ public BlockWorldPositionComponent(string name = "blockWorldPosition") { } - public Task SetBlockWorldPosition(BlockWorldPos value) => + public void SetBlockWorldPosition(BlockWorldPos value) => AttachedObject.SetLocalValue(BlockWorldPositionProperty, value); } } diff --git a/src/MineCase.Server.Grains/Components/EntityIdComponent.cs b/src/MineCase.Server.Grains/Components/EntityIdComponent.cs index 4625466b..f1a85e89 100644 --- a/src/MineCase.Server.Grains/Components/EntityIdComponent.cs +++ b/src/MineCase.Server.Grains/Components/EntityIdComponent.cs @@ -21,7 +21,8 @@ public EntityIdComponent(string name = "entityId") Task IHandle.Handle(SpawnEntity message) { - return AttachedObject.SetLocalValue(EntityIdProperty, message.EntityId); + AttachedObject.SetLocalValue(EntityIdProperty, message.EntityId); + return Task.CompletedTask; } } } diff --git a/src/MineCase.Server.Grains/Components/EntityLookComponent.cs b/src/MineCase.Server.Grains/Components/EntityLookComponent.cs index e04a2e7f..56e81e23 100644 --- a/src/MineCase.Server.Grains/Components/EntityLookComponent.cs +++ b/src/MineCase.Server.Grains/Components/EntityLookComponent.cs @@ -29,13 +29,13 @@ public EntityLookComponent(string name = "entityLook") { } - public Task SetPitch(float value) => + public void SetPitch(float value) => AttachedObject.SetLocalValue(PitchProperty, value); - public Task SetYaw(float value) => + public void SetYaw(float value) => AttachedObject.SetLocalValue(YawProperty, value); - public Task SetHeadYaw(float value) => + public void SetHeadYaw(float value) => AttachedObject.SetLocalValue(HeadYawProperty, value); } } diff --git a/src/MineCase.Server.Grains/Components/EntityOnGroundComponent.cs b/src/MineCase.Server.Grains/Components/EntityOnGroundComponent.cs index acd89404..2b5832d4 100644 --- a/src/MineCase.Server.Grains/Components/EntityOnGroundComponent.cs +++ b/src/MineCase.Server.Grains/Components/EntityOnGroundComponent.cs @@ -18,7 +18,7 @@ public EntityOnGroundComponent(string name = "isOnGround") { } - public Task SetIsOnGround(bool value) => + public void SetIsOnGround(bool value) => AttachedObject.SetLocalValue(IsOnGroundProperty, value); } } diff --git a/src/MineCase.Server.Grains/Components/EntityWorldPositionComponent.cs b/src/MineCase.Server.Grains/Components/EntityWorldPositionComponent.cs index 417c37ac..349410d1 100644 --- a/src/MineCase.Server.Grains/Components/EntityWorldPositionComponent.cs +++ b/src/MineCase.Server.Grains/Components/EntityWorldPositionComponent.cs @@ -18,7 +18,7 @@ public EntityWorldPositionComponent(string name = "entityWorldPosition") { } - public Task SetPosition(EntityWorldPos entityWorldPos) + public void SetPosition(EntityWorldPos entityWorldPos) => AttachedObject.SetLocalValue(EntityWorldPositionProperty, entityWorldPos); } diff --git a/src/MineCase.Server.Grains/Components/GameTickComponent.cs b/src/MineCase.Server.Grains/Components/GameTickComponent.cs index 73d09a8d..d75844f6 100644 --- a/src/MineCase.Server.Grains/Components/GameTickComponent.cs +++ b/src/MineCase.Server.Grains/Components/GameTickComponent.cs @@ -19,35 +19,37 @@ public GameTickComponent(string name = "gameTick") { } - protected override Task OnAttached() + protected override void OnAttached() { AttachedObject.GetComponent() .KeyChanged += OnAddressByPartitionKeyChanged; AttachedObject.RegisterPropertyChangedHandler(IsEnabledComponent.IsEnabledProperty, OnIsEnabledChanged); AttachedObject.QueueOperation(TrySubscribe); - return base.OnAttached(); } - protected override async Task OnDetached() + protected override void OnDetached() { AttachedObject.GetComponent() .KeyChanged -= OnAddressByPartitionKeyChanged; - await TryUnsubscribe(); + AttachedObject.QueueOperation(TryUnsubscribe); } - private async Task OnAddressByPartitionKeyChanged(object sender, (string oldKey, string newKey) e) + private void OnAddressByPartitionKeyChanged(object sender, (string oldKey, string newKey) e) { - if (!string.IsNullOrEmpty(e.oldKey)) - await GrainFactory.GetGrain(e.oldKey).Unsubscribe(AttachedObject); - await TrySubscribe(); + AttachedObject.QueueOperation(async () => + { + if (!string.IsNullOrEmpty(e.oldKey)) + await GrainFactory.GetGrain(e.oldKey).Unsubscribe(AttachedObject); + await TrySubscribe(); + }); } - private Task OnIsEnabledChanged(object sender, PropertyChangedEventArgs e) + private void OnIsEnabledChanged(object sender, PropertyChangedEventArgs e) { if (e.NewValue) - return TrySubscribe(); + AttachedObject.QueueOperation(TrySubscribe); else - return TryUnsubscribe(); + AttachedObject.QueueOperation(TryUnsubscribe); } public Task OnGameTick(GameTickArgs e) diff --git a/src/MineCase.Server.Grains/Components/IsEnabledComponent.cs b/src/MineCase.Server.Grains/Components/IsEnabledComponent.cs index 94fb0557..bd859e21 100644 --- a/src/MineCase.Server.Grains/Components/IsEnabledComponent.cs +++ b/src/MineCase.Server.Grains/Components/IsEnabledComponent.cs @@ -20,12 +20,14 @@ public IsEnabledComponent(string name = "isEnabled") Task IHandle.Handle(Enable message) { - return AttachedObject.SetLocalValue(IsEnabledProperty, true); + AttachedObject.SetLocalValue(IsEnabledProperty, true); + return Task.CompletedTask; } Task IHandle.Handle(Disable message) { - return AttachedObject.SetLocalValue(IsEnabledProperty, false); + AttachedObject.SetLocalValue(IsEnabledProperty, false); + return Task.CompletedTask; } } } diff --git a/src/MineCase.Server.Grains/Components/NameComponent.cs b/src/MineCase.Server.Grains/Components/NameComponent.cs index 2be0366e..6976b865 100644 --- a/src/MineCase.Server.Grains/Components/NameComponent.cs +++ b/src/MineCase.Server.Grains/Components/NameComponent.cs @@ -18,7 +18,7 @@ public NameComponent(string name = "name") { } - public Task SetName(string value) => + public void SetName(string value) => AttachedObject.SetLocalValue(NameProperty, value); } } diff --git a/src/MineCase.Server.Grains/Components/WorldComponent.cs b/src/MineCase.Server.Grains/Components/WorldComponent.cs index 089affb1..d406eb4f 100644 --- a/src/MineCase.Server.Grains/Components/WorldComponent.cs +++ b/src/MineCase.Server.Grains/Components/WorldComponent.cs @@ -17,7 +17,7 @@ public WorldComponent(string name = "world") { } - public Task SetWorld(IWorld value) => + public void SetWorld(IWorld value) => AttachedObject.SetLocalValue(WorldProperty, value); } diff --git a/src/MineCase.Server.Grains/Game/BlockEntities/BlockEntityGrain.cs b/src/MineCase.Server.Grains/Game/BlockEntities/BlockEntityGrain.cs index c09c1887..132f2493 100644 --- a/src/MineCase.Server.Grains/Game/BlockEntities/BlockEntityGrain.cs +++ b/src/MineCase.Server.Grains/Game/BlockEntities/BlockEntityGrain.cs @@ -22,16 +22,16 @@ internal abstract class BlockEntityGrain : PersistableDependencyObject, IBlockEn public BlockWorldPos Position => GetValue(BlockWorldPositionComponent.BlockWorldPositionProperty); - protected override async Task InitializeComponents() + protected override void InitializeComponents() { - await SetComponent(new IsEnabledComponent()); - await SetComponent(new WorldComponent()); - await SetComponent(new BlockWorldPositionComponent()); - await SetComponent(new AddressByPartitionKeyComponent()); - await SetComponent(new ChunkEventBroadcastComponent()); - await SetComponent(new GameTickComponent()); - await SetComponent(new BlockEntityLiftTimeComponent()); - await SetComponent(new AutoSaveStateComponent(AutoSaveStateComponent.PerMinute)); + SetComponent(new IsEnabledComponent()); + SetComponent(new WorldComponent()); + SetComponent(new BlockWorldPositionComponent()); + SetComponent(new AddressByPartitionKeyComponent()); + SetComponent(new ChunkEventBroadcastComponent()); + SetComponent(new GameTickComponent()); + SetComponent(new BlockEntityLiftTimeComponent()); + SetComponent(new AutoSaveStateComponent(AutoSaveStateComponent.PerMinute)); } Task IBlockEntity.GetWorld() => diff --git a/src/MineCase.Server.Grains/Game/BlockEntities/ChestBlockEntityGrain.cs b/src/MineCase.Server.Grains/Game/BlockEntities/ChestBlockEntityGrain.cs index 2d63813f..65ad0f08 100644 --- a/src/MineCase.Server.Grains/Game/BlockEntities/ChestBlockEntityGrain.cs +++ b/src/MineCase.Server.Grains/Game/BlockEntities/ChestBlockEntityGrain.cs @@ -16,11 +16,11 @@ namespace MineCase.Server.Game.BlockEntities [Reentrant] internal class ChestBlockEntityGrain : BlockEntityGrain, IChestBlockEntity { - protected override async Task InitializeComponents() + protected override void InitializeComponents() { - await base.InitializeComponents(); - await SetComponent(new SlotContainerComponent(ChestSlotArea.ChestSlotsCount)); - await SetComponent(new ChestComponent()); + base.InitializeComponents(); + SetComponent(new SlotContainerComponent(ChestSlotArea.ChestSlotsCount)); + SetComponent(new ChestComponent()); } } } diff --git a/src/MineCase.Server.Grains/Game/BlockEntities/Components/BlockEntityLiftTimeComponent.cs b/src/MineCase.Server.Grains/Game/BlockEntities/Components/BlockEntityLiftTimeComponent.cs index 6cdf2185..9b4f7ebf 100644 --- a/src/MineCase.Server.Grains/Game/BlockEntities/Components/BlockEntityLiftTimeComponent.cs +++ b/src/MineCase.Server.Grains/Game/BlockEntities/Components/BlockEntityLiftTimeComponent.cs @@ -14,16 +14,17 @@ public BlockEntityLiftTimeComponent(string name = "blockEntityLifeTime") { } - async Task IHandle.Handle(SpawnBlockEntity message) + Task IHandle.Handle(SpawnBlockEntity message) { - await AttachedObject.GetComponent().SetWorld(message.World); - await AttachedObject.GetComponent().SetBlockWorldPosition(message.Position); + AttachedObject.GetComponent().SetWorld(message.World); + AttachedObject.GetComponent().SetBlockWorldPosition(message.Position); AttachedObject.QueueOperation(async () => { await AttachedObject.Tell(Enable.Default); if (AttachedObject.ValueStorage.IsDirty) await AttachedObject.WriteStateAsync(); }); + return Task.CompletedTask; } Task IHandle.Handle(DestroyBlockEntity message) diff --git a/src/MineCase.Server.Grains/Game/BlockEntities/Components/ChestComponent.cs b/src/MineCase.Server.Grains/Game/BlockEntities/Components/ChestComponent.cs index fa801a89..576981e1 100644 --- a/src/MineCase.Server.Grains/Game/BlockEntities/Components/ChestComponent.cs +++ b/src/MineCase.Server.Grains/Game/BlockEntities/Components/ChestComponent.cs @@ -29,23 +29,32 @@ public ChestComponent(string name = "chest") { } - Task IHandle.Handle(NeighborEntityChanged message) => + Task IHandle.Handle(NeighborEntityChanged message) + { AttachedObject.SetLocalValue(NeighborEntityProperty, message.Entity); + return Task.CompletedTask; + } - private static async Task OnNeighborEntityChanged(object sender, PropertyChangedEventArgs e) + private static void OnNeighborEntityChanged(object sender, PropertyChangedEventArgs e) { var component = ((DependencyObject)sender).GetComponent(); var window = component?.ChestWindow; if (window == null) return; if (e.NewValue == null) { - await window.Destroy(); - await window.SetEntities(new[] { component.AttachedObject.AsReference() }.AsImmutable()); + component.AttachedObject.QueueOperation(async () => + { + await window.Destroy(); + await window.SetEntities(new[] { component.AttachedObject.AsReference() }.AsImmutable()); + }); } else { - await window.Destroy(); - await window.SetEntities(new[] { component.AttachedObject.AsReference(), e.NewValue.AsReference() }.AsImmutable()); + component.AttachedObject.QueueOperation(async () => + { + await window.Destroy(); + await window.SetEntities(new[] { component.AttachedObject.AsReference(), e.NewValue.AsReference() }.AsImmutable()); + }); } } @@ -62,7 +71,7 @@ async Task IHandle.Handle(UseBy message) { if (ChestWindow == null) { - await AttachedObject.SetLocalValue(ChestWindowProperty, GrainFactory.GetGrain(Guid.NewGuid())); + AttachedObject.SetLocalValue(ChestWindowProperty, GrainFactory.GetGrain(Guid.NewGuid())); await ChestWindow.SetEntities((NeighborEntity == null ? new[] { AttachedObject.AsReference() } : new[] { AttachedObject.AsReference(), NeighborEntity }).AsImmutable()); diff --git a/src/MineCase.Server.Grains/Game/BlockEntities/Components/FurnaceComponent.cs b/src/MineCase.Server.Grains/Game/BlockEntities/Components/FurnaceComponent.cs index 566e56b7..c232eefb 100644 --- a/src/MineCase.Server.Grains/Game/BlockEntities/Components/FurnaceComponent.cs +++ b/src/MineCase.Server.Grains/Game/BlockEntities/Components/FurnaceComponent.cs @@ -46,7 +46,7 @@ public FurnaceComponent(string name = "furnace") { } - protected override Task OnAttached() + protected override void OnAttached() { if (State == null) { @@ -57,7 +57,6 @@ protected override Task OnAttached() } Register(); - return base.OnAttached(); } private bool CanCook() @@ -114,7 +113,7 @@ async Task IHandle.Handle(SetSlot message) private Slot GetSlot(int index) => AttachedObject.GetComponent().GetSlot(index); - private Task SetSlot(int index, Slot slot) => + private void SetSlot(int index, Slot slot) => AttachedObject.GetComponent().SetSlot(index, slot); private async Task UpdateFuel() @@ -143,9 +142,9 @@ private async Task Produce() { var state = State; if (GetSlot(2).IsEmpty) - await SetSlot(2, state.CurrentRecipe.Output); + SetSlot(2, state.CurrentRecipe.Output); else - await SetSlot(2, GetSlot(2).AddItemCount(state.CurrentRecipe.Output.ItemCount)); + SetSlot(2, GetSlot(2).AddItemCount(state.CurrentRecipe.Output.ItemCount)); state.CookProgress = 0; MarkDirty(); if (FurnaceWindow != null) @@ -160,7 +159,7 @@ private async Task TakeFuel() var state = State; var slot = GetSlot(1).AddItemCount(-state.CurrentFuel.Slot.ItemCount); slot.MakeEmptyIfZero(); - await SetSlot(1, slot); + SetSlot(1, slot); state.MaxFuelTime = state.FuelLeft = state.CurrentFuel.Time; MarkDirty(); if (FurnaceWindow != null) @@ -181,7 +180,7 @@ private async Task TakeIngredient() { var slot = GetSlot(0).AddItemCount(-state.CurrentRecipe.Input.ItemCount); slot.MakeEmptyIfZero(); - await SetSlot(0, slot); + SetSlot(0, slot); state.CookProgress = 0; state.MaxProgress = state.CurrentRecipe.Time; MarkDirty(); @@ -242,7 +241,7 @@ async Task IHandle.Handle(UseBy message) { if (FurnaceWindow == null) { - await AttachedObject.SetLocalValue(FurnaceWindowProperty, GrainFactory.GetGrain(Guid.NewGuid())); + AttachedObject.SetLocalValue(FurnaceWindowProperty, GrainFactory.GetGrain(Guid.NewGuid())); await FurnaceWindow.SetEntity(AttachedObject); } diff --git a/src/MineCase.Server.Grains/Game/BlockEntities/FurnaceBlockEntity.cs b/src/MineCase.Server.Grains/Game/BlockEntities/FurnaceBlockEntity.cs index 571fbbf1..92be1493 100644 --- a/src/MineCase.Server.Grains/Game/BlockEntities/FurnaceBlockEntity.cs +++ b/src/MineCase.Server.Grains/Game/BlockEntities/FurnaceBlockEntity.cs @@ -18,11 +18,11 @@ namespace MineCase.Server.Game.BlockEntities [Reentrant] internal class FurnaceBlockEntity : BlockEntityGrain, IFurnaceBlockEntity { - protected override async Task InitializeComponents() + protected override void InitializeComponents() { - await base.InitializeComponents(); - await SetComponent(new SlotContainerComponent(FurnaceSlotArea.FurnaceSlotsCount)); - await SetComponent(new FurnaceComponent()); + base.InitializeComponents(); + SetComponent(new SlotContainerComponent(FurnaceSlotArea.FurnaceSlotsCount)); + SetComponent(new FurnaceComponent()); } } } diff --git a/src/MineCase.Server.Grains/Game/Entities/Components/ActiveWorldPartitionComponent.cs b/src/MineCase.Server.Grains/Game/Entities/Components/ActiveWorldPartitionComponent.cs index 4320076f..767417a2 100644 --- a/src/MineCase.Server.Grains/Game/Entities/Components/ActiveWorldPartitionComponent.cs +++ b/src/MineCase.Server.Grains/Game/Entities/Components/ActiveWorldPartitionComponent.cs @@ -15,26 +15,27 @@ public ActiveWorldPartitionComponent(string name = "activeWorldPartition") { } - protected override Task OnAttached() + protected override void OnAttached() { AttachedObject.GetComponent() .KeyChanged += ActiveWorldPartitionComponent_KeyChanged; - return base.OnAttached(); } - protected override Task OnDetached() + protected override void OnDetached() { AttachedObject.GetComponent() .KeyChanged -= ActiveWorldPartitionComponent_KeyChanged; - return base.OnDetached(); } - private async Task ActiveWorldPartitionComponent_KeyChanged(object sender, (string oldKey, string newKey) e) + private void ActiveWorldPartitionComponent_KeyChanged(object sender, (string oldKey, string newKey) e) { - if (!string.IsNullOrEmpty(e.oldKey)) - await GrainFactory.GetGrain(e.oldKey).Leave(AttachedObject); - if (!string.IsNullOrEmpty(e.newKey)) - await GrainFactory.GetGrain(e.newKey).Enter(AttachedObject); + AttachedObject.QueueOperation(async () => + { + if (!string.IsNullOrEmpty(e.oldKey)) + await GrainFactory.GetGrain(e.oldKey).Leave(AttachedObject); + if (!string.IsNullOrEmpty(e.newKey)) + await GrainFactory.GetGrain(e.newKey).Enter(AttachedObject); + }); } } } diff --git a/src/MineCase.Server.Grains/Game/Entities/Components/ChunkLoaderComponent.cs b/src/MineCase.Server.Grains/Game/Entities/Components/ChunkLoaderComponent.cs index e4979093..d575f2a3 100644 --- a/src/MineCase.Server.Grains/Game/Entities/Components/ChunkLoaderComponent.cs +++ b/src/MineCase.Server.Grains/Game/Entities/Components/ChunkLoaderComponent.cs @@ -20,13 +20,12 @@ public ChunkLoaderComponent(string name = "chunkLoader") { } - protected override Task OnAttached() + protected override void OnAttached() { _loaded = false; _chunkLoader = GrainFactory.GetGrain(AttachedObject.GetPrimaryKey()); AttachedObject.RegisterPropertyChangedHandler(ViewDistanceComponent.ViewDistanceProperty, OnViewDistanceChanged); AttachedObject.GetComponent().Tick += OnGameTick; - return base.OnAttached(); } private Task OnGameTick(object sender, GameTickArgs e) @@ -36,9 +35,9 @@ private Task OnGameTick(object sender, GameTickArgs e) return Task.CompletedTask; } - private Task OnViewDistanceChanged(object sender, PropertyChangedEventArgs e) + private void OnViewDistanceChanged(object sender, PropertyChangedEventArgs e) { - return _chunkLoader.SetViewDistance(e.NewValue); + AttachedObject.QueueOperation(() => _chunkLoader.SetViewDistance(e.NewValue)); } async Task IHandle.Handle(PlayerLoggedIn message) diff --git a/src/MineCase.Server.Grains/Game/Entities/Components/ColliderComponent.cs b/src/MineCase.Server.Grains/Game/Entities/Components/ColliderComponent.cs index 60fbdb78..11d84ef0 100644 --- a/src/MineCase.Server.Grains/Game/Entities/Components/ColliderComponent.cs +++ b/src/MineCase.Server.Grains/Game/Entities/Components/ColliderComponent.cs @@ -22,55 +22,57 @@ public ColliderComponent(string name = "collider") { } - protected override Task OnAttached() + protected override void OnAttached() { AttachedObject.GetComponent() .KeyChanged += AddressByPartitionKeyChanged; AttachedObject.RegisterPropertyChangedHandler(IsEnabledComponent.IsEnabledProperty, OnIsEnabledChanged); AttachedObject.QueueOperation(TrySubscribe); - return base.OnAttached(); } - protected override async Task OnDetached() + protected override void OnDetached() { AttachedObject.GetComponent() .KeyChanged -= AddressByPartitionKeyChanged; - await TryUnsubscribe(); + AttachedObject.QueueOperation(TryUnsubscribe); } - private async Task AddressByPartitionKeyChanged(object sender, (string oldKey, string newKey) e) + private void AddressByPartitionKeyChanged(object sender, (string oldKey, string newKey) e) { - var shape = ColliderShape; - if (!string.IsNullOrEmpty(e.oldKey)) - await GrainFactory.GetGrain(e.oldKey).UnregisterCollider(AttachedObject); - await TrySubscribe(); + AttachedObject.QueueOperation(async () => + { + var shape = ColliderShape; + if (!string.IsNullOrEmpty(e.oldKey)) + await GrainFactory.GetGrain(e.oldKey).UnregisterCollider(AttachedObject); + await TrySubscribe(); + }); } - private Task OnIsEnabledChanged(object sender, PropertyChangedEventArgs e) + private void OnIsEnabledChanged(object sender, PropertyChangedEventArgs e) { if (e.NewValue) - return TrySubscribe(); + AttachedObject.QueueOperation(TrySubscribe); else - return TryUnsubscribe(); + AttachedObject.QueueOperation(TryUnsubscribe); } - private async Task OnColliderShapeChanged(PropertyChangedEventArgs e) + private void OnColliderShapeChanged(PropertyChangedEventArgs e) { var shape = ColliderShape; var key = AttachedObject.GetValue(AddressByPartitionKeyComponent.AddressByPartitionKeyProperty); if (shape != null) - await GrainFactory.GetGrain(key).RegisterCollider(AttachedObject, shape); + AttachedObject.QueueOperation(() => GrainFactory.GetGrain(key).RegisterCollider(AttachedObject, shape)); else - await TrySubscribe(); + AttachedObject.QueueOperation(TrySubscribe); } - private static Task OnColliderShapeChanged(object sender, PropertyChangedEventArgs e) + private static void OnColliderShapeChanged(object sender, PropertyChangedEventArgs e) { var component = ((DependencyObject)sender).GetComponent(); - return component.OnColliderShapeChanged(e); + component.OnColliderShapeChanged(e); } - public Task SetColliderShape(Shape value) => + public void SetColliderShape(Shape value) => AttachedObject.SetLocalValue(ColliderShapeProperty, value); private async Task TrySubscribe() diff --git a/src/MineCase.Server.Grains/Game/Entities/Components/DiscoveryRegisterComponent.cs b/src/MineCase.Server.Grains/Game/Entities/Components/DiscoveryRegisterComponent.cs index 14b7dd19..64043d1e 100644 --- a/src/MineCase.Server.Grains/Game/Entities/Components/DiscoveryRegisterComponent.cs +++ b/src/MineCase.Server.Grains/Game/Entities/Components/DiscoveryRegisterComponent.cs @@ -15,35 +15,37 @@ public DiscoveryRegisterComponent(string name = "discoveryRegister") { } - protected override Task OnAttached() + protected override void OnAttached() { AttachedObject.GetComponent() .KeyChanged += AddressByPartitionKeyChanged; AttachedObject.RegisterPropertyChangedHandler(IsEnabledComponent.IsEnabledProperty, OnIsEnabledChanged); AttachedObject.QueueOperation(TrySubscribe); - return base.OnAttached(); } - protected override async Task OnDetached() + protected override void OnDetached() { AttachedObject.GetComponent() .KeyChanged -= AddressByPartitionKeyChanged; - await TryUnsubscribe(); + AttachedObject.QueueOperation(TryUnsubscribe); } - private async Task AddressByPartitionKeyChanged(object sender, (string oldKey, string newKey) e) + private void AddressByPartitionKeyChanged(object sender, (string oldKey, string newKey) e) { - if (!string.IsNullOrEmpty(e.oldKey)) - await GrainFactory.GetGrain(e.oldKey).UnsubscribeDiscovery(AttachedObject); - await TrySubscribe(); + AttachedObject.QueueOperation(async () => + { + if (!string.IsNullOrEmpty(e.oldKey)) + await GrainFactory.GetGrain(e.oldKey).UnsubscribeDiscovery(AttachedObject); + await TrySubscribe(); + }); } - private Task OnIsEnabledChanged(object sender, PropertyChangedEventArgs e) + private void OnIsEnabledChanged(object sender, PropertyChangedEventArgs e) { if (e.NewValue) - return TrySubscribe(); + AttachedObject.QueueOperation(TrySubscribe); else - return TryUnsubscribe(); + AttachedObject.QueueOperation(TryUnsubscribe); } private async Task TrySubscribe() diff --git a/src/MineCase.Server.Grains/Game/Entities/Components/DraggedSlotComponent.cs b/src/MineCase.Server.Grains/Game/Entities/Components/DraggedSlotComponent.cs index c3149cbf..76a92f13 100644 --- a/src/MineCase.Server.Grains/Game/Entities/Components/DraggedSlotComponent.cs +++ b/src/MineCase.Server.Grains/Game/Entities/Components/DraggedSlotComponent.cs @@ -18,12 +18,13 @@ public DraggedSlotComponent(string name = "draggedSlot") { } - public Task SetDraggedSlot(Slot value) => + public void SetDraggedSlot(Slot value) => AttachedObject.SetLocalValue(DraggedSlotProperty, value); Task IHandle.Handle(SetDraggedSlot message) { - return SetDraggedSlot(message.Slot); + SetDraggedSlot(message.Slot); + return Task.CompletedTask; } Task IHandle.Handle(AskDraggedSlot message) diff --git a/src/MineCase.Server.Grains/Game/Entities/Components/EntityAiComponent.cs b/src/MineCase.Server.Grains/Game/Entities/Components/EntityAiComponent.cs index cb3388db..ca0f4332 100644 --- a/src/MineCase.Server.Grains/Game/Entities/Components/EntityAiComponent.cs +++ b/src/MineCase.Server.Grains/Game/Entities/Components/EntityAiComponent.cs @@ -38,24 +38,22 @@ public EntityAiComponent(string name = "entityAi") random = new Random(); } - protected override async Task OnAttached() + protected override void OnAttached() { Register(); - await AttachedObject.SetLocalValue(EntityAiComponent.CreatureStateProperty, CreatureState.Stop); + AttachedObject.SetLocalValue(EntityAiComponent.CreatureStateProperty, CreatureState.Stop); CreateAi(MobType); AttachedObject.RegisterPropertyChangedHandler(MobTypeComponent.MobTypeProperty, OnMobTypeChanged); } - private Task OnMobTypeChanged(object sender, PropertyChangedEventArgs e) + private void OnMobTypeChanged(object sender, PropertyChangedEventArgs e) { CreateAi(e.NewValue); - return Task.CompletedTask; } - protected override Task OnDetached() + protected override void OnDetached() { Unregister(); - return base.OnDetached(); } private void Register() @@ -73,7 +71,7 @@ private void Unregister() private void CreateAi(MobType mobType) { Func getter = () => AttachedObject.GetValue(CreatureStateProperty); - Action setter = v => AttachedObject.SetLocalValue(CreatureStateProperty, v).Wait(); + Action setter = v => AttachedObject.SetLocalValue(CreatureStateProperty, v); CreatureAi ai; switch (mobType) @@ -147,8 +145,8 @@ private async Task ActionWalk() head = (float)(yaw / 180.0f * Math.PI); } - await AttachedObject.SetLocalValue(EntityLookComponent.YawProperty, (float)(head / Math.PI * 180.0f)); - await AttachedObject.SetLocalValue(EntityLookComponent.HeadYawProperty, (float)(head / Math.PI * 180.0f)); + AttachedObject.SetLocalValue(EntityLookComponent.YawProperty, (float)(head / Math.PI * 180.0f)); + AttachedObject.SetLocalValue(EntityLookComponent.HeadYawProperty, (float)(head / Math.PI * 180.0f)); // 新的位置 EntityWorldPos entityPos = new EntityWorldPos(pos.X - step * (float)Math.Sin(head), pos.Y, pos.Z + step * (float)Math.Cos(head)); @@ -192,7 +190,7 @@ private async Task ActionWalk() if (!isCollided && canWalk) { - await AttachedObject.SetLocalValue( + AttachedObject.SetLocalValue( EntityWorldPositionComponent.EntityWorldPositionProperty, EntityWorldPos.Add(entityPos, 0, yJumpHeight, 0)); } @@ -216,9 +214,9 @@ private async Task ActionLook() { (var yaw, var pitch) = VectorToYawAndPitch(entityPos, playerPosition); - await AttachedObject.SetLocalValue(EntityLookComponent.YawProperty, yaw); - await AttachedObject.SetLocalValue(EntityLookComponent.HeadYawProperty, yaw); - await AttachedObject.SetLocalValue(EntityLookComponent.PitchProperty, pitch); + AttachedObject.SetLocalValue(EntityLookComponent.YawProperty, yaw); + AttachedObject.SetLocalValue(EntityLookComponent.HeadYawProperty, yaw); + AttachedObject.SetLocalValue(EntityLookComponent.PitchProperty, pitch); break; } } @@ -269,7 +267,7 @@ private async Task GenerateEvent() nextEvent = CreatureEvent.Stop; } - await _ai.FireAsync(nextEvent); + _ai.Fire(nextEvent); } private async Task OnGameTick(object sender, GameTickArgs e) diff --git a/src/MineCase.Server.Grains/Game/Entities/Components/EntityDiscoveryComponentBase.cs b/src/MineCase.Server.Grains/Game/Entities/Components/EntityDiscoveryComponentBase.cs index 89eb442c..1b36ecbd 100644 --- a/src/MineCase.Server.Grains/Game/Entities/Components/EntityDiscoveryComponentBase.cs +++ b/src/MineCase.Server.Grains/Game/Entities/Components/EntityDiscoveryComponentBase.cs @@ -19,11 +19,6 @@ public EntityDiscoveryComponentBase(string name) { } - protected override Task OnAttached() - { - return base.OnAttached(); - } - private ClientPlayPacketGenerator GetPlayerPacketGenerator(IPlayer player) => new ClientPlayPacketGenerator(new ForwardToPlayerPacketSink(player, ServiceProvider.GetRequiredService())); diff --git a/src/MineCase.Server.Grains/Game/Entities/Components/EntityLifeTimeComponent.cs b/src/MineCase.Server.Grains/Game/Entities/Components/EntityLifeTimeComponent.cs index 7c07a4a2..fbb5cc05 100644 --- a/src/MineCase.Server.Grains/Game/Entities/Components/EntityLifeTimeComponent.cs +++ b/src/MineCase.Server.Grains/Game/Entities/Components/EntityLifeTimeComponent.cs @@ -15,13 +15,14 @@ public EntityLifeTimeComponent(string name = "entityLiftTime") { } - async Task IHandle.Handle(SpawnEntity message) + Task IHandle.Handle(SpawnEntity message) { - await AttachedObject.GetComponent().SetWorld(message.World); - await AttachedObject.GetComponent().SetPosition(message.Position); + AttachedObject.GetComponent().SetWorld(message.World); + AttachedObject.GetComponent().SetPosition(message.Position); var lookComponent = AttachedObject.GetComponent(); - await lookComponent.SetPitch(message.Pitch); - await lookComponent.SetYaw(message.Yaw); + lookComponent.SetPitch(message.Pitch); + lookComponent.SetYaw(message.Yaw); + return Task.CompletedTask; } async Task IHandle.Handle(DestroyEntity message) diff --git a/src/MineCase.Server.Grains/Game/Entities/Components/EntityLookComponentBase.cs b/src/MineCase.Server.Grains/Game/Entities/Components/EntityLookComponentBase.cs index ba1028e2..9d8e9469 100644 --- a/src/MineCase.Server.Grains/Game/Entities/Components/EntityLookComponentBase.cs +++ b/src/MineCase.Server.Grains/Game/Entities/Components/EntityLookComponentBase.cs @@ -19,11 +19,6 @@ public EntityLookComponentBase(string name) { } - protected override Task OnAttached() - { - return base.OnAttached(); - } - private ClientPlayPacketGenerator GetPlayerPacketGenerator(IPlayer player) => new ClientPlayPacketGenerator(new ForwardToPlayerPacketSink(player, ServiceProvider.GetRequiredService())); diff --git a/src/MineCase.Server.Grains/Game/Entities/Components/EntityMoveComponent.cs b/src/MineCase.Server.Grains/Game/Entities/Components/EntityMoveComponent.cs index fd48b319..6c6b43b2 100644 --- a/src/MineCase.Server.Grains/Game/Entities/Components/EntityMoveComponent.cs +++ b/src/MineCase.Server.Grains/Game/Entities/Components/EntityMoveComponent.cs @@ -20,11 +20,6 @@ public EntityMoveComponent(string name) { } - protected override Task OnAttached() - { - return base.OnAttached(); - } - private ClientPlayPacketGenerator GetPlayerPacketGenerator(IPlayer player) => new ClientPlayPacketGenerator(new ForwardToPlayerPacketSink(player, ServiceProvider.GetRequiredService())); diff --git a/src/MineCase.Server.Grains/Game/Entities/Components/FoodComponent.cs b/src/MineCase.Server.Grains/Game/Entities/Components/FoodComponent.cs index 0752b93f..c6cfb8cc 100644 --- a/src/MineCase.Server.Grains/Game/Entities/Components/FoodComponent.cs +++ b/src/MineCase.Server.Grains/Game/Entities/Components/FoodComponent.cs @@ -28,13 +28,13 @@ public FoodComponent(string name = "food") { } - public Task SetFood(uint value) => + public void SetFood(uint value) => AttachedObject.SetLocalValue(FoodProperty, value); - public Task SetMaxFood(uint value) => + public void SetMaxFood(uint value) => AttachedObject.SetLocalValue(MaxFoodProperty, value); - public Task SetFoodSaturation(float value) => + public void SetFoodSaturation(float value) => AttachedObject.SetLocalValue(FoodSaturationProperty, value); } } diff --git a/src/MineCase.Server.Grains/Game/Entities/Components/HealthComponent.cs b/src/MineCase.Server.Grains/Game/Entities/Components/HealthComponent.cs index 87a219a0..f609882f 100644 --- a/src/MineCase.Server.Grains/Game/Entities/Components/HealthComponent.cs +++ b/src/MineCase.Server.Grains/Game/Entities/Components/HealthComponent.cs @@ -23,10 +23,10 @@ public HealthComponent(string name = "health") { } - public Task SetHealth(uint value) => + public void SetHealth(uint value) => AttachedObject.SetLocalValue(HealthProperty, value); - public Task SetMaxHealth(uint value) => + public void SetMaxHealth(uint value) => AttachedObject.SetLocalValue(MaxHealthProperty, value); } } diff --git a/src/MineCase.Server.Grains/Game/Entities/Components/HeldItemComponent.cs b/src/MineCase.Server.Grains/Game/Entities/Components/HeldItemComponent.cs index b7cb0a3b..4925cf36 100644 --- a/src/MineCase.Server.Grains/Game/Entities/Components/HeldItemComponent.cs +++ b/src/MineCase.Server.Grains/Game/Entities/Components/HeldItemComponent.cs @@ -25,11 +25,14 @@ public HeldItemComponent(string name = "heldItem") return (index, await inventory.GetSlot(AttachedObject, index)); } - public Task SetHeldItemIndex(int index) => + public void SetHeldItemIndex(int index) => AttachedObject.SetLocalValue(HeldItemIndexProperty, index); - Task IHandle.Handle(SetHeldItemIndex message) => + Task IHandle.Handle(SetHeldItemIndex message) + { SetHeldItemIndex(message.Index); + return Task.CompletedTask; + } Task<(int index, Slot slot)> IHandle.Handle(AskHeldItem message) => GetHeldItem(); diff --git a/src/MineCase.Server.Grains/Game/Entities/Components/MobDiscoveryComponent.cs b/src/MineCase.Server.Grains/Game/Entities/Components/MobDiscoveryComponent.cs index 8a4d59a6..d2e1d582 100644 --- a/src/MineCase.Server.Grains/Game/Entities/Components/MobDiscoveryComponent.cs +++ b/src/MineCase.Server.Grains/Game/Entities/Components/MobDiscoveryComponent.cs @@ -19,14 +19,15 @@ public MobDiscoveryComponent(string name = "mobDiscovery") { } - async Task IHandle.Handle(SpawnMob message) + Task IHandle.Handle(SpawnMob message) { - await AttachedObject.Tell(message); - await AttachedObject.SetLocalValue(MobTypeComponent.MobTypeProperty, message.MobType); + AttachedObject.Tell(message); + AttachedObject.SetLocalValue(MobTypeComponent.MobTypeProperty, message.MobType); CompleteSpawn(); // Logger.LogInformation($"Mob spawn, key: {AttachedObject.GetAddressByPartitionKey()}"); // Logger.LogInformation($"Mob spawn, type: {message.MobType}"); + return Task.CompletedTask; } protected override Task SendSpawnPacket(ClientPlayPacketGenerator generator) diff --git a/src/MineCase.Server.Grains/Game/Entities/Components/MobSpawnerComponent.cs b/src/MineCase.Server.Grains/Game/Entities/Components/MobSpawnerComponent.cs index e44a702a..029fe052 100644 --- a/src/MineCase.Server.Grains/Game/Entities/Components/MobSpawnerComponent.cs +++ b/src/MineCase.Server.Grains/Game/Entities/Components/MobSpawnerComponent.cs @@ -32,16 +32,14 @@ public MobSpawnerComponent(string name = "mobSpawner") random = new Random(); } - protected override Task OnAttached() + protected override void OnAttached() { Register(); - return base.OnAttached(); } - protected override Task OnDetached() + protected override void OnDetached() { Unregister(); - return base.OnDetached(); } private void Register() diff --git a/src/MineCase.Server.Grains/Game/Entities/Components/MobTypeComponent.cs b/src/MineCase.Server.Grains/Game/Entities/Components/MobTypeComponent.cs index 3d0e58eb..ddd0c2d9 100644 --- a/src/MineCase.Server.Grains/Game/Entities/Components/MobTypeComponent.cs +++ b/src/MineCase.Server.Grains/Game/Entities/Components/MobTypeComponent.cs @@ -18,7 +18,7 @@ public MobTypeComponent(string name = "mobType") { } - public Task SetMobType(MobType value) => + public void SetMobType(MobType value) => AttachedObject.SetLocalValue(MobTypeProperty, value); } } diff --git a/src/MineCase.Server.Grains/Game/Entities/Components/PickupDiscoveryComponent.cs b/src/MineCase.Server.Grains/Game/Entities/Components/PickupDiscoveryComponent.cs index 6353d975..adb70e2e 100644 --- a/src/MineCase.Server.Grains/Game/Entities/Components/PickupDiscoveryComponent.cs +++ b/src/MineCase.Server.Grains/Game/Entities/Components/PickupDiscoveryComponent.cs @@ -31,13 +31,15 @@ Task IHandle.Handle(DestroyEntity message) .DestroyEntities(new[] { AttachedObject.EntityId }); } - async Task IHandle.Handle(SpawnEntity message) + Task IHandle.Handle(SpawnEntity message) { var pos = message.Position; var bb = BoundingBox.Item(); var box = new Cuboid(new Point3d(pos.X, pos.Z, pos.Y), new Size(bb.X, bb.Y, bb.Z)); - await AttachedObject.SetLocalValue(ColliderComponent.ColliderShapeProperty, box); + AttachedObject.SetLocalValue(ColliderComponent.ColliderShapeProperty, box); CompleteSpawn(); + + return Task.CompletedTask; } } } diff --git a/src/MineCase.Server.Grains/Game/Entities/Components/PickupMetadataComponent.cs b/src/MineCase.Server.Grains/Game/Entities/Components/PickupMetadataComponent.cs index 409d5cea..90ccfcb9 100644 --- a/src/MineCase.Server.Grains/Game/Entities/Components/PickupMetadataComponent.cs +++ b/src/MineCase.Server.Grains/Game/Entities/Components/PickupMetadataComponent.cs @@ -21,10 +21,9 @@ public PickupMetadataComponent(string name = "pickupMetadata") { } - protected override async Task OnAttached() + protected override void OnAttached() { - await base.OnAttached(); - await AttachedObject.SetLocalValue(PickupMetadataProperty, new Pickup()); + AttachedObject.SetLocalValue(PickupMetadataProperty, new Pickup()); } async Task IHandle.Handle(SetSlot message) diff --git a/src/MineCase.Server.Grains/Game/Entities/Components/SlotContainerComponent.cs b/src/MineCase.Server.Grains/Game/Entities/Components/SlotContainerComponent.cs index 3211a578..fee69653 100644 --- a/src/MineCase.Server.Grains/Game/Entities/Components/SlotContainerComponent.cs +++ b/src/MineCase.Server.Grains/Game/Entities/Components/SlotContainerComponent.cs @@ -14,7 +14,7 @@ internal class SlotContainerComponent : Component, IHandle, IHandle SlotChanged; + public event EventHandler<(int index, Slot slot)> SlotChanged; public SlotContainerComponent(int slotsCount, string name = "slotContainer") : base(name) @@ -22,42 +22,42 @@ public SlotContainerComponent(int slotsCount, string name = "slotContainer") _slotsCount = slotsCount; } - protected override async Task OnAttached() + protected override void OnAttached() { var slots = AttachedObject.GetValue(SlotsProperty); if (slots == null || slots.Length != _slotsCount) - await AttachedObject.SetLocalValue(SlotsProperty, Enumerable.Repeat(Slot.Empty, _slotsCount).ToArray()); - await base.OnAttached(); + AttachedObject.SetLocalValue(SlotsProperty, Enumerable.Repeat(Slot.Empty, _slotsCount).ToArray()); } public Slot GetSlot(int index) => AttachedObject.GetValue(SlotsProperty)[index]; - public Task SetSlot(int index, Slot slot) + public void SetSlot(int index, Slot slot) { ref var old = ref AttachedObject.GetValue(SlotsProperty)[index]; if (old != slot) { old = slot; MarkDirty(); - return SlotChanged.InvokeSerial(this, (index, slot)); + SlotChanged?.Invoke(this, (index, slot)); } - - return Task.CompletedTask; } - public async Task SetSlots(Slot[] slots) + public void SetSlots(Slot[] slots) { if (slots.Length != _slotsCount) throw new ArgumentException(nameof(slots)); - await AttachedObject.SetLocalValue(SlotsProperty, slots); + AttachedObject.SetLocalValue(SlotsProperty, slots); for (int i = 0; i < _slotsCount; i++) - await SlotChanged.InvokeSerial(this, (i, slots[i])); + SlotChanged?.Invoke(this, (i, slots[i])); } Task IHandle.Handle(SetSlot message) - => SetSlot(message.Index, message.Slot); + { + SetSlot(message.Index, message.Slot); + return Task.CompletedTask; + } Task IHandle.Handle(AskSlot message) => Task.FromResult(GetSlot(message.Index)); diff --git a/src/MineCase.Server.Grains/Game/Entities/Components/StandaloneHeldItemComponent.cs b/src/MineCase.Server.Grains/Game/Entities/Components/StandaloneHeldItemComponent.cs index 0a8594ce..888eaabc 100644 --- a/src/MineCase.Server.Grains/Game/Entities/Components/StandaloneHeldItemComponent.cs +++ b/src/MineCase.Server.Grains/Game/Entities/Components/StandaloneHeldItemComponent.cs @@ -18,7 +18,7 @@ public StandaloneHeldItemComponent(string name = "standaloneHeldItem") { } - public Task SetHeldItem(Slot value) => + public void SetHeldItem(Slot value) => AttachedObject.SetLocalValue(HeldItemProperty, value); Task IHandle.Handle(SetHeldItemIndex message) @@ -33,7 +33,8 @@ Task IHandle.Handle(SetHeldItemIndex message) Task IHandle.Handle(SetHeldItem message) { - return SetHeldItem(message.Slot); + SetHeldItem(message.Slot); + return Task.CompletedTask; } } } diff --git a/src/MineCase.Server.Grains/Game/Entities/Components/SyncMobStateComponent.cs b/src/MineCase.Server.Grains/Game/Entities/Components/SyncMobStateComponent.cs index 7f1da07d..50dd3c0e 100644 --- a/src/MineCase.Server.Grains/Game/Entities/Components/SyncMobStateComponent.cs +++ b/src/MineCase.Server.Grains/Game/Entities/Components/SyncMobStateComponent.cs @@ -16,11 +16,10 @@ public SyncMobStateComponent(string name = "syncPlayerState") { } - protected override Task OnAttached() + protected override void OnAttached() { if (AttachedObject.GetValue(IsEnabledComponent.IsEnabledProperty)) InstallPropertyChangedHandlers(); - return base.OnAttached(); } Task IHandle.Handle(SpawnMob message) @@ -37,14 +36,14 @@ private void InstallPropertyChangedHandlers() AttachedObject.RegisterPropertyChangedHandler(EntityWorldPositionComponent.EntityWorldPositionProperty, OnPositionChanged); } - private Task OnHeadYawChanged(object sender, PropertyChangedEventArgs e) + private void OnHeadYawChanged(object sender, PropertyChangedEventArgs e) { uint eid = AttachedObject.GetValue(EntityIdComponent.EntityIdProperty); byte headyaw = (byte)(AttachedObject.GetValue(EntityLookComponent.HeadYawProperty) / 360 * 255); - return AttachedObject.GetComponent().GetGenerator().EntityHeadLook(eid, headyaw); + AttachedObject.QueueOperation(() => AttachedObject.GetComponent().GetGenerator().EntityHeadLook(eid, headyaw)); } - private Task OnYawChanged(object sender, PropertyChangedEventArgs e) + private void OnYawChanged(object sender, PropertyChangedEventArgs e) { /* uint eid = AttachedObject.GetValue(EntityIdComponent.EntityIdProperty); @@ -55,10 +54,9 @@ private Task OnYawChanged(object sender, PropertyChangedEventArgs e) // return AttachedObject.GetComponent().GetGenerator().EntityLook(eid, yaw, pitch, onGround); return AttachedObject.GetComponent().GetGenerator().EntityLookAndRelativeMove(eid, 0, 0, 0, yaw, pitch, onGround); */ - return Task.CompletedTask; } - private Task OnPitchChanged(object sender, PropertyChangedEventArgs e) + private void OnPitchChanged(object sender, PropertyChangedEventArgs e) { uint eid = AttachedObject.GetValue(EntityIdComponent.EntityIdProperty); byte yaw = (byte)(AttachedObject.GetValue(EntityLookComponent.YawProperty) / 360 * 255); @@ -66,10 +64,10 @@ private Task OnPitchChanged(object sender, PropertyChangedEventArgs e) bool onGround = AttachedObject.GetValue(EntityOnGroundComponent.IsOnGroundProperty); // return AttachedObject.GetComponent().GetGenerator().EntityLook(eid, yaw, pitch, onGround); - return AttachedObject.GetComponent().GetGenerator().EntityLookAndRelativeMove(eid, 0, 0, 0, yaw, pitch, onGround); + AttachedObject.QueueOperation(() => AttachedObject.GetComponent().GetGenerator().EntityLookAndRelativeMove(eid, 0, 0, 0, yaw, pitch, onGround)); } - private Task OnPositionChanged(object sender, PropertyChangedEventArgs e) + private void OnPositionChanged(object sender, PropertyChangedEventArgs e) { uint eid = AttachedObject.GetValue(EntityIdComponent.EntityIdProperty); short x = (short)((e.NewValue.X - e.OldValue.X) * 32 * 128); @@ -79,7 +77,7 @@ private Task OnPositionChanged(object sender, PropertyChangedEventArgs().GetGenerator().EntityLookAndRelativeMove(eid, x, y, z, yaw, pitch, isOnGround); + AttachedObject.QueueOperation(() => AttachedObject.GetComponent().GetGenerator().EntityLookAndRelativeMove(eid, x, y, z, yaw, pitch, isOnGround)); } } } diff --git a/src/MineCase.Server.Grains/Game/Entities/Components/SyncPlayerStateComponent.cs b/src/MineCase.Server.Grains/Game/Entities/Components/SyncPlayerStateComponent.cs index 19fcbba9..60627f75 100644 --- a/src/MineCase.Server.Grains/Game/Entities/Components/SyncPlayerStateComponent.cs +++ b/src/MineCase.Server.Grains/Game/Entities/Components/SyncPlayerStateComponent.cs @@ -52,17 +52,17 @@ private void InstallPropertyChangedHandlers() AttachedObject.RegisterPropertyChangedHandler(EntityWorldPositionComponent.EntityWorldPositionProperty, OnEntityWorldPositionChanged); } - private Task OnEntityWorldPositionChanged(object sender, PropertyChangedEventArgs e) + private void OnEntityWorldPositionChanged(object sender, PropertyChangedEventArgs e) { var pos = e.NewValue; var box = new Cuboid(new Point3d(pos.X, pos.Z, pos.Y), new Size(0.6f, 0.6f, 1.75f)); - return AttachedObject.SetLocalValue(ColliderComponent.ColliderShapeProperty, box); + AttachedObject.SetLocalValue(ColliderComponent.ColliderShapeProperty, box); } - private Task OnDraggedSlotChanged(object sender, PropertyChangedEventArgs e) + private void OnDraggedSlotChanged(object sender, PropertyChangedEventArgs e) { - return AttachedObject.GetComponent().GetGenerator() - .SetSlot(0xFF, 0, e.NewValue); + AttachedObject.QueueOperation(() => AttachedObject.GetComponent().GetGenerator() + .SetSlot(0xFF, 0, e.NewValue)); } async Task IHandle.Handle(BindToUser message) @@ -70,15 +70,15 @@ async Task IHandle.Handle(BindToUser message) AttachedObject.GetComponent().SlotChanged -= InventorySlotChanged; _user = message.User; - await AttachedObject.GetComponent().SetName(await message.User.GetName()); - await AttachedObject.GetComponent().SetSlots(await message.User.GetInventorySlots()); + AttachedObject.GetComponent().SetName(await message.User.GetName()); + AttachedObject.GetComponent().SetSlots(await message.User.GetInventorySlots()); AttachedObject.GetComponent().SlotChanged += InventorySlotChanged; } - private Task InventorySlotChanged(object sender, (int index, Slot slot) e) + private void InventorySlotChanged(object sender, (int index, Slot slot) e) { - return _user.SetInventorySlot(e.index, e.slot); + AttachedObject.QueueOperation(() => _user.SetInventorySlot(e.index, e.slot)); } } } diff --git a/src/MineCase.Server.Grains/Game/Entities/Components/WindowManagerComponent.cs b/src/MineCase.Server.Grains/Game/Entities/Components/WindowManagerComponent.cs index e0b6c05c..a82afba4 100644 --- a/src/MineCase.Server.Grains/Game/Entities/Components/WindowManagerComponent.cs +++ b/src/MineCase.Server.Grains/Game/Entities/Components/WindowManagerComponent.cs @@ -19,13 +19,12 @@ public WindowManagerComponent(string name = "windowManager") { } - protected override Task OnAttached() + protected override void OnAttached() { _windows = new Dictionary { { 0, new WindowContext { Window = AttachedObject.GetComponent().GetInventoryWindow() } } }; - return base.OnAttached(); } public async Task ClickWindow(byte windowId, short slot, ClickAction clickAction, short actionNumber, Slot clickedItem) diff --git a/src/MineCase.Server.Grains/Game/Entities/EntityGrain.cs b/src/MineCase.Server.Grains/Game/Entities/EntityGrain.cs index b4593689..beb9d63e 100644 --- a/src/MineCase.Server.Grains/Game/Entities/EntityGrain.cs +++ b/src/MineCase.Server.Grains/Game/Entities/EntityGrain.cs @@ -32,18 +32,18 @@ internal abstract class EntityGrain : PersistableDependencyObject, IEntity public float Yaw => GetValue(EntityLookComponent.YawProperty); - protected override async Task InitializeComponents() + protected override void InitializeComponents() { - await SetComponent(new IsEnabledComponent()); - await SetComponent(new EntityIdComponent()); - await SetComponent(new WorldComponent()); - await SetComponent(new EntityWorldPositionComponent()); - await SetComponent(new EntityLookComponent()); - await SetComponent(new AddressByPartitionKeyComponent()); - await SetComponent(new ChunkEventBroadcastComponent()); - await SetComponent(new GameTickComponent()); - await SetComponent(new ChunkAccessorComponent()); - await SetComponent(new AutoSaveStateComponent(AutoSaveStateComponent.PerMinute)); + SetComponent(new IsEnabledComponent()); + SetComponent(new EntityIdComponent()); + SetComponent(new WorldComponent()); + SetComponent(new EntityWorldPositionComponent()); + SetComponent(new EntityLookComponent()); + SetComponent(new AddressByPartitionKeyComponent()); + SetComponent(new ChunkEventBroadcastComponent()); + SetComponent(new GameTickComponent()); + SetComponent(new ChunkAccessorComponent()); + SetComponent(new AutoSaveStateComponent(AutoSaveStateComponent.PerMinute)); } Task IEntity.GetEntityId() => diff --git a/src/MineCase.Server.Grains/Game/Entities/MobGrain.cs b/src/MineCase.Server.Grains/Game/Entities/MobGrain.cs index 47cf901a..f4e6a46b 100644 --- a/src/MineCase.Server.Grains/Game/Entities/MobGrain.cs +++ b/src/MineCase.Server.Grains/Game/Entities/MobGrain.cs @@ -13,21 +13,21 @@ namespace MineCase.Server.Game.Entities [Reentrant] internal class MobGrain : EntityGrain, IMob { - protected override async Task InitializeComponents() + protected override void InitializeComponents() { - await base.InitializeComponents(); + base.InitializeComponents(); // await SetComponent(new ActiveWorldPartitionComponent()); - await SetComponent(new EntityLifeTimeComponent()); - await SetComponent(new EntityOnGroundComponent()); - await SetComponent(new HealthComponent()); - await SetComponent(new StandaloneHeldItemComponent()); - await SetComponent(new NameComponent()); - await SetComponent(new EntityAiComponent()); - await SetComponent(new DiscoveryRegisterComponent()); - await SetComponent(new MobDiscoveryComponent()); - await SetComponent(new MobTypeComponent()); - await SetComponent(new SyncMobStateComponent()); + SetComponent(new EntityLifeTimeComponent()); + SetComponent(new EntityOnGroundComponent()); + SetComponent(new HealthComponent()); + SetComponent(new StandaloneHeldItemComponent()); + SetComponent(new NameComponent()); + SetComponent(new EntityAiComponent()); + SetComponent(new DiscoveryRegisterComponent()); + SetComponent(new MobDiscoveryComponent()); + SetComponent(new MobTypeComponent()); + SetComponent(new SyncMobStateComponent()); /* if (MobType == MobType.Enderman) { @@ -40,9 +40,9 @@ protected override async Task InitializeComponents() public async override Task OnActivateAsync() { await base.OnActivateAsync(); - await this.SetLocalValue(HealthComponent.MaxHealthProperty, 20u); - await this.SetLocalValue(HealthComponent.HealthProperty, GetValue(HealthComponent.MaxHealthProperty)); - await this.SetLocalValue(EntityOnGroundComponent.IsOnGroundProperty, true); + this.SetLocalValue(HealthComponent.MaxHealthProperty, 20u); + this.SetLocalValue(HealthComponent.HealthProperty, GetValue(HealthComponent.MaxHealthProperty)); + this.SetLocalValue(EntityOnGroundComponent.IsOnGroundProperty, true); } } } diff --git a/src/MineCase.Server.Grains/Game/Entities/MonsterGrain.cs b/src/MineCase.Server.Grains/Game/Entities/MonsterGrain.cs index 7f12e4d3..f661341d 100644 --- a/src/MineCase.Server.Grains/Game/Entities/MonsterGrain.cs +++ b/src/MineCase.Server.Grains/Game/Entities/MonsterGrain.cs @@ -31,26 +31,26 @@ internal class MonsterGrain : EntityGrain, IMonster private Queue _tasks; */ - protected override async Task InitializeComponents() + protected override void InitializeComponents() { - await base.InitializeComponents(); - await SetComponent(new BlockPlacementComponent()); // 末影人 - await SetComponent(new DiggingComponent()); // 末影人 - await SetComponent(new EntityLifeTimeComponent()); - await SetComponent(new EntityOnGroundComponent()); - await SetComponent(new HealthComponent()); - await SetComponent(new StandaloneHeldItemComponent()); - await SetComponent(new NameComponent()); - await SetComponent(new DiscoveryRegisterComponent()); + base.InitializeComponents(); + SetComponent(new BlockPlacementComponent()); // 末影人 + SetComponent(new DiggingComponent()); // 末影人 + SetComponent(new EntityLifeTimeComponent()); + SetComponent(new EntityOnGroundComponent()); + SetComponent(new HealthComponent()); + SetComponent(new StandaloneHeldItemComponent()); + SetComponent(new NameComponent()); + SetComponent(new DiscoveryRegisterComponent()); } public async override Task OnActivateAsync() { await base.OnActivateAsync(); - await this.SetLocalValue(HealthComponent.MaxHealthProperty, 20u); - await this.SetLocalValue(FoodComponent.MaxFoodProperty, 20u); - await this.SetLocalValue(HealthComponent.HealthProperty, GetValue(HealthComponent.MaxHealthProperty)); - await this.SetLocalValue(FoodComponent.FoodProperty, GetValue(FoodComponent.MaxFoodProperty)); + this.SetLocalValue(HealthComponent.MaxHealthProperty, 20u); + this.SetLocalValue(FoodComponent.MaxFoodProperty, 20u); + this.SetLocalValue(HealthComponent.HealthProperty, GetValue(HealthComponent.MaxHealthProperty)); + this.SetLocalValue(FoodComponent.FoodProperty, GetValue(FoodComponent.MaxFoodProperty)); } /* diff --git a/src/MineCase.Server.Grains/Game/Entities/PassiveMobGrain.cs b/src/MineCase.Server.Grains/Game/Entities/PassiveMobGrain.cs index 411b89cb..3ac8d3c8 100644 --- a/src/MineCase.Server.Grains/Game/Entities/PassiveMobGrain.cs +++ b/src/MineCase.Server.Grains/Game/Entities/PassiveMobGrain.cs @@ -32,29 +32,29 @@ internal class PassiveMobGrain : EntityGrain, IPassiveMob private Queue _tasks; */ - protected override async Task InitializeComponents() + protected override void InitializeComponents() { - await base.InitializeComponents(); + base.InitializeComponents(); // await SetComponent(new BlockPlacementComponent()); // 末影人 // await SetComponent(new DiggingComponent()); // 末影人 - await SetComponent(new EntityLifeTimeComponent()); - await SetComponent(new EntityOnGroundComponent()); - await SetComponent(new HealthComponent()); - await SetComponent(new StandaloneHeldItemComponent()); - await SetComponent(new NameComponent()); - await SetComponent(new DiscoveryRegisterComponent()); - await SetComponent(new EntityAiComponent()); + SetComponent(new EntityLifeTimeComponent()); + SetComponent(new EntityOnGroundComponent()); + SetComponent(new HealthComponent()); + SetComponent(new StandaloneHeldItemComponent()); + SetComponent(new NameComponent()); + SetComponent(new DiscoveryRegisterComponent()); + SetComponent(new EntityAiComponent()); } public async override Task OnActivateAsync() { await base.OnActivateAsync(); - await this.SetLocalValue(HealthComponent.MaxHealthProperty, 20u); - await this.SetLocalValue(FoodComponent.MaxFoodProperty, 20u); - await this.SetLocalValue(HealthComponent.HealthProperty, GetValue(HealthComponent.MaxHealthProperty)); - await this.SetLocalValue(FoodComponent.FoodProperty, GetValue(FoodComponent.MaxFoodProperty)); + this.SetLocalValue(HealthComponent.MaxHealthProperty, 20u); + this.SetLocalValue(FoodComponent.MaxFoodProperty, 20u); + this.SetLocalValue(HealthComponent.HealthProperty, GetValue(HealthComponent.MaxHealthProperty)); + this.SetLocalValue(FoodComponent.FoodProperty, GetValue(FoodComponent.MaxFoodProperty)); } /* diff --git a/src/MineCase.Server.Grains/Game/Entities/PickupGrain.cs b/src/MineCase.Server.Grains/Game/Entities/PickupGrain.cs index ecb20c78..c8c75080 100644 --- a/src/MineCase.Server.Grains/Game/Entities/PickupGrain.cs +++ b/src/MineCase.Server.Grains/Game/Entities/PickupGrain.cs @@ -14,15 +14,15 @@ namespace MineCase.Server.Game.Entities [Reentrant] internal class PickupGrain : EntityGrain, IPickup { - protected override async Task InitializeComponents() + protected override void InitializeComponents() { - await base.InitializeComponents(); - await SetComponent(new EntityLifeTimeComponent()); - await SetComponent(new PickupMetadataComponent()); - await SetComponent(new DiscoveryRegisterComponent()); - await SetComponent(new PickupDiscoveryComponent()); - await SetComponent(new CollectorComponent()); - await SetComponent(new ColliderComponent()); + base.InitializeComponents(); + SetComponent(new EntityLifeTimeComponent()); + SetComponent(new PickupMetadataComponent()); + SetComponent(new DiscoveryRegisterComponent()); + SetComponent(new PickupDiscoveryComponent()); + SetComponent(new CollectorComponent()); + SetComponent(new ColliderComponent()); } /* diff --git a/src/MineCase.Server.Grains/Game/Entities/PlayerGrain.cs b/src/MineCase.Server.Grains/Game/Entities/PlayerGrain.cs index 882b166f..368ab6bb 100644 --- a/src/MineCase.Server.Grains/Game/Entities/PlayerGrain.cs +++ b/src/MineCase.Server.Grains/Game/Entities/PlayerGrain.cs @@ -25,46 +25,46 @@ namespace MineCase.Server.Game.Entities [Reentrant] internal class PlayerGrain : EntityGrain, IPlayer { - protected override async Task InitializeComponents() + protected override void InitializeComponents() { - await base.InitializeComponents(); - await SetComponent(new EntityLifeTimeComponent()); - await SetComponent(new ActiveWorldPartitionComponent()); - await SetComponent(new BlockPlacementComponent()); - await SetComponent(new ClientboundPacketComponent()); - await SetComponent(new ChunkLoaderComponent()); - await SetComponent(new DiggingComponent()); - await SetComponent(new DiscoveryRegisterComponent()); - await SetComponent(new DraggedSlotComponent()); - await SetComponent(new ExperienceComponent()); - await SetComponent(new EntityOnGroundComponent()); - await SetComponent(new FoodComponent()); - await SetComponent(new HealthComponent()); - await SetComponent(new HeldItemComponent()); - await SetComponent(new InventoryComponent()); - await SetComponent(new KeepAliveComponent()); - await SetComponent(new NameComponent()); - await SetComponent(new PlayerListComponent()); - await SetComponent(new PlayerDiscoveryComponent()); - await SetComponent(new ServerboundPacketComponent()); - await SetComponent(new SlotContainerComponent(SlotArea.UserSlotsCount)); - await SetComponent(new SyncPlayerStateComponent()); - await SetComponent(new TeleportComponent()); - await SetComponent(new TossPickupComponent()); - await SetComponent(new ViewDistanceComponent()); - await SetComponent(new WindowManagerComponent()); - await SetComponent(new CollectorComponent()); - await SetComponent(new ColliderComponent()); - await SetComponent(new MobSpawnerComponent()); + base.InitializeComponents(); + SetComponent(new EntityLifeTimeComponent()); + SetComponent(new ActiveWorldPartitionComponent()); + SetComponent(new BlockPlacementComponent()); + SetComponent(new ClientboundPacketComponent()); + SetComponent(new ChunkLoaderComponent()); + SetComponent(new DiggingComponent()); + SetComponent(new DiscoveryRegisterComponent()); + SetComponent(new DraggedSlotComponent()); + SetComponent(new ExperienceComponent()); + SetComponent(new EntityOnGroundComponent()); + SetComponent(new FoodComponent()); + SetComponent(new HealthComponent()); + SetComponent(new HeldItemComponent()); + SetComponent(new InventoryComponent()); + SetComponent(new KeepAliveComponent()); + SetComponent(new NameComponent()); + SetComponent(new PlayerListComponent()); + SetComponent(new PlayerDiscoveryComponent()); + SetComponent(new ServerboundPacketComponent()); + SetComponent(new SlotContainerComponent(SlotArea.UserSlotsCount)); + SetComponent(new SyncPlayerStateComponent()); + SetComponent(new TeleportComponent()); + SetComponent(new TossPickupComponent()); + SetComponent(new ViewDistanceComponent()); + SetComponent(new WindowManagerComponent()); + SetComponent(new CollectorComponent()); + SetComponent(new ColliderComponent()); + SetComponent(new MobSpawnerComponent()); } public override async Task OnActivateAsync() { await base.OnActivateAsync(); - await this.SetLocalValue(HealthComponent.MaxHealthProperty, 20u); - await this.SetLocalValue(FoodComponent.MaxFoodProperty, 20u); - await this.SetLocalValue(HealthComponent.HealthProperty, GetValue(HealthComponent.MaxHealthProperty)); - await this.SetLocalValue(FoodComponent.FoodProperty, GetValue(FoodComponent.MaxFoodProperty)); + this.SetLocalValue(HealthComponent.MaxHealthProperty, 20u); + this.SetLocalValue(FoodComponent.MaxFoodProperty, 20u); + this.SetLocalValue(HealthComponent.HealthProperty, GetValue(HealthComponent.MaxHealthProperty)); + this.SetLocalValue(FoodComponent.FoodProperty, GetValue(FoodComponent.MaxFoodProperty)); } public Task OnSwingHand(SwingHandState handState) diff --git a/src/MineCase.Server.Grains/Network/Play/ServerboundPacketComponent.cs b/src/MineCase.Server.Grains/Network/Play/ServerboundPacketComponent.cs index 56dd725c..f0163b3a 100644 --- a/src/MineCase.Server.Grains/Network/Play/ServerboundPacketComponent.cs +++ b/src/MineCase.Server.Grains/Network/Play/ServerboundPacketComponent.cs @@ -30,18 +30,16 @@ public ServerboundPacketComponent(string name = "serverboundPacket") _receivePacket = new ActionBlock((Action)OnReceivePacket); } - protected override Task OnAttached() + protected override void OnAttached() { AttachedObject.GetComponent() .Tick += OnGameTick; - return base.OnAttached(); } - protected override Task OnDetached() + protected override void OnDetached() { AttachedObject.GetComponent() .Tick -= OnGameTick; - return base.OnDetached(); } private async Task OnGameTick(object sender, GameTickArgs e) @@ -182,9 +180,10 @@ private Task DispatchPacket(ServerboundChatMessage packet) return Task.CompletedTask; } - private async Task DispatchPacket(ClientSettings packet) + private Task DispatchPacket(ClientSettings packet) { - await AttachedObject.SetLocalValue(ViewDistanceComponent.ViewDistanceProperty, packet.ViewDistance); + AttachedObject.SetLocalValue(ViewDistanceComponent.ViewDistanceProperty, packet.ViewDistance); + return Task.CompletedTask; } private Task DispatchPacket(ServerboundPluginMessage packet) @@ -197,38 +196,42 @@ private Task DispatchPacket(ServerboundKeepAlive packet) return AttachedObject.GetComponent().ReceiveResponse(packet.KeepAliveId); } - private async Task DispatchPacket(ServerboundPositionAndLook packet) + private Task DispatchPacket(ServerboundPositionAndLook packet) { - await AttachedObject.GetComponent() + AttachedObject.GetComponent() .SetPosition(new EntityWorldPos((float)packet.X, (float)packet.FeetY, (float)packet.Z)); var lookComponent = AttachedObject.GetComponent(); - await lookComponent.SetPitch(packet.Pitch); - await lookComponent.SetYaw(packet.Yaw); - await AttachedObject.GetComponent() + lookComponent.SetPitch(packet.Pitch); + lookComponent.SetYaw(packet.Yaw); + AttachedObject.GetComponent() .SetIsOnGround(packet.OnGround); + return Task.CompletedTask; } - private async Task DispatchPacket(PlayerOnGround packet) + private Task DispatchPacket(PlayerOnGround packet) { - await AttachedObject.GetComponent() + AttachedObject.GetComponent() .SetIsOnGround(packet.OnGround); + return Task.CompletedTask; } - private async Task DispatchPacket(PlayerPosition packet) + private Task DispatchPacket(PlayerPosition packet) { - await AttachedObject.GetComponent() + AttachedObject.GetComponent() .SetPosition(new EntityWorldPos((float)packet.X, (float)packet.FeetY, (float)packet.Z)); - await AttachedObject.GetComponent() + AttachedObject.GetComponent() .SetIsOnGround(packet.OnGround); + return Task.CompletedTask; } - private async Task DispatchPacket(PlayerLook packet) + private Task DispatchPacket(PlayerLook packet) { var lookComponent = AttachedObject.GetComponent(); - await lookComponent.SetPitch(packet.Pitch); - await lookComponent.SetYaw(packet.Yaw); - await AttachedObject.GetComponent() + lookComponent.SetPitch(packet.Pitch); + lookComponent.SetYaw(packet.Yaw); + AttachedObject.GetComponent() .SetIsOnGround(packet.OnGround); + return Task.CompletedTask; } private Task DispatchPacket(UseEntity packet) @@ -242,7 +245,8 @@ private Task DispatchPacket(UseEntity packet) private Task DispatchPacket(ServerboundHeldItemChange packet) { - return AttachedObject.GetComponent().SetHeldItemIndex(packet.Slot); + AttachedObject.GetComponent().SetHeldItemIndex(packet.Slot); + return Task.CompletedTask; } private async Task DispatchPacket(PlayerDigging packet) diff --git a/src/MineCase.Server.Grains/Persistence/Components/AutoSaveStateComponent.cs b/src/MineCase.Server.Grains/Persistence/Components/AutoSaveStateComponent.cs index fe107808..9820f3bc 100644 --- a/src/MineCase.Server.Grains/Persistence/Components/AutoSaveStateComponent.cs +++ b/src/MineCase.Server.Grains/Persistence/Components/AutoSaveStateComponent.cs @@ -20,12 +20,11 @@ public AutoSaveStateComponent(int periodTime, string name = "autoSaveState") _periodTime = periodTime; } - protected override Task OnAttached() + protected override void OnAttached() { var tickComponent = AttachedObject.GetComponent(); if (tickComponent != null) tickComponent.Tick += OnGameTick; - return base.OnAttached(); } public Task OnGameTick(object sender, GameTickArgs e) diff --git a/src/MineCase.Server.Grains/Persistence/Components/StateComponent.cs b/src/MineCase.Server.Grains/Persistence/Components/StateComponent.cs index d37e5098..1f4295bd 100644 --- a/src/MineCase.Server.Grains/Persistence/Components/StateComponent.cs +++ b/src/MineCase.Server.Grains/Persistence/Components/StateComponent.cs @@ -19,27 +19,29 @@ public class StateComponent : Component, IHandle, IHandle AttachedObject.GetValue(StateProperty); - public event AsyncEventHandler BeforeWriteState; + public event EventHandler BeforeWriteState; - public event AsyncEventHandler AfterReadState; + public event EventHandler AfterReadState; public StateComponent(string name = "state") : base(name) { } - async Task IHandle.Handle(AfterReadState message) + Task IHandle.Handle(AfterReadState message) { // 如果为 null 需要初始化状态 if (State == null) - await AttachedObject.SetLocalValue(StateProperty, (T)Activator.CreateInstance(typeof(T), InitializeStateMark.Default)); + AttachedObject.SetLocalValue(StateProperty, (T)Activator.CreateInstance(typeof(T), InitializeStateMark.Default)); - await AfterReadState.InvokeSerial(this, EventArgs.Empty); + AfterReadState?.Invoke(this, EventArgs.Empty); + return Task.CompletedTask; } Task IHandle.Handle(BeforeWriteState message) { - return BeforeWriteState.InvokeSerial(this, EventArgs.Empty); + BeforeWriteState?.Invoke(this, EventArgs.Empty); + return Task.CompletedTask; } } } diff --git a/src/MineCase.Server.Grains/User/NonAuthenticatedUserGrain.cs b/src/MineCase.Server.Grains/User/NonAuthenticatedUserGrain.cs index 89ba6dbc..75057aa7 100644 --- a/src/MineCase.Server.Grains/User/NonAuthenticatedUserGrain.cs +++ b/src/MineCase.Server.Grains/User/NonAuthenticatedUserGrain.cs @@ -15,9 +15,9 @@ internal class NonAuthenticatedUserGrain : PersistableDependencyObject, INonAuth { private StateHolder State => GetValue(StateComponent.StateProperty); - protected override async Task InitializePreLoadComponent() + protected override void InitializePreLoadComponent() { - await SetComponent(new StateComponent()); + SetComponent(new StateComponent()); } public Task GetUUID() => Task.FromResult(State.UUID); diff --git a/src/MineCase.Server.Grains/User/UserGrain.cs b/src/MineCase.Server.Grains/User/UserGrain.cs index 58ba7213..ec723843 100644 --- a/src/MineCase.Server.Grains/User/UserGrain.cs +++ b/src/MineCase.Server.Grains/User/UserGrain.cs @@ -36,23 +36,26 @@ internal class UserGrain : PersistableDependencyObject, IUser private StateHolder State => GetValue(StateComponent.StateProperty); - protected override async Task InitializePreLoadComponent() + protected override void InitializePreLoadComponent() { var stateComponent = new StateComponent(); - await SetComponent(stateComponent); + SetComponent(stateComponent); stateComponent.AfterReadState += StateComponent_AfterReadState; _autoSave = new AutoSaveStateComponent(AutoSaveStateComponent.PerMinute); - await SetComponent(_autoSave); + SetComponent(_autoSave); } - private async Task StateComponent_AfterReadState(object sender, EventArgs e) + private void StateComponent_AfterReadState(object sender, EventArgs e) { if (State.World == null) { - var world = await GrainFactory.GetGrain(0).GetDefaultWorld(); - State.World = world; - MarkDirty(); + QueueOperation(async () => + { + var world = await GrainFactory.GetGrain(0).GetDefaultWorld(); + State.World = world; + MarkDirty(); + }); } } diff --git a/src/MineCase.Server.Grains/World/ChunkColumnGrain.cs b/src/MineCase.Server.Grains/World/ChunkColumnGrain.cs index c58c6c7c..448dd320 100644 --- a/src/MineCase.Server.Grains/World/ChunkColumnGrain.cs +++ b/src/MineCase.Server.Grains/World/ChunkColumnGrain.cs @@ -28,15 +28,15 @@ internal class ChunkColumnGrain : AddressByPartitionGrain, IChunkColumn private StateHolder State => GetValue(StateComponent.StateProperty); - protected override async Task InitializePreLoadComponent() + protected override void InitializePreLoadComponent() { - await SetComponent(new StateComponent()); + SetComponent(new StateComponent()); } - protected override async Task InitializeComponents() + protected override void InitializeComponents() { _autoSave = new AutoSaveStateComponent(AutoSaveStateComponent.PerMinute * 5); - await SetComponent(_autoSave); + SetComponent(_autoSave); } public async Task GetBlockState(int x, int y, int z) diff --git a/src/MineCase.Server.Grains/World/CollectableFinder.cs b/src/MineCase.Server.Grains/World/CollectableFinder.cs index 6ac61520..dd904764 100644 --- a/src/MineCase.Server.Grains/World/CollectableFinder.cs +++ b/src/MineCase.Server.Grains/World/CollectableFinder.cs @@ -44,16 +44,16 @@ public override async Task OnActivateAsync() } } - protected override async Task InitializePreLoadComponent() + protected override void InitializePreLoadComponent() { var state = new StateComponent(); - await SetComponent(state); + SetComponent(state); } - protected override async Task InitializeComponents() + protected override void InitializeComponents() { _autoSave = new AutoSaveStateComponent(AutoSaveStateComponent.PerMinute); - await SetComponent(_autoSave); + SetComponent(_autoSave); } public Task RegisterCollider(IDependencyObject entity, Shape colliderShape) diff --git a/src/MineCase.Server.Grains/World/TickEmitterGrain.cs b/src/MineCase.Server.Grains/World/TickEmitterGrain.cs index 5c1ad6e7..07f92d89 100644 --- a/src/MineCase.Server.Grains/World/TickEmitterGrain.cs +++ b/src/MineCase.Server.Grains/World/TickEmitterGrain.cs @@ -22,15 +22,15 @@ internal class TickEmitterGrain : PersistableDependencyObject, ITickEmitter private StateHolder State => GetValue(StateComponent.StateProperty); - protected override async Task InitializePreLoadComponent() + protected override void InitializePreLoadComponent() { - await SetComponent(new StateComponent()); + SetComponent(new StateComponent()); } - protected override async Task InitializeComponents() + protected override void InitializeComponents() { _autoSave = new AutoSaveStateComponent(AutoSaveStateComponent.PerMinute); - await SetComponent(_autoSave); + SetComponent(_autoSave); } public async Task OnGameTick(GameTickArgs e) diff --git a/src/MineCase.Server.Grains/World/WorldGrain.cs b/src/MineCase.Server.Grains/World/WorldGrain.cs index 69d2dcce..bc0fcd2a 100644 --- a/src/MineCase.Server.Grains/World/WorldGrain.cs +++ b/src/MineCase.Server.Grains/World/WorldGrain.cs @@ -25,9 +25,20 @@ internal class WorldGrain : PersistableDependencyObject, IWorld private StateHolder State => GetValue(StateComponent.StateProperty); - protected override async Task InitializePreLoadComponent() + protected override void InitializePreLoadComponent() { - await SetComponent(new StateComponent()); + SetComponent(new StateComponent()); + } + + protected override void InitializeComponents() + { + _autoSave = new AutoSaveStateComponent(AutoSaveStateComponent.PerMinute); + SetComponent(_autoSave); + } + + public override async Task OnActivateAsync() + { + await base.OnActivateAsync(); var serverSettings = GrainFactory.GetGrain(0); _genSettings = new GeneratorSettings(); @@ -35,12 +46,6 @@ protected override async Task InitializePreLoadComponent() _seed = (await serverSettings.GetSettings()).LevelSeed; } - protected override async Task InitializeComponents() - { - _autoSave = new AutoSaveStateComponent(AutoSaveStateComponent.PerMinute); - await SetComponent(_autoSave); - } - public Task GetTime() { return Task.FromResult(new WorldTime { WorldAge = State.WorldAge, TimeOfDay = State.WorldAge % 24000 }); diff --git a/src/MineCase.Server.Grains/World/WorldPartitionGrain.cs b/src/MineCase.Server.Grains/World/WorldPartitionGrain.cs index 646e314c..77e567c3 100644 --- a/src/MineCase.Server.Grains/World/WorldPartitionGrain.cs +++ b/src/MineCase.Server.Grains/World/WorldPartitionGrain.cs @@ -27,9 +27,9 @@ internal class WorldPartitionGrain : AddressByPartitionGrain, IWorldPartition private StateHolder State => GetValue(StateComponent.StateProperty); - protected override async Task InitializePreLoadComponent() + protected override void InitializePreLoadComponent() { - await SetComponent(new StateComponent()); + SetComponent(new StateComponent()); _tickEmitter = GrainFactory.GetPartitionGrain(this); _collectableFinder = GrainFactory.GetPartitionGrain(this); @@ -37,10 +37,10 @@ protected override async Task InitializePreLoadComponent() _chunkColumn = GrainFactory.GetPartitionGrain(this); } - protected override async Task InitializeComponents() + protected override void InitializeComponents() { _autoSave = new AutoSaveStateComponent(AutoSaveStateComponent.PerMinute); - await SetComponent(_autoSave); + SetComponent(_autoSave); } public async Task Enter(IPlayer player) diff --git a/tests/UnitTest/SerializationTest.cs b/tests/UnitTest/SerializationTest.cs index a8e5dd54..eac39c57 100644 --- a/tests/UnitTest/SerializationTest.cs +++ b/tests/UnitTest/SerializationTest.cs @@ -19,16 +19,16 @@ public class SerializationTest public DependencyProperty SlotProperty = DependencyProperty.Register("Slot", typeof(SerializationTest), new PropertyMetadata(Slot.Empty)); public DependencyProperty ShapeProperty = DependencyProperty.Register("Shape", typeof(SerializationTest)); public DependencyProperty CuboidProperty = DependencyProperty.Register("Cuboid", typeof(SerializationTest)); - internal DependencyProperty StateProperty = DependencyProperty.Register("State", typeof(SerializationTest)); + public DependencyProperty StateProperty = DependencyProperty.Register("State", typeof(SerializationTest)); - internal class Pair + public class Pair { public int Int { get; set; } public Shape Collider { get; set; } } - internal class StateHolder + public class StateHolder { public List Shape { get; set; } } @@ -47,10 +47,10 @@ public async Task Test1() var entity = new TestEntity(); await entity.ReadStateAsync(); - await entity.SetCurrentValue(SlotProperty, slot); - await entity.SetCurrentValue(ShapeProperty, shape); - await entity.SetCurrentValue(CuboidProperty, shape); - await entity.SetCurrentValue(StateProperty, state); + entity.SetCurrentValue(SlotProperty, slot); + entity.SetCurrentValue(ShapeProperty, shape); + entity.SetCurrentValue(CuboidProperty, shape); + entity.SetCurrentValue(StateProperty, state); var doc = Serialize(entity); From ce35626aa3f2bdd20381502b2f0b27010d98cd3a Mon Sep 17 00:00:00 2001 From: SunnyCase Date: Mon, 27 Nov 2017 18:44:08 +0800 Subject: [PATCH 2/7] Add mongodb storage --- .../Components/GameTickComponent.cs | 7 +++-- src/MineCase.Server.Grains/StreamProviders.cs | 4 +++ .../World/TickEmitterGrain.cs | 29 ++++++++----------- .../World/ITickEmitter.cs | 6 ++-- src/MineCase.Server/AppBootstrapper.cs | 2 ++ src/MineCase.Server/MineCase.Server.csproj | 1 + .../OrleansConfiguration.dev.xml | 2 +- .../OrleansConfiguration.docker.xml | 2 +- src/MineCase.Server/Program.cs | 2 +- 9 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/MineCase.Server.Grains/Components/GameTickComponent.cs b/src/MineCase.Server.Grains/Components/GameTickComponent.cs index d75844f6..1aab6e9a 100644 --- a/src/MineCase.Server.Grains/Components/GameTickComponent.cs +++ b/src/MineCase.Server.Grains/Components/GameTickComponent.cs @@ -38,8 +38,9 @@ private void OnAddressByPartitionKeyChanged(object sender, (string oldKey, strin { AttachedObject.QueueOperation(async () => { + /* if (!string.IsNullOrEmpty(e.oldKey)) - await GrainFactory.GetGrain(e.oldKey).Unsubscribe(AttachedObject); + await GrainFactory.GetGrain(e.oldKey).Unsubscribe(AttachedObject);*/ await TrySubscribe(); }); } @@ -68,7 +69,7 @@ private async Task TrySubscribe() { var key = AttachedObject.GetAddressByPartitionKey(); if (!string.IsNullOrEmpty(key)) - await GrainFactory.GetGrain(key).Subscribe(AttachedObject); + await Task.CompletedTask; // GrainFactory.GetGrain(key).Subscribe(AttachedObject); } } @@ -76,7 +77,7 @@ private async Task TryUnsubscribe() { var key = AttachedObject.GetAddressByPartitionKey(); if (!string.IsNullOrEmpty(key)) - await GrainFactory.GetGrain(key).Unsubscribe(AttachedObject); + await Task.CompletedTask; // await GrainFactory.GetGrain(key).Unsubscribe(AttachedObject); } } } diff --git a/src/MineCase.Server.Grains/StreamProviders.cs b/src/MineCase.Server.Grains/StreamProviders.cs index eb904300..b85bdda0 100644 --- a/src/MineCase.Server.Grains/StreamProviders.cs +++ b/src/MineCase.Server.Grains/StreamProviders.cs @@ -8,9 +8,13 @@ internal class StreamProviders { public const string JobsProvider = "JobsProvider"; + public const string TransientProvider = "TransientProvider"; + public static class Namespaces { public const string ChunkSender = "ChunkSender"; + + public const string TickEmitter = "TickEmitter"; } } } diff --git a/src/MineCase.Server.Grains/World/TickEmitterGrain.cs b/src/MineCase.Server.Grains/World/TickEmitterGrain.cs index 07f92d89..98637425 100644 --- a/src/MineCase.Server.Grains/World/TickEmitterGrain.cs +++ b/src/MineCase.Server.Grains/World/TickEmitterGrain.cs @@ -11,6 +11,7 @@ using MineCase.World; using Orleans; using Orleans.Concurrency; +using Orleans.Streams; namespace MineCase.Server.World { @@ -19,6 +20,7 @@ namespace MineCase.Server.World internal class TickEmitterGrain : PersistableDependencyObject, ITickEmitter { private AutoSaveStateComponent _autoSave; + private IAsyncStream _tickStream; private StateHolder State => GetValue(StateComponent.StateProperty); @@ -33,25 +35,16 @@ protected override void InitializeComponents() SetComponent(_autoSave); } - public async Task OnGameTick(GameTickArgs e) - { - var message = new GameTick { Args = e }; - await Task.WhenAll(from en in State.Subscription select en.Tell(message)); - await _autoSave.OnGameTick(this, e); - } - - public Task Subscribe(IDependencyObject observer) + public override async Task OnActivateAsync() { - if (State.Subscription.Add(observer)) - MarkDirty(); - return Task.CompletedTask; + await base.OnActivateAsync(); + _tickStream = GetStreamProvider(StreamProviders.TransientProvider).GetStream(State.SubscriptionStreamId, StreamProviders.Namespaces.TickEmitter); } - public Task Unsubscribe(IDependencyObject observer) + public async Task OnGameTick(GameTickArgs e) { - if (State.Subscription.Remove(observer)) - MarkDirty(); - return Task.CompletedTask; + await _tickStream.OnNextAsync(e); + await _autoSave.OnGameTick(this, e); } private void MarkDirty() @@ -59,9 +52,11 @@ private void MarkDirty() ValueStorage.IsDirty = true; } + public Task GetSubscriptionStreamId() => Task.FromResult(State.SubscriptionStreamId); + internal class StateHolder { - public HashSet Subscription { get; set; } + public Guid SubscriptionStreamId { get; set; } public StateHolder() { @@ -69,7 +64,7 @@ public StateHolder() public StateHolder(InitializeStateMark mark) { - Subscription = new HashSet(); + SubscriptionStreamId = Guid.NewGuid(); } } } diff --git a/src/MineCase.Server.Interfaces/World/ITickEmitter.cs b/src/MineCase.Server.Interfaces/World/ITickEmitter.cs index 1aedd256..700bb376 100644 --- a/src/MineCase.Server.Interfaces/World/ITickEmitter.cs +++ b/src/MineCase.Server.Interfaces/World/ITickEmitter.cs @@ -12,10 +12,8 @@ namespace MineCase.Server.World { public interface ITickEmitter : IAddressByPartition { - Task OnGameTick(GameTickArgs e); - - Task Subscribe(IDependencyObject observer); + Task GetSubscriptionStreamId(); - Task Unsubscribe(IDependencyObject observer); + Task OnGameTick(GameTickArgs e); } } diff --git a/src/MineCase.Server/AppBootstrapper.cs b/src/MineCase.Server/AppBootstrapper.cs index 39e7ce85..2b27087d 100644 --- a/src/MineCase.Server/AppBootstrapper.cs +++ b/src/MineCase.Server/AppBootstrapper.cs @@ -39,6 +39,8 @@ private static void ConfigureAppConfiguration(IConfigurationBuilder configuratio private static void SelectAssemblies() { var assemblies = new List(); + assemblies.Add(typeof(Orleans.Providers.MemoryStreamProvider).Assembly); + assemblies.Add(typeof(Orleans.Providers.MongoDB.StorageProviders.MongoStorageProvider).Assembly); assemblies .AddEngine() .AddInterfaces() diff --git a/src/MineCase.Server/MineCase.Server.csproj b/src/MineCase.Server/MineCase.Server.csproj index dc669649..50499f0b 100644 --- a/src/MineCase.Server/MineCase.Server.csproj +++ b/src/MineCase.Server/MineCase.Server.csproj @@ -36,6 +36,7 @@ + diff --git a/src/MineCase.Server/OrleansConfiguration.dev.xml b/src/MineCase.Server/OrleansConfiguration.dev.xml index 947f7a17..c1a1c362 100644 --- a/src/MineCase.Server/OrleansConfiguration.dev.xml +++ b/src/MineCase.Server/OrleansConfiguration.dev.xml @@ -4,7 +4,7 @@ - + diff --git a/src/MineCase.Server/OrleansConfiguration.docker.xml b/src/MineCase.Server/OrleansConfiguration.docker.xml index e353a922..8ba28405 100644 --- a/src/MineCase.Server/OrleansConfiguration.docker.xml +++ b/src/MineCase.Server/OrleansConfiguration.docker.xml @@ -4,7 +4,7 @@ - + diff --git a/src/MineCase.Server/Program.cs b/src/MineCase.Server/Program.cs index 2e360e4d..ea21a899 100644 --- a/src/MineCase.Server/Program.cs +++ b/src/MineCase.Server/Program.cs @@ -6,6 +6,7 @@ using System.Threading; using System.Threading.Tasks; using MineCase.Serialization.Serializers; +using Orleans; namespace MineCase.Server { @@ -52,7 +53,6 @@ private static ClusterConfiguration LoadClusterConfiguration() { var cluster = new ClusterConfiguration(); cluster.LoadFromFile("OrleansConfiguration.dev.xml"); - cluster.AddMemoryStorageProvider(); return cluster; } From ebab35be72567047455e3d070464b01a55fc44e3 Mon Sep 17 00:00:00 2001 From: SunnyCase Date: Tue, 28 Nov 2017 17:32:22 +0800 Subject: [PATCH 3/7] Update --- src/MineCase.Core/MineCase.Core.csproj | 4 ++ src/MineCase.Core/World/GameTickArgs.cs | 3 ++ .../DependencyObject.Server.cs | 11 ++++ .../Components/GameTickComponent.cs | 7 ++- .../MineCase.Server.Grains.csproj | 1 + .../Persistence/AppDbContext.cs | 7 ++- .../Components/PeriodicSaveStateComponent.cs | 36 +++++++++++++ .../World/ChunkColumnGrain.cs | 10 +--- .../World/ChunkTrackingHub.cs | 5 -- .../World/CollectableFinder.cs | 9 +--- .../World/TickEmitterGrain.cs | 53 +++++-------------- .../World/WorldPartitionGrain.cs | 25 +++------ .../Game/ITickable.cs | 11 ---- .../World/IChunkColumn.cs | 2 - .../World/IChunkTrackingHub.cs | 2 - .../World/ICollectableFinder.cs | 2 - .../World/ITickEmitter.cs | 6 ++- src/MineCase.Server/AppBootstrapper.cs | 2 - .../OrleansConfiguration.dev.xml | 4 +- .../OrleansConfiguration.docker.xml | 4 +- src/MineCase.Server/Program.cs | 5 ++ src/MineCase.Server/config.docker.json | 2 +- src/MineCase.Server/config.json | 2 +- 23 files changed, 94 insertions(+), 119 deletions(-) create mode 100644 src/MineCase.Server.Grains/Persistence/Components/PeriodicSaveStateComponent.cs delete mode 100644 src/MineCase.Server.Interfaces/Game/ITickable.cs diff --git a/src/MineCase.Core/MineCase.Core.csproj b/src/MineCase.Core/MineCase.Core.csproj index 55fbb0ef..37988cbc 100644 --- a/src/MineCase.Core/MineCase.Core.csproj +++ b/src/MineCase.Core/MineCase.Core.csproj @@ -38,6 +38,10 @@ + + + + diff --git a/src/MineCase.Core/World/GameTickArgs.cs b/src/MineCase.Core/World/GameTickArgs.cs index a7000745..2ce1b9bc 100644 --- a/src/MineCase.Core/World/GameTickArgs.cs +++ b/src/MineCase.Core/World/GameTickArgs.cs @@ -4,6 +4,9 @@ namespace MineCase.World { +#if !NET46 + [Orleans.Concurrency.Immutable] +#endif public sealed class GameTickArgs { public TimeSpan DeltaTime { get; set; } diff --git a/src/MineCase.Engine/DependencyObject.Server.cs b/src/MineCase.Engine/DependencyObject.Server.cs index 2c8b3502..0f9b7546 100644 --- a/src/MineCase.Engine/DependencyObject.Server.cs +++ b/src/MineCase.Engine/DependencyObject.Server.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using MineCase.Engine.Serialization; +using Orleans.Streams; namespace MineCase.Engine { @@ -113,5 +114,15 @@ public async Task ClearOperationQueue() await _operationQueue.Dequeue()(); } } + + public IAsyncStream GetStream(string providerName, Guid streamId, string streamNamespace) + { + return GetStreamProvider(providerName).GetStream(streamId, streamNamespace); + } + + public new IDisposable RegisterTimer(Func callback, object state, TimeSpan dueTime, TimeSpan period) + { + return base.RegisterTimer(callback, state, dueTime, period); + } } } diff --git a/src/MineCase.Server.Grains/Components/GameTickComponent.cs b/src/MineCase.Server.Grains/Components/GameTickComponent.cs index 1aab6e9a..d75844f6 100644 --- a/src/MineCase.Server.Grains/Components/GameTickComponent.cs +++ b/src/MineCase.Server.Grains/Components/GameTickComponent.cs @@ -38,9 +38,8 @@ private void OnAddressByPartitionKeyChanged(object sender, (string oldKey, strin { AttachedObject.QueueOperation(async () => { - /* if (!string.IsNullOrEmpty(e.oldKey)) - await GrainFactory.GetGrain(e.oldKey).Unsubscribe(AttachedObject);*/ + await GrainFactory.GetGrain(e.oldKey).Unsubscribe(AttachedObject); await TrySubscribe(); }); } @@ -69,7 +68,7 @@ private async Task TrySubscribe() { var key = AttachedObject.GetAddressByPartitionKey(); if (!string.IsNullOrEmpty(key)) - await Task.CompletedTask; // GrainFactory.GetGrain(key).Subscribe(AttachedObject); + await GrainFactory.GetGrain(key).Subscribe(AttachedObject); } } @@ -77,7 +76,7 @@ private async Task TryUnsubscribe() { var key = AttachedObject.GetAddressByPartitionKey(); if (!string.IsNullOrEmpty(key)) - await Task.CompletedTask; // await GrainFactory.GetGrain(key).Unsubscribe(AttachedObject); + await GrainFactory.GetGrain(key).Unsubscribe(AttachedObject); } } } diff --git a/src/MineCase.Server.Grains/MineCase.Server.Grains.csproj b/src/MineCase.Server.Grains/MineCase.Server.Grains.csproj index 4553f064..9488692f 100644 --- a/src/MineCase.Server.Grains/MineCase.Server.Grains.csproj +++ b/src/MineCase.Server.Grains/MineCase.Server.Grains.csproj @@ -22,6 +22,7 @@ + diff --git a/src/MineCase.Server.Grains/Persistence/AppDbContext.cs b/src/MineCase.Server.Grains/Persistence/AppDbContext.cs index 322154da..07827c34 100644 --- a/src/MineCase.Server.Grains/Persistence/AppDbContext.cs +++ b/src/MineCase.Server.Grains/Persistence/AppDbContext.cs @@ -10,14 +10,13 @@ namespace MineCase.Server.Persistence { internal class AppDbContext { - public const string DatabaseName = "minecase"; - private readonly IMongoDatabase _db; public AppDbContext(IOptions options) { - var client = new MongoClient(options.Value.ConnectionString); - _db = client.GetDatabase(DatabaseName); + var url = new MongoUrl(options.Value.ConnectionString); + var client = new MongoClient(url); + _db = client.GetDatabase(url.DatabaseName); } public IMongoCollection GetEntityStateCollection(string name) diff --git a/src/MineCase.Server.Grains/Persistence/Components/PeriodicSaveStateComponent.cs b/src/MineCase.Server.Grains/Persistence/Components/PeriodicSaveStateComponent.cs new file mode 100644 index 00000000..253b7811 --- /dev/null +++ b/src/MineCase.Server.Grains/Persistence/Components/PeriodicSaveStateComponent.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using MineCase.Engine; +using MineCase.Server.Components; +using MineCase.World; + +namespace MineCase.Server.Persistence.Components +{ + internal class PeriodicSaveStateComponent : Component + { + private readonly TimeSpan _periodTime; + + public PeriodicSaveStateComponent(TimeSpan periodTime, string name = "periodicSaveState") + : base(name) + { + _periodTime = periodTime; + } + + protected override void OnAttached() + { + AttachedObject.RegisterTimer(SaveIfDirty, null, _periodTime, _periodTime); + } + + private Task SaveIfDirty(object state) + { + if (AttachedObject.ValueStorage.IsDirty) + { + return AttachedObject.WriteStateAsync(); + } + + return Task.CompletedTask; + } + } +} diff --git a/src/MineCase.Server.Grains/World/ChunkColumnGrain.cs b/src/MineCase.Server.Grains/World/ChunkColumnGrain.cs index 448dd320..5db68b11 100644 --- a/src/MineCase.Server.Grains/World/ChunkColumnGrain.cs +++ b/src/MineCase.Server.Grains/World/ChunkColumnGrain.cs @@ -24,8 +24,6 @@ namespace MineCase.Server.World [Reentrant] internal class ChunkColumnGrain : AddressByPartitionGrain, IChunkColumn { - private AutoSaveStateComponent _autoSave; - private StateHolder State => GetValue(StateComponent.StateProperty); protected override void InitializePreLoadComponent() @@ -35,8 +33,7 @@ protected override void InitializePreLoadComponent() protected override void InitializeComponents() { - _autoSave = new AutoSaveStateComponent(AutoSaveStateComponent.PerMinute * 5); - SetComponent(_autoSave); + SetComponent(new PeriodicSaveStateComponent(TimeSpan.FromMinutes(1))); } public async Task GetBlockState(int x, int y, int z) @@ -187,11 +184,6 @@ public Task OnBlockNeighborChanged(int x, int y, int z, BlockWorldPos neighborPo return Task.CompletedTask; } - public Task OnGameTick(GameTickArgs e) - { - return _autoSave.OnGameTick(this, e); - } - private void MarkDirty() { ValueStorage.IsDirty = true; diff --git a/src/MineCase.Server.Grains/World/ChunkTrackingHub.cs b/src/MineCase.Server.Grains/World/ChunkTrackingHub.cs index be1f97b2..9b343292 100644 --- a/src/MineCase.Server.Grains/World/ChunkTrackingHub.cs +++ b/src/MineCase.Server.Grains/World/ChunkTrackingHub.cs @@ -59,10 +59,5 @@ public Task> GetTrackedPlayers() { return Task.FromResult(_trackingPlayers.Keys.ToList()); } - - public Task OnGameTick(GameTickArgs e) - { - return Task.CompletedTask; - } } } diff --git a/src/MineCase.Server.Grains/World/CollectableFinder.cs b/src/MineCase.Server.Grains/World/CollectableFinder.cs index dd904764..6e8d8e4f 100644 --- a/src/MineCase.Server.Grains/World/CollectableFinder.cs +++ b/src/MineCase.Server.Grains/World/CollectableFinder.cs @@ -27,7 +27,6 @@ public static readonly (int x, int z)[] CrossCoords = new[] (0, 0), (-1, 0), (-1, 1), (0, 1), (1, 1), (1, 0), (1, -1), (0, -1), (-1, -1) }; - private AutoSaveStateComponent _autoSave; private List<(Cuboid box, ICollectableFinder finder)> _neighborFinders; private StateHolder State => GetValue(StateComponent.StateProperty); @@ -52,8 +51,7 @@ protected override void InitializePreLoadComponent() protected override void InitializeComponents() { - _autoSave = new AutoSaveStateComponent(AutoSaveStateComponent.PerMinute); - SetComponent(_autoSave); + SetComponent(new PeriodicSaveStateComponent(TimeSpan.FromMinutes(1))); } public Task RegisterCollider(IDependencyObject entity, Shape colliderShape) @@ -117,11 +115,6 @@ private void MarkDirty() ValueStorage.IsDirty = true; } - public Task OnGameTick(GameTickArgs e) - { - return _autoSave.OnGameTick(this, e); - } - public class StateHolder { public Dictionary Colliders { get; set; } diff --git a/src/MineCase.Server.Grains/World/TickEmitterGrain.cs b/src/MineCase.Server.Grains/World/TickEmitterGrain.cs index 98637425..d208257b 100644 --- a/src/MineCase.Server.Grains/World/TickEmitterGrain.cs +++ b/src/MineCase.Server.Grains/World/TickEmitterGrain.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -15,57 +16,27 @@ namespace MineCase.Server.World { - [PersistTableName("tickEmitter")] [Reentrant] - internal class TickEmitterGrain : PersistableDependencyObject, ITickEmitter + internal class TickEmitterGrain : Grain, ITickEmitter { - private AutoSaveStateComponent _autoSave; - private IAsyncStream _tickStream; + private ImmutableHashSet _tickables = ImmutableHashSet.Empty; - private StateHolder State => GetValue(StateComponent.StateProperty); - - protected override void InitializePreLoadComponent() - { - SetComponent(new StateComponent()); - } - - protected override void InitializeComponents() - { - _autoSave = new AutoSaveStateComponent(AutoSaveStateComponent.PerMinute); - SetComponent(_autoSave); - } - - public override async Task OnActivateAsync() + public Task OnGameTick(GameTickArgs e) { - await base.OnActivateAsync(); - _tickStream = GetStreamProvider(StreamProviders.TransientProvider).GetStream(State.SubscriptionStreamId, StreamProviders.Namespaces.TickEmitter); + var msg = new GameTick { Args = e }; + return Task.WhenAll(from t in _tickables select t.Tell(msg)); } - public async Task OnGameTick(GameTickArgs e) + public Task Subscribe(IDependencyObject observer) { - await _tickStream.OnNextAsync(e); - await _autoSave.OnGameTick(this, e); + _tickables = _tickables.Add(observer); + return Task.CompletedTask; } - private void MarkDirty() + public Task Unsubscribe(IDependencyObject observer) { - ValueStorage.IsDirty = true; - } - - public Task GetSubscriptionStreamId() => Task.FromResult(State.SubscriptionStreamId); - - internal class StateHolder - { - public Guid SubscriptionStreamId { get; set; } - - public StateHolder() - { - } - - public StateHolder(InitializeStateMark mark) - { - SubscriptionStreamId = Guid.NewGuid(); - } + _tickables = _tickables.Remove(observer); + return Task.CompletedTask; } } } diff --git a/src/MineCase.Server.Grains/World/WorldPartitionGrain.cs b/src/MineCase.Server.Grains/World/WorldPartitionGrain.cs index 77e567c3..9586b528 100644 --- a/src/MineCase.Server.Grains/World/WorldPartitionGrain.cs +++ b/src/MineCase.Server.Grains/World/WorldPartitionGrain.cs @@ -19,10 +19,6 @@ namespace MineCase.Server.World internal class WorldPartitionGrain : AddressByPartitionGrain, IWorldPartition { private ITickEmitter _tickEmitter; - private ICollectableFinder _collectableFinder; - private IChunkTrackingHub _chunkTrackingHub; - private IChunkColumn _chunkColumn; - private AutoSaveStateComponent _autoSave; private HashSet _players = new HashSet(); private StateHolder State => GetValue(StateComponent.StateProperty); @@ -32,15 +28,11 @@ protected override void InitializePreLoadComponent() SetComponent(new StateComponent()); _tickEmitter = GrainFactory.GetPartitionGrain(this); - _collectableFinder = GrainFactory.GetPartitionGrain(this); - _chunkTrackingHub = GrainFactory.GetPartitionGrain(this); - _chunkColumn = GrainFactory.GetPartitionGrain(this); } protected override void InitializeComponents() { - _autoSave = new AutoSaveStateComponent(AutoSaveStateComponent.PerMinute); - SetComponent(_autoSave); + SetComponent(new PeriodicSaveStateComponent(TimeSpan.FromMinutes(1))); } public async Task Enter(IPlayer player) @@ -69,16 +61,6 @@ public async Task Leave(IPlayer player) } } - public async Task OnGameTick(GameTickArgs e) - { - await Task.WhenAll( - _tickEmitter.OnGameTick(e), - _collectableFinder.OnGameTick(e), - _chunkTrackingHub.OnGameTick(e), - _chunkColumn.OnGameTick(e)); - await _autoSave.OnGameTick(this, e); - } - async Task IWorldPartition.SubscribeDiscovery(IEntity entity) { if (State.DiscoveryEntities.Add(entity)) @@ -100,6 +82,11 @@ private void MarkDirty() ValueStorage.IsDirty = true; } + public Task OnGameTick(GameTickArgs e) + { + return _tickEmitter.OnGameTick(e); + } + internal class StateHolder { public HashSet DiscoveryEntities { get; set; } diff --git a/src/MineCase.Server.Interfaces/Game/ITickable.cs b/src/MineCase.Server.Interfaces/Game/ITickable.cs deleted file mode 100644 index 9b0c89f0..00000000 --- a/src/MineCase.Server.Interfaces/Game/ITickable.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using System.Threading.Tasks; -using Orleans; - -namespace MineCase.Server.Game -{ - public interface ITickable : IGrainWithStringKey - { - Task OnGameTick(TimeSpan deltaTime, long worldAge); - } -} diff --git a/src/MineCase.Server.Interfaces/World/IChunkColumn.cs b/src/MineCase.Server.Interfaces/World/IChunkColumn.cs index 59fd0188..e10e6c22 100644 --- a/src/MineCase.Server.Interfaces/World/IChunkColumn.cs +++ b/src/MineCase.Server.Interfaces/World/IChunkColumn.cs @@ -24,7 +24,5 @@ public interface IChunkColumn : IAddressByPartition Task GetBlockEntity(int x, int y, int z); Task OnBlockNeighborChanged(int x, int y, int z, BlockWorldPos neighborPosition, BlockState oldState, BlockState newState); - - Task OnGameTick(GameTickArgs e); } } diff --git a/src/MineCase.Server.Interfaces/World/IChunkTrackingHub.cs b/src/MineCase.Server.Interfaces/World/IChunkTrackingHub.cs index 8f419ea7..aecc8ba2 100644 --- a/src/MineCase.Server.Interfaces/World/IChunkTrackingHub.cs +++ b/src/MineCase.Server.Interfaces/World/IChunkTrackingHub.cs @@ -18,7 +18,5 @@ public interface IChunkTrackingHub : IAddressByPartition, IPacketSink Task Unsubscribe(IPlayer player); Task> GetTrackedPlayers(); - - Task OnGameTick(GameTickArgs e); } } diff --git a/src/MineCase.Server.Interfaces/World/ICollectableFinder.cs b/src/MineCase.Server.Interfaces/World/ICollectableFinder.cs index 95624dd7..c5a623b6 100644 --- a/src/MineCase.Server.Interfaces/World/ICollectableFinder.cs +++ b/src/MineCase.Server.Interfaces/World/ICollectableFinder.cs @@ -22,7 +22,5 @@ public interface ICollectableFinder : IAddressByPartition Task> CollisionInChunk(Shape colliderShape); Task SpawnPickup(Vector3 position, Immutable slots); - - Task OnGameTick(GameTickArgs e); } } diff --git a/src/MineCase.Server.Interfaces/World/ITickEmitter.cs b/src/MineCase.Server.Interfaces/World/ITickEmitter.cs index 700bb376..1aedd256 100644 --- a/src/MineCase.Server.Interfaces/World/ITickEmitter.cs +++ b/src/MineCase.Server.Interfaces/World/ITickEmitter.cs @@ -12,8 +12,10 @@ namespace MineCase.Server.World { public interface ITickEmitter : IAddressByPartition { - Task GetSubscriptionStreamId(); - Task OnGameTick(GameTickArgs e); + + Task Subscribe(IDependencyObject observer); + + Task Unsubscribe(IDependencyObject observer); } } diff --git a/src/MineCase.Server/AppBootstrapper.cs b/src/MineCase.Server/AppBootstrapper.cs index 2b27087d..39e7ce85 100644 --- a/src/MineCase.Server/AppBootstrapper.cs +++ b/src/MineCase.Server/AppBootstrapper.cs @@ -39,8 +39,6 @@ private static void ConfigureAppConfiguration(IConfigurationBuilder configuratio private static void SelectAssemblies() { var assemblies = new List(); - assemblies.Add(typeof(Orleans.Providers.MemoryStreamProvider).Assembly); - assemblies.Add(typeof(Orleans.Providers.MongoDB.StorageProviders.MongoStorageProvider).Assembly); assemblies .AddEngine() .AddInterfaces() diff --git a/src/MineCase.Server/OrleansConfiguration.dev.xml b/src/MineCase.Server/OrleansConfiguration.dev.xml index c1a1c362..c7f8de0e 100644 --- a/src/MineCase.Server/OrleansConfiguration.dev.xml +++ b/src/MineCase.Server/OrleansConfiguration.dev.xml @@ -3,11 +3,9 @@ - - - + diff --git a/src/MineCase.Server/OrleansConfiguration.docker.xml b/src/MineCase.Server/OrleansConfiguration.docker.xml index 8ba28405..7cdc61a6 100644 --- a/src/MineCase.Server/OrleansConfiguration.docker.xml +++ b/src/MineCase.Server/OrleansConfiguration.docker.xml @@ -3,11 +3,9 @@ - - - + diff --git a/src/MineCase.Server/Program.cs b/src/MineCase.Server/Program.cs index ea21a899..4b7fa497 100644 --- a/src/MineCase.Server/Program.cs +++ b/src/MineCase.Server/Program.cs @@ -53,6 +53,11 @@ private static ClusterConfiguration LoadClusterConfiguration() { var cluster = new ClusterConfiguration(); cluster.LoadFromFile("OrleansConfiguration.dev.xml"); + cluster.AddMongoDBStorageProvider("PubSubStore", c => + { + c.ConnectionString = Configuration.GetSection("persistenceOptions")["connectionString"]; + c.UseJsonFormat = true; + }); return cluster; } diff --git a/src/MineCase.Server/config.docker.json b/src/MineCase.Server/config.docker.json index 3cad04bd..cf0adbc3 100644 --- a/src/MineCase.Server/config.docker.json +++ b/src/MineCase.Server/config.docker.json @@ -1,5 +1,5 @@ { "persistenceOptions": { - "connectionString": "mongodb://minecase.persistdb:27017" + "connectionString": "mongodb://minecase.persistdb:27017/minecase" } } \ No newline at end of file diff --git a/src/MineCase.Server/config.json b/src/MineCase.Server/config.json index 03bcbdf3..d22abd3e 100644 --- a/src/MineCase.Server/config.json +++ b/src/MineCase.Server/config.json @@ -1,5 +1,5 @@ { "persistenceOptions": { - "connectionString": "mongodb://localhost:27017" + "connectionString": "mongodb://localhost:27017/minecase" } } \ No newline at end of file From 3e3243d90cec9d6a0ef798b8c29dee04090d6a00 Mon Sep 17 00:00:00 2001 From: SunnyCase Date: Tue, 28 Nov 2017 18:37:41 +0800 Subject: [PATCH 4/7] Update --- .../World/WorldGrain.cs | 9 ++---- .../World/WorldPartitionGrain.cs | 28 +++++++++++++++++++ .../World/IWorldPartition.cs | 2 -- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/MineCase.Server.Grains/World/WorldGrain.cs b/src/MineCase.Server.Grains/World/WorldGrain.cs index bc0fcd2a..45319e3e 100644 --- a/src/MineCase.Server.Grains/World/WorldGrain.cs +++ b/src/MineCase.Server.Grains/World/WorldGrain.cs @@ -20,7 +20,6 @@ internal class WorldGrain : PersistableDependencyObject, IWorld { private GeneratorSettings _genSettings; // 生成设置 private string _seed; // 世界种子 - private AutoSaveStateComponent _autoSave; private readonly HashSet _activedPartitions = new HashSet(); private StateHolder State => GetValue(StateComponent.StateProperty); @@ -32,8 +31,7 @@ protected override void InitializePreLoadComponent() protected override void InitializeComponents() { - _autoSave = new AutoSaveStateComponent(AutoSaveStateComponent.PerMinute); - SetComponent(_autoSave); + SetComponent(new PeriodicSaveStateComponent(TimeSpan.FromMinutes(1))); } public override async Task OnActivateAsync() @@ -58,12 +56,11 @@ public Task NewEntityId() return Task.FromResult(id); } - public async Task OnGameTick(GameTickArgs e) + public Task OnGameTick(GameTickArgs e) { State.WorldAge++; MarkDirty(); - await Task.WhenAll(from p in _activedPartitions select p.OnGameTick(e)); - await _autoSave.OnGameTick(this, e); + return Task.CompletedTask; } public Task GetAge() => Task.FromResult(State.WorldAge); diff --git a/src/MineCase.Server.Grains/World/WorldPartitionGrain.cs b/src/MineCase.Server.Grains/World/WorldPartitionGrain.cs index 9586b528..ea3794c7 100644 --- a/src/MineCase.Server.Grains/World/WorldPartitionGrain.cs +++ b/src/MineCase.Server.Grains/World/WorldPartitionGrain.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -20,6 +21,11 @@ internal class WorldPartitionGrain : AddressByPartitionGrain, IWorldPartition { private ITickEmitter _tickEmitter; private HashSet _players = new HashSet(); + private IDisposable _tickTimer; + private Stopwatch _stopwatch; + private long _worldAge; + private long _actualAge; + private static readonly long _updateTick = TimeSpan.FromMilliseconds(50).Ticks; private StateHolder State => GetValue(StateComponent.StateProperty); @@ -45,7 +51,29 @@ await Task.WhenAll(from e in State.DiscoveryEntities select e.Tell(message)); if (active) + { await World.ActivePartition(this); + _worldAge = await World.GetAge(); + _actualAge = 0; + _stopwatch = new Stopwatch(); + _stopwatch.Start(); + _tickTimer = RegisterTimer(OnTick, null, TimeSpan.Zero, TimeSpan.FromMilliseconds(5)); + } + } + } + + private async Task OnTick(object arg) + { + var expectedAge = _stopwatch.ElapsedTicks / _updateTick; + var e = new GameTickArgs { DeltaTime = TimeSpan.FromMilliseconds(50) }; + var updateTimes = expectedAge - _actualAge; + for (int i = 0; i < updateTimes; i++) + { + e.WorldAge = _worldAge; + e.TimeOfDay = _worldAge % 24000; + await _tickEmitter.OnGameTick(e); + _worldAge++; + _actualAge++; } } diff --git a/src/MineCase.Server.Interfaces/World/IWorldPartition.cs b/src/MineCase.Server.Interfaces/World/IWorldPartition.cs index affa59c7..9fafe118 100644 --- a/src/MineCase.Server.Interfaces/World/IWorldPartition.cs +++ b/src/MineCase.Server.Interfaces/World/IWorldPartition.cs @@ -14,8 +14,6 @@ public interface IWorldPartition : IAddressByPartition Task Leave(IPlayer player); - Task OnGameTick(GameTickArgs e); - Task SubscribeDiscovery(IEntity entity); Task UnsubscribeDiscovery(IEntity entity); From 1ceb60926cd2cea5b5ff5ed78a4a400857489661 Mon Sep 17 00:00:00 2001 From: SunnyCase Date: Wed, 29 Nov 2017 11:25:08 +0800 Subject: [PATCH 5/7] Add FixedUpdateComponent --- .../Components/FixedUpdateComponent.cs | 63 +++++++++++++++++++ .../Game/GameSession.cs | 56 +++++++---------- .../World/WorldPartitionGrain.cs | 38 ++++------- 3 files changed, 99 insertions(+), 58 deletions(-) create mode 100644 src/MineCase.Server.Grains/Components/FixedUpdateComponent.cs diff --git a/src/MineCase.Server.Grains/Components/FixedUpdateComponent.cs b/src/MineCase.Server.Grains/Components/FixedUpdateComponent.cs new file mode 100644 index 00000000..f253d93c --- /dev/null +++ b/src/MineCase.Server.Grains/Components/FixedUpdateComponent.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using MineCase.Engine; +using MineCase.Server.World; +using MineCase.World; + +namespace MineCase.Server.Components +{ + public class FixedUpdateComponent : Component + { + private IDisposable _tickTimer; + private Stopwatch _stopwatch; + private long _worldAge; + private long _actualAge; + private TimeSpan _lastUpdate; + private static readonly long _updateTick = TimeSpan.FromMilliseconds(50).Ticks; + + public event AsyncEventHandler Tick; + + public FixedUpdateComponent(string name = "fixedUpdate") + : base(name) + { + } + + public async Task Start(IWorld world) + { + _worldAge = await world.GetAge(); + _actualAge = 0; + _stopwatch = new Stopwatch(); + _stopwatch.Start(); + _tickTimer = AttachedObject.RegisterTimer(OnTick, null, TimeSpan.Zero, TimeSpan.FromMilliseconds(5)); + } + + private async Task OnTick(object arg) + { + var expectedAge = _stopwatch.ElapsedTicks / _updateTick; + var e = new GameTickArgs { DeltaTime = TimeSpan.FromMilliseconds(50) }; + var updateTimes = expectedAge - _actualAge; + var now = _stopwatch.Elapsed; + for (int i = 0; i < updateTimes; i++) + { + e.WorldAge = _worldAge; + e.TimeOfDay = _worldAge % 24000; + await Tick.InvokeSerial(this, e); + _worldAge++; + _actualAge++; + } + + var deltaTime = now - _lastUpdate; + _lastUpdate = now; + } + + public void Stop() + { + _tickTimer?.Dispose(); + _tickTimer = null; + } + } +} diff --git a/src/MineCase.Server.Grains/Game/GameSession.cs b/src/MineCase.Server.Grains/Game/GameSession.cs index 85680df2..4057702e 100644 --- a/src/MineCase.Server.Grains/Game/GameSession.cs +++ b/src/MineCase.Server.Grains/Game/GameSession.cs @@ -5,8 +5,11 @@ using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using MineCase.Engine; using MineCase.Protocol.Play; +using MineCase.Server.Components; using MineCase.Server.Network.Play; +using MineCase.Server.Persistence.Components; using MineCase.Server.User; using MineCase.Server.World; using MineCase.World; @@ -16,24 +19,38 @@ namespace MineCase.Server.Game { [Reentrant] - internal class GameSession : Grain, IGameSession + internal class GameSession : DependencyObject, IGameSession { private IWorld _world; private IChunkSender _chunkSender; + private FixedUpdateComponent _fixedUpdate; private readonly Dictionary _users = new Dictionary(); - private IDisposable _gameTick; - private DateTime _lastGameTickTime; - private ILogger _logger; public override async Task OnActivateAsync() { + await base.OnActivateAsync(); _logger = ServiceProvider.GetRequiredService().CreateLogger(); _world = await GrainFactory.GetGrain(0).GetWorld(this.GetPrimaryKeyString()); _chunkSender = GrainFactory.GetGrain(this.GetPrimaryKeyString()); - _lastGameTickTime = DateTime.UtcNow; - _gameTick = RegisterTimer(OnGameTick, null, TimeSpan.Zero, TimeSpan.FromMilliseconds(5)); + await _fixedUpdate.Start(_world); + } + + protected override void InitializeComponents() + { + SetComponent(new PeriodicSaveStateComponent(TimeSpan.FromMinutes(1))); + + _fixedUpdate = new FixedUpdateComponent(); + _fixedUpdate.Tick += OnFixedUpdate; + SetComponent(_fixedUpdate); + } + + private async Task OnFixedUpdate(object sender, GameTickArgs e) + { + await _world.OnGameTick(e); + await Task.WhenAll(from u in _users.Keys + select u.OnGameTick(e)); } public async Task JoinGame(IUser user) @@ -93,33 +110,6 @@ await item.GetName() == senderName) } } - private async Task OnGameTick(object state) - { - try - { - var now = DateTime.UtcNow; - var deltaTime = now - _lastGameTickTime; - - if (deltaTime.TotalMilliseconds < 30) return; - - _lastGameTickTime = now; - - var worldTime = await _world.GetTime(); - var timeArgs = new GameTickArgs { DeltaTime = deltaTime, WorldAge = worldTime.WorldAge, TimeOfDay = worldTime.TimeOfDay }; - - await _world.OnGameTick(timeArgs); - Task.WhenAll(from u in _users.Keys - select u.OnGameTick(timeArgs)).Ignore(); - - if (worldTime.WorldAge % 20 == 0) - _logger.LogInformation($"Delta Game Tick: {deltaTime.TotalMilliseconds}ms."); - } - catch (Exception ex) - { - _logger.LogError(ex, ex.Message); - } - } - private Task CreateStandardChatMessage(string name, string message) { StringComponent nameComponent = new StringComponent(name); diff --git a/src/MineCase.Server.Grains/World/WorldPartitionGrain.cs b/src/MineCase.Server.Grains/World/WorldPartitionGrain.cs index ea3794c7..757904ef 100644 --- a/src/MineCase.Server.Grains/World/WorldPartitionGrain.cs +++ b/src/MineCase.Server.Grains/World/WorldPartitionGrain.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using MineCase.Server.Components; using MineCase.Server.Game.BlockEntities; using MineCase.Server.Game.Entities; using MineCase.Server.Game.Entities.Components; @@ -21,11 +22,7 @@ internal class WorldPartitionGrain : AddressByPartitionGrain, IWorldPartition { private ITickEmitter _tickEmitter; private HashSet _players = new HashSet(); - private IDisposable _tickTimer; - private Stopwatch _stopwatch; - private long _worldAge; - private long _actualAge; - private static readonly long _updateTick = TimeSpan.FromMilliseconds(50).Ticks; + private FixedUpdateComponent _fixedUpdate; private StateHolder State => GetValue(StateComponent.StateProperty); @@ -39,6 +36,15 @@ protected override void InitializePreLoadComponent() protected override void InitializeComponents() { SetComponent(new PeriodicSaveStateComponent(TimeSpan.FromMinutes(1))); + + _fixedUpdate = new FixedUpdateComponent(); + _fixedUpdate.Tick += OnFixedUpdate; + SetComponent(_fixedUpdate); + } + + private Task OnFixedUpdate(object sender, GameTickArgs e) + { + return _tickEmitter.OnGameTick(e); } public async Task Enter(IPlayer player) @@ -53,30 +59,11 @@ await Task.WhenAll(from e in State.DiscoveryEntities if (active) { await World.ActivePartition(this); - _worldAge = await World.GetAge(); - _actualAge = 0; - _stopwatch = new Stopwatch(); - _stopwatch.Start(); - _tickTimer = RegisterTimer(OnTick, null, TimeSpan.Zero, TimeSpan.FromMilliseconds(5)); + await _fixedUpdate.Start(World); } } } - private async Task OnTick(object arg) - { - var expectedAge = _stopwatch.ElapsedTicks / _updateTick; - var e = new GameTickArgs { DeltaTime = TimeSpan.FromMilliseconds(50) }; - var updateTimes = expectedAge - _actualAge; - for (int i = 0; i < updateTimes; i++) - { - e.WorldAge = _worldAge; - e.TimeOfDay = _worldAge % 24000; - await _tickEmitter.OnGameTick(e); - _worldAge++; - _actualAge++; - } - } - public async Task Leave(IPlayer player) { if (_players.Remove(player)) @@ -84,6 +71,7 @@ public async Task Leave(IPlayer player) if (_players.Count == 0) { await World.DeactivePartition(this); + _fixedUpdate.Stop(); DeactivateOnIdle(); } } From bb113efef4f7f1c95335930581e0b4167166e5e5 Mon Sep 17 00:00:00 2001 From: SunnyCase Date: Wed, 29 Nov 2017 14:31:18 +0800 Subject: [PATCH 6/7] Fix a serialization bug --- src/MineCase.Server.Grains/World/ChunkColumnGrain.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/MineCase.Server.Grains/World/ChunkColumnGrain.cs b/src/MineCase.Server.Grains/World/ChunkColumnGrain.cs index 5db68b11..b9f4ec17 100644 --- a/src/MineCase.Server.Grains/World/ChunkColumnGrain.cs +++ b/src/MineCase.Server.Grains/World/ChunkColumnGrain.cs @@ -15,6 +15,8 @@ using MineCase.World; using MineCase.World.Biomes; using MineCase.World.Generation; +using MongoDB.Bson.Serialization.Attributes; +using MongoDB.Bson.Serialization.Options; using Orleans; using Orleans.Concurrency; @@ -195,6 +197,7 @@ internal class StateHolder public ChunkColumnCompactStorage Storage { get; set; } + [BsonDictionaryOptions(DictionaryRepresentation.ArrayOfDocuments)] public Dictionary BlockEntities { get; set; } public StateHolder() From f5dee770278fba68ec77d5d0470a128ec6c89214 Mon Sep 17 00:00:00 2001 From: SunnyCase Date: Wed, 29 Nov 2017 15:31:05 +0800 Subject: [PATCH 7/7] Move fixedUpdate --- .../Components/FixedUpdateComponent.cs | 1 + .../PersistableDependencyObject.cs | 34 ++++++++++++++----- .../World/TickEmitterGrain.cs | 29 +++++++++++++--- .../World/WorldPartitionGrain.cs | 26 -------------- .../World/ITickEmitter.cs | 2 -- 5 files changed, 51 insertions(+), 41 deletions(-) diff --git a/src/MineCase.Server.Grains/Components/FixedUpdateComponent.cs b/src/MineCase.Server.Grains/Components/FixedUpdateComponent.cs index f253d93c..4c4d9c45 100644 --- a/src/MineCase.Server.Grains/Components/FixedUpdateComponent.cs +++ b/src/MineCase.Server.Grains/Components/FixedUpdateComponent.cs @@ -28,6 +28,7 @@ public FixedUpdateComponent(string name = "fixedUpdate") public async Task Start(IWorld world) { + _tickTimer?.Dispose(); _worldAge = await world.GetAge(); _actualAge = 0; _stopwatch = new Stopwatch(); diff --git a/src/MineCase.Server.Grains/Persistence/PersistableDependencyObject.cs b/src/MineCase.Server.Grains/Persistence/PersistableDependencyObject.cs index 48f82808..ddcd865a 100644 --- a/src/MineCase.Server.Grains/Persistence/PersistableDependencyObject.cs +++ b/src/MineCase.Server.Grains/Persistence/PersistableDependencyObject.cs @@ -27,23 +27,34 @@ public abstract class PersistableDependencyObject : DependencyObject { protected override async Task SerializeStateAsync(DependencyObjectState state) { - var coll = GetStateCollection(); - var key = GrainReference.ToKeyString(); - await coll.ReplaceOneAsync(o => o.GrainKeyString == key, state, new UpdateOptions { IsUpsert = true }); + if (CanPersist()) + { + var coll = GetStateCollection(); + var key = GrainReference.ToKeyString(); + await coll.ReplaceOneAsync(o => o.GrainKeyString == key, state, new UpdateOptions { IsUpsert = true }); + } } protected override async Task DeserializeStateAsync() { - var coll = GetStateCollection(); - var key = GrainReference.ToKeyString(); - return await coll.Find(o => o.GrainKeyString == key).FirstOrDefaultAsync(); + if (CanPersist()) + { + var coll = GetStateCollection(); + var key = GrainReference.ToKeyString(); + return await coll.Find(o => o.GrainKeyString == key).FirstOrDefaultAsync(); + } + + return null; } protected override async Task ClearStateAsync() { - var coll = GetStateCollection(); - var key = GrainReference.ToKeyString(); - await coll.DeleteOneAsync(o => o.GrainKeyString == key); + if (CanPersist()) + { + var coll = GetStateCollection(); + var key = GrainReference.ToKeyString(); + await coll.DeleteOneAsync(o => o.GrainKeyString == key); + } } private IMongoCollection GetStateCollection() @@ -56,5 +67,10 @@ private string GetTablePrefix() { return GetType().GetCustomAttribute().TableName; } + + private bool CanPersist() + { + return GetType().IsDefined(typeof(PersistTableName), true); + } } } diff --git a/src/MineCase.Server.Grains/World/TickEmitterGrain.cs b/src/MineCase.Server.Grains/World/TickEmitterGrain.cs index d208257b..f5bb44fb 100644 --- a/src/MineCase.Server.Grains/World/TickEmitterGrain.cs +++ b/src/MineCase.Server.Grains/World/TickEmitterGrain.cs @@ -17,25 +17,46 @@ namespace MineCase.Server.World { [Reentrant] - internal class TickEmitterGrain : Grain, ITickEmitter + internal class TickEmitterGrain : AddressByPartitionGrain, ITickEmitter { private ImmutableHashSet _tickables = ImmutableHashSet.Empty; - public Task OnGameTick(GameTickArgs e) + private FixedUpdateComponent _fixedUpdate; + + protected override void InitializeComponents() + { + SetComponent(new PeriodicSaveStateComponent(TimeSpan.FromMinutes(1))); + + _fixedUpdate = new FixedUpdateComponent(); + _fixedUpdate.Tick += OnFixedUpdate; + SetComponent(_fixedUpdate); + } + + private Task OnFixedUpdate(object sender, GameTickArgs e) { var msg = new GameTick { Args = e }; return Task.WhenAll(from t in _tickables select t.Tell(msg)); } - public Task Subscribe(IDependencyObject observer) + public async Task Subscribe(IDependencyObject observer) { + bool active = _tickables.IsEmpty; _tickables = _tickables.Add(observer); - return Task.CompletedTask; + + if (active) + { + await _fixedUpdate.Start(World); + } } public Task Unsubscribe(IDependencyObject observer) { _tickables = _tickables.Remove(observer); + if (_tickables.IsEmpty) + { + _fixedUpdate.Stop(); + } + return Task.CompletedTask; } } diff --git a/src/MineCase.Server.Grains/World/WorldPartitionGrain.cs b/src/MineCase.Server.Grains/World/WorldPartitionGrain.cs index 757904ef..eed759ee 100644 --- a/src/MineCase.Server.Grains/World/WorldPartitionGrain.cs +++ b/src/MineCase.Server.Grains/World/WorldPartitionGrain.cs @@ -20,47 +20,27 @@ namespace MineCase.Server.World [Reentrant] internal class WorldPartitionGrain : AddressByPartitionGrain, IWorldPartition { - private ITickEmitter _tickEmitter; private HashSet _players = new HashSet(); - private FixedUpdateComponent _fixedUpdate; private StateHolder State => GetValue(StateComponent.StateProperty); protected override void InitializePreLoadComponent() { SetComponent(new StateComponent()); - - _tickEmitter = GrainFactory.GetPartitionGrain(this); } protected override void InitializeComponents() { SetComponent(new PeriodicSaveStateComponent(TimeSpan.FromMinutes(1))); - - _fixedUpdate = new FixedUpdateComponent(); - _fixedUpdate.Tick += OnFixedUpdate; - SetComponent(_fixedUpdate); - } - - private Task OnFixedUpdate(object sender, GameTickArgs e) - { - return _tickEmitter.OnGameTick(e); } public async Task Enter(IPlayer player) { - bool active = _players.Count == 0; if (_players.Add(player)) { var message = new DiscoveredByPlayer { Player = player }; await Task.WhenAll(from e in State.DiscoveryEntities select e.Tell(message)); - - if (active) - { - await World.ActivePartition(this); - await _fixedUpdate.Start(World); - } } } @@ -71,7 +51,6 @@ public async Task Leave(IPlayer player) if (_players.Count == 0) { await World.DeactivePartition(this); - _fixedUpdate.Stop(); DeactivateOnIdle(); } } @@ -98,11 +77,6 @@ private void MarkDirty() ValueStorage.IsDirty = true; } - public Task OnGameTick(GameTickArgs e) - { - return _tickEmitter.OnGameTick(e); - } - internal class StateHolder { public HashSet DiscoveryEntities { get; set; } diff --git a/src/MineCase.Server.Interfaces/World/ITickEmitter.cs b/src/MineCase.Server.Interfaces/World/ITickEmitter.cs index 1aedd256..8ab6af8b 100644 --- a/src/MineCase.Server.Interfaces/World/ITickEmitter.cs +++ b/src/MineCase.Server.Interfaces/World/ITickEmitter.cs @@ -12,8 +12,6 @@ namespace MineCase.Server.World { public interface ITickEmitter : IAddressByPartition { - Task OnGameTick(GameTickArgs e); - Task Subscribe(IDependencyObject observer); Task Unsubscribe(IDependencyObject observer);