ALib C++ Framework
by
Library Version: 2511 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
app.inl
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of module \alib_app of the \aliblong.
4///
5/// \emoji :copyright: 2013-2025 A-Worx GmbH, Germany.
6/// Published under #"mainpage_license".
7//==================================================================================================
8ALIB_EXPORT namespace alib { namespace app {
9
10//==================================================================================================
11/// This is a central class of library module \alib_app_nl.
12///
13/// For information about general use and features of this class consult the
14/// #"alib::app;ALib App User Manual".
15//==================================================================================================
16class App {
17 public:
18 //================================================================================================
19 // App Inner Types
20 //================================================================================================
21
22 //=========================================== Exceptions =========================================
23 /// Generic Exceptions handled by class #"App".
24 /// This enumeration contains only one single entry.
25 enum class Exceptions {
26 /// This exception is used to support the exception/error/exit code paradigm introduced
27 /// by class #"App".
28 /// @see A detailed description on the usage of this exception is given in chapter
29 /// #"alib_app_controlledearlyexit" of the Programmer's Manual of the
30 /// module \alib_app.
32 };
33
34
35 //=========================================== ExitCodes ==========================================
36 /// Built-in exit-codes of the \alib application.
37 /// The underlying integer values may be used by a descendant application as the result
38 /// of C/C++ method \c main().<br>
39 /// They are provided here rather as a sample and to be able to provide a default
40 /// implementation of the method #"exceptionToExitCode". In the case that an application
41 /// desires to use different exit codes, the latter method has to be overridden.
42 ///
43 /// When using the derived class #"AppCli", this enumeration gets the according
44 /// #"alib_enums_records;ALib Enum Records" assigned and default resources are defined.
46 {
47 OK = 0, ///< Success.
48 ErrConfigFileNotFound = 10, ///< The default configuration file(s), or that (those)
49 ///< specified by option '--config', could not be found
50 ///< or read.
51 ErrConfigFileNotWritable= 11, ///< The configuration file(s) could not be written.
52 ErrUnknown = 127, ///< An unknown exception occurred.
53 };
54
55
56 protected:
57 //============================================= Flags ============================================
58 /// Configuration flags used with class #"App".
59 enum class Flags {
60 /// No flags set.
61 NONE = 0 ,
62
63 /// If set, method #"App::onBsSetupALox;*" will create a release #"Lox"
64 /// instance available via field #"App::GetRLox;*", as well as an attached logger
65 /// available via field #"App::GetRLogger;*".
67
68 /// If set, method #"App::onBsSetupALox;*" will create and attach the release
69 /// logger to the debug \b Lox #"Lox".
71
72 /// If set, method #"App::onSdExportConfig;*" adds 'ExportAll' and 'writeback' to the
73 /// verbosity variable of the #"App::releaseLogger;*" in the case that this variable
74 /// had not been read from the INI file with #"App::onBsImportConfig;*".
76
77 /// If set, method #"App::onSdExportConfig;*" adds 'ExportAll' and 'writeback' to
78 /// the verbosity variable of the debug-logger in the case that this variable had not been
79 /// read from the INI file with #"App::onBsImportConfig;*".
81 };
82
83
84 //============================================= States ===========================================
85 /// The predefined states of the simple linear state-machine implemented by outer class #"App".
86 /// For each state, a corresponding virtual function exists.
87 /// The pairs of states and the corresponding virtual functions are collected in the field
88 /// #"StateMachine::Program;2".<br>
89 /// Custom applications (derived from class \b %App) define their own enum type in case they
90 /// want to insert additional pairs of state/methods into the program.
91 /// This is possible because the collection of states in the field
92 /// #"StateMachine::Program;2" is implemented as type #"boxing::Enum", which may
93 /// hold enumeration elements of an arbitrary type.
94 ///
95 /// Note that the numbering of the enum elements is \b not of importance. The numbers
96 /// found here were chosen to be quickly identifiable while debugging.
97 /// The simple scheme is:
98 /// - 1x: Bootstrap phase resources. (See also #"BootstrapPhases").
99 /// - 2x: Bootstrap phase configuration/variables.
100 /// - 3x: Bootstrap phase finalization.
101 /// - 1xx: running phase.
102 /// - 9xx: shutdown phase. (See also #"ShutdownPhases").
103 ///
104 /// Also, the numbers are \b not defining the order of execution, which is solely defined by
105 /// the order in the vector #"StateMachine::Program;2".<br>
106 ///
107 /// The custom enumeration type used for potential custom states may but does not need to
108 /// align. It even may have the same integral values as given here. This flexibility is
109 /// gained by the little magic of class #"boxing::Enum" introduced by module \alib_boxing.
110 enum class States {
111 /// Initial state before starting the App.
112 NOT_STARTED = 0, ///< The starting state not associated with a method.
113
114 //---------------------------------- initialize resources --------------------------------
115 SetCamps = 11 , ///< Invokes the virtual method #"onBsSetCamps".
116 PrepareResources = 12 , ///< Invokes the virtual method #"onBsPrepareResources".
117 SetNameVersionAndInfo= 13 , ///< Invokes the virtual method #onBsSetNameVersionAndInfo.
118 // 3
119 //------------------------ Initialize camps on configuration level -----------------------
120 PrepareConfig = 21, ///< Invokes the virtual method #onBsPrepareConfig.
121 PreloadVariables = 22, ///< Invokes the virtual method #onBsPreloadVariables.
122 ImportConfig = 23, ///< Invokes the virtual method #onBsImportConfig.
123 // 6
124
125 //--------------------------- After alib::BootstrapPhases::Final -------------------------
126 FinalizeBootstrap = 31, ///< Invokes the virtual method #onBsFinalizeBootstrap.
127 SetupALox = 33, ///< Invokes the virtual method #onBsSetupALox.
128 // 9
129
130 //------------------------------------ The custom code -----------------------------------
131 RunStart =100, ///< Invokes the virtual method #onRunStart.
132 Run =111, ///< Invokes the virtual method #onRun.
133 RunEnd =120, ///< Invokes the virtual method #onRunEnd.
134 // 12
135
136 //---------------------------------------- Shutdown --------------------------------------
137 AnnounceShutdown =910, ///< Invokes the virtual method #onSdAnnounceShutdown.
138 CleanALox =920, ///< Invokes the virtual method #onSdCleanALox.
139 ExportConfig =930, ///< Invokes the virtual method #onSdExportConfig.
140 Output =940, ///< Invokes the virtual method #onSdOutput.
141 FinalizeShutdown =950, ///< Invokes the virtual method #onSdFinalizeShutdown.
142 // 16
143
144 CNTD_BUILTIN_STATES = 16 ///< The number of built-in states.
145 ///< Only used for reserving the 'program's' capacity.
146 };
147
148 //========================================== StateMachine ========================================
149 /// This struct is used a single time with the member #machine and comprises all
150 /// fields associated with the state of the application and the execution of the 'program'.
152
153 //=================================== StateMachine::Command ==================================
154 /// A struct denoting the next state and the corresponding method to execute.
155 struct Command {
156 /// A union holding either a pointer to a virtual method of class \b App or one to
157 /// a non-virtual method of a different type.
159 /// A pointer to a virtual method of class \b %App.
160 void (App::*BuiltIn)();
161
162 /// A pointer to a method of a custom derived type.
163 void (*Custom )(App&);
164
165 /// Constructor accepting a pointer to a virtual method of class \b %App.
166 /// @param method The method to call.
167 MethodPointer( void (App::*method)() ) : BuiltIn(method) {}
168
169 /// Constructor accepting a pointer to a non-virtual method of a derived type.
170 /// @param method The non-virtual method of a derived type.
171 MethodPointer( void ( *method)(App&) ) : Custom (method) {}
172 };
173
174 /// The identifier of the command which is likewise the state of the machine.
175 /// During execution, this identifier will be stored in the member
176 /// #"StateMachine::State" of the outer class \b %StateMachine.
177 /// In case it is a built-in identifier of type #"App::States", it will
178 /// be stored in addition in its field
179 /// #"App::StateMachine::BuiltInState".
181
182 /// A pointer union to either a built-in virtual method or a method of the custom
183 /// derived type.
185
186
187 /// A static helper-function that creates a custom command, i.e. a command that is
188 /// not built-in and as such is not executing one of the pre-defined virtual methods
189 /// of class #"App".
190 /// Instead, it is executing a non-virtual member of the given type \p{TDerived}, which
191 /// is usually the descendant singleton-type, that is implementing the custom
192 /// application.
193 /// \note For technical reasons, the invocation of this static function is a little
194 /// counter-intuitive. The two template parameters have to be explicitly provided,
195 /// where the second is the address of the custom method! (This is C++ 20 magic).
196 /// The only normal parameter then is the custom enumeration element.
197 /// @tparam TDerived The enclosing type of the method. This usually is the
198 /// custom implementation type of class \b %App.
199 /// @tparam TMethodAddress The address of the member which is to be called with this
200 /// command.
201 /// @param state The enum element (of a custom type) to identify the command
202 /// and define the state of the machine during execution.
203 /// @return The command object.
204 template<typename TDerived, auto TMethodAddress >
205 static Command MakeCustom(Enum state) {
206
207 struct Helper {
208 static void Wrapper(App& base) {
209 auto& self = static_cast<TDerived&>(base);
210 (self.*TMethodAddress)();
211 }
212 };
213
214 return Command { state, &Helper::Wrapper };
215 }
216 };
217
218 //================================= StateMachine::CommandList ================================
219 /// A list of pairs of states and corresponding methods to process.
220 /// This struct is used only once, namely with the field #"StateMachine::Program;2".
221 /// The constructor of class \b App fills this list with all commands defined in the
222 /// enumeration #"App::States;*".
223 /// While the insertion methods #"CommandList::AddBefore" and #"CommandList::AddAfter"
224 /// are provided for convenience, more complex manipulation of the list is allowed using
225 /// the interface inherited from <c>std::vector</c>.
226 struct CommandList : std::vector<Command> {
227
228 /// Adds a custom execution command (and state) before the given \p{cmd}.
229 /// @see The helper-method #"App::StateMachine::Command::MakeCustom;*"
230 /// should be used to create the command that is to be provided as parameter
231 /// \p{cmd}.
232 /// @param anchor The associated state to search in this vector and use as the
233 /// insertion place.<br>
234 /// If \c nullptr is passed, \p{cmd} will be inserted at the end of the
235 /// list.
236 /// @param cmd The command to be added.
237 void AddBefore( Enum anchor, const Command& cmd ) {
238 auto it= end();
239 if ( anchor.IsNotNull() )
240 for ( it= begin() ; it!= end() && it->State != anchor ; ++it)
241 ;
242
243 ALIB_ASSERT_ERROR(anchor.IsNull() || it!=end(), "APP","Command anchor not found")
244
245 insert(it, cmd );
246 }
247 /// Adds a custom execution command (and state) after the given \p{cmd}.
248 /// @see The helper-method #"App::StateMachine::Command::MakeCustom;*"
249 /// should be used to create the command that is to be provided as parameter
250 /// \p{cmd}.
251 /// @param anchor The associated state to search in this vector and use as the
252 /// insertion place.<br>
253 /// If \c nullptr is passed, \p{cmd} will be inserted at the beginning of
254 /// the list.
255 /// @param cmd The command to be added.
256 void AddAfter( Enum anchor, const Command& cmd ) {
257 auto it= begin();
258 if ( anchor.IsNotNull() )
259 for ( ; it!= end() && it->State != anchor ; ++it)
260 ;
261
262 ALIB_ASSERT_ERROR(anchor.IsNull() || it!=end(), "APP","Command anchor not found")
263
264 insert(it== end() ? begin() : it + 1, cmd );
265 }
266 };
267
268 //==================================== StateMachine Fields ===================================
269 protected:
270 /// The exit code. Only the first set is stored and returned later.
272
273 #if ALIB_DEBUG
274 /// This vector collects exit codes which are not used, as they got set
275 /// after a first code was given. This field is available in debug-compilations only.
276 std::vector<Enum> dbgFurtherExitCodes;
277 #endif
278
279 //=================================== StateMachine Interface =================================
280 public:
281 /// The list of commands to execute.
283
284 /// The current state in respect to the built-in program commands. Note that this is
285 /// not of type #"boxing::Enum", but uses the original C++ enum type.
286 /// Consequently, this is only updated when a built-in command is processed.
287 /// With that, methods may check for a more general state without getting "confused"
288 /// by custom insertions which often are not relevant for the decision-making.
290
291 /// The current state. Either a built-in state enumeration or a custom one.
292 /// @see Field #BuiltInState, which is more appropriate to use in most cases.
294
295 /// Emergency stopper. As soon as this gets set, the execution of the application
296 /// will stop. The only thing that is still performed is the standard
297 /// #"alib::Shutdown;ALib shutdown procedure", but not the shutdown procedure defined
298 /// by this app (or its derived type). I.e., no configuration files are written.
299 bool EmergencyStop =false;
300
301 /// Sets this applications' cli-exit code (the result of the method \c main()).
302 /// If the given \p{pExitCode}'s integral value is \c 0, nothing is done.
303 ///
304 /// Only the value of the first call is used. Later calls will not overwrite the first
305 /// given value. In debug-builds, the method #DbgDumpFurtherExitCodes may be used
306 /// to display later given codes, what the default implementation of the method
307 /// #"App::onSdFinalizeShutdown;*" does.
308 /// @param pExitCode The exit code to set.
309 ///
310 void SetExitCode(Enum pExitCode) {
311 if ( pExitCode.Integral() == 0)
312 return;
313
314 if ( exitCode.IsNull() || exitCode.Integral() == 0 )
315 exitCode= pExitCode;
316 #if ALIB_DEBUG
317 else
318 dbgFurtherExitCodes.push_back(pExitCode);
319 #endif
320 }
321
322 /// Returns this applications' cli-exit code (the result of the method \c main()).
323 /// @return The first value given with #SetExitCode.
325
326 /// Writes exit codes not respected by the method #SetExitCode (because an earlier code
327 /// was already set) to the \p{target} string. Then clears the debug-field
328 /// #dbgFurtherExitCodes.
329 /// This method is called by the default implementations of the methods
330 /// #exceptionDisplay and #onSdOutput<br>.
331 /// In release-builds, this method is pruned.
332 /// @param target The target string.
334 #if ALIB_DEBUG
335 for ( auto& ec : dbgFurtherExitCodes )
336 target << "Unused (later) exit-code: " << ec << NEW_LINE;
337 dbgFurtherExitCodes.clear();
338 #else
339 (void) target;
340 #endif
341 }
342 };
343
344 //====================================== ConfigFileDescriptor ====================================
345 /// A record collecting information about configuration files. A vector of this type is
346 /// created by the method #"App::getConfigFilePaths;*".
348 /// The resolved full path to the file.
350
351 /// A comma-separated list of variables (and especially variable tree paths) to be
352 /// explicitly exported to this configuration file.
354
355 /// The files' main comment to set, in case it does not exist, yet.
357
358 /// If set, the file name (and maybe path) came from option '--CONFIG'.
359 bool FromCfgOption =false;
360
361 /// If set, the file did not exist or was empty at the start of the application.
362 bool WasEmpty =false;
363 };
364
365
366 //================================================================================================
367 // App Fields
368 //================================================================================================
369
370 /// The state-machine singleton.
372
373 /// A stop-watch usable for measuring performance of different steps of an application.
374 /// Time is taken in the constructor.
376
377 /// The main camp of the application. This is where resources are loaded from.
378 /// @see Notes are given in the #"App::App;constructor".
380
381 /// The name of the application.
382 /// If not set from the descendant, it is tried to be loaded from resource <c>"AppName"</c>
383 /// by the default implementation of #onBsSetNameVersionAndInfo.
384 String appName =nullptr;
385
386 /// A version string of the application.
387 /// If not set from the descendant, it is tried to be loaded from resource <c>"AppVersion"</c>
388 /// by the default implementation of #onBsSetNameVersionAndInfo.
390
391 /// Some short information and probably copyright message of the application.
392 /// If not set from the descendant, it is tried to be loaded from resource <c>"AppInfo"</c>
393 /// by the default implementation of #onBsSetNameVersionAndInfo.
394 String appInfo =nullptr;
395
396 /// Used to assemble and collect the output for standard output character stream \c std::cout
397 /// during the run of this application.<br>
398 /// The collected output is scheduled to be written by the method #onSdOutput. This method,
399 /// may also be "manually" invoked at any time to flush the current buffers to the output
400 /// streams.
401 Paragraphs* cOut =nullptr;
402
403 /// Same as #cOut, but used for stream \c std::err.
404 Paragraphs* cErr =nullptr;
405
406
407 //============================================== ALox ============================================
408 /// This will be the name of the release \b Lox.
409 /// The name defaults to <c>"RLOX"</c> and may be changed prior to the call to the method
410 /// #onBsSetupALox.<br>
412
413 /// This will be the name of the release logger attached to the release \b Lox.
414 /// The name defaults to <c>"RLOGGER"</c> and may be changed prior to the call to the method
415 /// #onBsSetupALox.<br>
417
418 /// The release \b Lox used by the application.
419 /// @see Method onBsSetupALox.
421
422 /// The release logger used by the application.
423 /// @see Method onBsSetupALox.
425
426 /// Various boolean flags used to configure the application.
428
429 //================================================================================================
430 // Constructors/destructor
431 //================================================================================================
432 /// Constructor.
433 /// Initializes this app. Mainly by filling the vector #".StateMachine::Program;2" with all
434 /// states found in the enumeration #States along with the corresponding virtual methods.<br>
435 ///
436 /// While the parameter \p{appCamp} is optional, it is intentionally not provided with a default
437 /// value of \c nullptr. Derived types should create and provide a custom camp here
438 /// (See the #"alib_mod_camp;Programmer's Manual" of the module \alibcamp_nl).
439 /// If it is missing, many default implementations of the virtual methods render useless, and
440 /// return instantly.<br>
441 /// If not given, it will be set in the default implementation of the method #onBsSetCamps
442 /// to the last camp in the list #"CAMPS". If given that default implementation will
443 /// add it to the end of this list.
444 ///
445 /// @param appCamp An optional camp instance to search resources in.
448
449
450 /// Virtual destructor.
452 virtual ~App();
453
454 //================================================================================================
455 // Public Interface
456 //================================================================================================
457 public:
458 /// Stores cli-parameters and executes this app.
459 /// @param argc The number of command-line arguments.
460 /// @param argv List of command-line arguments, given as single byte character strings.
461 /// @param argvw The CLI arguments on platforms that use wide command-line strings.
462 /// Defaults to \c nullptr. If given, parameter \p{argv} has to be nulled.
463 /// @return The exit code to be returned by C/C++ \c main().
465 virtual int Main( int argc, const char** argv, const wchar_t** argvw= nullptr );
466
467 /// Has to return the \b Lox instance used with release-logging.
468 /// @return This implementation returns field #releaseLox.
469 virtual lox::Lox* GetRLox() { return releaseLox; }
470
471 /// Has to return the \b Logger instance used with release-logging.
472 /// @return This implementation returns field #releaseLogger.
474
475 /// Returns the name of this application.
476 /// This default implementation returns the field #appName.
477 /// This is not necessarily equal to the process module name which can be received with
478 /// <c>ProcessInfo::Current().ExecFileName</c>.
479 /// @return This application's name.
480 String GetName() { return appName; }
481
482 /// Returns the version of this application.
483 /// This default implementation returns the field #appVersion.
484 /// @return A string containing version information of this application.
486
487 /// Returns the version of this application.
488 /// This default implementation returns the field #appVersion.
489 /// @return A usually multi-line string containing information about this application.
490 String GetInfo() { return appInfo; }
491
492 //================================================================================================
493 // Helper Hooks usable by the Program Methods
494 //================================================================================================
495 /// Todo: This implementation does not do the same as CLIUtil::GetExitCode.
496 /// Das muss noch eingebaut werden, oder? Oder wir bauen es lieber nicht ein und
497 /// ändern den Text hier. Schließlich kann das die AppCLi machen.
498 /// TODO(251208 17:30):
499 /// Also insgesamt ist das noch ne größere Baustelle/Design Problem!!!
500 /// Zusammen mit der nächsten method exceptionDisplay
501 /// Es ist wirklich schwierig. Wo ist es am besten Exit codes zu erzeugen und den cErr Text
502 /// dazu? Exceptions zu werfen ist schon blöd. Dann muss man sich die ganzen Infos wieder
503 /// rausziehen. Andererseits hat man es dann wirklich an einer stelle.
504 /// Aber an dieser Stelle fehlen dann manche dinge. Zb. File not open. Tja, ok nicht nur
505 /// welches file? Manchmal gibt es auch von file-typen mehrere. Zb. beim DoxygenXLinks
506 /// mehrere tag-files. Es wäre dann schon schön zu wissen woher die Info über das Tag-file
507 /// käme. Also bewegt man sich na oben im callstack zur stelle wo es auftritt, und wirft erst
508 /// gar keine Exception.
509 /// Tja, dann muss man den ganzen Stack alleine abbauen (also überall den exit code
510 /// durchreichen und ihn abfragen. Das geht nicht. Dazhu sind ja exceptions da.
511 /// Vielleicht sollte man eine einzige Exception zulassen, nämlich eine built-in "Handled Exception"
512 /// Bevor die geworfen wird, wird eine ordentlich Ausgabe ins CErr geworfen und der ExitCode
513 /// wird als parameter in die exception mit reingegeben. Ja, das ist ein guter Ansatz.
514 /// Die App muss dann cOut und cErr public freigeben. Dass kann aber auch die abgeleitete
515 /// MyApp machen.
516 /// Aber so ginge es: überall wo ein ExitCode auftritt wird dieser in einer Exception
517 /// gekapselt und diese exception wird geworfen.
518 /// Und diese zwei Funktionen hier können ja dennoch da bleiben. Vielleicht etwas hübscher
519 /// ...hab schon mal angefangen damit und die exception eingebaut.
520 ///
521 /// Translates exceptions to exit-codes of the application.
522 /// This default implementation performs similarly to #"CLIUtil::GetExitCode;*" to convert
523 /// command-line exceptions to exit-codes.
524 /// Thus, if all exceptions have an exit-code conversion defined, there is no need to override
525 /// this method.<br>
526 /// Implementations should call this method first and, if necessary, perform their own
527 /// conversions then. If they do so, they should check whether this default
528 /// version returned <c>BuiltInExitCodes::ErrUnknown</c>, perform their own translation
529 /// in that case and probably debug-assert on failure.
530 /// @param exception The exception that was thrown.
531 /// @return On success, the exit-code resulting from the given \p{exception}.
532 /// Otherwise a \e nulled \b Enum.
533 virtual Enum exceptionToExitCode( alib::Exception& exception );
534
535 /// Writes exception information to \c std::cerr<br>.
536 /// @param exception The exception that was thrown.
537 /// @param target The target string to write into. An option is to pass <c>cErr->Buffer</c>
538 /// here. Of course a custom buffer might be passed, i.e. if the text is to be
539 /// logged with \alox.
540 virtual void exceptionDisplay( Exception& exception, AString& target );
541
542 /// Writes configuration file information into the given \p{target}.
543 /// @param target The target to write into. The common option is to pass #"cOut" here.
544 virtual void printConfigFileInfo( Paragraphs& target );
545
546 /// This default implementation in turn calls the virtual helper methods
547 /// #getConfigFilePathsFromResources and #getConfigFilePathsMakeAbsolutePaths.
548 /// @param files A pointer to an object of type <c>StdVectorMA<ConfigFileDescriptor></c> that
549 /// is to be filled by this method.
552
553 /// If the given vector \p{files} is empty, this method tries resources named
554 /// <c>"CFGF_NAME_1"</c>, <c>"CFGF_NAME_2"</c>, <c>"CFGF_NAME_3"</c> and so forth until
555 /// a first name is not found. For all names found, an entry in vector \p{files} is
556 /// created.
557 ///
558 /// Then, for each entry in the vector (regardless if they were preexisting or created with
559 /// this method), comment information is loaded from resources. The resource name is composed
560 /// from <c>"CFGF_CMT_"</c> and the number of the entry. If found, the resource is assigned
561 /// to the field #"App::ConfigFileDescriptor::Comment;*".
562 ///
563 /// Then for each entry resources named <c>"CFGF_EXP_"</c> and the number of the entry
564 /// are searched. If found, the field #"App::ConfigFileDescriptor::Exports;*" is set.
565 /// If more resources (with higher numbers) are existing, such additional exports are
566 /// appended to the list of the last config file entry.
567 /// @param files The vector of file paths that is to be filled or modified by this method.
570
571 /// Checks all filenames in the given vector and converts them to an absolute path.
572 /// @param files The vector of file paths that is to be modified by this method.
575
576
577 //================================================================================================
578 // Virtual Methods called by the State-Machine Program - Bootstrap
579 //================================================================================================
580 /// Called on transition to state #"App::States::SetCamps".<br>
581 /// This default implementation calls the #"alib::BootstrapAddDefaultCamps" and then
582 /// adds camp #appCamp to the end of that list. In case field #appCamp is \e nulled, rather
583 /// the opposite is done: the field is set to point to the end of the list.
585 virtual void onBsSetCamps();
586
587 /// Called on transition to state #"App::States::PrepareResources".<br>
588 /// This default implementation
589 /// - calls the #"alib::Bootstrap(BootstrapPhases)" passing
590 /// #"BootstrapPhases::PrepareResources;2" as its parameter.
591 /// - creates instances for fields #cOut and #cErr inside the global allocator.
592 /// - if configuration macro #"ALIB_DEBUG_RESOURCES" is set, then the field
593 /// #"LocalResourcePool::DbgResourceLoadObserver;*" is set to <c>std::cout</c>.
595 virtual void onBsPrepareResources();
596
597 /// Called on transition to state #"App::States::SetNameVersionAndInfo".<br>
598 /// This default implementation tries resources <c>"AppName"</c>, <c>"AppVersion"</c>, and
599 /// <c>"AppInfo"</c> to set fields #appName, #appVersion, and #appInfo.
600 /// The latter is supported with three placeholders: the name, the version, and the current
601 /// year and is created using the method #"Paragraphs::AddMarked(const BoxedObjects& ...);*".
602 ///
603 /// A string that is set before this method is called, is not replaced.
605 virtual void onBsSetNameVersionAndInfo();
606
607
608 /// Called on transition to state #"App::States::PrepareConfig".<br>
609 /// This default implementation just calls the function #"alib::Bootstrap(BootstrapPhases)"
610 /// passing #"BootstrapPhases::PrepareConfig;2" as the parameter.
612 virtual void onBsPrepareConfig();
613
614 /// Called on transition to state #"App::States::PreloadVariables".<br>
615 /// Preloading variables allows later fetching and exporting those variables into a
616 /// configuration file (if freshly created), even if they have not been read/used in the
617 /// first run of an application.<br>
618 /// This default implementation calls #"Configuration::PreloadVariables;*"
619 /// on the variables found with the enumeration #"lox::Variables".
621 virtual void onBsPreloadVariables();
622
623 /// Called on transition to state #"App::States::ImportConfig".<br>
624 /// This default implementation creates the vector of file descriptors using
625 /// #getConfigFilePaths and then uses type #"IniFileFeeder" to import the
626 /// variables from the INI-files.
628 virtual void onBsImportConfig();
629
630 /// Called on transition to state #"App::States::FinalizeBootstrap".<br>
631 /// This default implementation just calls the function #"alib::Bootstrap(BootstrapPhases)"
632 /// passing #"BootstrapPhases::Final;2" as the parameter.
634 virtual void onBsFinalizeBootstrap();
635
636 /// Called on transition to state #"App::States::SetupALox".<br>
637 /// If this method returns an error, bootstrapping is aborted.
638 /// This default implementation interprets the flags
639 /// #"App::Flags::CreateReleaseLox" and
640 /// #"App::Flags::UseReleaseLoggerForDebugLogging", and furthermore
641 /// uses the fields #releaseLoxName and #releaseLoggerName
642 /// into account and potentially creates #releaseLox and #releaseLogger.
644 virtual void onBsSetupALox();
645
646 //================================================================================================
647 // Virtual Methods called by the State-Machine Program - Run
648 //================================================================================================
649 /// This method is preceding the main execution method #onRun. When this is called, all
650 /// bootstrapping is done. Final preparations might be performed here to unclutter #onRun.<br>
652 virtual void onRunStart() {}
653
654 /// This is the main execution method of the application.
655 /// The default-implementation is not just empty, but is (the only) abstract method of this
656 /// class.
657 virtual void onRun() =0;
658
659 /// This method is following the main execution method #onRun.
660 /// Overwriting this method is useful to collect code which has to be executed at the end
661 /// of all (or most) execution paths of the custom implementation of #onRun.
663 virtual void onRunEnd() {}
664
665 //================================================================================================
666 // Virtual Methods called by the State-Machine Program - Shutdown
667 //================================================================================================
668 /// Called on transition to state #"App::States::AnnounceShutdown".<br>
669 /// This default implementation just calls the function #"alib::Shutdown" passing
670 /// #"ShutdownPhases::Announce;2" as the parameter.
672 virtual void onSdAnnounceShutdown();
673
674 /// Called on transition to state #"App::States::CleanALox".<br>
675 /// This default implementation checks the flags
676 /// #"App::Flags::ALoxVerbosityExportAllAndWriteBackRelLogger", and
677 /// #"App::Flags::ALoxVerbosityExportAllAndWriteBackDbgLogger" and calls
678 /// #"Logger::SetVerbosityExport;*" if set.<br>
679 /// Then, if set, the release logger and \b Lox are deleted.
681 virtual void onSdCleanALox();
682
683 /// Called on transition to state #"App::States::ExportConfig".<br>
684 /// This default implementation creates the vector of file descriptors using
685 /// #getConfigFilePaths and then uses type #"IniFileFeeder" to export
686 /// variables that are either not existing yet, or which have a writeback flag set,
687 /// into the INI-files.<br>
688 /// This is done for all variables (and variable trees) determined by the field
689 /// #"App::ConfigFileDescriptor::Exports;*".
691 virtual void onSdExportConfig();
692
693 /// Flushes what is collected in the fields #cOut and #cErr to their respective streams and
694 /// clears the buffers.
695 /// With that, this method - while named with the prefix <em>onSd</em> and scheduled at
696 /// the end of the #"StateMachine::Program;2" - may be directly called by
697 /// descendants whenever they wish to flush the current collected output stream, for example,
698 /// after important milestones, before long-running operations, or prior to program termination
699 /// when early partial output is desired.
701 virtual void onSdOutput();
702
703 /// Called on transition to state #"App::States::FinalizeShutdown".<br>
704 /// This default implementation calls the function #"alib::Shutdown" passing
705 /// #"ShutdownPhases::Destruct;2" as the parameter.<br>
706 /// Prior to that, some memory cleaning and debug exercises are done.
708 virtual void onSdFinalizeShutdown();
709
710
711}; // class App
712
713/// The application singleton-instance. This defaults to \c nullptr and is set by the
714/// constructor of class #"App".
715ALIB_DLL extern App* APP_SINGLETON;
716
717/// Convenience function that returns the singleton instance of an \alib application.
718/// @tparam TApp The app type to cast to.
719/// @return The dereferenced pointer to #"APP_SINGLETON".
720template<typename TApp= app::App>
721inline TApp& Get() { return *dynamic_cast<TApp*>(app::APP_SINGLETON); }
722
723} // namespace alib[::app]
724
725
726
727} // namespace [alib]
728
730
731#if !DOXYGEN
732# undef LOX_LOX
733# define LOX_LOX (*::alib::app::APP_SINGLETON->GetRLox())
734#endif
#define ALIB_DLL
Definition alib.inl:573
#define A_CHAR(STR)
Definition alib.inl:1325
#define ALIB_EXPORT
Definition alib.inl:562
#define ALIB_ASSERT_ERROR(cond, domain,...)
Definition alib.inl:1144
virtual void onRunEnd()
Definition app.inl:663
virtual void onBsImportConfig()
Definition app.cpp:337
virtual void onBsPreloadVariables()
Definition app.cpp:335
virtual void onBsSetNameVersionAndInfo()
Definition app.cpp:316
camp::Camp * appCamp
Definition app.inl:379
@ NOT_STARTED
Initial state before starting the App.
Definition app.inl:112
@ CleanALox
Invokes the virtual method onSdCleanALox.
Definition app.inl:138
@ ExportConfig
Invokes the virtual method onSdExportConfig.
Definition app.inl:139
@ SetCamps
Invokes the virtual method #"onBsSetCamps".
Definition app.inl:115
@ FinalizeBootstrap
Invokes the virtual method onBsFinalizeBootstrap.
Definition app.inl:126
@ Output
Invokes the virtual method onSdOutput.
Definition app.inl:140
@ RunStart
Invokes the virtual method onRunStart.
Definition app.inl:131
@ FinalizeShutdown
Invokes the virtual method onSdFinalizeShutdown.
Definition app.inl:141
@ SetupALox
Invokes the virtual method onBsSetupALox.
Definition app.inl:127
@ AnnounceShutdown
Invokes the virtual method onSdAnnounceShutdown.
Definition app.inl:137
@ PrepareResources
Invokes the virtual method #"onBsPrepareResources".
Definition app.inl:116
@ PrepareConfig
Invokes the virtual method onBsPrepareConfig.
Definition app.inl:120
@ PreloadVariables
Invokes the virtual method onBsPreloadVariables.
Definition app.inl:121
@ Run
Invokes the virtual method onRun.
Definition app.inl:132
@ SetNameVersionAndInfo
Invokes the virtual method onBsSetNameVersionAndInfo.
Definition app.inl:117
@ ImportConfig
Invokes the virtual method onBsImportConfig.
Definition app.inl:122
@ RunEnd
Invokes the virtual method onRunEnd.
Definition app.inl:133
virtual void onSdFinalizeShutdown()
Definition app.cpp:483
String GetName()
Definition app.inl:480
String appName
Definition app.inl:384
String appVersion
Definition app.inl:389
virtual void onBsSetCamps()
Definition app.cpp:290
virtual lox::textlogger::TextLogger * GetRLogger()
Definition app.inl:473
String releaseLoggerName
Definition app.inl:416
StateMachine machine
The state-machine singleton.
Definition app.inl:371
virtual int Main(int argc, const char **argv, const wchar_t **argvw=nullptr)
Definition app.cpp:75
Paragraphs * cOut
Definition app.inl:401
String appInfo
Definition app.inl:394
String releaseLoxName
Definition app.inl:411
virtual void onSdOutput()
Definition app.cpp:465
virtual void getConfigFilePathsFromResources(StdVectorMA< ConfigFileDescriptor > &files)
Definition app.cpp:210
virtual void onBsPrepareConfig()
Definition app.cpp:333
virtual ~App()
Virtual destructor.
Definition app.cpp:73
virtual Enum exceptionToExitCode(alib::Exception &exception)
Definition app.cpp:141
Flags
Configuration flags used with class #"App".
Definition app.inl:59
@ UseReleaseLoggerForDebugLogging
Definition app.inl:70
@ ALoxVerbosityExportAllAndWriteBackDbgLogger
Definition app.inl:80
@ NONE
No flags set.
Definition app.inl:61
@ ALoxVerbosityExportAllAndWriteBackRelLogger
Definition app.inl:75
virtual void onSdCleanALox()
Definition app.cpp:393
virtual void onRunStart()
Definition app.inl:652
String GetInfo()
Definition app.inl:490
virtual void onBsPrepareResources()
Definition app.cpp:300
virtual void printConfigFileInfo(Paragraphs &target)
Definition app.cpp:189
lox::Lox * releaseLox
Definition app.inl:420
virtual void exceptionDisplay(Exception &exception, AString &target)
Definition app.cpp:159
App(camp::Camp *appCamp)
Definition app.cpp:43
virtual void onBsSetupALox()
Definition app.cpp:364
Flags flags
Various boolean flags used to configure the application.
Definition app.inl:427
virtual lox::Lox * GetRLox()
Definition app.inl:469
virtual void onSdAnnounceShutdown()
Definition app.cpp:390
virtual void getConfigFilePaths(StdVectorMA< ConfigFileDescriptor > &files)
Definition app.cpp:282
virtual void getConfigFilePathsMakeAbsolutePaths(StdVectorMA< ConfigFileDescriptor > &files)
Definition app.cpp:270
String GetVersion()
Definition app.inl:485
lox::textlogger::TextLogger * releaseLogger
Definition app.inl:424
StopWatch stopWatch
Definition app.inl:375
@ ErrUnknown
An unknown exception occurred.
Definition app.inl:52
@ ErrConfigFileNotWritable
The configuration file(s) could not be written.
Definition app.inl:51
virtual void onRun()=0
virtual void onBsFinalizeBootstrap()
Definition app.cpp:361
Paragraphs * cErr
Same as cOut, but used for stream std::err.
Definition app.inl:404
virtual void onSdExportConfig()
Definition app.cpp:416
This class acts as a container for Loggers and provides a convenient interface to logging.
Definition lox.inl:14
#define ALIB_ENUMS_MAKE_BITWISE(TEnum)
TApp & Get()
Definition app.inl:721
App * APP_SINGLETON
Definition app.cpp:40
constexpr CString NEW_LINE
A zero-terminated string containing the new-line character sequence.
Definition cstring.inl:540
time::StopWatch StopWatch
Type alias in namespace alib.
strings::TString< character > String
Type alias in namespace alib.
Definition string.inl:2172
system::Path Path
Type alias in namespace alib.
Definition path.inl:375
exceptions::Exception Exception
Type alias in namespace alib.
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace alib.
format::Paragraphs Paragraphs
Type alias in namespace alib.
std::vector< T, StdMA< T > > StdVectorMA
Type alias in namespace alib.
boxing::Enum Enum
Type alias in namespace alib.
Definition enum.inl:211
Path Pathname
The resolved full path to the file.
Definition app.inl:349
bool WasEmpty
If set, the file did not exist or was empty at the start of the application.
Definition app.inl:362
String Comment
The files' main comment to set, in case it does not exist, yet.
Definition app.inl:356
bool FromCfgOption
If set, the file name (and maybe path) came from option '–CONFIG'.
Definition app.inl:359
void AddBefore(Enum anchor, const Command &cmd)
Definition app.inl:237
void AddAfter(Enum anchor, const Command &cmd)
Definition app.inl:256
A struct denoting the next state and the corresponding method to execute.
Definition app.inl:155
static Command MakeCustom(Enum state)
Definition app.inl:205
void SetExitCode(Enum pExitCode)
Definition app.inl:310
CommandList Program
The list of commands to execute.
Definition app.inl:282
Enum exitCode
The exit code. Only the first set is stored and returned later.
Definition app.inl:271
void DbgDumpFurtherExitCodes(AString &target)
Definition app.inl:333
std::vector< Enum > dbgFurtherExitCodes
Definition app.inl:276
bool IsNull() const
Definition enum.inl:150
TIntegral Integral() const
Definition enum.inl:88
bool IsNotNull() const
Definition enum.inl:155
void(* Custom)(App &)
A pointer to a method of a custom derived type.
Definition app.inl:163
void(App::* BuiltIn)()
A pointer to a virtual method of class App.
Definition app.inl:160