diff --git a/README.md b/README.md index c524860..421b5fe 100644 --- a/README.md +++ b/README.md @@ -1,249 +1,5 @@ # cigui -## CIGUI Style Guide - -This document outlines the coding standards and best practices for the CIGUI library. Following these guidelines ensures consistency across the project and makes the codebase more maintainable. - -### General Principles - -- **Clarity over cleverness**: Write code that's easy to understand, not code that's clever. -- **Consistency**: Follow established patterns within the codebase. -- **Documentation**: Document public APIs thoroughly. -- **Testability**: Write code that can be easily tested. - -### Naming Conventions - -#### Files - -- Header files: `.hpp` for C++ headers, `.h` for C-compatible headers -- Implementation files: `.cpp` -- Template implementation files: `.inl` -- File names: lowercase with underscores (e.g., `grid_layout.hpp`) - -#### Classes and Types - -- Class names: PascalCase (e.g., `Button`, `GridLayout`) -- Type aliases/typedefs: PascalCase (e.g., `using WidgetPtr = std::shared_ptr`) -- Enum names: PascalCase -- Enum values: PascalCase (e.g., `enum class Alignment { TopLeft, Center, BottomRight }`) - -#### Functions and Variables - -- Function names: camelCase (e.g., `getPosition()`, `setVisible()`) -- Variable names: camelCase (e.g., `buttonText`, `isVisible`) -- Member variables: prefix with `m_` (e.g., `m_position`, `m_size`) -- Static variables: prefix with `s_` (e.g., `s_defaultFont`) -- Constants and macros: ALL_CAPS with underscores (e.g., `MAX_WIDGETS`, `CIGUI_API`) - -### Code Structure - -#### Namespaces - -- All library code should be inside the `cig` namespace -- Avoid deeply nested namespaces -- Do not use `using namespace` in headers - -```cpp -// Good -namespace cig { - class Button : public View { - // ... - }; -} - -// Bad -using namespace sf; // Don't do this in headers -``` - -#### Headers - -- Always use include guards with project-specific prefix -- Order includes as follows: - 1. Related header - 2. C++ standard library headers - 3. Third-party library headers (SFML) - 4. CIGUI headers -- Forward declare classes when possible to reduce dependencies - -```cpp -// Example of a good header structure -#pragma once - -#include -#include -#include -#include -#include - -namespace cig { - -class View; // Forward declaration - -class CIGUI_API Container { - // Implementation -}; - -} // namespace cig -``` - -#### Classes - -- Separate public, protected, and private sections -- Order within sections: - 1. Constructors/Destructors - 2. Public methods - 3. Event callbacks - 4. Static methods - 5. Member variables - -```cpp -class Button : public View { -public: - // Constructors/Destructors - Button(); - explicit Button(const std::string& text); - ~Button() override; - - // Methods - void setText(const std::string& text); - const std::string& getText() const; - - // Event dispatcher - EventDispatcher onClicked; - -protected: - // Protected methods - void updateAppearance(); - -private: - // Private methods - void initializeGraphics(); - - // Member variables - std::string m_text; - sf::RectangleShape m_background; - bool m_isHovered; -}; -``` - -### Templates - -- Template implementation should be in `.inl` files -- Use explicit instantiation for common types in DLLs -- Document template parameters - -```cpp -// In .hpp file -template -class Container { - // ... -}; - -// Include the implementation -#include - -// In .inl file -template -Container::Container() { - // ... -} - -// In .cpp file for explicit instantiation -template class Container; -template class Container; -``` - -### C++ Features - -- **C++ Standard**: Use C++20 features where appropriate -- **Smart Pointers**: Use `std::unique_ptr` for exclusive ownership, `std::shared_ptr` for shared ownership -- **Auto**: Use `auto` when the type is obvious or when using iterators -- **Range-based for loops**: Prefer over traditional for loops -- **Lambdas**: Use for short callbacks and event handlers -- **Move Semantics**: Support move operations where appropriate - -### Comments and Documentation - -- Use Doxygen-style comments for public APIs -- Comment complex algorithms and non-obvious code -- Avoid redundant comments that just repeat the code - -```cpp -/** - * @brief Creates a button with the specified label text - * - * @param text The text to display on the button - * @param size The size of the button (default: 100x30) - */ -Button(const std::string& text, const sf::Vector2f& size = {100.f, 30.f}); -``` - -### Error Handling - -- Use exceptions for exceptional cases only -- Validate input parameters and handle edge cases -- Document error conditions in function comments - -### Memory Management - -- Prefer automatic memory management with smart pointers -- Explicitly define ownership models in documentation -- Design with RAII principles (Resource Acquisition Is Initialization) - -### DLL/Shared Library Considerations - -- Use `CIGUI_API` macro for all classes and non-inline functions -- Use `CIGUI_TEMPLATE_API` for template classes -- Handle template instantiation properly (see Templates section) - -### SFML Integration - -- Wrap SFML types when extending functionality -- Use SFML conventions for graphics-related code -- Don't expose SFML implementation details in public APIs when avoidable - -### Testing - -- Write unit tests for core functionality -- Test edge cases and error conditions -- Create interactive examples for UI components - -### Formatting - -- Indentation: 4 spaces (no tabs) -- Line length: 100 characters maximum -- Braces: Open brace on same line, close brace on new line -- Space after keywords (if, for, while) -- No space after function names -- Place * and & with the type, not the variable name - -```cpp -// Good formatting example -if (condition) { - doSomething(); -} else { - doSomethingElse(); -} - -void setPosition(const sf::Vector2f& position) { - m_position = position; -} -``` - -### Best Practices - -- Prefer composition over inheritance -- Design interfaces that are hard to use incorrectly -- Follow the Rule of Five/Zero for class design -- Make data members private and provide accessors when needed -- Consider performance implications in UI code (avoid work in draw methods) - ---- - -This style guide is a living document and may evolve as the project grows. When in doubt, maintain consistency with the existing codebase. - ---- - ## Goal ```cpp diff --git a/StyleGuide.md b/StyleGuide.md new file mode 100644 index 0000000..bb6753c --- /dev/null +++ b/StyleGuide.md @@ -0,0 +1,240 @@ +## CIGUI Style Guide + +This document outlines the coding standards and best practices for the CIGUI library. Following these guidelines ensures consistency across the project and makes the codebase more maintainable. + +### General Principles + +- **Clarity over cleverness**: Write code that's easy to understand, not code that's clever. +- **Consistency**: Follow established patterns within the codebase. +- **Documentation**: Document public APIs thoroughly. +- **Testability**: Write code that can be easily tested. + +### Naming Conventions + +#### Files + +- Header files: `.hpp` for C++ headers, `.h` for C-compatible headers +- Implementation files: `.cpp` +- Template implementation files: `.inl` +- File names: lowercase with underscores (e.g., `grid_layout.hpp`) + +#### Classes and Types + +- Class names: PascalCase (e.g., `Button`, `GridLayout`) +- Type aliases/typedefs: PascalCase (e.g., `using WidgetPtr = std::shared_ptr`) +- Enum names: PascalCase +- Enum values: PascalCase (e.g., `enum class Alignment { TopLeft, Center, BottomRight }`) + +#### Functions and Variables + +- Function names: camelCase (e.g., `getPosition()`, `setVisible()`) +- Variable names: camelCase (e.g., `buttonText`, `isVisible`) +- Member variables: prefix with `m_` (e.g., `m_position`, `m_size`) +- Static variables: prefix with `s_` (e.g., `s_defaultFont`) +- Constants and macros: ALL_CAPS with underscores (e.g., `MAX_WIDGETS`, `CIGUI_API`) + +### Code Structure + +#### Namespaces + +- All library code should be inside the `cig` namespace +- Avoid deeply nested namespaces +- Do not use `using namespace` in headers + +```cpp +// Good +namespace cig { + class Button : public View { + // ... + }; +} + +// Bad +using namespace sf; // Don't do this in headers +``` + +#### Headers + +- Always use `#pragma once` +- Order includes as follows: + 1. Related header + 2. C++ standard library headers + 3. Third-party library headers (SFML) + 4. CIGUI headers +- Forward declare classes when possible to reduce dependencies + +```cpp +// Example of a good header structure +#pragma once + +#include +#include +#include +#include +#include + +namespace cig { + +class View; // Forward declaration + +class CIGUI_API Container { + // Implementation +}; + +} // namespace cig +``` + +#### Classes + +- Separate public, protected, and private sections +- Order within sections: + 1. Constructors/Destructors + 2. Public methods + 3. Event callbacks + 4. Static methods + 5. Member variables + +```cpp +class Button : public View { +public: + // Constructors/Destructors + Button(); + explicit Button(const std::string& text); + ~Button() override; + + // Methods + void setText(const std::string& text); + const std::string& getText() const; + + // Event dispatcher + EventDispatcher onClicked; + +protected: + // Protected methods + void updateAppearance(); + +private: + // Private methods + void initializeGraphics(); + + // Member variables + std::string m_text; + sf::RectangleShape m_background; + bool m_isHovered; +}; +``` + +### Templates + +- Template implementation should be in `.inl` files +- Use explicit instantiation for common types in DLLs +- Document template parameters + +```cpp +// In .hpp file +template +class Container { + // ... +}; + +// Include the implementation +#include + +// In .inl file +template +Container::Container() { + // ... +} + +// In .cpp file for explicit instantiation +template class Container; +template class Container; +``` + +### C++ Features + +- **C++ Standard**: Use C++20 features where appropriate +- **Smart Pointers**: Use `std::unique_ptr` for exclusive ownership, `std::shared_ptr` for shared ownership +- **Auto**: Use `auto` when the type is obvious or when using iterators +- **Range-based for loops**: Prefer over traditional for loops +- **Lambdas**: Use for short callbacks and event handlers +- **Move Semantics**: Support move operations where appropriate + +### Comments and Documentation + +- Use Doxygen-style comments for public APIs +- Comment complex algorithms and non-obvious code +- Avoid redundant comments that just repeat the code + +```cpp +/** + * @brief Creates a button with the specified label text + * + * @param text The text to display on the button + * @param size The size of the button (default: 100x30) + */ +Button(const std::string& text, const sf::Vector2f& size = {100.f, 30.f}); +``` + +### Error Handling + +- Use exceptions for exceptional cases only +- Validate input parameters and handle edge cases +- Document error conditions in function comments + +### Memory Management + +- Prefer automatic memory management with smart pointers +- Explicitly define ownership models in documentation +- Design with RAII principles (Resource Acquisition Is Initialization) + +### DLL/Shared Library Considerations +**TODO:** Think about this and add more details + +### SFML Integration + +- Wrap SFML types when extending functionality +- Use SFML conventions for graphics-related code +- Don't expose SFML implementation details in public APIs when avoidable + +### Testing + +- Write unit tests for core functionality +- Test edge cases and error conditions +- Create interactive examples for UI components + +### Formatting + +- Indentation: 4 spaces (no tabs) +- Line length: 100 characters maximum +- Braces: Open brace on same line, close brace on new line +- Space after keywords (if, for, while) +- No space after function names +- Place * and & with the type, not the variable name + +```cpp +// Good formatting example +if (condition) { + doSomething(); +} else { + doSomethingElse(); +} + +void setPosition(const sf::Vector2f& position) { + m_position = position; +} +``` + +### Best Practices + +- Prefer composition over inheritance +- Design interfaces that are hard to use incorrectly +- Follow the Rule of Five/Zero for class design +- Make data members private and provide accessors when needed +- Consider performance implications in UI code (avoid work in draw methods) + +--- + +This style guide is a living document and may evolve as the project grows. When in doubt, maintain consistency with the existing codebase. + +---