PixelLightAPI
.
|
00001 /*********************************************************\ 00002 * File: CoreApplication.h * 00003 * 00004 * Copyright (C) 2002-2012 The PixelLight Team (http://www.pixellight.org/) 00005 * 00006 * This file is part of PixelLight. 00007 * 00008 * PixelLight is free software: you can redistribute it and/or modify 00009 * it under the terms of the GNU Lesser General Public License as published by 00010 * the Free Software Foundation, either version 3 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * PixelLight is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public License 00019 * along with PixelLight. If not, see <http://www.gnu.org/licenses/>. 00020 \*********************************************************/ 00021 00022 00023 #ifndef __PLCORE_CONSOLE_APPLICATION_H__ 00024 #define __PLCORE_CONSOLE_APPLICATION_H__ 00025 #pragma once 00026 00027 00028 //[-------------------------------------------------------] 00029 //[ Includes ] 00030 //[-------------------------------------------------------] 00031 #include "PLCore/Base/Object.h" 00032 #include "PLCore/Tools/Version.h" 00033 #include "PLCore/Tools/CommandLine.h" 00034 #include "PLCore/Core/AbstractLifecycle.h" 00035 #include "PLCore/Application/ApplicationContext.h" 00036 #include "PLCore/Config/Config.h" 00037 00038 00039 //[-------------------------------------------------------] 00040 //[ Namespace ] 00041 //[-------------------------------------------------------] 00042 namespace PLCore { 00043 00044 00045 //[-------------------------------------------------------] 00046 //[ Classes ] 00047 //[-------------------------------------------------------] 00048 /** 00049 * @brief 00050 * Application base class 00051 * 00052 * @remarks 00053 * An application class is a template for all kind of applications. 00054 * It controls the main loop of the program and provides all typical data that 00055 * is needed for an application. Derived classes are provided for specific tasks, 00056 * e.g. GUI or server applications. Please note that derived application classes 00057 * are allowed to hand over the main loop as well as other logic to e.g. a host 00058 * in order to become passive. 00059 * 00060 * This class provides a most basic framework for console applications. 00061 * It keeps the filename and startup directory of the executable for later use and 00062 * provides a name, title and version of the application. It also provides an instance 00063 * of the command line parser to work with command line parameters (see CommandLine 00064 * for further explanations). 00065 * 00066 * @note 00067 * - Implementation of the template method design pattern (although this class is not abstract) 00068 */ 00069 class CoreApplication : public Object, protected AbstractLifecycle { 00070 00071 00072 //[-------------------------------------------------------] 00073 //[ RTTI interface ] 00074 //[-------------------------------------------------------] 00075 pl_class(PLCORE_RTTI_EXPORT, CoreApplication, "PLCore", PLCore::Object, "Application class") 00076 #ifdef PLCORE_EXPORTS // The following is only required when compiling PLCore 00077 // Constructors 00078 pl_constructor_0(DefaultConstructor, "Default constructor", "") 00079 // Methods 00080 pl_method_0(GetApplicationContext, pl_ret_type(const ApplicationContext&), "Get application context.", "") 00081 pl_method_1(Exit, pl_ret_type(void), int, "Exit application. Return code for application as first parameter (usually 0 means no error).", "") 00082 #endif 00083 pl_class_end 00084 00085 00086 //[-------------------------------------------------------] 00087 //[ Public data types ] 00088 //[-------------------------------------------------------] 00089 public: 00090 /** 00091 * @brief 00092 * Signal 00093 */ 00094 enum ESignal { 00095 SignalInterrupt = 1, /**< Application interrupted (caused by ctrl-c) */ 00096 SignalTerm /**< Exit application */ 00097 }; 00098 00099 00100 //[-------------------------------------------------------] 00101 //[ Public static functions ] 00102 //[-------------------------------------------------------] 00103 public: 00104 /** 00105 * @brief 00106 * Get pointer to current application 00107 * 00108 * @return 00109 * Pointer to application 00110 * 00111 * @remarks 00112 * The global application pointer is set when the constructor of an Application 00113 * is called and reset when it's destructor is called. While this makes it safe 00114 * to use two or more Application instances after each other, you should *never* 00115 * use more than one Application instance at a time! 00116 */ 00117 static inline CoreApplication *GetApplication(); 00118 00119 00120 //[-------------------------------------------------------] 00121 //[ Private static data ] 00122 //[-------------------------------------------------------] 00123 private: 00124 static PLCORE_API CoreApplication *g_pApplication; /**< Pointer to the current application instance */ 00125 00126 00127 //[-------------------------------------------------------] 00128 //[ Public functions ] 00129 //[-------------------------------------------------------] 00130 public: 00131 /** 00132 * @brief 00133 * Constructor 00134 */ 00135 PLCORE_API CoreApplication(); 00136 00137 /** 00138 * @brief 00139 * Destructor 00140 */ 00141 PLCORE_API virtual ~CoreApplication(); 00142 00143 /** 00144 * @brief 00145 * Get application context 00146 * 00147 * @return 00148 * Application context 00149 */ 00150 inline const ApplicationContext &GetApplicationContext() const; 00151 00152 /** 00153 * @brief 00154 * Get application name 00155 * 00156 * @return 00157 * Name of the application 00158 */ 00159 inline String GetName() const; 00160 00161 /** 00162 * @brief 00163 * Set application name 00164 * 00165 * @param[in] sName 00166 * Name of the application 00167 */ 00168 PLCORE_API void SetName(const String &sName); 00169 00170 /** 00171 * @brief 00172 * Get application title 00173 * 00174 * @return 00175 * Title of the application 00176 */ 00177 inline String GetTitle() const; 00178 00179 /** 00180 * @brief 00181 * Set application title 00182 * 00183 * @param[in] sTitle 00184 * Title of the application 00185 */ 00186 inline void SetTitle(const String &sTitle); 00187 00188 /** 00189 * @brief 00190 * Get version of application 00191 * 00192 * @return 00193 * Version of the program 00194 */ 00195 inline const Version &GetVersion() const; 00196 00197 /** 00198 * @brief 00199 * Set version of application 00200 * 00201 * @param[in] cVersion 00202 * Version of the program 00203 */ 00204 inline void SetVersion(const Version &cVersion); 00205 00206 /** 00207 * @brief 00208 * Check if application uses multi-user environment 00209 * 00210 * @return 00211 * 'true' if multi-user environment is used, else 'false' 00212 */ 00213 inline bool GetMultiUser() const; 00214 00215 /** 00216 * @brief 00217 * Set if application uses multi-user environment 00218 * 00219 * @param[in] bMultiUser 00220 * 'true' if multi-user environment is used, else 'false' 00221 * 00222 * @remarks 00223 * By default, multi-user environment is used. 00224 * If on, e.g. config and log files are loaded and saved in the user directory 00225 */ 00226 inline void SetMultiUser(bool bMultiUser); 00227 00228 /** 00229 * @brief 00230 * Get name of config file 00231 * 00232 * @return 00233 * Config filename (only filename, not a path!) 00234 */ 00235 inline String GetConfigName() const; 00236 00237 /** 00238 * @brief 00239 * Set name of config file 00240 * 00241 * @param[in] sConfigName 00242 * Config filename (only filename, not a path!) 00243 * 00244 * @remarks 00245 * Default is "<appname>.cfg" 00246 */ 00247 inline void SetConfigName(const String &sConfigName); 00248 00249 /** 00250 * @brief 00251 * Get name of log file 00252 * 00253 * @return 00254 * Log filename (only filename, not a path!) 00255 */ 00256 inline String GetLogName() const; 00257 00258 /** 00259 * @brief 00260 * Set name of log file 00261 * 00262 * @param[in] sLogName 00263 * Log filename (only filename, not a path!) 00264 * 00265 * @remarks 00266 * Default is "<appname>.log" 00267 */ 00268 inline void SetLogName(const String &sLogName); 00269 00270 /** 00271 * @brief 00272 * Get subdirectory for application data files 00273 * 00274 * @return 00275 * Subdirectory (relative path) 00276 */ 00277 inline String GetAppDataSubdir() const; 00278 00279 /** 00280 * @brief 00281 * Set subdirectory for application data files 00282 * 00283 * @param[in] sSubdir 00284 * Subdirectory (relative path) 00285 * 00286 * @remarks 00287 * Default is "PixelLight" (Windows) respectively ".pixellight" (Linux). 00288 * If you change this, you should use System::GetDataDirName(), to convert your name 00289 * into the typical style for the used OS. Example: 00290 * SetAppDataSubdir(System::GetInstance()->GetDataDirName("MyApplication")) 00291 */ 00292 inline void SetAppDataSubdir(const String &sSubdir); 00293 00294 /** 00295 * @brief 00296 * Returns the configuration instance 00297 * 00298 * @return 00299 * The configuration instance 00300 */ 00301 inline Config &GetConfig(); 00302 00303 /** 00304 * @brief 00305 * Returns whether or not the application is currently running 00306 * 00307 * @return 00308 * 'true' if the application is currently running, else 'false' 00309 */ 00310 inline bool IsRunning() const; 00311 00312 /** 00313 * @brief 00314 * Exit application 00315 * 00316 * @param[in] nResult 00317 * Return code for application (usually 0 means no error) 00318 * 00319 * @remarks 00320 * This will set the application return code and set m_bRunning to 'false', so that the application 00321 * should exit as soon as possible. To immediately terminate the execution, use System::Exit() 00322 */ 00323 inline void Exit(int nResult); 00324 00325 /** 00326 * @brief 00327 * Run the application 00328 * 00329 * @param[in] sExecutableFilename 00330 * Absolute application executable filename 00331 * @param[in] lstArguments 00332 * List of arguments to the program 00333 * 00334 * @remarks 00335 * The implementation does the following tasks: 00336 * - Connect Linux signals 00337 * - Fill application context 00338 * - Call OnStart() 00339 * - Call OnInit() 00340 * - Call Main() 00341 * - Call OnDeInit() 00342 * - Call OnStop() 00343 * 00344 * @return 00345 * Exit code (usually 0 means no error) 00346 */ 00347 PLCORE_API int Run(const String &sExecutableFilename, const Array<String> &lstArguments); 00348 00349 00350 //[-------------------------------------------------------] 00351 //[ Protected virtual AbstractLifecycle functions ] 00352 //[-------------------------------------------------------] 00353 protected: 00354 /** 00355 * @brief 00356 * Called directly after the object has been created 00357 * 00358 * @remarks 00359 * The default implementation does the following tasks: 00360 * - none (implement in derived classes) 00361 */ 00362 PLCORE_API virtual void OnCreate() override; 00363 00364 /** 00365 * @brief 00366 * Called directly before a stopped object is going to start again (always followed by "OnStart()") 00367 * 00368 * @remarks 00369 * The default implementation does the following tasks: 00370 * - none (implement in derived classes) 00371 */ 00372 PLCORE_API virtual void OnRestart() override; 00373 00374 /** 00375 * @brief 00376 * Initialization function that is called prior to OnInit() 00377 * 00378 * @return 00379 * 'true' if all went fine, else 'false' which will stop the application 00380 * 00381 * @remarks 00382 * The default implementation does the following tasks: 00383 * - Parse the command line (m_cCommandLine), set your options in the constructor 00384 * - Call OnInitLog() 00385 * - Call OnInitCmdLine() 00386 * - Call OnInitConfig() 00387 * - Call OnInitPlugins() 00388 * - Call OnInitData() 00389 * - Return and go on with OnInit() 00390 */ 00391 PLCORE_API virtual bool OnStart() override; 00392 00393 /** 00394 * @brief 00395 * Called when the object has the focus (keep the implementation lightweight) 00396 * 00397 * @remarks 00398 * The default implementation does the following tasks: 00399 * - none (implement in derived classes) 00400 */ 00401 PLCORE_API virtual void OnResume() override; 00402 00403 /** 00404 * @brief 00405 * Called when the object has no longer the focus (keep the implementation lightweight) 00406 * 00407 * @remarks 00408 * The default implementation does the following tasks: 00409 * - none (implement in derived classes) 00410 */ 00411 PLCORE_API virtual void OnPause() override; 00412 00413 /** 00414 * @brief 00415 * De-initialization function that is called after OnDeInit() 00416 * 00417 * @remarks 00418 * The default implementation does the following tasks: 00419 * - Save configuration 00420 * - Close log 00421 */ 00422 PLCORE_API virtual void OnStop() override; 00423 00424 /** 00425 * @brief 00426 * Called before the object is going to be finally destroyed 00427 * 00428 * @remarks 00429 * The default implementation does the following tasks: 00430 * - none (implement in derived classes) 00431 */ 00432 PLCORE_API virtual void OnDestroy() override; 00433 00434 00435 //[-------------------------------------------------------] 00436 //[ Protected virtual CoreApplication functions ] 00437 //[-------------------------------------------------------] 00438 protected: 00439 /** 00440 * @brief 00441 * Main function 00442 * 00443 * @remarks 00444 * The default implementation does the following tasks: 00445 * - none (implement in derived classes) 00446 */ 00447 PLCORE_API virtual void Main(); 00448 00449 /** 00450 * @brief 00451 * Called when application should initialize it's log 00452 * 00453 * @remarks 00454 * The default implementation does the following tasks: 00455 * - Open log file according to parameter '--logfile' (default: <appname>.log) 00456 * - Set verbose mode according to parameter '--verbose' 00457 * - Write some general information into the log 00458 * 00459 * @note 00460 * - Part of the application framework initialization function "OnStart()" 00461 */ 00462 PLCORE_API virtual void OnInitLog(); 00463 00464 /** 00465 * @brief 00466 * Called when application should check command line options 00467 * 00468 * @remarks 00469 * The default implementation does the following tasks: 00470 * - Check for command line errors or the parameters --help or --version 00471 * - On '--help' or on error, call OnPrintHelp() and exit 00472 * - On '--version', call OnPrintVersion() and exit 00473 * 00474 * @note 00475 * - Part of the application framework initialization function "OnStart()" 00476 * - To end the application here, use Application::Exit() 00477 */ 00478 PLCORE_API virtual void OnInitCmdLine(); 00479 00480 /** 00481 * @brief 00482 * Called when application should initialize it's configuration 00483 * 00484 * @remarks 00485 * The default implementation does the following tasks: 00486 * - Load configuration from file <appname>.cfg 00487 * - Save config file name to ApplicationContext 00488 * - If a config has been loaded or created: 00489 * - Read 'FirstRun' and call OnFirstRun() if set 00490 * 00491 * @note 00492 * - Part of the application framework initialization function "OnStart()" 00493 */ 00494 PLCORE_API virtual void OnInitConfig(); 00495 00496 /** 00497 * @brief 00498 * Called when application should load it's plugins 00499 * 00500 * @remarks 00501 * The default implementation does the following tasks: 00502 * - Scan for plugins in PixelLight runtime directory non-recursively 00503 * - Scan for plugins in application executable directory non-recursively 00504 * - If the application executable directory is not the same as the application startup directory, scan for plugins in application startup directory non-recursively 00505 * 00506 * @note 00507 * - Part of the application framework initialization function "OnStart()" 00508 */ 00509 PLCORE_API virtual void OnInitPlugins(); 00510 00511 /** 00512 * @brief 00513 * Called when application should set it's data paths 00514 * 00515 * @remarks 00516 * The default implementation does the following tasks: 00517 * - Set PixelLight runtime directory as base path in LoadableManager 00518 * - Scan for data packages in PixelLight runtime directory 00519 * - Set '.' as base path in LoadableManager 00520 * - Scan for packages in "Data/" directory 00521 * - Set application directory as base path in LoadableManager 00522 * - Scan for packages in application directory "Data/" directory 00523 * - Get current language and load PixelLight localization file, if no language is defined, English is used as default 00524 * 00525 * @note 00526 * - Part of the application framework initialization function "OnStart()" 00527 */ 00528 PLCORE_API virtual void OnInitData(); 00529 00530 /** 00531 * @brief 00532 * Called when application should initialize itself 00533 * 00534 * @remarks 00535 * The default implementation does the following tasks: 00536 * - Reset timing class 00537 * - Return and go on with Main() 00538 */ 00539 PLCORE_API virtual void OnInit(); 00540 00541 /** 00542 * @brief 00543 * Called when application should de-initialize itself 00544 * 00545 * @remarks 00546 * The default implementation does the following tasks: 00547 * - none (implement in derived classes) 00548 * - Return and go on with DeInit() 00549 */ 00550 PLCORE_API virtual void OnDeInit(); 00551 00552 /** 00553 * @brief 00554 * Function that is called when the program has been started for the first time 00555 * 00556 * @remarks 00557 * The default implementation does the following tasks: 00558 * - Write message into log 00559 */ 00560 PLCORE_API virtual void OnFirstProgramStart(); 00561 00562 /** 00563 * @brief 00564 * Function that is called to display a help message about the application 00565 * 00566 * @remarks 00567 * The default implementation prints the application title and it's command line 00568 * options onto the screen 00569 */ 00570 PLCORE_API virtual void OnPrintHelp(); 00571 00572 /** 00573 * @brief 00574 * Function that is called to display version information of the application 00575 * 00576 * @remarks 00577 * The default implementation prints the application title and version that is 00578 * stored in Application 00579 */ 00580 PLCORE_API virtual void OnPrintVersion(); 00581 00582 /** 00583 * @brief 00584 * Function that is called when a signal has arrive 00585 * 00586 * @param[in] nSignal 00587 * Signal 00588 * @return 00589 * 'true' to go on with the signal (e.g. terminate application), 'false' to cancel 00590 * 00591 * @remarks 00592 * This function is called when the operation system has sent a signal to the process. 00593 * Use this to make your application exit gracefully, e.g. set a flag that lets your main function exit 00594 * after finishing the current task and cleaning up the application. Otherwise, your process is likely to 00595 * be killed by the system. 00596 * 00597 * @remarks 00598 * The default implementation sets m_bRunning to 'false', be sure to react to this flag! 00599 */ 00600 PLCORE_API virtual bool OnSignal(ESignal nSignal); 00601 00602 00603 //[-------------------------------------------------------] 00604 //[ Private static functions ] 00605 //[-------------------------------------------------------] 00606 private: 00607 /** 00608 * @brief 00609 * Signal handler callback 00610 * 00611 * @param[in] nSignal 00612 * Signal 00613 */ 00614 static void SignalHandler(int nSignal); 00615 00616 00617 //[-------------------------------------------------------] 00618 //[ Protected data ] 00619 //[-------------------------------------------------------] 00620 protected: 00621 ApplicationContext m_cApplicationContext; /**< Application context */ 00622 String m_sName; /**< Name of application */ 00623 String m_sTitle; /**< Title of application */ 00624 Version m_cVersion; /**< Version of application */ 00625 bool m_bMultiUser; /**< Use multi-user environment? */ 00626 String m_sConfigName; /**< File name (not path) of config */ 00627 String m_sLogName; /**< File name (not path) of log */ 00628 String m_sAppDataSubdir; /**< Subdirectory for application data */ 00629 Config m_cConfig; /**< Configuration instance */ 00630 CommandLine m_cCommandLine; /**< Command line arguments */ 00631 bool m_bRunning; /**< Is the application currently running? */ 00632 int m_nResult; /**< Return code */ 00633 00634 00635 }; 00636 00637 00638 //[-------------------------------------------------------] 00639 //[ Namespace ] 00640 //[-------------------------------------------------------] 00641 } // PLCore 00642 00643 00644 //[-------------------------------------------------------] 00645 //[ Implementation ] 00646 //[-------------------------------------------------------] 00647 #include "PLCore/Application/CoreApplication.inl" 00648 00649 00650 #endif // __PLCORE_CONSOLE_APPLICATION_H__
|