diff --git a/NLog.config b/NLog.config
index 2b900e3..abf43fd 100644
--- a/NLog.config
+++ b/NLog.config
@@ -18,7 +18,7 @@
-
+
diff --git a/Torch.Server/Managers/EntityControlManager.cs b/Torch.Server/Managers/EntityControlManager.cs
new file mode 100644
index 0000000..308cb61
--- /dev/null
+++ b/Torch.Server/Managers/EntityControlManager.cs
@@ -0,0 +1,214 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Controls;
+using NLog;
+using NLog.Fluent;
+using Torch.API;
+using Torch.Collections;
+using Torch.Managers;
+using Torch.Server.ViewModels.Entities;
+using Torch.Utils;
+
+using WeakEntityControlFactoryResult = System.Collections.Generic.KeyValuePair, System.WeakReference>;
+
+namespace Torch.Server.Managers
+{
+ ///
+ /// Manager that lets users bind random view models to entities in Torch's Entity Manager
+ ///
+ public class EntityControlManager : Manager
+ {
+ private static readonly Logger _log = LogManager.GetCurrentClassLogger();
+
+ ///
+ /// Creates an entity control manager for the given instance of torch
+ ///
+ /// Torch instance
+ internal EntityControlManager(ITorchBase torchInstance) : base(torchInstance)
+ {
+ }
+
+ private readonly Dictionary> _modelFactories = new Dictionary>();
+ private readonly List _controlFactories = new List();
+
+ private readonly List> _boundEntityViewModels = new List>();
+ private readonly ConditionalWeakTable> _boundViewModels = new ConditionalWeakTable>();
+
+ ///
+ /// This factory will be used to create component models for matching entity models.
+ ///
+ /// entity model type to match
+ /// Method to create component model from entity model.
+ public void RegisterModelFactory(Func modelFactory)
+ where TEntityBaseModel : EntityViewModel
+ {
+ if (!typeof(TEntityBaseModel).IsAssignableFrom(modelFactory.Method.GetParameters()[0].ParameterType))
+ throw new ArgumentException("Generic type must match lamda type", nameof(modelFactory));
+ lock (this)
+ {
+ var results = new List();
+ _modelFactories.Add(modelFactory, results);
+
+ var i = 0;
+ while (i < _boundEntityViewModels.Count)
+ {
+ if (_boundEntityViewModels[i].TryGetTarget(out EntityViewModel target) &&
+ _boundViewModels.TryGetValue(target, out MtObservableList components))
+ {
+ if (target is TEntityBaseModel tent)
+ {
+ EntityControlViewModel result = modelFactory.Invoke(tent);
+ if (result != null)
+ {
+ _log.Debug($"Model factory {modelFactory.Method} created {result} for {tent}");
+ components.Add(result);
+ results.Add(new WeakEntityControlFactoryResult(new WeakReference(target), new WeakReference(result)));
+ }
+ }
+ i++;
+ }
+ else
+ _boundEntityViewModels.RemoveAtFast(i);
+ }
+ }
+ }
+
+ ///
+ /// Unregisters a factory registered with
+ ///
+ /// entity model type to match
+ /// Method to create component model from entity model.
+ public void UnregisterModelFactory(Func modelFactory)
+ where TEntityBaseModel : EntityViewModel
+ {
+ if (!typeof(TEntityBaseModel).IsAssignableFrom(modelFactory.Method.GetParameters()[0].ParameterType))
+ throw new ArgumentException("Generic type must match lamda type", nameof(modelFactory));
+ lock (this)
+ {
+ if (!_modelFactories.TryGetValue(modelFactory, out var results))
+ return;
+ _modelFactories.Remove(modelFactory);
+ foreach (WeakEntityControlFactoryResult result in results)
+ {
+ if (result.Key.TryGetTarget(out EntityViewModel target) &&
+ result.Value.TryGetTarget(out EntityControlViewModel created)
+ && _boundViewModels.TryGetValue(target, out MtObservableList registered))
+ {
+ registered.Remove(created);
+ }
+ }
+ }
+ }
+
+ ///
+ /// This factory will be used to create controls for matching view models.
+ ///
+ /// component model to match
+ /// Method to create control from component model
+ public void RegisterControlFactory(
+ Func controlFactory)
+ where TEntityComponentModel : EntityControlViewModel
+ {
+ if (!typeof(TEntityComponentModel).IsAssignableFrom(controlFactory.Method.GetParameters()[0].ParameterType))
+ throw new ArgumentException("Generic type must match lamda type", nameof(controlFactory));
+ lock (this)
+ {
+ _controlFactories.Add(controlFactory);
+ RefreshControls();
+ }
+ }
+
+ ///
+ /// Unregisters a factory registered with
+ ///
+ /// component model to match
+ /// Method to create control from component model
+ public void UnregisterControlFactory(
+ Func controlFactory)
+ where TEntityComponentModel : EntityControlViewModel
+ {
+ if (!typeof(TEntityComponentModel).IsAssignableFrom(controlFactory.Method.GetParameters()[0].ParameterType))
+ throw new ArgumentException("Generic type must match lamda type", nameof(controlFactory));
+ lock (this)
+ {
+ _controlFactories.Remove(controlFactory);
+ RefreshControls();
+ }
+ }
+
+ private void RefreshControls() where TEntityComponentModel : EntityControlViewModel
+ {
+ var i = 0;
+ while (i < _boundEntityViewModels.Count)
+ {
+ if (_boundEntityViewModels[i].TryGetTarget(out EntityViewModel target) &&
+ _boundViewModels.TryGetValue(target, out MtObservableList components))
+ {
+ foreach (EntityControlViewModel component in components)
+ if (component is TEntityComponentModel)
+ component.InvalidateControl();
+ i++;
+ }
+ else
+ _boundEntityViewModels.RemoveAtFast(i);
+ }
+ }
+
+ ///
+ /// Gets the models bound to the given entity view model.
+ ///
+ /// view model to query
+ ///
+ public MtObservableList BoundModels(EntityViewModel entity)
+ {
+ return _boundViewModels.GetValue(entity, CreateFreshBinding);
+ }
+
+ ///
+ /// Gets a control for the given view model type.
+ ///
+ /// model to create a control for
+ /// control, or null if none
+ public Control CreateControl(EntityControlViewModel model)
+ {
+ lock (this)
+ foreach (Delegate factory in _controlFactories)
+ if (factory.Method.GetParameters()[0].ParameterType.IsInstanceOfType(model) &&
+ factory.DynamicInvoke(model) is Control result)
+ {
+ _log.Debug($"Control factory {factory.Method} created {result}");
+ return result;
+ }
+ _log.Warn($"No control created for {model}");
+ return null;
+ }
+
+ private MtObservableList CreateFreshBinding(EntityViewModel key)
+ {
+ var binding = new MtObservableList();
+ lock (this)
+ {
+ foreach (KeyValuePair> factory in _modelFactories)
+ {
+ Type ptype = factory.Key.Method.GetParameters()[0].ParameterType;
+ if (ptype.IsInstanceOfType(key) &&
+ factory.Key.DynamicInvoke(key) is EntityControlViewModel result)
+ {
+ _log.Debug($"Model factory {factory.Key.Method} created {result} for {key}");
+ binding.Add(result);
+ result.InvalidateControl();
+ factory.Value.Add(new WeakEntityControlFactoryResult(new WeakReference(key), new WeakReference(result)));
+ }
+ }
+ _boundEntityViewModels.Add(new WeakReference(key));
+ }
+ return binding;
+ }
+ }
+}
diff --git a/Torch.Server/Torch.Server.csproj b/Torch.Server/Torch.Server.csproj
index d632099..ea5c705 100644
--- a/Torch.Server/Torch.Server.csproj
+++ b/Torch.Server/Torch.Server.csproj
@@ -195,6 +195,7 @@
Properties\AssemblyVersion.cs
+
@@ -214,6 +215,13 @@
+
+
+ EntityControlHost.xaml
+
+
+ EntityControlsView.xaml
+
@@ -221,7 +229,6 @@
-
@@ -262,9 +269,6 @@
PluginsControl.xaml
-
- ProfilerConfigControl.xaml
-
TorchUI.xaml
@@ -309,6 +313,14 @@
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
@@ -337,6 +349,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
@@ -349,14 +365,6 @@
Designer
MSBuild:Compile
-
- Designer
- MSBuild:Compile
-
-
- Designer
- MSBuild:Compile
-
MSBuild:Compile
Designer
diff --git a/Torch.Server/TorchServer.cs b/Torch.Server/TorchServer.cs
index 44729df..ee8d1a5 100644
--- a/Torch.Server/TorchServer.cs
+++ b/Torch.Server/TorchServer.cs
@@ -72,6 +72,7 @@ namespace Torch.Server
{
DedicatedInstance = new InstanceManager(this);
AddManager(DedicatedInstance);
+ AddManager(new EntityControlManager(this));
Config = config ?? new TorchConfig();
var sessionManager = Managers.GetManager();
diff --git a/Torch.Server/ViewModels/Entities/EntityControlViewModel.cs b/Torch.Server/ViewModels/Entities/EntityControlViewModel.cs
new file mode 100644
index 0000000..3258365
--- /dev/null
+++ b/Torch.Server/ViewModels/Entities/EntityControlViewModel.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace Torch.Server.ViewModels.Entities
+{
+ public class EntityControlViewModel : ViewModel
+ {
+ internal const string SignalPropertyInvalidateControl =
+ "InvalidateControl-4124a476-704f-4762-8b5e-336a18e2f7e5";
+
+ internal void InvalidateControl()
+ {
+ // ReSharper disable once ExplicitCallerInfoArgument
+ OnPropertyChanged(SignalPropertyInvalidateControl);
+ }
+
+ private bool _hide;
+
+ ///
+ /// Should this element be forced into the
+ ///
+ public bool Hide
+ {
+ get => _hide;
+ protected set
+ {
+ if (_hide == value)
+ return;
+ _hide = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+}
diff --git a/Torch.Server/ViewModels/Entities/EntityViewModel.cs b/Torch.Server/ViewModels/Entities/EntityViewModel.cs
index f9b8dcd..05eabbc 100644
--- a/Torch.Server/ViewModels/Entities/EntityViewModel.cs
+++ b/Torch.Server/ViewModels/Entities/EntityViewModel.cs
@@ -1,7 +1,7 @@
using System.Windows.Controls;
using Torch.API.Managers;
using Torch.Collections;
-using Torch.Managers.Profiler;
+using Torch.Server.Managers;
using VRage.Game.ModAPI;
using VRage.ModAPI;
using VRageMath;
@@ -11,14 +11,24 @@ namespace Torch.Server.ViewModels.Entities
public class EntityViewModel : ViewModel
{
protected EntityTreeViewModel Tree { get; }
- public IMyEntity Entity { get; }
- public long Id => Entity.EntityId;
- public ProfilerEntryViewModel Profiler
+
+ private IMyEntity _backing;
+ public IMyEntity Entity
{
- get => ProfilerTreeAlias[0];
- set => ProfilerTreeAlias[0] = value;
+ get => _backing;
+ protected set
+ {
+ _backing = value;
+ OnPropertyChanged();
+ EntityControls = TorchBase.Instance?.Managers.GetManager()?.BoundModels(this);
+ // ReSharper disable once ExplicitCallerInfoArgument
+ OnPropertyChanged(nameof(EntityControls));
+ }
}
- public MtObservableList ProfilerTreeAlias { get; } = new MtObservableList(1){null};
+
+ public long Id => Entity.EntityId;
+
+ public MtObservableList EntityControls { get; private set; }
public virtual string Name
{
@@ -56,7 +66,6 @@ namespace Torch.Server.ViewModels.Entities
{
Entity = entity;
Tree = tree;
- Profiler = TorchBase.Instance.Managers.GetManager()?.EntityData(entity, Profiler);
}
public EntityViewModel()
diff --git a/Torch.Server/ViewModels/Entities/GridViewModel.cs b/Torch.Server/ViewModels/Entities/GridViewModel.cs
index 9cbd2cc..8d06f26 100644
--- a/Torch.Server/ViewModels/Entities/GridViewModel.cs
+++ b/Torch.Server/ViewModels/Entities/GridViewModel.cs
@@ -4,7 +4,6 @@ using Sandbox.Game.Entities;
using Sandbox.ModAPI;
using Torch.API.Managers;
using Torch.Collections;
-using Torch.Managers.Profiler;
using Torch.Server.ViewModels.Blocks;
namespace Torch.Server.ViewModels.Entities
diff --git a/Torch.Server/ViewModels/EntityTreeViewModel.cs b/Torch.Server/ViewModels/EntityTreeViewModel.cs
index 87b00cf..76de7da 100644
--- a/Torch.Server/ViewModels/EntityTreeViewModel.cs
+++ b/Torch.Server/ViewModels/EntityTreeViewModel.cs
@@ -17,6 +17,8 @@ namespace Torch.Server.ViewModels
{
public class EntityTreeViewModel : ViewModel
{
+ private static readonly Logger _log = LogManager.GetCurrentClassLogger();
+
//TODO: these should be sorted sets for speed
public MtObservableList Grids { get; set; } = new MtObservableList();
public MtObservableList Characters { get; set; } = new MtObservableList();
@@ -46,39 +48,55 @@ namespace Torch.Server.ViewModels
private void MyEntities_OnEntityRemove(VRage.Game.Entity.MyEntity obj)
{
- switch (obj)
+ try
{
- case MyCubeGrid grid:
- Grids.RemoveWhere(m => m.Id == grid.EntityId);
- break;
- case MyCharacter character:
- Characters.RemoveWhere(m => m.Id == character.EntityId);
- break;
- case MyFloatingObject floating:
- FloatingObjects.RemoveWhere(m => m.Id == floating.EntityId);
- break;
- case MyVoxelBase voxel:
- VoxelMaps.RemoveWhere(m => m.Id == voxel.EntityId);
- break;
+ switch (obj)
+ {
+ case MyCubeGrid grid:
+ Grids.RemoveWhere(m => m.Id == grid.EntityId);
+ break;
+ case MyCharacter character:
+ Characters.RemoveWhere(m => m.Id == character.EntityId);
+ break;
+ case MyFloatingObject floating:
+ FloatingObjects.RemoveWhere(m => m.Id == floating.EntityId);
+ break;
+ case MyVoxelBase voxel:
+ VoxelMaps.RemoveWhere(m => m.Id == voxel.EntityId);
+ break;
+ }
+ }
+ catch (Exception e)
+ {
+ _log.Error(e);
+ // ignore error "it's only UI"
}
}
private void MyEntities_OnEntityAdd(VRage.Game.Entity.MyEntity obj)
{
- switch (obj)
+ try
{
- case MyCubeGrid grid:
- Grids.Add(new GridViewModel(grid, this));
- break;
- case MyCharacter character:
- Characters.Add(new CharacterViewModel(character, this));
- break;
- case MyFloatingObject floating:
- FloatingObjects.Add(new FloatingObjectViewModel(floating, this));
- break;
- case MyVoxelBase voxel:
- VoxelMaps.Add(new VoxelMapViewModel(voxel, this));
- break;
+ switch (obj)
+ {
+ case MyCubeGrid grid:
+ Grids.Add(new GridViewModel(grid, this));
+ break;
+ case MyCharacter character:
+ Characters.Add(new CharacterViewModel(character, this));
+ break;
+ case MyFloatingObject floating:
+ FloatingObjects.Add(new FloatingObjectViewModel(floating, this));
+ break;
+ case MyVoxelBase voxel:
+ VoxelMaps.Add(new VoxelMapViewModel(voxel, this));
+ break;
+ }
+ }
+ catch (Exception e)
+ {
+ _log.Error(e);
+ // ignore error "it's only UI"
}
}
}
diff --git a/Torch.Server/ViewModels/ProfilerViewModel.cs b/Torch.Server/ViewModels/ProfilerViewModel.cs
deleted file mode 100644
index 247f6c8..0000000
--- a/Torch.Server/ViewModels/ProfilerViewModel.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Torch.API.Managers;
-using Torch.Collections;
-using Torch.Managers.Profiler;
-
-namespace Torch.Server.ViewModels
-{
- public class ProfilerViewModel : ViewModel
- {
- public MtObservableList ProfilerTreeAlias { get; } = new MtObservableList();
-
- private readonly ProfilerManager _manager;
-
- public ProfilerViewModel()
- {
- _manager = null;
- }
-
- public ProfilerViewModel(ProfilerManager profilerManager)
- {
- _manager = profilerManager;
- ProfilerTreeAlias.Add(_manager.SessionData());
- ProfilerTreeAlias.Add(_manager.EntitiesData());
- }
-
- ///
- public bool ProfileGridsUpdate
- {
- get => _manager?.ProfileGridsUpdate ?? false;
- set
- {
- if (_manager != null)
- _manager.ProfileGridsUpdate = value;
- OnPropertyChanged();
- }
- }
-
- ///
- public bool ProfileBlocksUpdate
- {
- get => _manager?.ProfileBlocksUpdate ?? false;
- set
- {
- if (_manager != null)
- _manager.ProfileBlocksUpdate = value;
- OnPropertyChanged();
- }
- }
-
- ///
- public bool ProfileEntityComponentsUpdate
- {
- get => _manager?.ProfileEntityComponentsUpdate ?? false;
- set
- {
- if (_manager != null)
- _manager.ProfileEntityComponentsUpdate = value;
- OnPropertyChanged();
- }
- }
-
- ///
- public bool ProfileGridSystemUpdates
- {
- get => _manager?.ProfileGridSystemUpdates ?? false;
- set
- {
- if (_manager != null)
- _manager.ProfileGridSystemUpdates = value;
- OnPropertyChanged();
- }
- }
-
- ///
- public bool ProfileSessionComponentsUpdate
- {
- get => _manager?.ProfileSessionComponentsUpdate ?? false;
- set => _manager.ProfileSessionComponentsUpdate = value;
- }
- }
-}
diff --git a/Torch.Server/Views/Entities/Blocks/BlockView.xaml b/Torch.Server/Views/Entities/Blocks/BlockView.xaml
index 8020097..53cca60 100644
--- a/Torch.Server/Views/Entities/Blocks/BlockView.xaml
+++ b/Torch.Server/Views/Entities/Blocks/BlockView.xaml
@@ -5,6 +5,8 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Torch.Server.Views.Blocks"
xmlns:blocks="clr-namespace:Torch.Server.ViewModels.Blocks"
+ xmlns:entities="clr-namespace:Torch.Server.Views.Entities"
+ xmlns:entities1="clr-namespace:Torch.Server.ViewModels.Entities"
mc:Ignorable="d">
@@ -12,6 +14,7 @@
+
@@ -22,22 +25,27 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Torch.Server/Views/Entities/EntityControlHost.xaml b/Torch.Server/Views/Entities/EntityControlHost.xaml
new file mode 100644
index 0000000..a7b11af
--- /dev/null
+++ b/Torch.Server/Views/Entities/EntityControlHost.xaml
@@ -0,0 +1,8 @@
+
+
diff --git a/Torch.Server/Views/Entities/EntityControlHost.xaml.cs b/Torch.Server/Views/Entities/EntityControlHost.xaml.cs
new file mode 100644
index 0000000..bea6ada
--- /dev/null
+++ b/Torch.Server/Views/Entities/EntityControlHost.xaml.cs
@@ -0,0 +1,60 @@
+using System.ComponentModel;
+using System.Windows;
+using System.Windows.Controls;
+using Torch.Server.Managers;
+using Torch.API.Managers;
+using Torch.Server.ViewModels.Entities;
+
+namespace Torch.Server.Views.Entities
+{
+ ///
+ /// Interaction logic for EntityControlHost.xaml
+ ///
+ public partial class EntityControlHost : UserControl
+ {
+ public EntityControlHost()
+ {
+ InitializeComponent();
+ DataContextChanged += OnDataContextChanged;
+ }
+
+ private void OnDataContextChanged(object sender, System.Windows.DependencyPropertyChangedEventArgs e)
+ {
+ if (e.OldValue is ViewModel vmo)
+ {
+ vmo.PropertyChanged -= DataContext_OnPropertyChanged;
+ }
+ if (e.NewValue is ViewModel vmn)
+ {
+ vmn.PropertyChanged += DataContext_OnPropertyChanged;
+ }
+ RefreshControl();
+ }
+
+ private void DataContext_OnPropertyChanged(object sender, PropertyChangedEventArgs pa)
+ {
+ if (pa.PropertyName.Equals(EntityControlViewModel.SignalPropertyInvalidateControl))
+ RefreshControl();
+ else if (pa.PropertyName.Equals(nameof(EntityControlViewModel.Hide)))
+ RefreshVisibility();
+ }
+
+ private Control _currentControl;
+
+ private void RefreshControl()
+ {
+ _currentControl = DataContext is EntityControlViewModel ecvm
+ ? TorchBase.Instance?.Managers.GetManager()?.CreateControl(ecvm)
+ : null;
+ Content = _currentControl;
+ RefreshVisibility();
+ }
+
+ private void RefreshVisibility()
+ {
+ Visibility = (DataContext is EntityControlViewModel ecvm) && !ecvm.Hide && _currentControl != null
+ ? Visibility.Visible
+ : Visibility.Collapsed;
+ }
+ }
+}
diff --git a/Torch.Server/Views/Entities/EntityControlsView.xaml b/Torch.Server/Views/Entities/EntityControlsView.xaml
new file mode 100644
index 0000000..9f4fba1
--- /dev/null
+++ b/Torch.Server/Views/Entities/EntityControlsView.xaml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Torch.Server/Views/Entities/EntityControlsView.xaml.cs b/Torch.Server/Views/Entities/EntityControlsView.xaml.cs
new file mode 100644
index 0000000..b490a5a
--- /dev/null
+++ b/Torch.Server/Views/Entities/EntityControlsView.xaml.cs
@@ -0,0 +1,15 @@
+using System.Windows.Controls;
+
+namespace Torch.Server.Views.Entities
+{
+ ///
+ /// Interaction logic for EntityControlsView.xaml
+ ///
+ public partial class EntityControlsView : ItemsControl
+ {
+ public EntityControlsView()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Torch.Server/Views/Entities/GridView.xaml b/Torch.Server/Views/Entities/GridView.xaml
index 36620ee..f183117 100644
--- a/Torch.Server/Views/Entities/GridView.xaml
+++ b/Torch.Server/Views/Entities/GridView.xaml
@@ -3,30 +3,28 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:profiler="clr-namespace:Torch.Managers.Profiler;assembly=Torch"
xmlns:entities="clr-namespace:Torch.Server.ViewModels.Entities"
+ xmlns:local="clr-namespace:Torch.Server.Views.Entities"
mc:Ignorable="d">
-
-
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
\ No newline at end of file
diff --git a/Torch.Server/Views/Entities/VoxelMapView.xaml b/Torch.Server/Views/Entities/VoxelMapView.xaml
index 4333edf..3c0409b 100644
--- a/Torch.Server/Views/Entities/VoxelMapView.xaml
+++ b/Torch.Server/Views/Entities/VoxelMapView.xaml
@@ -9,14 +9,23 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Torch.Server/Views/PlayerListControl.xaml.cs b/Torch.Server/Views/PlayerListControl.xaml.cs
index a920eb3..49c40a7 100644
--- a/Torch.Server/Views/PlayerListControl.xaml.cs
+++ b/Torch.Server/Views/PlayerListControl.xaml.cs
@@ -57,10 +57,10 @@ namespace Torch.Server
switch (newState)
{
case TorchSessionState.Loaded:
- Dispatcher.Invoke(() => DataContext = _server?.CurrentSession?.Managers.GetManager());
+ Dispatcher.InvokeAsync(() => DataContext = _server?.CurrentSession?.Managers.GetManager());
break;
case TorchSessionState.Unloading:
- Dispatcher.Invoke(() => DataContext = null);
+ Dispatcher.InvokeAsync(() => DataContext = null);
break;
}
}
diff --git a/Torch.Server/Views/ProfilerConfigControl.xaml b/Torch.Server/Views/ProfilerConfigControl.xaml
deleted file mode 100644
index b90876f..0000000
--- a/Torch.Server/Views/ProfilerConfigControl.xaml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Torch.Server/Views/ProfilerConfigControl.xaml.cs b/Torch.Server/Views/ProfilerConfigControl.xaml.cs
deleted file mode 100644
index 8ecb7bd..0000000
--- a/Torch.Server/Views/ProfilerConfigControl.xaml.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Navigation;
-using System.Windows.Shapes;
-using Torch.API.Managers;
-using Torch.Managers.Profiler;
-using Torch.Server.ViewModels;
-
-namespace Torch.Server.Views
-{
- ///
- /// Interaction logic for ProfilerControl.xaml
- ///
- public partial class ProfilerControl : UserControl
- {
- public ProfilerControl()
- {
- InitializeComponent();
- }
-
- public void BindServer(TorchServer server)
- {
- DataContext = new ProfilerViewModel(server.Managers.GetManager());
- }
- }
-}
diff --git a/Torch.Server/Views/TorchUI.xaml b/Torch.Server/Views/TorchUI.xaml
index 97729f7..1848f6c 100644
--- a/Torch.Server/Views/TorchUI.xaml
+++ b/Torch.Server/Views/TorchUI.xaml
@@ -69,9 +69,6 @@
-
-
-
diff --git a/Torch.Server/Views/TorchUI.xaml.cs b/Torch.Server/Views/TorchUI.xaml.cs
index 6e7716d..92b1083 100644
--- a/Torch.Server/Views/TorchUI.xaml.cs
+++ b/Torch.Server/Views/TorchUI.xaml.cs
@@ -48,7 +48,6 @@ namespace Torch.Server
Chat.BindServer(server);
PlayerList.BindServer(server);
Plugins.BindServer(server);
- Profiler.BindServer(server);
LoadConfig((TorchConfig)server.Config);
}
diff --git a/Torch/Collections/MtObservableEvent.cs b/Torch/Collections/MtObservableEvent.cs
index cc27c6b..c3ef257 100644
--- a/Torch/Collections/MtObservableEvent.cs
+++ b/Torch/Collections/MtObservableEvent.cs
@@ -11,7 +11,7 @@ namespace Torch.Collections
///
/// Event argument type
/// Event handler delegate type
- internal sealed class MtObservableEvent where TEvtArgs : EventArgs
+ public sealed class MtObservableEvent where TEvtArgs : EventArgs
{
private delegate void DelInvokeHandler(TEvtHandle handler, object sender, TEvtArgs args);
@@ -28,19 +28,32 @@ namespace Torch.Collections
private event EventHandler Event;
- internal void Raise(object sender, TEvtArgs args)
+ ///
+ /// Raises this event for the given sender, with the given args
+ ///
+ /// sender
+ /// args
+ public void Raise(object sender, TEvtArgs args)
{
Event?.Invoke(sender, args);
}
- internal void Add(TEvtHandle evt)
+ ///
+ /// Adds the given event handler.
+ ///
+ ///
+ public void Add(TEvtHandle evt)
{
if (evt == null)
return;
Event += new DispatcherDelegate(evt).Invoke;
}
- internal void Remove(TEvtHandle evt)
+ ///
+ /// Removes the given event handler
+ ///
+ ///
+ public void Remove(TEvtHandle evt)
{
if (Event == null || evt == null)
return;
diff --git a/Torch/Managers/PatchManager/PatchManager.cs b/Torch/Managers/PatchManager/PatchManager.cs
index fce9991..bcc90c4 100644
--- a/Torch/Managers/PatchManager/PatchManager.cs
+++ b/Torch/Managers/PatchManager/PatchManager.cs
@@ -148,12 +148,20 @@ namespace Torch.Managers.PatchManager
return count;
}
+
///
internal static void CommitInternal()
{
lock (_rewritePatterns)
- foreach (DecoratedMethod m in _rewritePatterns.Values)
- m.Commit();
+ {
+#if true
+ ParallelTasks.Parallel.ForEach(_rewritePatterns.Values, x => x.Commit());
+#else
+ foreach (DecoratedMethod m in _rewritePatterns.Values)
+ m.Commit();
+#endif
+
+ }
}
///
diff --git a/Torch/Managers/Profiler/FatProfilerEntry.cs b/Torch/Managers/Profiler/FatProfilerEntry.cs
deleted file mode 100644
index 6479a96..0000000
--- a/Torch/Managers/Profiler/FatProfilerEntry.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Runtime.CompilerServices;
-using Torch.Collections;
-
-namespace Torch.Managers.Profiler
-{
- public class FatProfilerEntry : SlimProfilerEntry
- {
- private readonly ConditionalWeakTable