# 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& 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 (``, ``, ``) 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` 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& 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 `) - 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 (``, ``, ``, ``, ``, ``) ### 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` - `` (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.