/*! * * Copyright (c) 2019-2024 Diality Inc. - All Rights Reserved. * \copyright * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * \file main.h * \author (last) Behrouz NematiPour * \date (last) 04-Apr-2024 * \author (original) Behrouz NematiPour * \date (original) 28-Oct-2019 * */ #pragma once // Qt #include #include // Project // Application #define PRINT_THREAD_NAME_ENABLE 0 #if (PRINT_THREAD_NAME_ENABLE) #include #define PRINT_THREAD_NAME qDebug() << " ----- " << QThread::currentThread()->objectName() << metaObject()->className() << __func__ ; #else #define PRINT_THREAD_NAME #endif // TODO : A singleton parent class needs to be created // to taking care of the Threading, init, quit, and so // TODO : Threading // - We still need to work on threading on other classes // - We need to have a singleton parent class // - Some code has been added to debug can interface (We still have swap frames) #define SINGLETON(vCLASS) \ private: \ explicit vCLASS(QObject *parent = nullptr); \ virtual ~vCLASS() { } \ vCLASS(vCLASS const &) = delete; \ vCLASS & operator = (vCLASS const &) = delete; \ public: \ /*! \brief instance accessor \details A singleton class single instance creator/accessor \return reference to the class static instance */\ static vCLASS &I() { \ static vCLASS _instance; \ return _instance; \ } \ static bool _disable; \ /* Intentionally disable made private */ \ static void disable(); \ public: \ static bool isDisable() { \ return _disable; \ } \ private: //--------------------------------------------------------------------------------// #include #define SINGLETON_DISABLE(vCLASS) \ bool vCLASS::_disable = false; \ void vCLASS:: disable() { \ if ( QThread::currentThread() == qApp->thread() ) { \ LOG_DEBUG(QString(" !!! Failed Disable "#vCLASS" [%1] !!!").arg(QThread::currentThread()->objectName())); \ return; \ } \ LOG_DEBUG(QString(" !!! Disabled "#vCLASS" [%1] !!!").arg(QThread::currentThread()->objectName())); \ QEventLoopLocker _eventLoopLocker(QThread::currentThread()); \ _disable = true; \ } //--------------------------------------------------------------------------------// #define SINGLETON_DISABLE_CONNECT(vSIGNAL) \ connect(&_ApplicationController , \ &ApplicationController::vSIGNAL , \ this , \ [=](bool vPass) { if ( ! vPass ) disable(); }); //--------------------------------------------------------------------------------// //--------------------------------------------------------------------------------// extern int gFakeInterval ; extern QByteArray gFakeData ; extern const char*gFakeData_default ; extern bool gSendEmptyKeepAwake ; extern bool gFakeSeqAtBegin ; extern bool gDisableUnhandledReport ; extern bool gDisableDialinUnhandled ; extern bool gDisableTimeout ; extern bool gDisableAlarmNoMinimize ; extern bool gDisableSDCFailLogStop ; extern bool gDisableCloudSyncFailStop ; extern bool gDisableCheckInLog ; extern bool gDisableAcknowLog ; extern bool gConsoleoutLogs ; extern bool gConsoleoutFrameInterface ; extern bool gConsoleoutCanInterface ; extern bool gEnableDryDemo ; extern QString gActiveCANBus ; extern bool gEnableManufacturing ; extern bool gEnableUpdating ; extern bool gUseRootHome ; extern QString gStandard_tmp ; extern bool gLogSerialName ; extern bool gLogLongName ; extern bool gLogUpload ; extern bool gLogCompress ; //--------------------------------------------------------------------------------// //--------------------------------------------------------------------------------// #define SKIPPER_DEF(X) \ const quint8 skipperMaxTry = X; \ static quint8 skipperCounter = 0; #define SKIPPER_TST(WHAT) \ if ( skipperCounter < skipperMaxTry ) WHAT #define SKIPPER_TRY \ skipperCounter++ #define SKIPPER_RST \ skipperCounter = 0 //--------------------------------------------------------------------------------// #define DEBUG_PROPERTY_CHANGED(vVARIABLE, PREFIX) // qDebug() << "#" << #vVARIABLE << PREFIX##vVARIABLE; //--------------------------------------------------------------------------------// #define FROMVARIANT(vVARIABLE, vGROUP, vKEY, vCONVERSION) \ { \ bool ok = false; \ vVARIABLE( _Settings.value(mCategory, vGROUP, vKEY).to##vCONVERSION(&ok) ); \ if ( !ok ) LOG_DEBUG("incorrect configuration value for " #vVARIABLE); \ } //--------------------------------------------------------------------------------// #define FROMVARIANT_WITHRETURN(vVARIABLE, vGROUP, vKEY, vCONVERSION, vOVERALL_OK) \ { \ bool ok = false; \ vVARIABLE( _Settings.value(mCategory, vGROUP, vKEY).to##vCONVERSION(&ok) ); \ if ( !ok ) LOG_DEBUG("incorrect configuration value for " #vVARIABLE); \ vOVERALL_OK = vOVERALL_OK && ok; \ } //--------------------------------------------------------------------------------// #define PROPERTY_SLOT( vTYPE , vVARIABLE ) \ protected : \ /*! \brief Property setter \details The property setter which update the private variable \n - if only the value has been changed \n - or it's the first time property is set. \n emits the Property notify (...Changed) signal on update. \n the notify signal (...Changed) passes the new value as its parameter. \n \param new value */\ void vVARIABLE ( const vTYPE & v##vVARIABLE ) { \ static bool init = false; \ _##vVARIABLE##Changed = _##vVARIABLE != v##vVARIABLE; \ if ( !init || _##vVARIABLE##Changed ) { \ DEBUG_PROPERTY_CHANGED(vVARIABLE, v) \ init = true; \ _##vVARIABLE = v##vVARIABLE; \ emit vVARIABLE##Changed( _##vVARIABLE ); \ } \ } //--------------------------------------------------------------------------------// #define TRIGGER_SLOT( vTYPE , vVARIABLE ) \ protected: \ /*! \brief Trigger setter \details The Trigger setter which update the private variable \n with no condition each time the value the passed. \n emits the Trigger notify (...Triggered) signal after update. \n the notify signal (...Triggered) passes the new value as its parameter.\n \param new value */\ void vVARIABLE ( const vTYPE & v##vVARIABLE ) { \ DEBUG_PROPERTY_CHANGED(vVARIABLE, v) \ _##vVARIABLE##Changed = true; \ _##vVARIABLE = v##vVARIABLE; \ emit vVARIABLE##Triggered( _##vVARIABLE ); \ } //--------------------------------------------------------------------------------// #define STATE_SLOT( vTYPE , vVARIABLE ) \ protected : \ /*! \brief Property setter \details The property setter which update the private variable \n - if only the value has been changed \n emits the Property notify (...Entered) signal on update. \n the notify signal (...Entered) passes the new value as its parameter. \n \param new value */\ void vVARIABLE ( const vTYPE & v##vVARIABLE ) { \ _##vVARIABLE##Changed = _##vVARIABLE != v##vVARIABLE; \ if ( _##vVARIABLE##Changed ) { \ DEBUG_PROPERTY_CHANGED(vVARIABLE, v) \ _##vVARIABLE = v##vVARIABLE; \ emit vVARIABLE##Entered( _##vVARIABLE ); \ } \ } //--------------------------------------------------------------------------------// #define PROPERTY_POST_CONNECTION( vCLASS, vVARIABLE ) \ connect(this, &vCLASS::vVARIABLE##Changed \ , &vCLASS::vVARIABLE##_post ); //--------------------------------------------------------------------------------// #define PROPERTY_BASE(vTYPE , vVARIABLE , vDEFVALUE, vSIGNAL) \ /*! \brief Qt Property declaration \details The Qt Property definition by Q_PROPERTY documentation. */\ Q_PROPERTY( vTYPE vVARIABLE \ READ vVARIABLE \ WRITE vVARIABLE \ NOTIFY vVARIABLE##vSIGNAL) \ Q_SIGNALS: \ /*! \brief Property notify signal \details The property notify signal (...Changed) which will be emitted by property setter - if only the value has been changed \n - or it's the first time property is set. \n \return current value */\ void vVARIABLE##vSIGNAL( const vTYPE & v##vVARIABLE ); \ private: \ void vVARIABLE##_post ( const vTYPE & v##vVARIABLE ); \ private: \ vTYPE _##vVARIABLE = vDEFVALUE; \ bool _##vVARIABLE##Changed = false; \ protected: \ /*! \brief Property getter \details The property getter which reads the private variable \return current value */\ vTYPE vVARIABLE () const { \ return _##vVARIABLE ; \ } //--------------------------------------------------------------------------------// #define READONLY_BASE(vTYPE , vVARIABLE , vDEFVALUE, vSIGNAL) \ /*! \brief Qt Read-Only Property declaration \details The Qt Property definition by Q_PROPERTY documentation. */\ Q_PROPERTY( vTYPE vVARIABLE \ READ vVARIABLE \ NOTIFY vVARIABLE##vSIGNAL) \ Q_SIGNALS: \ /*! \brief Property notify signal \details The property notify signal (...Changed) which will be emitted by property setter - if only the value has been changed \n - or it's the first time property is set. \n \return current value */\ void vVARIABLE##vSIGNAL( const vTYPE & v##vVARIABLE ); \ private: \ vTYPE _##vVARIABLE = vDEFVALUE; \ bool _##vVARIABLE##Changed = false; \ protected: \ /*! \brief Property getter \details The property getter which reads the private variable \return current value */\ vTYPE vVARIABLE () const { \ return _##vVARIABLE ; \ } //--------------------------------------------------------------------------------// #define IDBASED_BASE(vTYPE , vVARIABLE , vDEFVALUE , vLIST , vID) \ /*! \brief Qt Property declaration \details The Qt Property definition by Q_PROPERTY documentation. */\ Q_PROPERTY( vTYPE vVARIABLE \ READ vVARIABLE \ WRITE vVARIABLE \ NOTIFY vID##Changed) \ Q_SIGNALS: \ /*! \brief Property notify signal \details The property notify signal (...Changed) which will be emitted by property setter - if only the value has been changed \n - or it's the first time property is set. \n \return current value */\ void vVARIABLE##Changed( const vTYPE & v##vVARIABLE ); \ private: \ vTYPE _##vVARIABLE = vDEFVALUE; \ bool _##vVARIABLE##Changed = false; \ bool _##vVARIABLE##ByID = true ; \ protected: \ /*! \brief Property byId setter \details The property sets the ByID value to be used in the getter */\ void vVARIABLE##ByID(bool vByID = true) { \ _##vVARIABLE##ByID = vByID ; \ } \ /*! \brief Property getter \details The property getter which reads the private variable \return current value */\ vTYPE vVARIABLE () const { \ if ( ! _##vVARIABLE##ByID ) return _##vVARIABLE; \ QString value = _##vLIST [ _##vID ].vVARIABLE; \ if ( ! value.isEmpty() ) return value; \ return vDEFVALUE; \ } //--------------------------------------------------------------------------------// #define READONLY( vTYPE , vVARIABLE , vDEFVALUE ) \ READONLY_BASE( vTYPE , vVARIABLE , vDEFVALUE , Changed ) \ PROPERTY_SLOT( vTYPE , vVARIABLE ) //--------------------------------------------------------------------------------// #define PROPERTY( vTYPE , vVARIABLE , vDEFVALUE ) \ PROPERTY_BASE( vTYPE , vVARIABLE , vDEFVALUE , Changed ) \ PROPERTY_SLOT( vTYPE , vVARIABLE ) //--------------------------------------------------------------------------------// #define TRIGGER( vTYPE , vVARIABLE , vDEFVALUE ) \ PROPERTY_BASE( vTYPE , vVARIABLE , vDEFVALUE , Triggered) \ TRIGGER_SLOT ( vTYPE , vVARIABLE ) //--------------------------------------------------------------------------------// #define STATE( vTYPE , vVARIABLE , vDEFVALUE ) \ PROPERTY_BASE( vTYPE , vVARIABLE , vDEFVALUE , Entered ) \ STATE_SLOT ( vTYPE , vVARIABLE ) //--------------------------------------------------------------------------------// #define IDBASED( vTYPE , vVARIABLE , vDEFVALUE , vLIST , vID ) \ IDBASED_BASE ( vTYPE , vVARIABLE , vDEFVALUE , vLIST , vID ) \ PROPERTY_SLOT( vTYPE , vVARIABLE ) //--------------------------------------------------------------------------------// #define VALUESET( vTYPE , vVARIABLE , vDEFVALUE ) \ PROPERTY( vTYPE , vVARIABLE , vDEFVALUE ) \ PROPERTY( bool , vVARIABLE##Set , false ) //--------------------------------------------------------------------------------// #define RANGESET( vTYPE , vVARIABLE , vDEFVALUE ) \ READONLY( vTYPE , vVARIABLE##Min , vDEFVALUE ) \ READONLY( vTYPE , vVARIABLE##Max , vDEFVALUE ) \ READONLY( vTYPE , vVARIABLE##Res , vDEFVALUE ) \ READONLY( vTYPE , vVARIABLE##Def , vDEFVALUE ) //--------------------------------------------------------------------------------// #define MEMBER( vTYPE , vVARIABLE , vDEFVALUE ) \ private: \ vTYPE _##vVARIABLE = vDEFVALUE; \ public: \ /*! \brief Property setter \details The property setter which update the private variable \n \param new value */\ void vVARIABLE ( const vTYPE & v##vVARIABLE ) { \ _##vVARIABLE = v##vVARIABLE; \ } \ public: \ /*! \brief Property getter \details The property getter which reads the private variable \return current value */\ vTYPE vVARIABLE () const { \ return _##vVARIABLE ; \ } //--------------------------------------------------------------------------------// #define CONSTANT( vTYPE , vVARIABLE , vDEFVALUE ) \ /*! \brief Qt Constant Property declaration \details The Qt Property definition by Q_PROPERTY documentation. */\ Q_PROPERTY( vTYPE vVARIABLE \ READ vVARIABLE \ CONSTANT) \ protected: \ /*! \brief Property getter \details The property getter which reads the private variable \return current value */\ vTYPE vVARIABLE () const { \ return vDEFVALUE ; \ } //--------------------------------------------------------------------------------// #define NOTIFIER( vVARIABLE ) \ Q_SIGNALS: \ /*! \brief Property notify signal \details The property notify signal (...Changed) which will be emitted by property setter - if only the value has been changed \n - or it's the first time property is set. \n \return current value */\ void vVARIABLE##Notified( const bool & v##vVARIABLE ); \ private: \ bool _##vVARIABLE = false; \ protected: \ /*! \brief Property getter \details The property getter which reads the private variable \return current value */\ bool vVARIABLE () const { \ return _##vVARIABLE ; \ } \ /*! \brief Notifier setter \details The notifier setter which update the private variable \n emits the notifier (is...) signal on update. \n the notify signal (is...) passes the new value as its parameter. \n \param new value */\ void vVARIABLE ( const bool & v##vVARIABLE ) { \ DEBUG_PROPERTY_CHANGED(vVARIABLE, v) \ _##vVARIABLE = v##vVARIABLE; \ emit vVARIABLE##Notified( _##vVARIABLE ); \ } //--------------------------------------------------------------------------------// #define SETTINGS_BASE( vVARIABLE , vCATEGORY , vGROUP , vKEY) \ private: \ /*! \brief Settings identifier \details identifies the settings by the given information \param vCategory - The category of the setting which includes on-level folder and the file name (without .conf extension) \param vGroup - The group setting key/value belongs to \param vKey - The key of the setting */\ bool is##vVARIABLE(const QString &vCategory , \ const QString &vGroup , \ const QString &vKey ) { \ return vCategory == vVARIABLE##Category() && \ vGroup == vVARIABLE##Group () && \ vKey == vVARIABLE##Key (); \ } \ /*! \brief Settings property category getter \details returns the category of the setting */\ QString vVARIABLE##Category() { \ return vCATEGORY; \ } \ /*! \brief Settings property group getter \details returns the group of the setting */\ QString vVARIABLE##Group() { \ return vGROUP; \ } \ /*! \brief Settings property key getter \details returns the key of the setting */\ QString vVARIABLE##Key() { \ return vKEY; \ } //--------------------------------------------------------------------------------// #define SETTINGS( vTYPE , vVARIABLE , vDEFVALUE , vCATEGORY , vGROUP , vKEY) \ PROPERTY_BASE( vTYPE , vVARIABLE , vDEFVALUE , Changed ) \ PROPERTY_SLOT( vTYPE , vVARIABLE ) \ SETTINGS_BASE( vVARIABLE , vCATEGORY , vGROUP , vKEY) //--------------------------------------------------------------------------------// //--------------------------------------------------------------------------------// #define ACTION_VIEW_CONNECTION(vTYPE) \ connect(&_GuiController, SIGNAL(didActionReceive(const vTYPE &)), \ this, SLOT( onActionReceive(const vTYPE &))); //--------------------------------------------------------------------------------// #define ADJUST_VIEW_CONNECTION(vTYPE) \ connect( this, SIGNAL(didAdjustment (const vTYPE &)), \ &_GuiController, SLOT( doAdjustment (const vTYPE &))); //--------------------------------------------------------------------------------// //--------------------------------------------------------------------------------// #define ACTION_METHOD_BRIDGE_CONNECTION(vMETHOD, vSOURCE, vTYPE) \ connect(&vSOURCE, SIGNAL(did##vMETHOD(const vTYPE &)), \ this , SLOT( on##vMETHOD(const vTYPE &))); //--------------------------------------------------------------------------------// #define ACTION_RECEIVE_BRIDGE_CONNECTION(vSOURCE, vTYPE) \ ACTION_METHOD_BRIDGE_CONNECTION(ActionReceive, vSOURCE, vTYPE) //--------------------------------------------------------------------------------// #define ADJUST_TRANSMT_BRIDGE_CONNECTION(vSOURCE, vTYPE) \ ACTION_METHOD_BRIDGE_CONNECTION(Adjustment , vSOURCE, vTYPE) //--------------------------------------------------------------------------------// #define ACTION_RECEIVE_PRIVATE_SLOT(vTYPE) \ private Q_SLOTS: \ /*! \brief Bridge slot \details The bridge slot is for thread safety between classes for received message and is used to emit its signal to pass the model data to next observer. \param vData - The model data which has been received. \note This method is private and the interface is signals only. (starts with 'on') */\ void onActionReceive (const vTYPE &vData) { \ emit didActionReceive(vData); \ } #define ACTION_RECEIVE_PRIVATE_SLOT_NOEMIT(vTYPE) \ private Q_SLOTS: \ /*! \brief The Received message slot that needs implementation \details The bridge slot is for thread safety between classes for received message and is used to emit its signal to pass the model data to next observer. \param vData - The model data which has been received. \note This method is private and the interface is signals only. (starts with 'on') */\ void onActionReceive (const vTYPE &vData) //--------------------------------------------------------------------------------// #define ADJUST_TRANSMT_PRIVATE_SLOT_DEFINITION(vTYPE) \ private Q_SLOTS: \ /*! \brief Adjustment slot \details The bridge slot is for thread safety between classes for adjustment messages and is used to emit its signal to pass the model data to next observer. \param vData - The model data to be used for adjustment \note This method is private and the interface is signals only. (starts with 'on') This slot has to have its specific implementation and is not a bridge (not a signal emitter). */\ void onAdjustment (const vTYPE &vData); //--------------------------------------------------------------------------------// #define ADJUST_TRANSMT_PRIVATE_SLOT(vTYPE) \ private Q_SLOTS: \ /*! \brief Adjustment bridge slot \details The bridge slot is for thread safety between classes for adjustment messages and is used to emit its signal to pass the model data to next observer. \param vData - The model data to be used for adjustment \note This method is private and the interface is signals only. (starts with 'on') */\ void onAdjustment (const vTYPE &vData) { \ emit didAdjustment( vData); \ } //--------------------------------------------------------------------------------// #define ADJUST_TRANSMT_PUBLIC_SLOT(vTYPE) \ public Q_SLOTS: \ /*! \brief Adjustment invocable/exposed slot \details This slot is able to be called within QML context when an object of the class is instantiated in QML. For thread safety it's calling its designated signal to notify observers. \note This method is public and is the interface. (starts with 'do') */\ void doAdjustment (const vTYPE &vData) { \ emit didAdjustment( vData); \ } //--------------------------------------------------------------------------------// #define ACTION_RECEIVE_SIGNAL(vTYPE) \ Q_SIGNALS: \ /*! \brief Receive bridge signal \details The bridge signal is for thread safety between classes for received message and is used to be emitted in its slot to pass the model data to next observer. \param vData - The model data which has been received. \note This method is public to be exposed to the observers to be able to connect to it as the interface. (starts with 'did') */\ void didActionReceive (const vTYPE &vData); //--------------------------------------------------------------------------------// #define ADJUST_TRANSMT_SIGNAL(vTYPE) \ Q_SIGNALS: \ /*! \brief Adjustment bridge signal \details The bridge signal is for thread safety between classes for received message and is used to be emitted in its slot to pass the model data to next observer. \param vData - The model data which has been received. \note This method is public to be exposed to the observers to be able to connect to it as the interface. (starts with 'did') */\ void didAdjustment (const vTYPE &vData); //--------------------------------------------------------------------------------// #define ACTION_RECEIVE_BRIDGE_DEFINITION(vTYPE) \ \ ACTION_RECEIVE_PRIVATE_SLOT (vTYPE) \ ACTION_RECEIVE_SIGNAL (vTYPE) \ //--------------------------------------------------------------------------------// #define ADJUST_TRANSMT_BRIDGE_DEFINITION_NOEMIT(vTYPE) \ \ ADJUST_TRANSMT_PRIVATE_SLOT_DEFINITION (vTYPE) \ ADJUST_TRANSMT_SIGNAL (vTYPE) \ //--------------------------------------------------------------------------------// #define ADJUST_TRANSMT_BRIDGE_DEFINITION(vTYPE) \ \ ADJUST_TRANSMT_PRIVATE_SLOT (vTYPE) \ ADJUST_TRANSMT_SIGNAL (vTYPE) \ //--------------------------------------------------------------------------------// #define ADJUST_TRANSMT_BRIDGE_DEFINITION_PUBLIC(vTYPE) \ \ ADJUST_TRANSMT_PUBLIC_SLOT (vTYPE) \ ADJUST_TRANSMT_SIGNAL (vTYPE) \ //--------------------------------------------------------------------------------// #define SAFE_CALL( vMETHOD) \ public Q_SLOTS : void vMETHOD() { \ static bool init = false; \ if ( ! init ) { \ connect(this, SIGNAL( did##vMETHOD()), \ this, SLOT( on##vMETHOD())); \ init = true; \ } \ emit did##vMETHOD(); \ } \ Q_SIGNALS : void did##vMETHOD(); \ private Q_SLOTS : void on##vMETHOD(); //--------------------------------------------------------------------------------// #define SAFE_CALL_EX( vMETHOD,vTYPE) \ public Q_SLOTS : void vMETHOD(vTYPE vData) { \ static bool init = false; \ if ( ! init ) { \ connect(this, SIGNAL( did##vMETHOD(vTYPE)), \ this, SLOT( on##vMETHOD(vTYPE))); \ init = true; \ } \ emit did##vMETHOD( vData); \ } \ Q_SIGNALS : void did##vMETHOD(vTYPE); \ private Q_SLOTS : void on##vMETHOD(vTYPE); //--------------------------------------------------------------------------------// #define SAFE_CALL_EX2( vMETHOD,vTYPE1 ,vTYPE2 ) \ public Q_SLOTS : void vMETHOD(vTYPE1 vDATA1 ,vTYPE2 vDATA2 ) { \ static bool init = false; \ if ( ! init ) { \ connect(this, SIGNAL( did##vMETHOD(vTYPE1 ,vTYPE2 )), \ this, SLOT( on##vMETHOD(vTYPE1 ,vTYPE2 )));\ init = true; \ } \ emit did##vMETHOD( vDATA1 , vDATA2 ); \ } \ Q_SIGNALS : void did##vMETHOD(vTYPE1 ,vTYPE2 ); \ private Q_SLOTS : void on##vMETHOD(vTYPE1 ,vTYPE2 ); //--------------------------------------------------------------------------------// #define TIME_CALL( vMETHOD,vCOUNT ) \ { \ static quint8 counter = 0; \ if ( ! counter-- ) { counter = vCOUNT; vMETHOD; } \ } \ //--------------------------------------------------------------------------------// #define REGISTER_METATYPE(vTYPE) \ qRegisterMetaType < vTYPE > (#vTYPE); //--------------------------------------------------------------------------------// #define REGISTER_TYPE(vTYPE) \ qmlRegisterType < vTYPE > (#vTYPE, 0, 1, #vTYPE); //--------------------------------------------------------------------------------//