Add a standalone style guide document
Moved the CIGUI style guide from `README.md` to a dedicated `StyleGuide.md` file for better organization. This improves readability and ensures the main README remains focused on project goals and usage.
This commit is contained in:
parent
3679beaa4e
commit
b12e608567
2 changed files with 240 additions and 244 deletions
244
README.md
244
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<View>`)
|
||||
- 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 <cigui/config.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <SFML/Graphics/Drawable.hpp>
|
||||
#include <cigui/utils/rect.hpp>
|
||||
|
||||
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<MouseEvent> 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<typename T>
|
||||
class Container {
|
||||
// ...
|
||||
};
|
||||
|
||||
// Include the implementation
|
||||
#include <cigui/widgets/container.inl>
|
||||
|
||||
// In .inl file
|
||||
template<typename T>
|
||||
Container<T>::Container() {
|
||||
// ...
|
||||
}
|
||||
|
||||
// In .cpp file for explicit instantiation
|
||||
template class Container<int>;
|
||||
template class Container<std::string>;
|
||||
```
|
||||
|
||||
### 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
|
||||
|
|
240
StyleGuide.md
Normal file
240
StyleGuide.md
Normal file
|
@ -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<View>`)
|
||||
- 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 <cigui/config.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <SFML/Graphics/Drawable.hpp>
|
||||
#include <cigui/utils/rect.hpp>
|
||||
|
||||
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<MouseEvent> 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<typename T>
|
||||
class Container {
|
||||
// ...
|
||||
};
|
||||
|
||||
// Include the implementation
|
||||
#include <cigui/widgets/container.inl>
|
||||
|
||||
// In .inl file
|
||||
template<typename T>
|
||||
Container<T>::Container() {
|
||||
// ...
|
||||
}
|
||||
|
||||
// In .cpp file for explicit instantiation
|
||||
template class Container<int>;
|
||||
template class Container<std::string>;
|
||||
```
|
||||
|
||||
### 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.
|
||||
|
||||
---
|
Loading…
Reference in a new issue