doc: update documentation
- use namespace bracket all content in documentation to reduce useless namespace prefix. - change the argument type of AbstractSetting and CoreManager to yycc_u8string_view instead of const yycc_char8_t*. - throw exception if given setting name is invalid in ConfigManager, instead of slient fallback.
This commit is contained in:
parent
598aae69ae
commit
1cfbcb3b18
|
@ -1,3 +1,4 @@
|
||||||
|
namespace YYCC::COMHelper {
|
||||||
/**
|
/**
|
||||||
|
|
||||||
\page com_helper COM Helper
|
\page com_helper COM Helper
|
||||||
|
@ -23,11 +24,12 @@ This namespace contain a COM Guard which make sure COM was initialized in curren
|
||||||
It is essential because all calling to COM functions should be under the premise that COM has been initialized.
|
It is essential because all calling to COM functions should be under the premise that COM has been initialized.
|
||||||
This guard also will uninitialize COM when unloading this module.
|
This guard also will uninitialize COM when unloading this module.
|
||||||
|
|
||||||
There is only an exposed function called YYCC::COMHelper::IsInitialized for user calling.
|
There is only an exposed function called #IsInitialized for user calling.
|
||||||
This function will check whether COM environment is initialized.
|
This function will check whether COM environment is initialized.
|
||||||
If you want YYCC automatically initialize COM environment for you,
|
If you want YYCC automatically initialize COM environment for you,
|
||||||
you must call this function in your program at least one time.
|
you must call this function in your program at least one time.
|
||||||
Otherwise COM Guard code may be unavailable,
|
Otherwise COM Guard code may be unavailable,
|
||||||
because compiler may think they are not essential code and drop them.
|
because compiler may think they are not essential code and drop them.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
namespace YYCC::ConsoleHelper {
|
||||||
/**
|
/**
|
||||||
|
|
||||||
\page console_helper Console Helper
|
\page console_helper Console Helper
|
||||||
|
@ -22,9 +23,9 @@ That's ASCII Escape Code.
|
||||||
|
|
||||||
As we introduced in above,
|
As we introduced in above,
|
||||||
you may know Windows console does not support ASCII Escape Code color in default.
|
you may know Windows console does not support ASCII Escape Code color in default.
|
||||||
However YYCC::ConsoleHelper::EnableColorfulConsole can fix this issue.
|
However #EnableColorfulConsole can fix this issue.
|
||||||
|
|
||||||
YYCC::ConsoleHelper::EnableColorfulConsole will forcely enable ASCII Escape Code support in Windows console if possible.
|
#EnableColorfulConsole will forcely enable ASCII Escape Code support in Windows console if possible.
|
||||||
Thus you can write colorful text in Windows console freely.
|
Thus you can write colorful text in Windows console freely.
|
||||||
We suggest you to call this function at the beginning of program.
|
We suggest you to call this function at the beginning of program.
|
||||||
|
|
||||||
|
@ -46,7 +47,7 @@ And for second line, it will make <TT>"Light Red"</TT> to be shown in light red
|
||||||
but <TT>"I am "</TT> will keep default console font color.
|
but <TT>"I am "</TT> will keep default console font color.
|
||||||
|
|
||||||
You also may notice this macro is used with YYCC_U8 macro.
|
You also may notice this macro is used with YYCC_U8 macro.
|
||||||
Because YYCC::ConsoleHelper::WriteLine only accept UTF8 argument.
|
Because #WriteLine only accept UTF8 argument.
|
||||||
So please note if you use console color macro with YYCC_U8,
|
So please note if you use console color macro with YYCC_U8,
|
||||||
please make YYCC_U8 always is located the outside.
|
please make YYCC_U8 always is located the outside.
|
||||||
Otherwise, YYCC_U8 will fail to make the whole become UTF8 stirng as we introduced in \ref library_encoding.
|
Otherwise, YYCC_U8 will fail to make the whole become UTF8 stirng as we introduced in \ref library_encoding.
|
||||||
|
@ -176,4 +177,5 @@ only write plain string like \c std::fputs().
|
||||||
This is commonly used, otherwise functions will only write the text provided by arguments,
|
This is commonly used, otherwise functions will only write the text provided by arguments,
|
||||||
without adding something.
|
without adding something.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
namespace YYCC::DialogHelper {
|
||||||
/**
|
/**
|
||||||
|
|
||||||
\page dialog_helper Dialog Helper
|
\page dialog_helper Dialog Helper
|
||||||
|
@ -12,7 +13,7 @@ It will be totally invisible if you are in other platforms.
|
||||||
|
|
||||||
\section dialog_helper__file_dialog Configure File Dialog
|
\section dialog_helper__file_dialog Configure File Dialog
|
||||||
|
|
||||||
The first thing is that we should initialize YYCC::DialogHelper::FileDialog,
|
The first thing is that we should initialize FileDialog,
|
||||||
and configure it according to your requirements.
|
and configure it according to your requirements.
|
||||||
|
|
||||||
This class is the data struct representing all aspects of file dialog.
|
This class is the data struct representing all aspects of file dialog.
|
||||||
|
@ -28,7 +29,7 @@ params.SetInitDirectory(initial_directory_getter());
|
||||||
|
|
||||||
\subsection dialog_helper__file_dialog__owner Owner
|
\subsection dialog_helper__file_dialog__owner Owner
|
||||||
|
|
||||||
YYCC::DialogHelper::FileDialog::SetOwner will set owner of this dialog.
|
FileDialog::SetOwner will set owner of this dialog.
|
||||||
It accepts a Microsoft defined \c HWND as argument which should be familiar with Windows programmer.
|
It accepts a Microsoft defined \c HWND as argument which should be familiar with Windows programmer.
|
||||||
If you pass \c NULL to it or skip calling this function, it indicate that there is no owner of this dialog.
|
If you pass \c NULL to it or skip calling this function, it indicate that there is no owner of this dialog.
|
||||||
<I>
|
<I>
|
||||||
|
@ -38,7 +39,7 @@ But it would be better to have an owner if possible.
|
||||||
|
|
||||||
\subsection dialog_helper__file_dialog__title Title
|
\subsection dialog_helper__file_dialog__title Title
|
||||||
|
|
||||||
YYCC::DialogHelper::FileDialog::SetTitle will set dialog title of this dialog.
|
FileDialog::SetTitle will set dialog title of this dialog.
|
||||||
If you pass \c nullptr or skip calling it,
|
If you pass \c nullptr or skip calling it,
|
||||||
the title of dialog will be filled by system and the function type you calling.
|
the title of dialog will be filled by system and the function type you calling.
|
||||||
For example, the title will be "Open..." if you call open file function,
|
For example, the title will be "Open..." if you call open file function,
|
||||||
|
@ -49,7 +50,7 @@ So I suggest you do not set title except you really want to modify title.
|
||||||
|
|
||||||
\subsection dialog_helper__file_dialog__init_file_name Initial File Name
|
\subsection dialog_helper__file_dialog__init_file_name Initial File Name
|
||||||
|
|
||||||
YYCC::DialogHelper::FileDialog::SetInitFileName will set the initial file name presented in dialog file name input box.
|
FileDialog::SetInitFileName will set the initial file name presented in dialog file name input box.
|
||||||
If you pass \c nullptr or skip calling it, the text in dialog file name input box will be empty.
|
If you pass \c nullptr or skip calling it, the text in dialog file name input box will be empty.
|
||||||
|
|
||||||
User can modify the name presented in input box later.
|
User can modify the name presented in input box later.
|
||||||
|
@ -59,7 +60,7 @@ However, if you specify this field, the dialog will always presented your specif
|
||||||
|
|
||||||
\subsection dialog_helper__file_dialog__init_directory Initial Directory
|
\subsection dialog_helper__file_dialog__init_directory Initial Directory
|
||||||
|
|
||||||
YYCC::DialogHelper::FileDialog::SetInitDirectory will set the initial directory (startup directory) when opening dialog.
|
FileDialog::SetInitDirectory will set the initial directory (startup directory) when opening dialog.
|
||||||
|
|
||||||
In following cases, initial directory will fall back to system behavior:
|
In following cases, initial directory will fall back to system behavior:
|
||||||
|
|
||||||
|
@ -80,7 +81,7 @@ It is beneficial to let user get the file which they want in a directory includi
|
||||||
Because the file dialog picking directory does not have file filter drop down box.
|
Because the file dialog picking directory does not have file filter drop down box.
|
||||||
Directory can not be filtered.
|
Directory can not be filtered.
|
||||||
|
|
||||||
YYCC::DialogHelper::FileFilters takes responsibility for this feature:
|
FileFilters takes responsibility for this feature:
|
||||||
|
|
||||||
\code
|
\code
|
||||||
auto& filters = params.ConfigreFileTypes();
|
auto& filters = params.ConfigreFileTypes();
|
||||||
|
@ -94,9 +95,9 @@ params.SetDefaultFileTypeIndex(0u);
|
||||||
|
|
||||||
\subsection dialog_helper__file_filters__setup File Filters
|
\subsection dialog_helper__file_filters__setup File Filters
|
||||||
|
|
||||||
We don't need to initialize YYCC::DialogHelper::FileFilters by ourselves.
|
We don't need to initialize FileFilters by ourselves.
|
||||||
Oppositely, we fetch it from YYCC::DialogHelper::FileDialog instance by calling YYCC::DialogHelper::FileDialog::ConfigreFileTypes.
|
Oppositely, we fetch it from FileDialog instance by calling FileDialog::ConfigreFileTypes.
|
||||||
After fetching, we can call YYCC::DialogHelper::FileFilters::Add to add a filter pair for file filters.
|
After fetching, we can call FileFilters::Add to add a filter pair for file filters.
|
||||||
|
|
||||||
The first argument is the display text which user will see in file filter drop down box.
|
The first argument is the display text which user will see in file filter drop down box.
|
||||||
|
|
||||||
|
@ -106,21 +107,21 @@ It is okey to use multiple wildcard string in list.
|
||||||
This is suit for those file types involving multiple file extensions, such as the old and new file types of Microsoft Office as we illustracted.
|
This is suit for those file types involving multiple file extensions, such as the old and new file types of Microsoft Office as we illustracted.
|
||||||
Empty list not allowed
|
Empty list not allowed
|
||||||
|
|
||||||
YYCC::DialogHelper::FileFilters::Add also will return a bool to indicate the success of this adding.
|
FileFilters::Add also will return a bool to indicate the success of this adding.
|
||||||
|
|
||||||
It should at least has one file filter in file dialog.
|
It should at least has one file filter in file dialog.
|
||||||
I don't know the consequence if you don't provide any file filter.
|
I don't know the consequence if you don't provide any file filter.
|
||||||
|
|
||||||
\subsection dialog_helper__file_filters__default_filter Default File Type
|
\subsection dialog_helper__file_filters__default_filter Default File Type
|
||||||
|
|
||||||
YYCC::DialogHelper::FileDialog::SetDefaultFileTypeIndex will set the default selected file filter of this dialog.
|
FileDialog::SetDefaultFileTypeIndex will set the default selected file filter of this dialog.
|
||||||
It accepts an index pointing to the file filter which you want to show in default for this file dialog.
|
It accepts an index pointing to the file filter which you want to show in default for this file dialog.
|
||||||
The index of file filters is the order where you call YYCC::DialogHelper::FileFilters::Add above.
|
The index of file filters is the order where you call FileFilters::Add above.
|
||||||
If you pass \c NULL to it or skip calling this function, the first one will be default.
|
If you pass \c NULL to it or skip calling this function, the first one will be default.
|
||||||
|
|
||||||
\section dialog_helper__result Create Dialog and Get Result
|
\section dialog_helper__result Create Dialog and Get Result
|
||||||
|
|
||||||
Finally, we can call file dialog functions by we initialized YYCC::DialogHelper::FileDialog
|
Finally, we can call file dialog functions by we initialized FileDialog
|
||||||
|
|
||||||
\code
|
\code
|
||||||
YYCC::yycc_u8string single_selection;
|
YYCC::yycc_u8string single_selection;
|
||||||
|
@ -134,14 +135,14 @@ YYCC::DialogHelper::OpenFolderDialog(params, single_selection);
|
||||||
|
|
||||||
There are 4 file dialogs you can choose:
|
There are 4 file dialogs you can choose:
|
||||||
|
|
||||||
\li YYCC::DialogHelper::OpenFileDialog: Open single file
|
\li #OpenFileDialog: Open single file
|
||||||
\li YYCC::DialogHelper::OpenMultipleFileDialog: Open multiple files
|
\li #OpenMultipleFileDialog: Open multiple files
|
||||||
\li YYCC::DialogHelper::SaveFileDialog: Save single file
|
\li #SaveFileDialog: Save single file
|
||||||
\li YYCC::DialogHelper::OpenFolderDialog: Open single directory
|
\li #OpenFolderDialog: Open single directory
|
||||||
|
|
||||||
\subsection dialog_helper__result__arguments Arguments
|
\subsection dialog_helper__result__arguments Arguments
|
||||||
|
|
||||||
Among these 4 functions, the first argument always is the reference to YYCC::DialogHelper::FileDialog.
|
Among these 4 functions, the first argument always is the reference to FileDialog.
|
||||||
Function will use it to decide what should be shown in this file dialog.
|
Function will use it to decide what should be shown in this file dialog.
|
||||||
|
|
||||||
The second argument always is the reference to the container receiving the result.
|
The second argument always is the reference to the container receiving the result.
|
||||||
|
@ -160,8 +161,9 @@ You may notice there are various classes which we never introduce.
|
||||||
Because they are intermediate classes and should not be used by programmer.
|
Because they are intermediate classes and should not be used by programmer.
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
\li YYCC::DialogHelper::WinFileDialog: The converted YYCC::DialogHelper::FileDialog passed to Windows.
|
\li WinFileDialog: The converted FileDialog passed to Windows.
|
||||||
\li YYCC::DialogHelper::WinFileFilters: Same as YYCC::DialogHelper::WinFileDialog. It will be passed to Windows functions.
|
\li WinFileFilters: Same as WinFileDialog. It will be passed to Windows functions.
|
||||||
\li etc...
|
\li etc...
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
namespace YYCC::EncodingHelper {
|
||||||
/**
|
/**
|
||||||
|
|
||||||
\page encoding_helper Encoding Helper
|
\page encoding_helper Encoding Helper
|
||||||
|
@ -15,10 +16,10 @@ See \ref library_encoding for more infomation.
|
||||||
|
|
||||||
YYCC supports following convertions:
|
YYCC supports following convertions:
|
||||||
|
|
||||||
\li YYCC::EncodingHelper::ToUTF8: Convert ordinary string to UTF8 string.
|
\li #ToUTF8: Convert ordinary string to UTF8 string.
|
||||||
\li YYCC::EncodingHelper::ToUTF8View: Same as ToUTF8, but return string view instead.
|
\li #ToUTF8View: Same as ToUTF8, but return string view instead.
|
||||||
\li YYCC::EncodingHelper::ToOrdinary: Convert UTF8 string to ordinary string.
|
\li #ToOrdinary: Convert UTF8 string to ordinary string.
|
||||||
\li YYCC::EncodingHelper::ToOrdinaryView: Same as ToOrdinary, but return string view instead.
|
\li #ToOrdinaryView: Same as ToOrdinary, but return string view instead.
|
||||||
|
|
||||||
\section encoding_helper__win_conv Windows Specific Convertion
|
\section encoding_helper__win_conv Windows Specific Convertion
|
||||||
|
|
||||||
|
@ -32,13 +33,13 @@ Please use them carefully (make sure that you are using them only in Windows env
|
||||||
|
|
||||||
YYCC supports following convertions:
|
YYCC supports following convertions:
|
||||||
|
|
||||||
\li YYCC::EncodingHelper::WcharToChar: Convert \c wchar_t string to code page specified string.
|
\li #WcharToChar: Convert \c wchar_t string to code page specified string.
|
||||||
\li YYCC::EncodingHelper::CharToWchar: The reversed convertion of WcharToChar.
|
\li #CharToWchar: The reversed convertion of WcharToChar.
|
||||||
\li YYCC::EncodingHelper::CharToChar: Convert string between 2 different code pages. It's a shortcut of calling CharToWchar and WcharToChar successively.
|
\li #CharToChar: Convert string between 2 different code pages. It's a shortcut of calling CharToWchar and WcharToChar successively.
|
||||||
\li YYCC::EncodingHelper::WcharToUTF8: Convert \c wchar_t string to UTF8 string.
|
\li #WcharToUTF8: Convert \c wchar_t string to UTF8 string.
|
||||||
\li YYCC::EncodingHelper::UTF8ToWchar: The reversed convertion of WcharToUTF8.
|
\li #UTF8ToWchar: The reversed convertion of WcharToUTF8.
|
||||||
\li YYCC::EncodingHelper::CharToUTF8: Convert code page specified string to UTF8 string.
|
\li #CharToUTF8: Convert code page specified string to UTF8 string.
|
||||||
\li YYCC::EncodingHelper::UTF8ToChar: The reversed convertion of CharToUTF8.
|
\li #UTF8ToChar: The reversed convertion of CharToUTF8.
|
||||||
|
|
||||||
Code Page is a Windows concept.
|
Code Page is a Windows concept.
|
||||||
If you don't understand it, please view corresponding Microsoft documentation.
|
If you don't understand it, please view corresponding Microsoft documentation.
|
||||||
|
@ -55,15 +56,15 @@ They can be used in any platform, not confined in Windows platforms.
|
||||||
|
|
||||||
YYCC supports following convertions:
|
YYCC supports following convertions:
|
||||||
|
|
||||||
\li YYCC::EncodingHelper::UTF8ToUTF16: Convert UTF8 string to UTF16 string.
|
\li #UTF8ToUTF16: Convert UTF8 string to UTF16 string.
|
||||||
\li YYCC::EncodingHelper::UTF16ToUTF8: The reversed convertion of UTF8ToUTF16.
|
\li #UTF16ToUTF8: The reversed convertion of UTF8ToUTF16.
|
||||||
\li YYCC::EncodingHelper::UTF8ToUTF32: Convert UTF8 string to UTF32 string.
|
\li #UTF8ToUTF32: Convert UTF8 string to UTF32 string.
|
||||||
\li YYCC::EncodingHelper::UTF32ToUTF8: The reversed convertion of UTF8ToUTF32.
|
\li #UTF32ToUTF8: The reversed convertion of UTF8ToUTF32.
|
||||||
|
|
||||||
\section encoding_helper__overloads Function Overloads
|
\section encoding_helper__overloads Function Overloads
|
||||||
|
|
||||||
Every encoding convertion functions (except the convertion between UTF8 and ordinary string) have 4 different overloads for different scenarios.
|
Every encoding convertion functions (except the convertion between UTF8 and ordinary string) have 4 different overloads for different scenarios.
|
||||||
Take YYCC::EncodingHelper::WcharToChar for example.
|
Take #WcharToChar for example.
|
||||||
There are following 4 overloads:
|
There are following 4 overloads:
|
||||||
|
|
||||||
\code
|
\code
|
||||||
|
@ -98,7 +99,7 @@ For the first type, please note that there is \b NO guarantee that the argument
|
||||||
Even the convertion is failed, the argument holding return value may still be changed by function itself.
|
Even the convertion is failed, the argument holding return value may still be changed by function itself.
|
||||||
|
|
||||||
In this case, the type of result is \c std::string because this is function required.
|
In this case, the type of result is \c std::string because this is function required.
|
||||||
In other functions, such as YYCC::EncodingHelper::WcharToUTF8, the type of result can be \c yycc_u8string or etc.
|
In other functions, such as #WcharToUTF8, the type of result can be \c yycc_u8string or etc.
|
||||||
So please note the type of result is decided by convertion function itself, not only \c std::string.
|
So please note the type of result is decided by convertion function itself, not only \c std::string.
|
||||||
|
|
||||||
\subsection encoding_helper__overloads__source Source String
|
\subsection encoding_helper__overloads__source Source String
|
||||||
|
@ -120,12 +121,12 @@ If you want to process string with \b embedded NUL terminal, please choose first
|
||||||
Otherwise the second type overload is enough.
|
Otherwise the second type overload is enough.
|
||||||
|
|
||||||
Same as destination string, the type of source is also decided by the convertion function itself.
|
Same as destination string, the type of source is also decided by the convertion function itself.
|
||||||
For exmaple, the type of source in YYCC::EncodingHelper::UTF8ToWchar is \c yycc_u8string_view and \c yycc_char8_t,
|
For exmaple, the type of source in #UTF8ToWchar is \c yycc_u8string_view and \c yycc_char8_t,
|
||||||
not \c std::wstring and \c wchar_t.
|
not \c std::wstring and \c wchar_t.
|
||||||
|
|
||||||
\subsection encoding_helper__overloads__extra Extra Argument
|
\subsection encoding_helper__overloads__extra Extra Argument
|
||||||
|
|
||||||
There is an extra argument called \c code_page for YYCC::EncodingHelper::WcharToChar.
|
There is an extra argument called \c code_page for #WcharToChar.
|
||||||
It indicates the code page of destination string,
|
It indicates the code page of destination string,
|
||||||
because this function will convert \c wchar_t string to the string with specified code page encoding.
|
because this function will convert \c wchar_t string to the string with specified code page encoding.
|
||||||
|
|
||||||
|
@ -143,4 +144,5 @@ we have 4 different overload as we illustrated before.
|
||||||
Programmer can use them freely according to your requirements.
|
Programmer can use them freely according to your requirements.
|
||||||
And don't forget to provide extra argument if function required.
|
And don't forget to provide extra argument if function required.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
namespace YYCC::ExceptionHelper {
|
||||||
/**
|
/**
|
||||||
|
|
||||||
\page exception_helper Unhandled Exception Handler
|
\page exception_helper Unhandled Exception Handler
|
||||||
|
@ -18,13 +19,13 @@ It will be invisible on other platforms.
|
||||||
|
|
||||||
\subsection exception_helper__usage__code Register Code
|
\subsection exception_helper__usage__code Register Code
|
||||||
|
|
||||||
In most scenarios, programmer only need call YYCC::ExceptionHelper::Register when program started or module loaded.
|
In most scenarios, programmer only need call #Register when program started or module loaded.
|
||||||
And call YYCC::ExceptionHelper::Unregister when program exited or module unloaded.
|
And call #Unregister when program exited or module unloaded.
|
||||||
All details are hidden by these 2 feature.
|
All details are hidden by these 2 feature.
|
||||||
Programmer do not need worried about the implementation of unhandled exception handler.
|
Programmer do not need worried about the implementation of unhandled exception handler.
|
||||||
|
|
||||||
Optionally, you can provide a function pointer during calling YYCC::ExceptionHelper::Register as a callback.
|
Optionally, you can provide a function pointer during calling #Register as a callback.
|
||||||
The prototype of this function pointer is YYCC::ExceptionHelper::ExceptionCallback.
|
The prototype of this function pointer is #ExceptionCallback.
|
||||||
This callback will be called if any unhandled exception happened.
|
This callback will be called if any unhandled exception happened.
|
||||||
It provides 2 pathes to log file and core dump file respectively.
|
It provides 2 pathes to log file and core dump file respectively.
|
||||||
So that you can use an explicit way, e.g. \c MessageBox, to tell user exception happened and where are the log files,
|
So that you can use an explicit way, e.g. \c MessageBox, to tell user exception happened and where are the log files,
|
||||||
|
@ -77,16 +78,16 @@ YYCC::ExceptionHelper also have a mechanism that make sure the same unhandled ex
|
||||||
For example, you have an executable program A.exe, and 2 dynamic libraries B.dll and C.dll.
|
For example, you have an executable program A.exe, and 2 dynamic libraries B.dll and C.dll.
|
||||||
A.exe and B.dll use YYCC unhandled exception handler feature but C.dll not.
|
A.exe and B.dll use YYCC unhandled exception handler feature but C.dll not.
|
||||||
A.exe will load B.dll and C.dll at runtime.
|
A.exe will load B.dll and C.dll at runtime.
|
||||||
Although both A.exe and B.dll call YYCC::ExceptionHelper::Register(),
|
Although both A.exe and B.dll call #Register,
|
||||||
when unhandled exception occurs, there is only one error report output,
|
when unhandled exception occurs, there is only one error report output,
|
||||||
which may be generated by A.exe or B.dll accoridng to their order of loading.
|
which may be generated by A.exe or B.dll accoridng to their order of loading.
|
||||||
|
|
||||||
The core purpose of this is making sure the program will not output too many error report for the same unhandled exception,
|
The core purpose of this is making sure the program will not output too many error report for the same unhandled exception,
|
||||||
no matter how many modules calling YYCC::ExceptionHelper::Register() are loaded.
|
no matter how many modules calling #Register are loaded.
|
||||||
Only one error report is enough.
|
Only one error report is enough.
|
||||||
|
|
||||||
More precisely, we use \c CreateMutexW to create an unique mutex in Windows global scope,
|
More precisely, we use \c CreateMutexW to create an unique mutex in Windows global scope,
|
||||||
to make sure YYCC::ExceptionHelper::Register() only run once in the same process.
|
to make sure #Register only run once in the same process.
|
||||||
It is very like the implementation of singleton application.
|
It is very like the implementation of singleton application.
|
||||||
|
|
||||||
\subsection exception_helper__notes__recursive_calling Recursive Calling
|
\subsection exception_helper__notes__recursive_calling Recursive Calling
|
||||||
|
@ -106,3 +107,4 @@ We want all essential log files has been written before calling it,
|
||||||
so that at least we can visit them on disk or console.
|
so that at least we can visit them on disk or console.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
namespace YYCC::FsPathPatch {
|
||||||
/**
|
/**
|
||||||
|
|
||||||
\page fs_path_patch std::filesystem::path Patch
|
\page fs_path_patch std::filesystem::path Patch
|
||||||
|
@ -24,7 +25,7 @@ and in other platforms, they just redirect request to corresponding vanilla C++
|
||||||
|
|
||||||
\section fs_path_patch__from_utf8_path Create Path from UTF8 String
|
\section fs_path_patch__from_utf8_path Create Path from UTF8 String
|
||||||
|
|
||||||
YYCC::FsPathPatch::FromUTF8Path provides this feature.
|
#FromUTF8Path provides this feature.
|
||||||
It accepts an string pointer to UTF8 string and try to create \c std::filesystem::path from it.
|
It accepts an string pointer to UTF8 string and try to create \c std::filesystem::path from it.
|
||||||
Function will throw exception if encoding convertion or constructor self failed.
|
Function will throw exception if encoding convertion or constructor self failed.
|
||||||
There are some example:
|
There are some example:
|
||||||
|
@ -59,8 +60,8 @@ Because C++ standard is volatile, we create this function to have an uniform pro
|
||||||
|
|
||||||
\section fs_path_patch__to_utf8_path Extract UTF8 Path String from Path
|
\section fs_path_patch__to_utf8_path Extract UTF8 Path String from Path
|
||||||
|
|
||||||
YYCC::FsPathPatch::ToUTF8Path provides this feature.
|
#ToUTF8Path provides this feature.
|
||||||
It basically is the reversed operation of YYCC::FsPathPatch::FromUTF8Path.
|
It basically is the reversed operation of #FromUTF8Path.
|
||||||
It is usually used when you have done all path work in \c std::filesystem::path
|
It is usually used when you have done all path work in \c std::filesystem::path
|
||||||
and want to get the result.
|
and want to get the result.
|
||||||
There is an example:
|
There is an example:
|
||||||
|
@ -71,3 +72,4 @@ auto result = YYCC::FsPathPatch::ToUTF8Path(foobar_path / YYCC::FsPathPatch::Fro
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
namespace YYCC::IOHelper {
|
||||||
/**
|
/**
|
||||||
|
|
||||||
\page io_helper IO Helper
|
\page io_helper IO Helper
|
||||||
|
@ -40,4 +41,5 @@ There is a simple example:
|
||||||
FILE* fs = YYCC::IOHelper::FOpen(YYCC_U8("/path/to/file"), YYCC_U8("rb"));
|
FILE* fs = YYCC::IOHelper::FOpen(YYCC_U8("/path/to/file"), YYCC_U8("rb"));
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
namespace YYCC {
|
||||||
/**
|
/**
|
||||||
|
|
||||||
\page library_encoding Library Encoding
|
\page library_encoding Library Encoding
|
||||||
|
@ -224,3 +225,4 @@ Linux user do not need care this.
|
||||||
Because almost Linux distro use UTF8 in default.
|
Because almost Linux distro use UTF8 in default.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
namespace YYCC::ParserHelper {
|
||||||
/**
|
/**
|
||||||
|
|
||||||
\page parser_helper Parser Helper
|
\page parser_helper Parser Helper
|
||||||
|
@ -18,7 +19,7 @@ For \c bool type, parser will try doing convertion between it and \c "true" \c "
|
||||||
|
|
||||||
\section parser_helper__try_parse Try Parse
|
\section parser_helper__try_parse Try Parse
|
||||||
|
|
||||||
YYCC::ParserHelper::TryParse will try to parse string into caller specified type.
|
#TryParse will try to parse string into caller specified type.
|
||||||
All of them accept an UTF8 string view at first argument,
|
All of them accept an UTF8 string view at first argument,
|
||||||
require that you provide a container receiving converted result in the second argument,
|
require that you provide a container receiving converted result in the second argument,
|
||||||
and return a bool value to indicate whether the convertion is successful.
|
and return a bool value to indicate whether the convertion is successful.
|
||||||
|
@ -34,7 +35,7 @@ For integral type, this function allows caller to specify extra argument providi
|
||||||
|
|
||||||
\section parser_helper__parse Parse
|
\section parser_helper__parse Parse
|
||||||
|
|
||||||
YYCC::ParserHelper::Parse is similar to YYCC::ParserHelper::TryParse.
|
#Parse is similar to #TryParse.
|
||||||
But it will not return bool value to indicate success and doesn't have the argument receiving result.
|
But it will not return bool value to indicate success and doesn't have the argument receiving result.
|
||||||
It only accepts an UTF8 string view as the only one argument, and return result directly.
|
It only accepts an UTF8 string view as the only one argument, and return result directly.
|
||||||
If the convertion failed, the return value is \b undefined (but usually is the default value of given type).
|
If the convertion failed, the return value is \b undefined (but usually is the default value of given type).
|
||||||
|
@ -44,15 +45,15 @@ There is an example:
|
||||||
uint32_t val = YYCC::ParserHelper::Parse<uint32_t>(YYCC_U8("123"));
|
uint32_t val = YYCC::ParserHelper::Parse<uint32_t>(YYCC_U8("123"));
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
Please note, for integral types, there is no base argument in YYCC::ParserHelper::Parse.
|
Please note, for integral types, there is no base argument in #Parse.
|
||||||
Please use YYCC::ParserHelper::TryParse instead.
|
Please use #TryParse instead.
|
||||||
|
|
||||||
Using this function is dangerous if the validation of your input is important.
|
Using this function is dangerous if the validation of your input is important.
|
||||||
In this case, please use YYCC::ParserHelper::TryParse instead.
|
In this case, please use #TryParse instead.
|
||||||
|
|
||||||
\section parser_helper__to_string To String
|
\section parser_helper__to_string To String
|
||||||
|
|
||||||
YYCC::ParserHelper::ToString basically is the reversed operation of YYCC::ParserHelper::Parse.
|
#ToString basically is the reversed operation of #Parse.
|
||||||
It gets the string representation of given type.
|
It gets the string representation of given type.
|
||||||
The only argument of these functions is the type which need to be converted to its string representation.
|
The only argument of these functions is the type which need to be converted to its string representation.
|
||||||
And they will return yycc_u8string as result.
|
And they will return yycc_u8string as result.
|
||||||
|
@ -77,4 +78,5 @@ The argument of template is the type these functions need to be processed.
|
||||||
Although C++ have \e smart template type deduction,
|
Although C++ have \e smart template type deduction,
|
||||||
it would be better to specify template argument manually to explicitly specify your desired type.
|
it would be better to specify template argument manually to explicitly specify your desired type.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
namespace YYCC {
|
||||||
/**
|
/**
|
||||||
|
|
||||||
\page platform_checker Platform Checker
|
\page platform_checker Platform Checker
|
||||||
|
@ -32,4 +33,5 @@ blabla();
|
||||||
|
|
||||||
It's enough and simple that use \c \#if to bracket the Windows specified code.
|
It's enough and simple that use \c \#if to bracket the Windows specified code.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
namespace YYCC::StringHelper {
|
||||||
/**
|
/**
|
||||||
|
|
||||||
\page string_helper String Helper
|
\page string_helper String Helper
|
||||||
|
@ -14,10 +15,10 @@ yycc_u8string Printf(const yycc_char8_t*, ...);
|
||||||
yycc_u8string VPrintf(const yycc_char8_t*, va_list argptr);
|
yycc_u8string VPrintf(const yycc_char8_t*, va_list argptr);
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
YYCC::StringHelper::Printf and YYCC::StringHelper::VPrintf is similar to \c std::sprintf and \c std::vsprintf.
|
#Printf and #VPrintf is similar to \c std::sprintf and \c std::vsprintf.
|
||||||
YYCC::StringHelper::Printf accepts UTF8 format string and variadic arguments specifying data to print.
|
#Printf accepts UTF8 format string and variadic arguments specifying data to print.
|
||||||
This is commonly used by programmer.
|
This is commonly used by programmer.
|
||||||
However, YYCC::StringHelper::VPrintf also do the same work but its second argument is \c va_list,
|
However, #VPrintf also do the same work but its second argument is \c va_list,
|
||||||
the representation of variadic arguments.
|
the representation of variadic arguments.
|
||||||
It is mostly used by other function which has variadic arguments.
|
It is mostly used by other function which has variadic arguments.
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ that you don't need to worry about whether the space of given buffer is enough,
|
||||||
because these functions help you to calculate this internally.
|
because these functions help you to calculate this internally.
|
||||||
|
|
||||||
There is the same design like we introduced in \ref encoding_helper.
|
There is the same design like we introduced in \ref encoding_helper.
|
||||||
There are 2 overloads for YYCC::StringHelper::Printf and YYCC::StringHelper::VPrintf respectively.
|
There are 2 overloads for #Printf and #VPrintf respectively.
|
||||||
First overload return bool value and require a string container as argument for storing result.
|
First overload return bool value and require a string container as argument for storing result.
|
||||||
The second overload return result string directly.
|
The second overload return result string directly.
|
||||||
As you expected, first overload will return false if fail to format string (this is barely happened).
|
As you expected, first overload will return false if fail to format string (this is barely happened).
|
||||||
|
@ -44,7 +45,7 @@ yycc_u8string Replace(const yycc_char8_t*, const yycc_char8_t*, const yycc_char8
|
||||||
The first overload will do replacement in given string container directly.
|
The first overload will do replacement in given string container directly.
|
||||||
The second overload will produce a copy of original string and do replacement on the copied string.
|
The second overload will produce a copy of original string and do replacement on the copied string.
|
||||||
|
|
||||||
YYCC::StringHelper::Replace has special treatments for following scenarios:
|
#Replace has special treatments for following scenarios:
|
||||||
|
|
||||||
\li If given string is empty or nullptr, the return value will be empty.
|
\li If given string is empty or nullptr, the return value will be empty.
|
||||||
\li If the character sequence to be replaced is nullptr or empty string, no replacement will happen.
|
\li If the character sequence to be replaced is nullptr or empty string, no replacement will happen.
|
||||||
|
@ -58,10 +59,10 @@ YYCC::StringHelper provide an universal way for joining string and various speci
|
||||||
|
|
||||||
Because C++ list types are various.
|
Because C++ list types are various.
|
||||||
There is no unique and convenient way to create an universal join function.
|
There is no unique and convenient way to create an universal join function.
|
||||||
So we create YYCC::StringHelper::JoinDataProvider to describe join context.
|
So we create #JoinDataProvider to describe join context.
|
||||||
|
|
||||||
Before using universal join function,
|
Before using universal join function,
|
||||||
you should setup YYCC::StringHelper::JoinDataProvider first, the context of join function.
|
you should setup #JoinDataProvider first, the context of join function.
|
||||||
It actually is an \c std::function object which can be easily fetched by C++ lambda syntax.
|
It actually is an \c std::function object which can be easily fetched by C++ lambda syntax.
|
||||||
This function pointer accept a reference to \c yycc_u8string_view,
|
This function pointer accept a reference to \c yycc_u8string_view,
|
||||||
programmer should set it to the string to be joined when at each calling.
|
programmer should set it to the string to be joined when at each calling.
|
||||||
|
@ -69,7 +70,7 @@ And this function pointer return a bool value to indicate the end of join.
|
||||||
You can simply return \c false to terminate join process.
|
You can simply return \c false to terminate join process.
|
||||||
The argument you assigned to argument will not be taken into join process when you return false.
|
The argument you assigned to argument will not be taken into join process when you return false.
|
||||||
|
|
||||||
Then, you can pass the created YYCC::StringHelper::JoinDataProvider object to YYCC::StringHelper::Join function.
|
Then, you can pass the created #JoinDataProvider object to #Join function.
|
||||||
And specify decilmer at the same time.
|
And specify decilmer at the same time.
|
||||||
Then you can get the final joined string.
|
Then you can get the final joined string.
|
||||||
There is an example:
|
There is an example:
|
||||||
|
@ -137,3 +138,4 @@ the result will only has 1 item and this item is source string itself.
|
||||||
There is no way that these methods return an empty list, except the code is buggy.
|
There is no way that these methods return an empty list, except the code is buggy.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
namespace YYCC::WinFctHelper {
|
||||||
/**
|
/**
|
||||||
|
|
||||||
\page win_fct_helper Windows Function Helper
|
\page win_fct_helper Windows Function Helper
|
||||||
|
@ -9,9 +10,10 @@ It will be entirely invisible in other platforms.
|
||||||
|
|
||||||
Currently this namespace has following functions:
|
Currently this namespace has following functions:
|
||||||
|
|
||||||
\li YYCC::WinFctHelper::GetCurrentModule: Get the handle to current module.
|
\li #GetCurrentModule: Get the handle to current module.
|
||||||
\li YYCC::WinFctHelper::GetTempDirectory: Get temporary directory in Windows.
|
\li #GetTempDirectory: Get temporary directory in Windows.
|
||||||
\li YYCC::WinFctHelper::GetModuleFileName: Get the path to module in file system by given handle.
|
\li #GetModuleFileName: Get the path to module in file system by given handle.
|
||||||
\li YYCC::WinFctHelper::GetLocalAppData: Get the path inside \%LOCALAPPDATA\%
|
\li #GetLocalAppData: Get the path inside \%LOCALAPPDATA\%
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
namespace YYCC {
|
||||||
/**
|
/**
|
||||||
|
|
||||||
\page win_import Windows Import Guard
|
\page win_import Windows Import Guard
|
||||||
|
@ -66,4 +67,5 @@ because the headers use \c \#if to check environment out and will do nothing in
|
||||||
However, we still highly recommend you use this pair with platform checker bracket like example does,
|
However, we still highly recommend you use this pair with platform checker bracket like example does,
|
||||||
if your program need to be run on multiple platforms.
|
if your program need to be run on multiple platforms.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
}
|
|
@ -6,16 +6,34 @@
|
||||||
|
|
||||||
namespace YYCC::ConfigManager {
|
namespace YYCC::ConfigManager {
|
||||||
|
|
||||||
|
#pragma region Abstract Setting
|
||||||
|
|
||||||
|
AbstractSetting::AbstractSetting(const yycc_u8string_view& name) : m_Name(name), m_RawData() {
|
||||||
|
if (m_Name.empty())
|
||||||
|
throw std::invalid_argument("the name of setting should not be empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractSetting::~AbstractSetting() {}
|
||||||
|
|
||||||
|
const yycc_u8string& AbstractSetting::GetName() const { return m_Name; }
|
||||||
|
|
||||||
|
void AbstractSetting::ResizeData(size_t new_size) { m_RawData.resize(new_size); }
|
||||||
|
const void* AbstractSetting::GetDataPtr() const { return m_RawData.data(); }
|
||||||
|
void* AbstractSetting::GetDataPtr() { return m_RawData.data(); }
|
||||||
|
size_t AbstractSetting::GetDataSize() const { return m_RawData.size(); }
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
#pragma region Core Manager
|
#pragma region Core Manager
|
||||||
|
|
||||||
CoreManager::CoreManager(
|
CoreManager::CoreManager(
|
||||||
const yycc_char8_t* cfg_file_path,
|
const yycc_u8string_view& cfg_file_path,
|
||||||
uint64_t version_identifier,
|
uint64_t version_identifier,
|
||||||
std::initializer_list<AbstractSetting*> settings) :
|
std::initializer_list<AbstractSetting*> settings) :
|
||||||
m_CfgFilePath(), m_VersionIdentifier(version_identifier), m_Settings() {
|
m_CfgFilePath(cfg_file_path), m_VersionIdentifier(version_identifier), m_Settings() {
|
||||||
// assign cfg path
|
// Mark: no need to check cfg file path
|
||||||
if (cfg_file_path != nullptr)
|
// it will be checked at creating file handle
|
||||||
m_CfgFilePath = cfg_file_path;
|
|
||||||
// assign settings
|
// assign settings
|
||||||
for (auto* setting : settings) {
|
for (auto* setting : settings) {
|
||||||
auto result = m_Settings.try_emplace(setting->GetName(), setting);
|
auto result = m_Settings.try_emplace(setting->GetName(), setting);
|
||||||
|
|
|
@ -26,17 +26,16 @@ namespace YYCC::ConfigManager {
|
||||||
/**
|
/**
|
||||||
* @brief Construct a setting
|
* @brief Construct a setting
|
||||||
* @param[in] name The name of this setting.
|
* @param[in] name The name of this setting.
|
||||||
|
* @exception std::invalid_argument Name of setting is empty.
|
||||||
*/
|
*/
|
||||||
AbstractSetting(const yycc_char8_t* name) : m_Name(), m_RawData() {
|
AbstractSetting(const yycc_u8string_view& name);
|
||||||
if (name != nullptr) m_Name = name;
|
virtual ~AbstractSetting();
|
||||||
}
|
|
||||||
virtual ~AbstractSetting() {}
|
|
||||||
|
|
||||||
// Name interface
|
// Name interface
|
||||||
public:
|
public:
|
||||||
/// @brief Get name of this setting.
|
/// @brief Get name of this setting.
|
||||||
/// @details Name was used in storing setting in file.
|
/// @details Name was used in storing setting in file.
|
||||||
const yycc_u8string& GetName() const { return m_Name; }
|
const yycc_u8string& GetName() const;
|
||||||
private:
|
private:
|
||||||
yycc_u8string m_Name;
|
yycc_u8string m_Name;
|
||||||
|
|
||||||
|
@ -63,15 +62,15 @@ namespace YYCC::ConfigManager {
|
||||||
/// @brief Resize internal buffer to given size.
|
/// @brief Resize internal buffer to given size.
|
||||||
/// @remarks It is usually used in UserSave.
|
/// @remarks It is usually used in UserSave.
|
||||||
/// @param[in] new_size The new size of internal buffer.
|
/// @param[in] new_size The new size of internal buffer.
|
||||||
void ResizeData(size_t new_size) { m_RawData.resize(new_size); }
|
void ResizeData(size_t new_size);
|
||||||
/// @brief Get data pointer to internal buffer.
|
/// @brief Get data pointer to internal buffer.
|
||||||
/// @remarks It is usually used in UserLoad.
|
/// @remarks It is usually used in UserLoad.
|
||||||
const void* GetDataPtr() const { return m_RawData.data(); }
|
const void* GetDataPtr() const;
|
||||||
/// @brief Get mutable data pointer to internal buffer.
|
/// @brief Get mutable data pointer to internal buffer.
|
||||||
/// @remarks It is usually used in UserSave.
|
/// @remarks It is usually used in UserSave.
|
||||||
void* GetDataPtr() { return m_RawData.data(); }
|
void* GetDataPtr();
|
||||||
/// @brief Get the length of internal buffer.
|
/// @brief Get the length of internal buffer.
|
||||||
size_t GetDataSize() const { return m_RawData.size(); }
|
size_t GetDataSize() const;
|
||||||
private:
|
private:
|
||||||
std::vector<uint8_t> m_RawData;
|
std::vector<uint8_t> m_RawData;
|
||||||
};
|
};
|
||||||
|
@ -86,7 +85,7 @@ namespace YYCC::ConfigManager {
|
||||||
* @param[in] settings An initializer list containing pointers to all managed settings.
|
* @param[in] settings An initializer list containing pointers to all managed settings.
|
||||||
*/
|
*/
|
||||||
CoreManager(
|
CoreManager(
|
||||||
const yycc_char8_t* cfg_file_path,
|
const yycc_u8string_view& cfg_file_path,
|
||||||
uint64_t version_identifier,
|
uint64_t version_identifier,
|
||||||
std::initializer_list<AbstractSetting*> settings);
|
std::initializer_list<AbstractSetting*> settings);
|
||||||
~CoreManager() {}
|
~CoreManager() {}
|
||||||
|
@ -126,9 +125,10 @@ namespace YYCC::ConfigManager {
|
||||||
* @param[in] name The name of this setting.
|
* @param[in] name The name of this setting.
|
||||||
* @param[in] default_value The default value of this setting.
|
* @param[in] default_value The default value of this setting.
|
||||||
* @param[in] constraint The constraint applied to this setting.
|
* @param[in] constraint The constraint applied to this setting.
|
||||||
|
* @exception std::invalid_argument Name of setting is empty.
|
||||||
*/
|
*/
|
||||||
NumberSetting(
|
NumberSetting(
|
||||||
const yycc_char8_t* name, _Ty default_value,
|
const yycc_u8string_view& name, _Ty default_value,
|
||||||
Constraints::Constraint<_Ty> constraint = Constraints::Constraint<_Ty> {}) :
|
Constraints::Constraint<_Ty> constraint = Constraints::Constraint<_Ty> {}) :
|
||||||
AbstractSetting(name), m_Data(default_value), m_DefaultData(default_value), m_Constraint(constraint) {}
|
AbstractSetting(name), m_Data(default_value), m_DefaultData(default_value), m_Constraint(constraint) {}
|
||||||
virtual ~NumberSetting() {}
|
virtual ~NumberSetting() {}
|
||||||
|
@ -182,9 +182,10 @@ namespace YYCC::ConfigManager {
|
||||||
* @param[in] name The name of this setting.
|
* @param[in] name The name of this setting.
|
||||||
* @param[in] default_value The default value of this setting.
|
* @param[in] default_value The default value of this setting.
|
||||||
* @param[in] constraint The constraint applied to this setting.
|
* @param[in] constraint The constraint applied to this setting.
|
||||||
|
* @exception std::invalid_argument Name of setting is empty.
|
||||||
*/
|
*/
|
||||||
StringSetting(
|
StringSetting(
|
||||||
const yycc_char8_t* name, const yycc_u8string_view& default_value,
|
const yycc_u8string_view& name, const yycc_u8string_view& default_value,
|
||||||
Constraints::Constraint<yycc_u8string> constraint = Constraints::Constraint<yycc_u8string> {}) :
|
Constraints::Constraint<yycc_u8string> constraint = Constraints::Constraint<yycc_u8string> {}) :
|
||||||
AbstractSetting(name), m_Data(), m_DefaultData(), m_Constraint(constraint) {
|
AbstractSetting(name), m_Data(), m_DefaultData(), m_Constraint(constraint) {
|
||||||
m_Data = default_value;
|
m_Data = default_value;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user