Пример #1
0
        /// <summary>
        /// Finishes the Pinball object.
        /// </summary>
        public void Finish()
        {
            try
            {
                Log.Write("Finishing framework");
                FinishMainThread();

                Alarms.Finish();
                Table.Finish();
                Cabinet.Finish();


                //         WriteStatisticsToLog();

                ThreadInfoList.ThreadTerminates();

                Log.Write("DirectOutput framework finished.");
                Log.Write("Bye and thanks for using!");
            }
            catch (Exception E)
            {
                Log.Exception("A exception occured while finishing the DirectOutput framework.", E);
                throw new Exception("DirectOutput framework has encountered while finishing.\n Inner exception: {0}".Build(E.Message), E);
            }
        }
Пример #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Pinball"/> class.
        /// </summary>
        public Pinball()
        {

            ThreadInfoList = new ThreadInfoList();
            TimeSpanStatistics = new TimeSpanStatisticsList();

        }
Пример #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Pinball"/> class.
 /// </summary>
 public Pinball()
 {
     ThreadInfoList     = new ThreadInfoList();
     TimeSpanStatistics = new TimeSpanStatisticsList();
 }
Пример #4
0
 /// <summary>
 /// Receives the table element data from the calling app.<br />
 /// The received data is put in a queue and the internal thread of the framework is notified about the availability of new data.
 /// </summary>
 /// <param name="TableElementData">The table element data to be received.</param>
 public void ReceiveData(TableElementData TableElementData)
 {
     InputQueue.Enqueue(TableElementData);
     MainThreadSignal();
     ThreadInfoList.HeartBeat("Data delivery");
 }
Пример #5
0
 /// <summary>
 /// Receives the table element data from the calling app (e.g. B2S.Server providing data through the plugin interface).<br/>
 /// The received data is put in a queue and the internal thread of the framework is notified about the availability of new data.
 /// </summary>
 /// <param name="TableElementTypeChar">The table element type char as specified in the TableElementTypeEnum.</param>
 /// <param name="Number">The number of the TableElement.</param>
 /// <param name="Value">The value of the TableElement.</param>
 public void ReceiveData(char TableElementTypeChar, int Number, int Value)
 {
     InputQueue.Enqueue(TableElementTypeChar, Number, Value);
     MainThreadSignal();
     ThreadInfoList.HeartBeat("Data delivery");
 }
Пример #6
0
        /// <summary>
        /// This method is constantly beeing executed by the main thread of the framework.<br/>
        /// Dont call this method directly. Use the Init and FinishMainThread methods.
        /// </summary>
        //TODO: Think about implement something which does really check on value changes on tableelements or triggered effects before setting update required.
        private void MainThreadDoIt()
        {
            ThreadInfoList.HeartBeat("DirectOutput");
            try
            {
                while (KeepMainThreadAlive)
                {
                    bool     UpdateRequired = false;
                    DateTime Start          = DateTime.Now;

                    //Consume the tableelement data delivered from the calling application
                    while (InputQueue.Count > 0 && (DateTime.Now - Start).Milliseconds <= MaxInputDataProcessingTimeMs && KeepMainThreadAlive)
                    {
                        TableElementData D;

                        D = InputQueue.Dequeue();
                        try
                        {
                            DateTime StartTime = DateTime.Now;
                            Table.UpdateTableElement(D);
                            UpdateRequired |= true;
                            UpdateTableElementStatistics(D, (DateTime.Now - StartTime));
                        }
                        catch (Exception E)
                        {
                            Log.Exception("A unhandled exception occured while processing data for table element {0} {1} with value {2}".Build(D.TableElementType, D.Number, D.Value), E);
                            ThreadInfoList.RecordException(E);
                        }
                    }

                    if (KeepMainThreadAlive)
                    {
                        try
                        {
                            //Executed all alarms which have been scheduled for the current time
                            UpdateRequired |= Alarms.ExecuteAlarms(DateTime.Now.AddMilliseconds(1));
                        }
                        catch (Exception E)
                        {
                            Log.Exception("A unhandled exception occured while executing timer events.", E);
                            ThreadInfoList.RecordException(E);
                        }
                    }


                    //Call update on output controllers if necessary
                    if (UpdateRequired && KeepMainThreadAlive)
                    {
                        try
                        {
                            Cabinet.Update();
                        }
                        catch (Exception E)
                        {
                            Log.Exception("A unhandled exception occured while updating the output controllers", E);
                            ThreadInfoList.RecordException(E);
                        }
                    }

                    if (KeepMainThreadAlive)
                    {
                        ThreadInfoList.HeartBeat();
                        //Sleep until we get more input data and/or a timer expires.
                        DateTime NextAlarm = Alarms.GetNextAlarmTime();

                        lock (MainThreadLocker)
                        {
                            while (InputQueue.Count == 0 && NextAlarm > DateTime.Now && KeepMainThreadAlive)
                            {
                                int TimeOut = ((int)(NextAlarm - DateTime.Now).TotalMilliseconds).Limit(1, 50);

                                Monitor.Wait(MainThreadLocker, TimeOut);  // Lock is released while we’re waiting
                                ThreadInfoList.HeartBeat();
                            }
                        }
                    }
                }
            }
            catch (Exception E)
            {
                Log.Exception("A unexpected exception occured in the DirectOutput MainThread", E);
                ThreadInfoList.RecordException(E);
            }

            ThreadInfoList.ThreadTerminates();
        }
