[nostaliga] Update Developer Handbook paragraph formating to one sentence/line
This commit is contained in:
parent
0420dfb545
commit
dce98590fc
@ -2,12 +2,13 @@
|
||||
|
||||
## About
|
||||
|
||||
The purpose of the Developer Handbook is similar to that of the README. The
|
||||
README should be viewed as a prerequisite to the Developer Handbook. The README
|
||||
should provide information needed to build the project, which might be used by
|
||||
an advanced user or a person trying to build and package the project. The
|
||||
Developer Handbook should focus on information needed by a developer working on
|
||||
the project.
|
||||
The purpose of the Developer Handbook is similar to that of the README.
|
||||
The README should be viewed as a prerequisite to the Developer Handbook.
|
||||
The README should provide information needed to build the project, which might
|
||||
be used by an advanced user or a person trying to build and package the
|
||||
project.
|
||||
The Developer Handbook should focus on information needed by a developer
|
||||
working on the project.
|
||||
|
||||
## Project Structure
|
||||
|
||||
@ -65,14 +66,16 @@ The C++ language designers aren't stupid. Question them, but don't ignore them.
|
||||
|
||||
#### Casting
|
||||
|
||||
Do not use C-style casts. C++ casts are more readable, and more explicit about
|
||||
the type of cast being used. Do not use ```dynamic_cast``` in code building for the
|
||||
GBA, as RTTI is disabled in GBA builds.
|
||||
Do not use C-style casts.
|
||||
C++ casts are more readable, and more explicit about the type of cast being
|
||||
used.
|
||||
Do not use ```dynamic_cast``` in code building for the GBA, as RTTI is disabled
|
||||
in GBA builds.
|
||||
|
||||
#### Library Usage
|
||||
|
||||
C++ libraries should generally be preferred to C libraries. C libraries are
|
||||
allowed, but pay extra attention.
|
||||
C++ libraries should generally be preferred to C libraries.
|
||||
C libraries are allowed, but pay extra attention.
|
||||
|
||||
This example from nostalgia::core demonstrates the type of problems that can
|
||||
arise from idiomatically mixed code.
|
||||
@ -115,37 +118,41 @@ int main() {
|
||||
The code base where this was observed actually got away with this for the most
|
||||
part, as the std::vector implementation used evidently waited until the
|
||||
internal array was needed before initializing and the memory was zeroed out
|
||||
because the allocation occurred early in the program's execution. While the
|
||||
std::vector implementation in question worked with this code and the memory leak
|
||||
is not noticeable because the std::vector was meant to exist for the entire life
|
||||
of the process, other classes likely will not get away with it due to more
|
||||
substantial constructors and more frequent instantiations of the classes in
|
||||
question.
|
||||
because the allocation occurred early in the program's execution.
|
||||
While the std::vector implementation in question worked with this code and the
|
||||
memory leak is not noticeable because the std::vector was meant to exist for
|
||||
the entire life of the process, other classes likely will not get away with it
|
||||
due to more substantial constructors and more frequent instantiations of the
|
||||
classes in question.
|
||||
|
||||
### Pointers vs References
|
||||
|
||||
Pointers are generally preferred to references. References should be used for
|
||||
optimizing the passing in of parameters and for returning from accessor
|
||||
operators (e.g. ```T &Vector::operator[](size_t)```). As parameters, references
|
||||
should always be const. A non-const reference is generally used because the
|
||||
parameter value is changed in the function, but it will look like it was passed
|
||||
in by value where it is called and thus not subject to change. The reference
|
||||
operator makes it clear that the value can and likely will change.
|
||||
operators (e.g. ```T &Vector::operator[](size_t)```).
|
||||
As parameters, references should always be const.
|
||||
A non-const reference is generally used because the parameter value is changed
|
||||
in the function, but it will look like it was passed in by value where it is
|
||||
called and thus not subject to change.
|
||||
The reference operator makes it clear that the value can and likely will change.
|
||||
|
||||
### Error Handling
|
||||
|
||||
Exceptions are clean and nice and gleefully encouraged in userland code running
|
||||
in environments with expansive system resources, but absolutely unacceptable in
|
||||
code running in restrictive bare metal environments. The GBA build has them
|
||||
disabled. Exceptions cause the compiler to generate a great deal of extra code
|
||||
that inflates the size of the binary. The binary size bloat is often cited as
|
||||
one of the main reasons why many embedded developers prefer C to C++.
|
||||
code running in restrictive bare metal environments.
|
||||
The GBA build has them disabled.
|
||||
Exceptions cause the compiler to generate a great deal of extra code that
|
||||
inflates the size of the binary.
|
||||
The binary size bloat is often cited as one of the main reasons why many
|
||||
embedded developers prefer C to C++.
|
||||
|
||||
Instead of throwing exceptions, all engine code must return error codes.
|
||||
Nostalgia and Ox both use ```ox::Error``` to report errors. ```ox::Error``` is
|
||||
a struct that has overloaded operators to behave like an integer error code,
|
||||
plus some extra fields to enhance debuggability. If instantiated through the
|
||||
```OxError(x)``` macro, it will also include the file and line of the error.
|
||||
plus some extra fields to enhance debuggability.
|
||||
If instantiated through the ```OxError(x)``` macro, it will also include the
|
||||
file and line of the error.
|
||||
The ```OxError(x)``` macro should only be used for the initial instantiation of
|
||||
an ```ox::Error```.
|
||||
|
||||
@ -192,18 +199,20 @@ Lastly, there are a few macros available to help in passing ```ox::Error```s
|
||||
back up the call stack, ```oxReturnError```, ```oxThrowError```,
|
||||
```oxIgnoreError```, and ```oxRequire```.
|
||||
|
||||
```oxReturnError``` is by far the more helpful of the two. ```oxReturnError```
|
||||
will return an ```ox::Error``` if it is not 0 and ```oxThrowError``` will throw
|
||||
an ```ox::Error``` if it is not 0. Because exceptions are disabled for GBA
|
||||
builds and thus cannot be used in the engine, ```oxThrowError``` is only really
|
||||
useful at the boundary between engine libraries and Nostalgia Studio.
|
||||
```oxReturnError``` is by far the more helpful of the two.
|
||||
```oxReturnError``` will return an ```ox::Error``` if it is not 0 and
|
||||
```oxThrowError``` will throw an ```ox::Error``` if it is not 0.
|
||||
Because exceptions are disabled for GBA builds and thus cannot be used in the
|
||||
engine, ```oxThrowError``` is only really useful at the boundary between
|
||||
engine libraries and Nostalgia Studio.
|
||||
|
||||
```oxIgnoreError``` does what it says, it ignores the error. Since
|
||||
```ox::Error```s always nodiscard, you must do something with them.
|
||||
```oxIgnoreError``` does what it says, it ignores the error.
|
||||
Since ```ox::Error```s always nodiscard, you must do something with them.
|
||||
In extremely rare cases, you may not have anything you can do with them or you
|
||||
may know the code will never fail in that particular instance.
|
||||
This should be used very sparingly. At the time of this writing, it has only
|
||||
been used 4 times in 20,000 lines of code.
|
||||
This should be used very sparingly.
|
||||
At the time of this writing, it has only been used 4 times in 20,000 lines of
|
||||
code.
|
||||
|
||||
|
||||
```cpp
|
||||
|
Loading…
Reference in New Issue
Block a user