Files
UwUGL/STYLEGUIDE.md

128 lines
5.7 KiB
Markdown

# UwUGL Styleguide
This document describes the coding conventions used in UwUGL, inferred from the existing codebase. It prioritizes readability and simplicity for a small graphics library.
---
## 1. File Organization
- **Single monolithic header**: `uwugl.h` is the public entry point and includes all implementation files.
- **Header-like `.cpp` files**: Every implementation file begins with `#pragma once` and is designed to be `#include`d directly by `uwugl.h` (or by other `.cpp` files). There are no traditional separate `.h`/`.cpp` pairs.
- **No separate headers for internal modules**: Classes and structs are declared and defined directly in `.cpp` files.
- **Exception**: `shaders/shaders.h` is a small aggregator file that includes the shader `.cpp` files.
- **Directory layout**:
- `primatives/` — shape classes (`Line`, `Point`, `Rectangle`, `Trapezoid`, `Triangle`)
- `shaders/` — shader classes and base
- `waymini/` — external Wayland helper library (C)
## 2. Naming Conventions
- **Namespace**: All library code lives in `namespace UwU`.
- **Classes / structs**: PascalCase (`Buffer`, `ColorShader`, `Rectangle`, `Helpers`).
- **Functions / methods**: camelCase (`drawPixel`, `lerpColor`, `bresenham`, `shouldClose`).
- **Member variables**: lowercase with no prefix (`pixels`, `width`, `x0`, `c`).
- **Template parameters**: PascalCase ending in `T` (`ShaderT`).
- **Enums**: PascalCase type name; UPPER_SNAKE_CASE values (`ShaderType`, `COLOR`, `HGRADIENT`, `VGRADIENT`).
- **Constants in code**: prefer lowercase; UPPER_SNAKE_CASE may be used for local compile-time-ish constants in comments or test code.
- **Filenames**: lowercase and descriptive (`buffer.cpp`, `colorshader.cpp`, `line.cpp`).
## 3. Formatting
- **Indentation**: 2 spaces.
- **Brace style**: K&R — opening brace on the same line as the class/function/control statement.
- **Pointer/reference syntax**: attach `*` and `&` to the variable name:
- `uint8_t* pixels`
- `ShaderBase<ShaderT>& shader`
- **Empty parameter lists**: use `()` for default constructors, e.g., `Color() {}`.
- **Spacing around operators**: use spaces around binary operators for readability (`x + y` instead of `x+y`).
- **Explicit `return;` at end of void functions**: Acceptable, but not required.
- **Comments**: use `//` for both inline and block-style comments. Keep them informal and focused on intent or known issues.
## 4. Includes
Include order within a file:
1. `#pragma once`
2. C/C++ standard headers (`<stdint.h>`, `<stdio.h>`, `<algorithm>`)
3. Project implementation files via relative paths (`"../datatypes.cpp"`, `"../buffer.cpp"`)
External C library headers (e.g., `"waymini/waymini.h"`) are included where needed.
## 5. Code Patterns
- **Composition over inheritance**: primitives hold data; shaders are passed into `draw()`.
- **CRTP for shaders**: `ShaderBase<ShaderT>` uses the Curiously Recurring Template Pattern for static polymorphism.
- **Template `draw` methods**: every primitive's `draw()` is templated on `ShaderT` and takes `(Buffer buffer, ShaderBase<ShaderT>& shader)`.
- **Manual memory management**: `new uint8_t[...]` in `Buffer`; no smart pointers.
- **C-style casts**: `(uint16_t)x`, `(uint8_t*)ptr`.
- **Bounds checks**: primitives guard `draw()` with `if (x > buffer.width || y > buffer.height) {return;};`.
- **Unused parameter suppression**: use `(void)param;` to silence warnings.
## 6. C++ Feature Usage
### Used
- Classes and structs
- Namespaces
- Templates (`template <class ShaderT>`)
- CRTP (Curiously Recurring Template Pattern)
- Function overloading (constructors)
- References
- C-style casts
- `new` / `new[]` for dynamic allocation
- Raw pointers
- Stack-allocated arrays
- C standard headers (`<stdint.h>`, `<stdio.h>`, `<stdlib.h>`, `<string.h>`, `<time.h>`, `<algorithm>`)
### Not Used but Allowed
- Smart pointers (`std::unique_ptr`, `std::shared_ptr`)
- Standard containers (`std::vector`, `std::array`, etc.)
- `enum class`
- Exceptions
- `std::string`
- `std::chrono`
- `std::function`
### Not Used
The following features are intentionally not used. This keeps the codebase small, predictable, and easy to reason about.
- `auto`
- Range-based `for` loops
- `nullptr`
- Lambda expressions
- `constexpr` / `consteval`
- `using` type aliases
- Move semantics / rvalue references
- Default member initializers
- Delegating constructors
- `override` / `final`
- Named casts (`static_cast`, `reinterpret_cast`, etc.)
- Structured bindings
- Concepts / `requires` (C++20)
- Virtual functions / runtime polymorphism / abstract base classes
- Operator overloading
- RTTI / `dynamic_cast` / `typeid`
- `<iostream>` (use C-style `printf`/`fflush`)
## 7. Build System
- **Makefile-based**.
- C library (`waymini`) compiled with `gcc`.
- Main example compiled with `g++`.
- Flags: `-Wall -Wextra -O3`, plus Wayland client flags from `pkg-config`.
## 8. Known Inconsistencies and Recommendations
The codebase currently has a few inconsistencies. The following recommendations aim to improve readability without adding complexity:
- **Indentation consistency**: some blocks are not aligned (e.g., `line.cpp` inner loop). Keep all indentation strictly at 2 spaces per level.
- **Spacing consistency**: standardize on spaces around binary operators and after commas.
- **Include consistency**: some primitives include `../shaders/shaders.h` while `rectangle.cpp` also includes `../shaders/shaderbase.cpp` directly. Prefer the aggregator `shaders.h` everywhere.
- **`return;` at end of void functions**: acceptable, but can be omitted when it adds no clarity.
- **Bounds check style**: the pattern `if (...) {return;};` has a redundant semicolon. Prefer `if (...) { return; }`.
---
This guide should evolve with the project. When in doubt, favor simplicity and consistency with the existing code.