llapp.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:10k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llapp.h
  3.  * @brief Declaration of the LLApp class.
  4.  *
  5.  * $LicenseInfo:firstyear=2003&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2003-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #ifndef LL_LLAPP_H
  33. #define LL_LLAPP_H
  34. #include <map>
  35. #include "llrun.h"
  36. #include "llsd.h"
  37. #include "lloptioninterface.h"
  38. // Forward declarations
  39. template <typename Type> class LLAtomic32;
  40. typedef LLAtomic32<U32> LLAtomicU32;
  41. class LLErrorThread;
  42. class LLLiveFile;
  43. #if LL_LINUX
  44. typedef struct siginfo siginfo_t;
  45. #endif
  46. typedef void (*LLAppErrorHandler)();
  47. typedef void (*LLAppChildCallback)(int pid, bool exited, int status);
  48. #if !LL_WINDOWS
  49. extern S32 LL_SMACKDOWN_SIGNAL;
  50. extern S32 LL_HEARTBEAT_SIGNAL;
  51. // Clear all of the signal handlers (which we want to do for the child process when we fork
  52. void clear_signals();
  53. class LLChildInfo
  54. {
  55. public:
  56. LLChildInfo() : mGotSigChild(FALSE), mCallback(NULL) {}
  57. BOOL mGotSigChild;
  58. LLAppChildCallback mCallback;
  59. };
  60. #endif
  61. class LL_COMMON_API LLApp : public LLOptionInterface
  62. {
  63. friend class LLErrorThread;
  64. public:
  65. typedef enum e_app_status
  66. {
  67. APP_STATUS_RUNNING, // The application is currently running - the default status
  68. APP_STATUS_QUITTING, // The application is currently quitting - threads should listen for this and clean up
  69. APP_STATUS_STOPPED, // The application is no longer running - tells the error thread it can exit
  70. APP_STATUS_ERROR // The application had a fatal error occur - tells the error thread to run
  71. } EAppStatus;
  72. LLApp();
  73. virtual ~LLApp();
  74. protected:
  75. LLApp(LLErrorThread* error_thread);
  76. void commonCtor();
  77. public:
  78. /** 
  79.  * @brief Return the static app instance if one was created.
  80.  */
  81. static LLApp* instance();
  82. /** @name Runtime options */
  83. //@{
  84. /** 
  85.  * @brief Enumeration to specify option priorities in highest to
  86.  * lowest order.
  87.  */
  88. enum OptionPriority
  89. {
  90. PRIORITY_RUNTIME_OVERRIDE,
  91. PRIORITY_COMMAND_LINE,
  92. PRIORITY_SPECIFIC_CONFIGURATION,
  93. PRIORITY_GENERAL_CONFIGURATION,
  94. PRIORITY_DEFAULT,
  95. PRIORITY_COUNT
  96. };
  97. /**
  98.  * @brief Get the application option at the highest priority.
  99.  *
  100.  * If the return value is undefined, the option does not exist.
  101.  * @param name The name of the option.
  102.  * @return Returns the option data.
  103.  */
  104. virtual LLSD getOption(const std::string& name) const;
  105. /** 
  106.  * @brief Parse command line options and insert them into
  107.  * application command line options.
  108.  *
  109.  * The name inserted into the option will have leading option
  110.  * identifiers (a minus or double minus) stripped. All options
  111.  * with values will be stored as a string, while all options
  112.  * without values will be stored as true.
  113.  * @param argc The argc passed into main().
  114.  * @param argv The argv passed into main().
  115.  * @return Returns true if the parse succeeded.
  116.  */
  117. bool parseCommandOptions(int argc, char** argv);
  118. /**
  119.  * @brief Keep track of live files automatically.
  120.  *
  121.  * *TODO: it currently uses the <code>addToEventTimer()</code> API
  122.  * instead of the runner. I should probalby use the runner.
  123.  *
  124.  * *NOTE: DO NOT add the livefile instance to any kind of check loop.
  125.  *
  126.  * @param livefile A valid instance of an LLLiveFile. This LLApp
  127.  * instance will delete the livefile instance.
  128.  */
  129. void manageLiveFile(LLLiveFile* livefile);
  130. /**
  131.  * @brief Set the options at the specified priority.
  132.  *
  133.  * This function completely replaces the options at the priority
  134.  * level with the data specified. This function will make sure
  135.  * level and data might be valid before doing the replace.
  136.  * @param level The priority level of the data.
  137.  * @param data The data to set.
  138.  * @return Returns true if the option was set.
  139.  */
  140. bool setOptionData(OptionPriority level, LLSD data);
  141. /**
  142.  * @brief Get the option data at the specified priority.
  143.  *
  144.  * This method is probably not so useful except when merging
  145.  * information.
  146.  * @param level The priority level of the data.
  147.  * @return Returns The data (if any) at the level priority.
  148.  */
  149. LLSD getOptionData(OptionPriority level);
  150. //@}
  151. //
  152. // Main application logic
  153. //
  154. virtual bool init() = 0; // Override to do application initialization
  155. //
  156. // cleanup()
  157. //
  158. // It's currently assumed that the cleanup() method will only get
  159. // called from the main thread or the error handling thread, as it will
  160. // likely do thread shutdown, among other things.
  161. //
  162. virtual bool cleanup() = 0; // Override to do application cleanup
  163. //
  164. // mainLoop()
  165. //
  166. // Runs the application main loop.  It's assumed that when you exit
  167. // this method, the application is in one of the cleanup states, either QUITTING or ERROR
  168. //
  169. virtual bool mainLoop() = 0; // Override for the application main loop.  Needs to at least gracefully notice the QUITTING state and exit.
  170. //
  171. // Application status
  172. //
  173. static void setQuitting(); // Set status to QUITTING, the app is now shutting down
  174. static void setStopped(); // Set status to STOPPED, the app is done running and should exit
  175. static void setError(); // Set status to ERROR, the error handler should run
  176. static bool isStopped();
  177. static bool isRunning();
  178. static bool isQuitting();
  179. static bool isError();
  180. static bool isExiting(); // Either quitting or error (app is exiting, cleanly or not)
  181. #if !LL_WINDOWS
  182. static U32  getSigChildCount();
  183. static void incSigChildCount();
  184. #endif
  185. static int getPid();
  186. /** @name Error handling methods */
  187. //@{
  188. /**
  189.  * @brief Do our generic platform-specific error-handling setup --
  190.  * signals on unix, structured exceptions on windows.
  191.  * 
  192.  * DO call this method if your app will either spawn children or be
  193.  * spawned by a launcher.
  194.  * Call just after app object construction.
  195.  * (Otherwise your app will crash when getting signals,
  196.  * and will not core dump.)
  197.  *
  198.  * DO NOT call this method if your application has specialized
  199.  * error handling code.
  200.  */
  201. void setupErrorHandling();
  202. void setErrorHandler(LLAppErrorHandler handler);
  203. void setSyncErrorHandler(LLAppErrorHandler handler);
  204. //@}
  205. #if !LL_WINDOWS
  206. //
  207. // Child process handling (Unix only for now)
  208. //
  209. // Set a callback to be run on exit of a child process
  210. // WARNING!  This callback is run from the signal handler due to the extreme crappiness of
  211. // Linux threading requiring waitpid() to be called from the thread that spawned the process.
  212. // At some point I will make this more behaved, but I'm not going to fix this right now - djs
  213. void setChildCallback(pid_t pid, LLAppChildCallback callback);
  214.     // The child callback to run if no specific handler is set
  215. void setDefaultChildCallback(LLAppChildCallback callback); 
  216.     // Fork and do the proper signal handling/error handling mojo
  217. // *NOTE: You need to make sure your signal handling callback is
  218. // correct after you fork, because not all threads are duplicated
  219. // when you fork!
  220. pid_t fork(); 
  221. #endif
  222. /**
  223.   * @brief Get a reference to the application runner
  224.   *
  225.   * Please use the runner with caution. Since the Runner usage
  226.   * pattern is not yet clear, this method just gives access to it
  227.   * to add and remove runnables.
  228.   * @return Returns the application runner. Do not save the
  229.   * pointer past the caller's stack frame.
  230.   */
  231. LLRunner& getRunner() { return mRunner; }
  232. public:
  233. typedef std::map<std::string, std::string> string_map;
  234. string_map mOptionMap; // Contains all command-line options and arguments in a map
  235. protected:
  236. static void setStatus(EAppStatus status); // Use this to change the application status.
  237. static EAppStatus sStatus; // Reflects current application status
  238. static BOOL sErrorThreadRunning; // Set while the error thread is running
  239. #if !LL_WINDOWS
  240. static LLAtomicU32* sSigChildCount; // Number of SIGCHLDs received.
  241. typedef std::map<pid_t, LLChildInfo> child_map; // Map key is a PID
  242. static child_map sChildMap;
  243. static LLAppChildCallback sDefaultChildCallback;
  244. #endif
  245. /**
  246.   * @brief This method is called once a frame to do once a frame tasks.
  247.   */
  248. void stepFrame();
  249. private:
  250. void startErrorThread();
  251. static void runErrorHandler(); // run shortly after we detect an error, ran in the relatively robust context of the LLErrorThread - preferred.
  252. static void runSyncErrorHandler(); // run IMMEDIATELY when we get an error, ran in the context of the faulting thread.
  253. // *NOTE: On Windows, we need a routine to reset the structured
  254. // exception handler when some evil driver has taken it over for
  255. // their own purposes
  256. typedef int(*signal_handler_func)(int signum);
  257. static LLAppErrorHandler sErrorHandler;
  258. static LLAppErrorHandler sSyncErrorHandler;
  259. // Default application threads
  260. LLErrorThread* mThreadErrorp; // Waits for app to go to status ERROR, then runs the error callback
  261. // This is the application level runnable scheduler.
  262. LLRunner mRunner;
  263. /** @name Runtime option implementation */
  264. //@{
  265. // The application options.
  266. LLSD mOptions;
  267. // The live files for this application
  268. std::vector<LLLiveFile*> mLiveFiles;
  269. //@}
  270. private:
  271. // the static application instance if it was created.
  272. static LLApp* sApplication;
  273. #if !LL_WINDOWS
  274. friend void default_unix_signal_handler(int signum, siginfo_t *info, void *);
  275. #endif
  276. public:
  277. static BOOL sLogInSignal;
  278. };
  279. #endif // LL_LLAPP_H