private void Application_OnPlayfieldLoaded(IPlayfield playfield) { PlayfieldScriptData data = null; InitGameDependedData(ModApi.Application.Mode == ApplicationMode.SinglePlayer); PlayfieldData.TryAdd(playfield.Name, data = new PlayfieldScriptData(this) { PlayfieldName = playfield.Name, Playfield = playfield, }); UpdateScriptingModInfoData(); ModApi.Log($"StartScripts for {playfield.Name} pending"); TaskTools.Delay(Configuration.Current.DelayStartForNSecondsOnPlayfieldLoad, () => { ModApi.Log($"StartScripts for {playfield.Name}"); data.PauseScripts = false; if (ModApi.Application.Mode == ApplicationMode.SinglePlayer) { ModApi.Log(playfield.Entities?.Aggregate($"Player:{playfield.Players.FirstOrDefault().Value?.Name} PlayerDriving:{playfield.Players.FirstOrDefault().Value?.DrivingEntity?.Name}", (L, E) => L + $" {E.Key}:{E.Value.Name}")); data.AddEntity(playfield.Players.FirstOrDefault().Value?.DrivingEntity); playfield.Entities?.ForEach(E => data.AddEntity(E.Value)); } }); data.Playfield.OnEntityLoaded += data.Playfield_OnEntityLoaded; data.Playfield.OnEntityUnloaded += data.Playfield_OnEntityUnloaded; }
private int ProcessAllInGameScripts(PlayfieldScriptData playfieldData, IEntity entity) { Log($"ProcessAllInGameScripts: {entity.Name}:{entity.Type} Pause:{playfieldData.PauseScripts}", LogLevel.Debug); if (entity.Type == EntityType.Proxy || entity.Type == EntityType.Unknown || playfieldData.PauseScripts) { return(0); } try { if (!entity.Structure.IsPowered) { return(0); } var entityScriptData = new ScriptRootData(playfieldData, playfieldData.AllEntities, playfieldData.CurrentEntities, playfieldData.Playfield, entity, playfieldData.PersistendData, (EventStore)playfieldData.EventStore.GetOrAdd(entity.Id, id => new EventStore(entity))); var deviceNames = entityScriptData.E.S.AllCustomDeviceNames.Where(N => IsScriptLCD(N)).ToArray(); Log($"ProcessAllInGameScripts: #{deviceNames.Length}", LogLevel.Debug); int count = 0; Parallel.ForEach(deviceNames, N => { if (playfieldData.PauseScripts) { return; } var lcd = entity.Structure.GetDevice <ILcd>(N); if (lcd == null) { return; } var scriptPriority = int.TryParse(N.Substring(0, 1), out var prio) ? prio : 0; if (scriptPriority == 0) { var lcdBlockPos = entity.Structure.GetDevicePositions(N); var lcdBlock = lcdBlockPos.Count > 0 ? entity.Structure.GetBlock(lcdBlockPos.First()) : null; if (lcdBlock != null) { lcdBlock.Get(out _, out _, out _, out var active); if (!active) { return; } } }
private int UpdateScripts(PlayfieldScriptData playfieldData, Func <PlayfieldScriptData, IEntity, int> process, string name) { try { if (playfieldData.Playfield == null) { ModApi.Log($"UpdateScripts no Playfield"); return(0); } if (playfieldData.Playfield.Entities == null) { ModApi.Log($"UpdateScripts no Entities"); return(0); } var timer = new Stopwatch(); timer.Start(); playfieldData.AllEntities = playfieldData.Playfield.Entities.Values.ToArray(); playfieldData.CurrentEntities = playfieldData.AllEntities .Where(E => E.Type == EntityType.BA || E.Type == EntityType.CV || E.Type == EntityType.SV || E.Type == EntityType.HV) .ToArray(); Log($"CurrentEntities: {playfieldData.CurrentEntities.Length}", LogLevel.Debug); playfieldData.EntityCultureInfo.Clear(); int count = 0; playfieldData.CurrentEntities.ForEach(E => count += process(playfieldData, E)); timer.Stop(); if (timer.Elapsed.TotalSeconds > 30) { Log($"UpdateScripts: {name} RUNS {timer.Elapsed} !!!!", LogLevel.Message); } else { Log($"UpdateScripts: {name} take {timer.Elapsed}", LogLevel.Debug); } return(count); } catch (Exception error) { ModApi.LogWarning("Next try because: " + ErrorFilter(error)); return(0); } }
public void CheckForEmergencyRestart(PlayfieldScriptData playfield) { lock (ExecQueue) { if (ExecQueue.IsEmpty && WaitForExec.Count > 0 && BackgroundWorkerToDo.Count == 0) { Log($"ExecQueue.IsEmpty restart [{playfield.PlayfieldName}]... #{WaitForExec.Count} => {WaitForExec.Aggregate("Pendingscripts:", (E, L) => E + "\n" + L.Key)}", LogLevel.Message); ThreadPool.GetAvailableThreads(out var availableWorkerThreads, out var availableCompletionPortThreads); Log($"ThreadPool available: WorkerThreads:{availableWorkerThreads} CompletionPortThreads:{availableCompletionPortThreads}", LogLevel.Message); ThreadPool.GetMaxThreads(out var maxWorkerThreads, out var maxCompletionPortThreads); Log($"ThreadPool max: WorkerThreads:{maxWorkerThreads} CompletionPortThreads:{maxCompletionPortThreads}", LogLevel.Message); ThreadPool.GetMinThreads(out var minWorkerThreads, out var minCompletionPortThreads); Log($"ThreadPool min: WorkerThreads:{minWorkerThreads} CompletionPortThreads:{minCompletionPortThreads}", LogLevel.Message); WaitForExec.Clear(); // robust error restart with fresh data } } }