NDEVR Coding Format
Naming
Naming Convensions
| Item | Format | Example |
|---|---|---|
| Class Names | Upper Camel Case | ExampleClass |
| Static Function | Upper Camel Case | ExampleStaticFunction |
| Member Function | Lower Camel Case | exampleMemberFunction |
| Enum Names | Upper Camel Case | ExampleEnum |
| Enum Item | Lower Snake Case with prefix e_ | e_example_ae_example_b |
| Local Variable | Lower Snake Case | example_local_var |
| Public Member Variable | Lower Snake Case | example_public_var |
| Protected/Private Member Variable | Lower Snake Case with prefix m_ | m_member_variable |
| Static Private/Protected Member Variable | Lower Snake Case with prefix s_ | s_static_variable |
| Templated Variable Type | Lower Snake Case with t_ | template<class t_type> |
| Macros | All CAPS Snake Case | EXAMPLE_MACRO_DEFINE |
| Enum Primitive Index | All CAPS | X, Y, LAT, LON |
Additional Naming Convensions
File Names
- File Names are Upper Camel Case.
- Paths in the code are always represented using / instead of \
- For Modules, Public Headers stored in a “Headers” Folder, Source Files in a “Source” Folder, Qt UI in the “UI” folder, and additional Resources in “Resources” folder. See Projects and Files
Qt Specific
- Signal functions should have the suffix of Signal
- Slot functions should have the suffix of Slot
- Classes that directly implement a Qt class, will usually be written QTCustom[classname]
Special Functions
set Functions are generally set[Var]. Get functions are generally just [var](). Both follow the function naming convention of lower camel case.
_t[X] are macros defined for translated strings. _t and _td being most notable. When using the function _td, the first argument should be lower snake case.
Variable Types
In general, we avoid using the built-in ambiguous types such as int, long, short, etc, opting instead to use the NDEVR explicit types
Projects and Files
Structure
In order for our automated tools to work optimally, we recommend using the directory structure described in the diagram.
Each Module should have its own code folder, as well as a folder within VS and QtCreator for the IDE specific files.
The “Create Module” Function within NDEVR DevTools can be used to easily add modules to projects that follow this directory structure.
Include Brackets
In C++, the #include directive is used to include header files in your code. The difference between using quotes (“”) and angle brackets (<>) lies in where the compiler searches for the header file:
Quotes (“”)
- Local Search: The compiler first searches for the header file in the same directory as the source file that contains the #include directive.
- Then System Search: If the file is not found locally, the compiler searches the system include directories.
Angle Brackets (<>)
- System Search: The compiler directly searches the system include directories specified by the compiler and environment variables.
When to Use Each:
- Quotes: Use quotes for header files that are part of your project, such as your own custom headers.
- Angle Brackets: Use angle brackets for standard library headers and external libraries.
#include "../Headers/ThirdPartyLibsDialog.h"//Relative Path include (Only use for library)
#include <ui_ThirdPartyLibsUI.h>//Use for "additional include directories"
#include <NDEVR/Button.h>//Use for other librariesStrings
Strings in NDEVR should be created and used with the built-in String class which uses Unicode, UTF-8, as its storage protocol. For functions that use UTF16 (Windows, Freetype, etc) getAs<std::wstring>() can be used as a convenient means of conversion.
Passwords
In order to prevent passwords from being included in memory dumps, logging, and to ensure they aren’t used directly in IO operations, NDEVR utilizes the PasswordString. Any passwords should be stored in this structure. User entry of passwords is done via QCustomLineEdit::setIsPassword(true), which will automatically return data as a PasswordString. The moment passwords are used they may decoded then and only then. In this way, we implicitly ensure protection of sensitive user data.
Display Strings
All textual information displayed to end users should be stored and created in the TranslatedString structure. This optimized structure hashes the string for use with a translation file, ensuring the user gets the message in the language of their choice while still allowing for readable English in-line comments. For simple strings, the macro _t(…) can be used. For more complicated strings or ones with replacement use the macro _td(…).
Virtualization
Virtual Functions have an impact on speed. Thus, their use should be limited when possible.
When To USe
- A software service used to augment functionality in the software (See NDEVR::SoftwareService)
- IO or file services such as PipeStreams or IO streams.
- Inheritance from Qt Objects
- Hardware Devices.
When Not To Use
- Any class inheriting from DesignObject.
- Any function that may potentially be executed in a large loop.
- Any class inheriting from Buffer
Exceptions
Exceptions provide for an alternative workflow, which, while can provide benefit, may also cause problems if not handled correctly.
When to use
- Inheriting from functions or classes that already throw exception.
- Classes inheriting from IOFactory. This allows quick exit and is guaranteed to be handled.
- When mentioned explicitly in the documentation.
When Not To Use
- For checks against logic that should not fail (programmer errors), use lib_assert
- Anything that can happen in a long loop as there is overhead to the throw function.
- For issues that can happen under normal conditions, at runtime, unless using or inheriting from CancelException.
- Undocumented code