2019-07-14 22:43:22 +02:00
# include <hyperion/HyperionIManager.h>
// hyperion
# include <hyperion/Hyperion.h>
# include <db/InstanceTable.h>
// qt
# include <QThread>
HyperionIManager * HyperionIManager : : HIMinstance ;
HyperionIManager : : HyperionIManager ( const QString & rootPath , QObject * parent )
: QObject ( parent )
, _log ( Logger : : getInstance ( " HYPERION " ) )
, _instanceTable ( new InstanceTable ( rootPath , this ) )
, _rootPath ( rootPath )
{
HIMinstance = this ;
2020-07-12 09:19:59 +02:00
qRegisterMetaType < InstanceState > ( " InstanceState " ) ;
2019-07-14 22:43:22 +02:00
}
2020-08-08 13:09:15 +02:00
Hyperion * HyperionIManager : : getHyperionInstance ( quint8 instance )
2019-07-14 22:43:22 +02:00
{
if ( _runningInstances . contains ( instance ) )
return _runningInstances . value ( instance ) ;
Warning ( _log , " The requested instance index '%d' with name '%s' isn't running, return main instance " , instance , QSTRING_CSTR ( _instanceTable - > getNamebyIndex ( instance ) ) ) ;
return _runningInstances . value ( 0 ) ;
}
2020-08-08 23:12:43 +02:00
QVector < QVariantMap > HyperionIManager : : getInstanceData ( ) const
2019-07-14 22:43:22 +02:00
{
QVector < QVariantMap > instances = _instanceTable - > getAllInstances ( ) ;
for ( auto & entry : instances )
{
// add running state
entry [ " running " ] = _runningInstances . contains ( entry [ " instance " ] . toInt ( ) ) ;
}
return instances ;
}
void HyperionIManager : : startAll ( )
{
2020-08-02 22:35:09 +02:00
for ( const auto & entry : _instanceTable - > getAllInstances ( true ) )
2019-07-14 22:43:22 +02:00
{
startInstance ( entry [ " instance " ] . toInt ( ) ) ;
}
}
void HyperionIManager : : stopAll ( )
{
// copy the instances due to loop corruption, even with .erase() return next iter
QMap < quint8 , Hyperion * > instCopy = _runningInstances ;
for ( const auto instance : instCopy )
{
instance - > stop ( ) ;
}
}
2020-08-08 13:09:15 +02:00
void HyperionIManager : : toggleStateAllInstances ( bool pause )
2020-03-26 19:37:39 +01:00
{
// copy the instances due to loop corruption, even with .erase() return next iter
QMap < quint8 , Hyperion * > instCopy = _runningInstances ;
for ( const auto instance : instCopy )
{
emit instance - > compStateChangeRequest ( hyperion : : COMP_ALL , pause ) ;
}
}
2020-10-18 17:05:07 +02:00
bool HyperionIManager : : startInstance ( quint8 inst , bool block , QObject * caller , int tan )
2019-07-14 22:43:22 +02:00
{
if ( _instanceTable - > instanceExist ( inst ) )
{
if ( ! _runningInstances . contains ( inst ) & & ! _startQueue . contains ( inst ) )
{
QThread * hyperionThread = new QThread ( ) ;
2020-07-19 15:13:41 +02:00
hyperionThread - > setObjectName ( " HyperionThread " ) ;
2019-07-14 22:43:22 +02:00
Hyperion * hyperion = new Hyperion ( inst ) ;
hyperion - > moveToThread ( hyperionThread ) ;
// setup thread management
connect ( hyperionThread , & QThread : : started , hyperion , & Hyperion : : start ) ;
2019-07-29 19:09:26 +02:00
connect ( hyperion , & Hyperion : : started , this , & HyperionIManager : : handleStarted ) ;
connect ( hyperion , & Hyperion : : finished , this , & HyperionIManager : : handleFinished ) ;
2019-07-25 18:23:19 +02:00
connect ( hyperion , & Hyperion : : finished , hyperionThread , & QThread : : quit , Qt : : DirectConnection ) ;
2019-07-14 22:43:22 +02:00
// setup further connections
// from Hyperion
2019-07-29 19:09:26 +02:00
connect ( hyperion , & Hyperion : : settingsChanged , this , & HyperionIManager : : settingsChanged ) ;
connect ( hyperion , & Hyperion : : videoMode , this , & HyperionIManager : : requestVideoMode ) ;
2020-02-26 18:54:56 +01:00
connect ( hyperion , & Hyperion : : compStateChangeRequest , this , & HyperionIManager : : compStateChangeRequest ) ;
2019-07-14 22:43:22 +02:00
// to Hyperion
2019-07-29 19:09:26 +02:00
connect ( this , & HyperionIManager : : newVideoMode , hyperion , & Hyperion : : newVideoMode ) ;
2019-07-14 22:43:22 +02:00
// add to queue and start
_startQueue < < inst ;
hyperionThread - > start ( ) ;
// update db
_instanceTable - > setLastUse ( inst ) ;
_instanceTable - > setEnable ( inst , true ) ;
if ( block )
{
while ( ! hyperionThread - > isRunning ( ) ) { } ;
}
2020-10-18 17:05:07 +02:00
if ( ! _pendingRequests . contains ( inst ) & & caller ! = nullptr )
{
PendingRequests newDef { caller , tan } ;
_pendingRequests [ inst ] = newDef ;
}
2019-07-14 22:43:22 +02:00
return true ;
}
Debug ( _log , " Can't start Hyperion instance index '%d' with name '%s' it's already running or queued for start " , inst , QSTRING_CSTR ( _instanceTable - > getNamebyIndex ( inst ) ) ) ;
return false ;
}
Debug ( _log , " Can't start Hyperion instance index '%d' it doesn't exist in DB " , inst ) ;
return false ;
}
2020-08-08 13:09:15 +02:00
bool HyperionIManager : : stopInstance ( quint8 inst )
2019-07-14 22:43:22 +02:00
{
// inst 0 can't be stopped
if ( ! isInstAllowed ( inst ) )
return false ;
if ( _instanceTable - > instanceExist ( inst ) )
{
if ( _runningInstances . contains ( inst ) )
{
// notify a ON_STOP rather sooner than later, queued signal listener should have some time to drop the pointer before it's deleted
2020-07-12 09:19:59 +02:00
emit instanceStateChanged ( InstanceState : : H_ON_STOP , inst ) ;
2019-07-14 22:43:22 +02:00
Hyperion * hyperion = _runningInstances . value ( inst ) ;
hyperion - > stop ( ) ;
// update db
_instanceTable - > setEnable ( inst , false ) ;
return true ;
}
Debug ( _log , " Can't stop Hyperion instance index '%d' with name '%s' it's not running' " , inst , QSTRING_CSTR ( _instanceTable - > getNamebyIndex ( inst ) ) ) ;
return false ;
}
Debug ( _log , " Can't stop Hyperion instance index '%d' it doesn't exist in DB " , inst ) ;
return false ;
}
2020-08-08 13:09:15 +02:00
bool HyperionIManager : : createInstance ( const QString & name , bool start )
2019-07-14 22:43:22 +02:00
{
quint8 inst ;
if ( _instanceTable - > createInstance ( name , inst ) )
{
Info ( _log , " New Hyperion instance created with name '%s' " , QSTRING_CSTR ( name ) ) ;
2020-07-12 09:19:59 +02:00
emit instanceStateChanged ( InstanceState : : H_CREATED , inst , name ) ;
2019-07-14 22:43:22 +02:00
emit change ( ) ;
if ( start )
startInstance ( inst ) ;
return true ;
}
return false ;
}
2020-08-08 13:09:15 +02:00
bool HyperionIManager : : deleteInstance ( quint8 inst )
2019-07-14 22:43:22 +02:00
{
// inst 0 can't be deleted
if ( ! isInstAllowed ( inst ) )
return false ;
2019-07-21 19:06:47 +02:00
// stop it if required as blocking and wait
2019-07-29 19:09:26 +02:00
stopInstance ( inst ) ;
2019-07-14 22:43:22 +02:00
if ( _instanceTable - > deleteInstance ( inst ) )
{
Info ( _log , " Hyperion instance with index '%d' has been deleted " , inst ) ;
2020-07-12 09:19:59 +02:00
emit instanceStateChanged ( InstanceState : : H_DELETED , inst ) ;
2019-07-14 22:43:22 +02:00
emit change ( ) ;
return true ;
}
return false ;
}
2020-08-08 13:09:15 +02:00
bool HyperionIManager : : saveName ( quint8 inst , const QString & name )
2019-07-14 22:43:22 +02:00
{
if ( _instanceTable - > saveName ( inst , name ) )
{
emit change ( ) ;
return true ;
}
return false ;
}
void HyperionIManager : : handleFinished ( )
{
Hyperion * hyperion = qobject_cast < Hyperion * > ( sender ( ) ) ;
2020-08-08 13:09:15 +02:00
quint8 instance = hyperion - > getInstanceIndex ( ) ;
2019-07-14 22:43:22 +02:00
Info ( _log , " Hyperion instance '%s' has been stopped " , QSTRING_CSTR ( _instanceTable - > getNamebyIndex ( instance ) ) ) ;
_runningInstances . remove ( instance ) ;
2020-07-12 09:22:05 +02:00
hyperion - > thread ( ) - > deleteLater ( ) ;
2019-07-14 22:43:22 +02:00
hyperion - > deleteLater ( ) ;
2020-07-12 09:19:59 +02:00
emit instanceStateChanged ( InstanceState : : H_STOPPED , instance ) ;
2019-07-14 22:43:22 +02:00
emit change ( ) ;
}
void HyperionIManager : : handleStarted ( )
{
Hyperion * hyperion = qobject_cast < Hyperion * > ( sender ( ) ) ;
2020-08-08 13:09:15 +02:00
quint8 instance = hyperion - > getInstanceIndex ( ) ;
2019-07-14 22:43:22 +02:00
Info ( _log , " Hyperion instance '%s' has been started " , QSTRING_CSTR ( _instanceTable - > getNamebyIndex ( instance ) ) ) ;
_startQueue . removeAll ( instance ) ;
_runningInstances . insert ( instance , hyperion ) ;
2020-07-12 09:19:59 +02:00
emit instanceStateChanged ( InstanceState : : H_STARTED , instance ) ;
2019-07-14 22:43:22 +02:00
emit change ( ) ;
2020-10-18 17:05:07 +02:00
if ( _pendingRequests . contains ( instance ) )
{
PendingRequests def = _pendingRequests . take ( instance ) ;
emit startInstanceResponse ( def . caller , def . tan ) ;
_pendingRequests . remove ( instance ) ;
}
2019-07-14 22:43:22 +02:00
}