Пример #1
0
        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;
        }
Пример #2
0
        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;
                            }
                        }
                    }
Пример #3
0
        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
         }
     }
 }