Пример #7
0
        /// <summary>
        /// Configures and initializes/starts and configures the Pinball object
        /// </summary>
        /// <param name="GlobalConfigFilename">The global config filename.</param>
        /// <param name="TableFilename">The table filename.</param>
        /// <param name="RomName">Name of the rom.</param>
        public void Init(string GlobalConfigFilename = "", string TableFilename = "", string RomName = "")
        {
            bool GlobalConfigLoaded = true;

            //Load the global config


            try
            {
                if (!GlobalConfigFilename.IsNullOrWhiteSpace())
                {
                    FileInfo GlobalConfigFile = new FileInfo(GlobalConfigFilename);


                    GlobalConfig = GlobalConfig.GetGlobalConfigFromConfigXmlFile(GlobalConfigFile.FullName);
                    if (GlobalConfig == null)
                    {
                        GlobalConfigLoaded = false;

                        //set new global config object if it config could not be loaded from the file.
                        GlobalConfig = new GlobalConfig();
                    }
                    GlobalConfig.GlobalConfigFilename = GlobalConfigFile.FullName;
                }
                else
                {
                    GlobalConfig = new GlobalConfig();
                    GlobalConfig.GlobalConfigFilename = GlobalConfigFilename;
                }
            }
            catch (Exception E)
            {
                throw new Exception("DirectOutput framework could initialize global config.\n Inner exception: {0}".Build(E.Message), E);
            }

            if (GlobalConfig.EnableLogging)
            {
                try
                {
                    Log.Filename = GlobalConfig.GetLogFilename((!TableFilename.IsNullOrWhiteSpace() ? new FileInfo(TableFilename).FullName : ""), RomName);
                    Log.Init();
                }
                catch (Exception E)
                {
                    throw new Exception("DirectOutput framework could initialize the log file.\n Inner exception: {0}".Build(E.Message), E);
                }
            }


            try
            {
                if (GlobalConfigLoaded)
                {
                    Log.Write("Global config loaded from: {0}".Build(GlobalConfigFilename));
                }
                else
                {
                    if (!GlobalConfigFilename.IsNullOrWhiteSpace())
                    {
                        Log.Write("Could not find or load theGlobalConfig file {0}".Build(GlobalConfigFilename));
                    }
                    else
                    {
                        Log.Write("No GlobalConfig file loaded. Using newly instanciated GlobalConfig object instead.");
                    }
                }



                Log.Write("Loading Pinball parts");



                //Load global script files
                Log.Write("Loading script files");
                Scripts.LoadAndAddScripts(GlobalConfig.GetGlobalScriptFiles());



                //Load table script files
                if (!TableFilename.IsNullOrWhiteSpace())
                {
                    Scripts.LoadAndAddScripts(GlobalConfig.GetTableScriptFiles(new FileInfo(TableFilename).FullName));
                }
                Log.Write("Script files loaded");


                Log.Write("Loading cabinet");
                //Load cabinet config
                Cabinet = null;
                FileInfo CCF = GlobalConfig.GetCabinetConfigFile();
                if (CCF != null)
                {
                    Log.Write("Will load cabinet config file: {0}".Build(CCF.FullName));
                    try
                    {
                        Cabinet = Cabinet.GetCabinetFromConfigXmlFile(CCF);
                        Cabinet.CabinetConfigurationFilename = CCF.FullName;
                        if (Cabinet.AutoConfigEnabled)
                        {
                            Log.Write("Cabinet config file has AutoConfig feature enable. Calling AutoConfig.");
                            Cabinet.AutoConfig();
                        }
                        Log.Write("Cabinet config loaded successfully from {0}".Build(CCF.FullName));
                    }
                    catch (Exception E)
                    {
                        Log.Exception("A exception occured when load cabinet config file: {0}".Build(CCF.FullName), E);
                    }
                }
                if (Cabinet == null)
                {
                    Log.Write("No cabinet config file loaded. Will use AutoConfig.");
                    //default to a new cabinet object if the config cant be loaded
                    Cabinet = new Cabinet();
                    Cabinet.AutoConfig();
                }

                Log.Write("Cabinet loaded");

                Log.Write("Loading table config");

                //Load table config

                Table = new DirectOutput.Table.Table();
                Table.AddLedControlConfig = true;

                if (!TableFilename.IsNullOrWhiteSpace())
                {
                    FileInfo TableFile = new FileInfo(TableFilename);
                    FileInfo TCF       = GlobalConfig.GetTableConfigFile(TableFile.FullName);
                    if (TCF != null)
                    {
                        Log.Write("Will load table config from {0}".Build(TCF.FullName));
                        try
                        {
                            Table = DirectOutput.Table.Table.GetTableFromConfigXmlFile(GlobalConfig.GetTableConfigFile(TableFile.FullName));
                            Table.TableConfigurationFilename = GlobalConfig.GetTableConfigFile(TableFile.FullName).FullName;
                            Log.Write("Table config loaded successfully from {0}".Build(TCF.FullName));
                        }
                        catch (Exception E)
                        {
                            Log.Exception("A exception occured when loading table config: {0}".Build(TCF.FullName), E);
                        }
                        if (Table.AddLedControlConfig)
                        {
                            Log.Write("Table config allows mix with ledcontrol configs.");
                        }
                    }
                    else
                    {
                        Log.Warning("No table config file found. Will try to load config from LedControl file(s).");
                    }
                }
                else
                {
                    Log.Write("No TableFilename specified, will use empty tableconfig");
                }
                if (Table.AddLedControlConfig)
                {
                    if (!RomName.IsNullOrWhiteSpace())
                    {
                        Log.Write("Will try to load configs from DirectOutput.ini or LedControl.ini file(s) for RomName {0}".Build(RomName));
                        //Load ledcontrol
                        LedControlConfigList L = new LedControlConfigList();
                        if (GlobalConfig.LedControlIniFiles.Count > 0)
                        {
                            Log.Write("Will try to load table config from LedControl  file(s) specified in global config.");
                            L.LoadLedControlFiles(GlobalConfig.LedControlIniFiles, false);
                        }
                        else
                        {
                            bool          FoundIt     = false;
                            List <string> LookupPaths = new List <string>();
                            if (!TableFilename.IsNullOrWhiteSpace())
                            {
                                if (new FileInfo(TableFilename).Directory.Exists)
                                {
                                    LookupPaths.Add(new FileInfo(TableFilename).Directory.FullName);
                                }
                            }
                            LookupPaths.AddRange(new string[] { GlobalConfig.GetGlobalConfigDirectory().FullName, Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) });

                            LedControlIniFileList LedControlIniFiles = new LedControlIniFileList();

                            string[] LedControlFilenames = { "directoutputconfig", "ledcontrol" };

                            foreach (string LedControlFilename in LedControlFilenames)
                            {
                                foreach (string P in LookupPaths)
                                {
                                    DirectoryInfo DI = new DirectoryInfo(P);

                                    List <FileInfo> Files = new List <FileInfo>();
                                    foreach (FileInfo FI in DI.EnumerateFiles())
                                    {
                                        if (FI.Name.ToLower().StartsWith(LedControlFilename.ToLower()) && FI.Name.ToLower().EndsWith(".ini"))
                                        {
                                            Files.Add(FI);
                                        }
                                    }


                                    foreach (FileInfo FI in Files)
                                    {
                                        if (string.Equals(FI.Name, "{0}.ini".Build(LedControlFilename), StringComparison.OrdinalIgnoreCase))
                                        {
                                            LedControlIniFiles.Add(FI.FullName, 1);
                                            FoundIt = true;
                                        }
                                        else
                                        {
                                            string F = FI.Name.Substring(LedControlFilename.Length, FI.Name.Length - LedControlFilename.Length - 4);
                                            if (F.IsInteger())
                                            {
                                                int LedWizNr = -1;
                                                if (int.TryParse(F, out LedWizNr))
                                                {
                                                    if (!LedControlIniFiles.Contains(LedWizNr))
                                                    {
                                                        LedControlIniFiles.Add(FI.FullName, LedWizNr);
                                                        FoundIt = true;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    ;
                                    if (FoundIt)
                                    {
                                        break;
                                    }
                                }
                                if (FoundIt)
                                {
                                    break;
                                }
                            }



                            if (FoundIt)
                            {
                                L.LoadLedControlFiles(LedControlIniFiles, false);
                                Log.Write("{0} directoutput.ini or ledcontrol.ini files loaded.".Build(LedControlIniFiles.Count));
                            }
                            else
                            {
                                Log.Write("No directoutput.ini or ledcontrol.ini files found. No directoutput.ini or ledcontrol.ini configs will be loaded.");
                            }
                        }
                        if (!L.ContainsConfig(RomName))
                        {
                            Log.Write("No config for table found in LedControl data for RomName {0}.".Build(RomName));
                        }
                        else
                        {
                            Log.Write("Config for RomName {0} exists in LedControl data. Updating cabinet and config.".Build(RomName));

                            DirectOutput.LedControl.Setup.Configurator C = new DirectOutput.LedControl.Setup.Configurator();
                            C.EffectMinDurationMs    = GlobalConfig.LedControlMinimumEffectDurationMs;
                            C.EffectRGBMinDurationMs = GlobalConfig.LedControlMinimumRGBEffectDurationMs;
                            C.Setup(L, Table, Cabinet, RomName);
                            C = null;
                            //                        L.UpdateTableConfig(Table, RomName, Cabinet);
                        }
                        L = null;
                    }
                    else
                    {
                        Log.Write("Cant load config from directoutput.ini or ledcontrol.ini file(s) since no RomName was supplied. No ledcontrol config will be loaded.");
                    }
                }
                if (Table.TableName.IsNullOrWhiteSpace())
                {
                    if (!TableFilename.IsNullOrWhiteSpace())
                    {
                        Table.TableName = Path.GetFileNameWithoutExtension(new FileInfo(TableFilename).FullName);
                    }
                    else if (!RomName.IsNullOrWhiteSpace())
                    {
                        Table.TableName = RomName;
                    }
                }
                if (!TableFilename.IsNullOrWhiteSpace())
                {
                    Table.TableFilename = new FileInfo(TableFilename).FullName;
                }
                if (!RomName.IsNullOrWhiteSpace())
                {
                    Table.RomName = RomName;
                }
                Log.Write("Table config loading finished");



                Log.Write("Pinball parts loaded");

                Log.Write("Starting processes");
                InitStatistics();
                Cabinet.Init(this);
                Table.Init(this);
                Alarms.Init(this);
                Table.TriggerStaticEffects();
                Cabinet.Update();

                //Add the thread initializing the framework to the threadinfo list
                ThreadInfo TI = new ThreadInfo(Thread.CurrentThread);
                TI.HeartBeatTimeOutMs = 10000;
                TI.HostName           = "External caller";
                TI.HeartBeat();
                ThreadInfoList.Add(TI);



                InitMainThread();
                Log.Write("Framework initialized.");
                Log.Write("Have fun! :)");
            }
            catch (Exception E)
            {
                Log.Exception("A eception occured during initialization", E);
                throw new Exception("DirectOutput framework has encountered a exception during initialization.\n Inner exception: {0}".Build(E.Message), E);
            }
        }