This document provides directive guidelines for AI assistants working on the YUP project. Use these rules when generating, reviewing, or suggesting code changes.
- Project Type: C++ graphics/audio library
- License: ISC License
- Copyright:
Copyright (c) 2026 - kunitoki@gmail.com - Based On: Fork of JUCE7 ISC Modules
- Build System: CMake
- Testing Framework: Google Test
- Primary Dependencies: Rive, OpenGL/Metal/D3D
NEVER EVER run bash commands to configure, compile or test the implementation, acknowledge that we should test and we'll run and report any issue.
ALWAYS start new files with this exact header:
/*
==============================================================================
This file is part of the YUP library.
Copyright (c) 2026 - kunitoki@gmail.com
YUP is an open source library subject to open-source licensing.
The code included in this file is provided under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
to use, copy, modify, and/or distribute this software for any purpose with or
without fee is hereby granted provided that the above copyright notice and
this permission notice appear in all copies.
YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/For main module headers (e.g., yup_graphics.h), include this declaration block after the file header:
/*
==============================================================================
BEGIN_YUP_MODULE_DECLARATION
ID: module_name
vendor: yup
version: 1.0.0
name: Module Display Name
description: Brief module description
website: https://github.com/kunitoki/yup
license: ISC
minimumCppStandard: 17
dependencies: yup_graphics [other_dependencies]
searchpaths: native
enableARC: 1
END_YUP_MODULE_DECLARATION
==============================================================================
*/// Classes
class MyClass
{
public:
MyClass();
~MyClass();
private:
int memberVariable;
};
// Functions
void functionName()
{
// implementation
}
// Control structures
if (condition)
{
// code
}
else
{
// code
}
for (int i = 0; i < count; ++i)
{
// code
}
while (condition)
{
// code
}- Classes:
PascalCase(e.g.,GraphicsContext) - Functions:
camelCase(e.g.,createRenderer) - Variables:
camelCase(e.g.,currentState) - Constants:
camelCase(e.g.,defaultSize) - Member variables:
camelCase(e.g.,bufferSize) - Files:
yup_ClassName.h/cppfor classes, one file per main class
#pragma once
// 1. Own module header (if in .cpp file)
#include <yup_graphics/yup_graphics.h>
// 2. Standard library
#include <memory>
#include <vector>
// 3. External libraries (Rive, etc.)
#include <rive/rive.h>
// 4. Other project modules
#include "yup_core/yup_core.h"
// 5. Same module headers
#include "graphics/yup_Color.h"
#include "primitives/yup_Point.h"// NEVER use "using namespace"
// In test files: OK for widely used namespaces
using namespace yup;
// Prefer limited scope usage
TEST (MyClassTests, someFunction)
{
using namespace std::chrono;
// use chrono types without std::chrono:: prefix
}modules/yup_module_name/
├── yup_module_name.h // Main module header
├── yup_module_name.cpp // Main module implementation
├── yup_module_name.mm // Objective-C++ (Apple platforms)
├── subdirectory/ // Logical groupings
│ ├── yup_ClassName.h
│ └── yup_ClassName.cpp
└── native/ // Platform-specific code
├── yup_ClassName_win32.cpp
├── yup_ClassName_linux.cpp
└── yup_ClassName_apple.mm
Avoid going deeply nested into modules. Prefer a single subdirectory whenever possible for YUP modules (might be ok for thirdparties as we don't control the upstream structure).
Headers and Implementation files are designed to be included through the main module header/implementation, so linter errors are expected when parsing the files in isolation.
tests/module_name/
├── ModuleClassName.cpp // Test file per class
└── ModuleIntegration.cpp // Integration tests
class ClassName
{
public:
ClassName();
~ClassName();
// Copy/move constructors if needed
ClassName (const ClassName& other) = delete;
ClassName& operator= (const ClassName& other) = delete;
// Public interface
void doSomething (int arg);
int getValue() const;
bool isValid() const;
private:
// Member variables
int value;
bool initialized;
// Helper methods
void initialize();
};class YupStyleClass
{
public:
YupStyleClass();
~YupStyleClass();
void publicMethod();
private:
int memberVar;
YUP_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (YupStyleClass)
};#include <gtest/gtest.h>
#include <module_name/ClassName.h>
using namespace yup;
namespace
{
// Test helpers and constants
constexpr int kTestValue = 42;
class TestHelper
{
public:
static void setupTestData() { /* ... */ }
};
}
class ClassNameTests : public ::testing::Test
{
protected:
void SetUp() override
{
// Setup before each test
}
void TearDown() override
{
// Cleanup after each test
}
// Test fixtures
ClassName instance;
};
TEST_F (ClassNameTests, ConstructorInitializesCorrectly)
{
EXPECT_TRUE (instance.isValid());
EXPECT_EQ (0, instance.getValue());
}
TEST (ClassNameTests, StaticMethodBehavesCorrectly)
{
auto result = ClassName::staticMethod();
EXPECT_NE (nullptr, result.get());
}- Check existing patterns in similar modules first
- Use YUP conventions for similar functionality
- Prefer composition over inheritance
- Make classes small and focused (single responsibility)
- Use const-correctness throughout
- Do not leak internal details
- Follow the open-closed principle
- Always provide extensive and useful doxygen documentation for public APIs
- Never assume we use plain JUCE7 functionality, always check APIs as they might have evolved
- Test primarily public interfaces only
- Cover normal, edge, and error cases
- Use descriptive test names (e.g.,
ReturnsNullForInvalidInput) - Group related tests in test fixtures
- Keep tests independent and deterministic
- Never Use C or C++ macros (like M_PI) use yup alternatives
- Maintain existing API contracts
- Follow established module patterns
- Preserve platform-specific code organization
- Update tests accordingly
- Consider performance implications
- Keep API usage simple and effective
#if YUP_WINDOWS
// Windows implementation
#elif YUP_MAC
// macOS implementation
#elif YUP_IOS
// iOS implementation
#elif YUP_LINUX
// Linux implementation
#elif YUP_ANDROID
// Android implementation
#elif YUP_WASM
// WebAssembly implementation
#endif// Use YUP Result or ResultValue<T> for operations that can fail
yup::Result performOperation()
{
if (preconditionFailed)
return yup::Result::fail ("Precondition not met");
return yup::Result::ok();
}
yup::ResultValue<int> maybeGetInteger()
{
if (preconditionFailed)
return yup::ResultValue<int>::fail ("Precondition not met");
return 1;
}
// Use assertions for programming errors
void publicMethod (int value)
{
jassert (value >= 0); // Debug builds only
if (value < 0)
return; // Graceful handling in release
}Before suggesting code, verify:
- Proper file header with correct copyright
- Allman-style braces throughout
- Consistent naming conventions
- Proper include order and guards
- Const-correctness whenever applicable
- Prefer flatter code and early exits over overly indented code
- Aim at simplifying and removing duplicated code, prefer removing rather than adding
- When changing implementation, don't copy it and change it, adapt the existing or remove the old one once the new is in place and working
- Platform-specific code properly guarded
- Proper TDD and ensure tests cover new functionality
- No memory leaks (prefer RAII/smart pointers)
- Thread safety considerations if applicable
- Documentation for public APIs
// Prefer RAII and smart pointers
class ResourceManager
{
private:
std::unique_ptr<Resource> resource;
std::vector<std::shared_ptr<Item>> items;
};// Use yup::var for dynamic types
// Use std::optional for optional values
std::optional<int> findValue (const String& key);// Use yup::String for most string operations
void processText (const yup::String& text);
// Use std::string only when interfacing with non-YUP code- We use American english in YUP, so it's
centerand notcentred, orColorand notColour - Always check the available API in the Graphics class, don't assume we use JUCE Graphics classes
- Graphics primitives have a template
.to<float>method nottoFloat - Fonts are obtained via ApplicationTheme, don't try to instantiate fonts inline
This document should be referenced for every code generation, review, and suggestion task in the YUP project.