2 using System.Collections.Generic;
43 get {
return _Table; }
44 set { _Table = value; }
56 get {
return _Cabinet; }
57 set { _Cabinet = value; }
72 get {
return _Alarms; }
73 private set { _Alarms = value; }
86 get {
return _GlobalConfig; }
87 private set { _GlobalConfig = value; }
104 public void Setup(
string GlobalConfigFilename =
"",
string TableFilename =
"",
string RomName =
"")
106 bool GlobalConfigLoaded =
true;
112 if (!GlobalConfigFilename.IsNullOrWhiteSpace())
114 FileInfo GlobalConfigFile =
new FileInfo(GlobalConfigFilename);
120 GlobalConfigLoaded =
false;
137 throw new Exception(
"DirectOutput framework could not initialize global config.\n Inner exception: {0}".Build(E.Message), E);
147 FileInfo LF =
new FileInfo(
GlobalConfig.
GetLogFilename((!TableFilename.IsNullOrWhiteSpace() ?
new FileInfo(TableFilename).FullName :
""), RomName));
165 throw new Exception(
"DirectOutput framework could initialize the log file.\n Inner exception: {0}".Build(E.Message), E);
172 if (GlobalConfigLoaded)
174 Log.
Write(
"Global config loaded from: {0}".Build(GlobalConfigFilename));
178 if (!GlobalConfigFilename.IsNullOrWhiteSpace())
180 Log.
Write(
"Could not find or load theGlobalConfig file {0}".Build(GlobalConfigFilename));
184 Log.
Write(
"No GlobalConfig file loaded. Using newly instanciated GlobalConfig object instead.");
202 Log.
Write(
"Will load cabinet config file: {0}".Build(CCF.FullName));
213 Log.
Write(
"Cabinet config file has AutoConfig feature enabled. Calling AutoConfig.");
220 Log.
Exception(
"A eception occured during cabinet auto configuration", E);
224 Log.
Write(
"Cabinet config loaded successfully from {0}".Build(CCF.FullName));
228 Log.
Exception(
"A exception occured when loading cabinet config file: {0}".Build(CCF.FullName), E);
235 Log.
Warning(
"Cabinet config file {0} does not exist.".Build(CCF.FullName));
240 Log.
Write(
"No cabinet config file loaded. Will use AutoConfig.");
255 if (!TableFilename.IsNullOrWhiteSpace())
257 FileInfo TableFile =
new FileInfo(TableFilename);
261 Log.
Write(
"Will load table config from {0}".Build(TCF.FullName));
266 Log.
Write(
"Table config loaded successfully from {0}".Build(TCF.FullName));
270 Log.
Exception(
"A exception occured when loading table config: {0}".Build(TCF.FullName), E);
274 Log.
Write(
"Table config allows mix with ledcontrol configs.");
279 Log.
Warning(
"No table config file found. Will try to load config from LedControl file(s).");
284 Log.
Write(
"No TableFilename specified, will use empty tableconfig");
288 if (!RomName.IsNullOrWhiteSpace())
290 Log.
Write(
"Will try to load configs from DirectOutput.ini or LedControl.ini file(s) for RomName {0}".Build(RomName));
297 if (LedControlIniFiles.Count > 0)
300 Log.
Write(
"{0} directoutputconfig.ini or ledcontrol.ini files loaded.".Build(LedControlIniFiles.Count));
304 Log.
Write(
"No directoutputconfig.ini or ledcontrol.ini files found.");
309 Log.
Write(
"No config for table found in LedControl data for RomName {0}.".Build(RomName));
313 Log.
Write(
"Config for RomName {0} exists in LedControl data. Updating cabinet and config.".Build(RomName));
323 Version DOFVersion = typeof(
Pinball).Assembly.GetName().Version;
325 if(L.Any(LC=>LC.MinDOFVersion!=null && LC.MinDOFVersion.CompareTo(DOFVersion)>0)) {
327 Version MaxVersion = null;
336 Log.
Warning(
"UPDATE DIRECT OUTPUT FRAMEWORK!");
337 if (MaxVersion != null)
339 Log.
Warning(
"Current DOF version is {0}, but DOF version {1} or later is required by one or several config files.".Build(DOFVersion, MaxVersion));
344 Process.Start(Path.Combine(Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().Location),
"UpdateNotification.exe"));
348 Log.
Exception(
"A exception occured when displaying the update notification", E);
361 Log.
Write(
"Cant load config from directoutput.ini or ledcontrol.ini file(s) since no RomName was supplied. No ledcontrol config will be loaded.");
367 if (!TableFilename.IsNullOrWhiteSpace())
369 Table.
TableName = Path.GetFileNameWithoutExtension(
new FileInfo(TableFilename).FullName);
371 else if (!RomName.IsNullOrWhiteSpace())
376 if (!TableFilename.IsNullOrWhiteSpace())
380 if (!RomName.IsNullOrWhiteSpace())
384 Log.
Write(
"Table config loading finished");
392 Log.
Exception(
"DirectOutput framework has encountered a exception during setup.", E);
393 throw new Exception(
"DirectOutput framework has encountered a exception during setup.\n Inner exception: {0}".Build(E.Message), E);
431 Log.
Write(
"Framework initialized.");
438 Log.
Exception(
"DirectOutput framework has encountered a exception during initialization.", E);
439 throw new Exception(
"DirectOutput framework has encountered a exception during initialization.\n Inner exception: {0}".Build(E.Message), E);
462 Log.
Write(
"DirectOutput framework finished.");
463 Log.
Write(
"Bye and thanks for using!");
468 Log.
Exception(
"A exception occured while finishing the DirectOutput framework.", E);
469 throw new Exception(
"DirectOutput framework has encountered while finishing.\n Inner exception: {0}".Build(E.Message), E);
478 private void InitMainThread()
487 KeepMainThreadAlive =
true;
490 MainThread =
new Thread(MainThreadDoIt);
491 MainThread.Name =
"DirectOutput MainThread ";
498 Log.Exception(
"DirectOutput MainThread could not start.", E);
499 throw new Exception(
"DirectOutput MainThread could not start.", E);
508 private void FinishMainThread()
510 if (MainThread != null)
514 KeepMainThreadAlive =
false;
515 lock (MainThreadLocker)
517 Monitor.Pulse(MainThreadLocker);
519 if (!MainThread.Join(1000))
527 Log.Exception(
"A error occured during termination of DirectOutput MainThread", E);
528 throw new Exception(
"A error occured during termination of DirectOutput MainThread", E);
541 if (MainThread != null)
543 if (MainThread.IsAlive)
557 lock (MainThreadLocker)
559 MainThreadDoWork =
true;
560 Monitor.Pulse(MainThreadLocker);
565 private Thread MainThread {
get; set; }
566 private object MainThreadLocker =
new object();
567 private bool KeepMainThreadAlive =
true;
568 private bool MainThreadDoWork =
false;
570 const int MaxInputDataProcessingTimeMs = 10;
578 private void MainThreadDoIt()
584 while (KeepMainThreadAlive)
586 bool UpdateRequired =
false;
587 DateTime Start = DateTime.Now;
590 while (
InputQueue.
Count > 0 && (DateTime.Now - Start).Milliseconds <= MaxInputDataProcessingTimeMs && KeepMainThreadAlive)
599 UpdateRequired |=
true;
604 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);
610 if (KeepMainThreadAlive)
619 Log.Exception(
"A unhandled exception occured while executing timer events.", E);
626 if (UpdateRequired && KeepMainThreadAlive)
634 Log.Exception(
"A unhandled exception occured while updating the output controllers", E);
639 if (KeepMainThreadAlive)
645 lock (MainThreadLocker)
647 while (
InputQueue.
Count == 0 && NextAlarm > DateTime.Now && !MainThreadDoWork && KeepMainThreadAlive)
649 int TimeOut = ((int)(NextAlarm - DateTime.Now).TotalMilliseconds).Limit(1, 50);
651 Monitor.Wait(MainThreadLocker, TimeOut);
655 MainThreadDoWork =
false;
663 Log.Exception(
"A unexpected exception occured in the DirectOutput MainThread", E);
688 public void ReceiveData(
char TableElementTypeChar,
int Number,
int Value)
690 InputQueue.
Enqueue(TableElementTypeChar, Number, Value);
707 InputQueue.
Enqueue(TableElementName, Value);
720 InputQueue.
Enqueue(TableElementData);
739 string S = this.GetType().FullName +
" {\n";
740 S +=
" GlobalConfig {\n";
750 S +=
" Table Effects count: " +
Table.
Effects.Count +
"\n";
755 S +=
" Output toys count: " +
Cabinet.
Toys.Count +
"\n";
bool EnableLogging
Gets or sets a value indicating whether impotant events in the framework are logged to a file...
void HeartBeat()
HeartBeat has to be called regularely to update the LastHeartBeat property.
The AlarmHandler classed is used to execute scheduled events (e.g. regular updates on a effect) in th...
The Cabinet object describes the parts of a pinball cabinet (toys, outputcontrollers, outputs and more).
TableElementTypeEnum TableElementType
The type of the table element.
void Setup(string GlobalConfigFilename="", string TableFilename="", string RomName="")
Configures the Pinball object. Loads the global config, table config and cabinet config ...
void MainThreadSignal()
Signals the main thread to continue its work (if currently sleeping).
int LedControlMinimumRGBEffectDurationMs
Gets or sets the minimum duration in milliseconds for LedControl effects controlling RGB leds...
void Finish()
Finishes the table and the contained objects (Effects, TableElements)
static Cabinet GetCabinetFromConfigXmlFile(string FileName)
Instanciates a Cabinet object from a cabinet configuration in a XML file.
DateTime GetNextAlarmTime()
Gets the time when the next alarm (interval or single) is scheduled.
FileInfo GetCabinetConfigFile()
FileInfo object for the file containing the configuration of the cabinet (outputs, toys and so on).
bool MainThreadIsActive
Indicates if the MainThread of DirectOutput is active
string RomName
Name of the table rom. Triggers RomNameChanged if value is changed.
void Init(Pinball Pinball)
Inits the object.
int Number
The number of the table element.
string GlobalConfigFilename
Gets or sets the global config filename.
string TableName
Name of the Table. Triggers TableNameChanged if value is changed.
static void Warning(string Message)
Writes a warning message to the log.
GlobalConfig GlobalConfig
Gets the global config for the Pinnball object.
void UpdateTableElement(TableElementData Data)
Updates the TableElements list with data received from Pinmame.
void TriggerStaticEffects()
Triggers the static effects for the table.
bool ContainsConfig(string RomName)
Determines whether a config for the spcified RomName exists in the configs.
DirectOutput.Cab.Toys.ToyList Toys
List of IToy objects describing the toys in the cabinet.
void LoadLedControlFiles(IList< string > LedControlFilenames, bool ThrowExceptions=false)
Loads a list of ledcontrol.ini files.
void Update()
Calls the update method for toys and output controllers in the cabinet
This object provides information on a thread.
Pinball is the main object of the DirectOutput framework. It holds all objects required to process P...
static void Write(string Message)
Writes the specified message to the logfile.
static void Init()
Initializes the log using the file defnied in the Filename property.
TableConfigSourceEnum ConfigurationSource
Gets or sets the configuration source.
A simple logger used to record important events and exceptions.
Cabinet Cabinet
Gets or sets the Cabinet object for the Pinball object.
void Init(Pinball Pinball)
Initializes the table and the contained objects(Effects, TableElements).
FileInfo GetTableConfigFile(string FullTableFilename)
Gets a FileInfo object for the table config file. The file is lookued up using the list of the prope...
int Value
The value of the table element.
int LedControlMinimumEffectDurationMs
Gets or sets the minimum duration in milliseconds for LedControl effects occupying one output (e...
Out.OutputControllerList OutputControllers
List of IOutputController objects representing the output controllers in the cabinet.
void ReceiveData(string TableElementName, int Value)
Receives data for named table elements. The received data is put in a queue and the internal thread o...
AlarmHandler Alarms
Gets the AlarmHandler object for the Pinball object.
void ReceiveData(TableElementData TableElementData)
Receives the table element data from the calling app. The received data is put in a queue and the in...
void Finish()
Finishes the Pinball object.
The namespace DirectOutput.Cab contains all cabinet related classes like the Cabinet class itself...
void Finish()
Finishes the cabinet
int EffectMinDurationMs
The min duration for effects targeting a single output.
string GetLogFilename(string TableFilename="", string RomName="")
Gets the log filename based on the LogFilePattern with replaced placeholders.
string TableFilename
Gets or sets the filename of the table.
The DirectOutput.LedControl namespace contains the classes to read and understand the classical LedCo...
string TableConfigurationFilename
Gets or sets the table configuration filename.
TableElementList TableElements
Lists the TableElement objects for the Table. This list is automaticaly extend with new TableElement...
Data representing the state of a table emlement
void Init()
Initializes/starts the Pinball object
EffectList Effects
List of table specific effects.
void ReceiveData(char TableElementTypeChar, int Number, int Value)
Receives the table element data from the calling app (e.g. B2S.Server providing data through the plug...
PinballSupport.AlarmHandler Alarms
int HeartBeatTimeOutMs
Gets or sets the heartbeat timeout in milliseconds.
Dictionary< int, FileInfo > GetIniFilesDictionary(string TableFilename="")
Gets the a dictionary containing all ini files (file) and their number (key).
Ledcontrol configuration read from a ledcontrol.ini file.
void Finish()
Finishes the object. Clears all alarm lists.
List of LedControlConfig objects loaded from LedControl.ini files.
void Init(ICabinetOwner CabinetOwner)
Initializes the cabinet.
void AutoConfig()
This method finds all classes implementing the IAutoConfigOutputController interface and uses the mem...
string HostName
Gets or sets the name of the object hosting the thread.
bool ClearLogOnSessionStart
Gets or sets a value indicating whether DOF clears the log file on session start. ...
Global configuration for the DirectOutput framework.
The Table namespace contains all table specific classes like the Table class itself, TableElement and effect assigment classes.
static Table GetTableFromConfigXmlFile(string FileName)
Instanciates a Table object from a Table configuration in a XML file.
bool ExecuteAlarms(DateTime AlarmTime)
Executes all Alarmes which have expired until the specified AlarmTime..
static string Filename
Gets or sets the filename for the log.
Configures the system based on data from ini files (either directoutputconfig.ini or ledcontrol...
Holds all table specific information and handles all TableElements
Dictionary< string, object > ConfigurationSettings
bool AutoConfigEnabled
Gets or sets a value indicating whether auto config is enabled. If auto config is enabled...
The namespace FX contains effect related classes. Effects can be assigned directly to a Table and wi...
string CabinetConfigurationFilename
Gets or sets the filename from which the cabiet configuration was loaded.
Table()
Initializes a new instance of the Table class.
The namespace DirectOutput.General contains classes for general use.
override string ToString()
Returns a System.String that represents this instance.
Support classes used by the Pinball object.
static void Exception(string Message, Exception E=null)
Writes a exception message to the log.
static GlobalConfig GetGlobalConfigFromConfigXmlFile(string GlobalConfigFileName)
Instanciates a GlobalConfig object from a global configuration in a XML file. If the global config f...
int Count
Number of items in the ExtList.
bool AddLedControlConfig
Gets or sets a value indicating whether configurations from ledcontrol files should be added to the t...
Pinball()
Initializes a new instance of the Pinball class.