public PluginManager(GameController gameController, Graphics graphics, MultiThreadManager multiThreadManager) { _gameController = gameController; _graphics = graphics; _multiThreadManager = multiThreadManager; Plugins = new List <PluginWrapper>(); Directories = new Dictionary <string, string>(); RootDirectory = AppDomain.CurrentDomain.BaseDirectory; Directories[PluginsDirectory] = Path.Combine(RootDirectory, PluginsDirectory); Directories[CompiledPluginsDirectory] = Path.Combine(Directories[PluginsDirectory], CompiledPluginsDirectory); Directories[SourcePluginsDirectory] = Path.Combine(Directories[PluginsDirectory], SourcePluginsDirectory); _gameController.EntityListWrapper.EntityAdded += EntityListWrapperOnEntityAdded; _gameController.EntityListWrapper.EntityRemoved += EntityListWrapperOnEntityRemoved; _gameController.EntityListWrapper.EntityAddedAny += EntityListWrapperOnEntityAddedAny; _gameController.EntityListWrapper.EntityIgnored += EntityListWrapperOnEntityIgnored; _gameController.Area.OnAreaChange += AreaOnOnAreaChange; foreach (var directory in Directories) { if (!Directory.Exists(directory.Value)) { DebugWindow.LogMsg($"{directory.Value} doesn't exists, but don't worry i created it for you."); Directory.CreateDirectory(directory.Value); } } Task.Run(() => LoadPlugins(gameController)); }
public PluginManager(GameController gameController, Graphics graphics, MultiThreadManager multiThreadManager) { _gameController = gameController; _graphics = graphics; _multiThreadManager = multiThreadManager; RootDirectory = AppDomain.CurrentDomain.BaseDirectory; Directories["Temp"] = Path.Combine(RootDirectory, PluginsDirectory, "Temp"); Directories[PluginsDirectory] = Path.Combine(RootDirectory, PluginsDirectory); Directories[CompiledPluginsDirectory] = Path.Combine(Directories[PluginsDirectory], CompiledPluginsDirectory); Directories[SourcePluginsDirectory] = Path.Combine(Directories[PluginsDirectory], SourcePluginsDirectory); _gameController.EntityListWrapper.EntityAdded += EntityListWrapperOnEntityAdded; _gameController.EntityListWrapper.EntityRemoved += EntityListWrapperOnEntityRemoved; _gameController.EntityListWrapper.EntityAddedAny += EntityListWrapperOnEntityAddedAny; _gameController.EntityListWrapper.EntityIgnored += EntityListWrapperOnEntityIgnored; _gameController.Area.OnAreaChange += AreaOnOnAreaChange; bool parallelLoading = _gameController.Settings.CoreSettings.MultiThreadLoadPlugins; foreach (var directory in Directories) { if (!Directory.Exists(directory.Value)) { DebugWindow.LogMsg($"{directory.Value} doesn't exists, but don't worry i created it for you."); Directory.CreateDirectory(directory.Value); } } (var compiledPlugins, var sourcePlugins) = SearchPlugins(); List <(Assembly asm, bool source)> assemblies = new List <(Assembly, bool)>(); var locker = new object(); var task = Task.Run(() => { var compilePluginsFromSource = CompilePluginsFromSource(sourcePlugins); lock (locker) { compilePluginsFromSource.ForEach(assembly => assemblies.Add((assembly, true))); } }); var task2 = Task.Run(() => { var compiledAssemblies = GetCompiledAssemblies(compiledPlugins); lock (locker) { compiledAssemblies.Where(x => x != null).ForEach(assembly => assemblies.Add((assembly, false))); } }); Task.WaitAll(task, task2); if (parallelLoading) { Parallel.ForEach(assemblies, tuple => TryLoadAssemble(tuple.asm, tuple.source)); } else { assemblies.ForEach(tuple => TryLoadAssemble(tuple.asm, tuple.source)); } Plugins = Plugins.OrderBy(x => x.Order).ThenByDescending(x => x.CanBeMultiThreading).ThenBy(x => x.Name).ToList(); if (parallelLoading) { //Pre init some general objects because with multi threading load they can null sometimes for some plugin var ingameStateIngameUi = gameController.IngameState.IngameUi; var ingameStateData = gameController.IngameState.Data; var ingameStateServerData = gameController.IngameState.ServerData; Parallel.ForEach(Plugins, wrapper => InitPlugin(wrapper.Plugin)); } else { Plugins.ForEach(wrapper => InitPlugin(wrapper.Plugin)); } AreaOnOnAreaChange(gameController.Area.CurrentArea); AllPluginsLoaded = true; }
public void ParallelUpdate() { if (MultiThreadManager == null || MultiThreadManager.ThreadsCount < 1) { Update(); return; } if (Coroutines.Count <= 0) { return; } jobs.Clear(); for (var i = 0; i < Coroutines.Count; i++) { var coroutine = Coroutines[i]; if (!coroutine.IsDone) { if (!coroutine.Running) { continue; } if (coroutine.NextIterRealWork && !coroutine.SyncModWork) { var addJob = MultiThreadManager.AddJob(() => { var moveNext = coroutine.MoveNext(); if (!moveNext) { coroutine.Done(); } }, coroutine.Name); jobs.Add(addJob); } else { time = sw.Elapsed.TotalMilliseconds; double delta = 0; var moveNext = coroutine.MoveNext(); if (!moveNext) { coroutine.Done(); } delta = sw.Elapsed.TotalMilliseconds - time; CoroutinePerformance[coroutine.Name] += delta; if (delta > CriticalTimeWork) { Console.WriteLine( $"Coroutine {coroutine.Name} ({coroutine.OwnerName}) [{Name}] {delta} $Performance coroutine"); } } } else { _finishedCoroutines.Add(new CoroutineDetails(coroutine.Name, coroutine.OwnerName, coroutine.Ticks, coroutine.Started, DateTime.Now)); FinishedCoroutineCount++; Coroutines.Remove(coroutine); } } MultiThreadManager.Process(this); SpinWait.SpinUntil(() => jobs.AllF(job => job.IsCompleted), 500); foreach (var job in jobs) { CoroutinePerformance[job.Name] += job.ElapsedMs; } }
public PluginManager(GameController gameController, Graphics graphics, MultiThreadManager multiThreadManager) { _gameController = gameController; _graphics = graphics; _multiThreadManager = multiThreadManager; RootDirectory = AppDomain.CurrentDomain.BaseDirectory; Directories["Temp"] = Path.Combine(RootDirectory, PluginsDirectory, "Temp"); Directories[PluginsDirectory] = Path.Combine(RootDirectory, PluginsDirectory); Directories[CompiledPluginsDirectory] = Path.Combine(Directories[PluginsDirectory], CompiledPluginsDirectory); Directories[SourcePluginsDirectory] = Path.Combine(Directories[PluginsDirectory], SourcePluginsDirectory); _gameController.EntityListWrapper.EntityAdded += EntityListWrapperOnEntityAdded; _gameController.EntityListWrapper.EntityRemoved += EntityListWrapperOnEntityRemoved; _gameController.EntityListWrapper.EntityAddedAny += EntityListWrapperOnEntityAddedAny; _gameController.EntityListWrapper.EntityIgnored += EntityListWrapperOnEntityIgnored; _gameController.Area.OnAreaChange += AreaOnOnAreaChange; parallelLoading = _gameController.Settings.CoreSettings.MultiThreadLoadPlugins; foreach (var directory in Directories) { if (!Directory.Exists(directory.Value)) { DebugWindow.LogMsg($"{directory.Value} doesn't exists, but don't worry i created it for you."); Directory.CreateDirectory(directory.Value); } } var(compiledPlugins, sourcePlugins) = SearchPlugins(); List <(Assembly asm, DirectoryInfo directoryInfo)> assemblies = new List <(Assembly, DirectoryInfo)>(); Task task = null; if (sourcePlugins.Length > 0) { task = Task.Run(() => { var compilePluginsFromSource = CompilePluginsFromSource(sourcePlugins); }); } var compiledAssemblies = GetCompiledAssemblies(compiledPlugins, parallelLoading); var devTree = Plugins.FirstOrDefault(x => x.Name.Equals("DevTree")); task?.Wait(); Plugins = Plugins.OrderBy(x => x.Order).ThenByDescending(x => x.CanBeMultiThreading).ThenBy(x => x.Name) .ToList(); if (devTree != null) { try { var fieldInfo = devTree.Plugin.GetType().GetField("Plugins"); List <PluginWrapper> devTreePlugins() => Plugins; fieldInfo.SetValue(devTree.Plugin, (Func <List <PluginWrapper> >)devTreePlugins); } catch (Exception e) { LogError(e.ToString()); } } if (parallelLoading) { //Pre init some general objects because with multi threading load they can null sometimes for some plugin var ingameStateIngameUi = gameController.IngameState.IngameUi; var ingameStateData = gameController.IngameState.Data; var ingameStateServerData = gameController.IngameState.ServerData; Parallel.ForEach(Plugins, wrapper => wrapper.Initialise(gameController)); } else { Plugins.ForEach(wrapper => wrapper.Initialise(gameController)); } AreaOnOnAreaChange(gameController.Area.CurrentArea); Plugins.ForEach(x => x.SubscrideOnFile(HotReloadDll)); AllPluginsLoaded = true; }