docs: add agent skill guides and update CMake build instructions
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
# Skill: Build uLib with Micromamba
|
||||
---
|
||||
trigger: always_on
|
||||
---
|
||||
|
||||
This skill provides instructions for building the uLib project using the micromamba environment.
|
||||
# Rule: Build uLib with Micromamba
|
||||
|
||||
This rule provides instructions for building the uLib project using the micromamba environment.
|
||||
|
||||
## Context
|
||||
- **Environment**: micromamba `uLib`
|
||||
@@ -14,26 +18,27 @@ This skill provides instructions for building the uLib project using the microma
|
||||
```bash
|
||||
export MAMBA_EXE="/home/share/micromamba/bin/micromamba"
|
||||
export MAMBA_ROOT_PREFIX="/home/share/micromamba"
|
||||
eval "$(/home/share/micromamba/bin/micromamba shell hook --shell bash)"
|
||||
export PRESET="clang-make"
|
||||
eval "$(${MAMBA_EXE} shell hook --shell bash)"
|
||||
micromamba activate uLib
|
||||
```
|
||||
|
||||
2. **Full Rebuild (if needed)**:
|
||||
If the `build` directory does not exist or a full reconfiguration is required:
|
||||
```bash
|
||||
conan profile detect --force
|
||||
conan install . --output-folder=build --build=missing
|
||||
cmake --preset conan-release
|
||||
conan install . --output-folder=build/${PRESET} --build=missing --profile=fast
|
||||
cmake --preset ${PRESET}
|
||||
cmake --build build/${PRESET} -j$(nproc)
|
||||
```
|
||||
|
||||
3. **Incremental Build**:
|
||||
Run the build command from the root directory, pointing to the `build` folder and using all cores.
|
||||
```bash
|
||||
cmake --build build -j$(nproc)
|
||||
cmake --build build/${PRESET} -j$(nproc)
|
||||
```
|
||||
|
||||
4. **Specific Target Build**:
|
||||
4. **Specific Target Build - gcompose**:
|
||||
To build a specific target (e.g., gcompose):
|
||||
```bash
|
||||
cmake --build build --target gcompose -j$(nproc)
|
||||
```
|
||||
cmake --build build/${PRESET} --target gcompose -j$(nproc)
|
||||
```
|
||||
49
.agents/skills/core_system.md
Normal file
49
.agents/skills/core_system.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Skill: Core Object & Property System
|
||||
|
||||
This skill defines the patterns for implementing and working with the `uLib` core object model.
|
||||
|
||||
## Context
|
||||
- **Base Class**: `uLib::Object`
|
||||
- **Property System**: `uLib::Property<T>`
|
||||
- **Registration**: All objects must register their properties for UI visibility and serialization.
|
||||
|
||||
## Implementation Patterns
|
||||
|
||||
### 1. Defining an Object
|
||||
Inherit from `uLib::Object` and use the `ULIB_PROPERTY` macro for members.
|
||||
```cpp
|
||||
class MyObject : public uLib::Object {
|
||||
public:
|
||||
ULIB_PROPERTY(double, Speed, 0.0)
|
||||
ULIB_PROPERTY(std::string, Description, "None")
|
||||
|
||||
MyObject() {
|
||||
// Required for property visibility in PropertyEditor
|
||||
ULIB_ACTIVATE_PROPERTIES(*this)
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### 2. Property Access
|
||||
Properties can be treated like their underlying types or accessed via `.Get()`/`.Set()`.
|
||||
```cpp
|
||||
obj.Speed = 10.5; // Triggers Updated() signal
|
||||
double s = obj.Speed; // Implicit conversion
|
||||
obj.Speed.SetRange(0.0, 100.0); // Setting metadata
|
||||
```
|
||||
|
||||
### 3. Serialization
|
||||
Implement `serialize` overloads for different archive types. Use `hrp` (Human Readable Property) to name fields.
|
||||
```cpp
|
||||
template <class ArchiveT>
|
||||
void serialize(ArchiveT &ar, const unsigned int version) {
|
||||
ar & boost::serialization::make_nvp("InstanceName", this->GetInstanceName());
|
||||
ar & boost::serialization::make_hrp("Speed", Speed, "m/s");
|
||||
}
|
||||
```
|
||||
|
||||
## Checklist
|
||||
- [ ] Inherit from `uLib::Object`.
|
||||
- [ ] Use `ULIB_PROPERTY` for members that should appear in the GUI.
|
||||
- [ ] Call `ULIB_ACTIVATE_PROPERTIES` in the constructor.
|
||||
- [ ] Implement `serialize` if persistence is required.
|
||||
39
.agents/skills/geant_simulation.md
Normal file
39
.agents/skills/geant_simulation.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Skill: HEP/Geant Simulation Rules
|
||||
|
||||
This skill provides instructions for developing the Geant4 simulation components within `uLib`.
|
||||
|
||||
## Context
|
||||
- **Domain Objects**: `Material`, `Solid`, `LogicalVolume`, `PhysicalVolume`.
|
||||
- **Integration**: `mutomGeant` library wraps Geant4 classes into `uLib::Object`s.
|
||||
|
||||
## Patterns
|
||||
|
||||
### 1. Adding a New Solid
|
||||
New solids must implement `GetPolyhedron()` to support VTK visualization.
|
||||
```cpp
|
||||
G4Polyhedron* MySolid::GetPolyhedron() const {
|
||||
// Return the tessellated representation of the Geant4 solid
|
||||
return m_G4Solid->GetPolyhedron();
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Physical Volume Hierarchy
|
||||
Maintain the relationship between `PhysicalVolume` and its parent `LogicalVolume`.
|
||||
```cpp
|
||||
auto* world = new LogicalVolume(worldSolid, worldMat);
|
||||
auto* detector = new PhysicalVolume(detectorLogic, world, "Detector1");
|
||||
detector->SetPosition({0, 0, 100}); // Relative to parent
|
||||
```
|
||||
|
||||
### 3. Transformation Synchronization
|
||||
Use the centralized `TRS` object to manage position and rotation. Synchronization with Geant4's internal stores should be reactive.
|
||||
- Listen to `Object::Updated` on the `Solid` or `PhysicalVolume`.
|
||||
- Update the underlying `G4VPhysicalVolume` position/rotation.
|
||||
|
||||
## Material Management
|
||||
Use the `Matter` class to manage Geant4 materials. Ensure materials are registered in the `G4NistManager` or custom material store if needed.
|
||||
|
||||
## Checklist
|
||||
- [ ] Does the solid implement `GetPolyhedron()`?
|
||||
- [ ] Are parents correctly assigned in `PhysicalVolume` constructors?
|
||||
- [ ] Is the `TRS` object used for all spatial transformations?
|
||||
40
.agents/skills/memory_management.md
Normal file
40
.agents/skills/memory_management.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# Skill: Memory Management & Object Lifecycle
|
||||
|
||||
This skill provides guidelines for managing memory safely within the `uLib` framework to prevent memory corruption and leaks.
|
||||
|
||||
## Context
|
||||
- **Ownership**: `ObjectsContext` typically owns its children.
|
||||
- **Shared Access**: Use `SmartPointer<T>` for objects shared across multiple systems (e.g., Geant4 and VTK).
|
||||
- **Core Principle**: Avoid manual `delete` on objects managed by the framework.
|
||||
|
||||
## Patterns
|
||||
|
||||
### 1. Context Ownership
|
||||
When an object is added to an `ObjectsContext`, it is managed by that context.
|
||||
```cpp
|
||||
auto* context = new ObjectsContext();
|
||||
auto* obj = new MyObject();
|
||||
context->AddObject(obj);
|
||||
// Do NOT delete obj; it will be deleted when context is destroyed.
|
||||
```
|
||||
|
||||
### 2. Smart Pointers
|
||||
Use `SmartPointer<T>` for resources like `Material` or `Solid` that are used by both domain logic and external engines (Geant4).
|
||||
```cpp
|
||||
uLib::SmartPointer<Material> mat = new Material("Lead");
|
||||
solid->SetMaterial(mat); // Shared ownership
|
||||
```
|
||||
|
||||
### 3. Geant4 Object Safety
|
||||
Geant4 often takes ownership of certain objects (like `G4VPhysicalVolume`). When wrapping these:
|
||||
- Ensure the wrapper doesn't double-free the Geant4-owned pointer.
|
||||
- Use `recursion_guard` if synchronizing transformations between `uLib::Object` and Geant4 volumes to prevent signal loops.
|
||||
|
||||
## Debugging Memory Issues
|
||||
- **SIGABRT (invalid pointer)**: Usually caused by deleting an object that was already managed (and deleted) by an `ObjectsContext` or `SmartPointer`.
|
||||
- **Leaks**: Check if objects were created but never added to a context or wrapped in a `SmartPointer`.
|
||||
|
||||
## Checklist
|
||||
- [ ] Are objects added to an `ObjectsContext`?
|
||||
- [ ] Is `SmartPointer` used for shared resources?
|
||||
- [ ] Is there a risk of double-freeing Geant4-managed pointers?
|
||||
34
.agents/skills/signal_bridge.md
Normal file
34
.agents/skills/signal_bridge.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Skill: Multi-System Signaling (uLib ↔ Qt)
|
||||
|
||||
This skill manages the coexistence of `uLib::Object` signals and Qt's `Q_OBJECT` signaling system.
|
||||
|
||||
## Context
|
||||
- **uLib Signals**: Used for domain logic and data changes (`uLib::Object::connect`).
|
||||
- **Qt Signals**: Used for UI events, widgets, and application-level control flow (`QObject::connect`).
|
||||
|
||||
## Patterns
|
||||
|
||||
### 1. Bridging Logic
|
||||
When a domain change needs to trigger a UI update, use a wrapper or a direct connection if the widget has access to the `uLib::Object`.
|
||||
```cpp
|
||||
// In a Qt Widget
|
||||
uLib::Object::connect(domainObj, &Object::Updated, [this]() {
|
||||
this->update(); // Trigger Qt repaint
|
||||
});
|
||||
```
|
||||
|
||||
### 2. Selection Flow
|
||||
Selection usually starts in the VTK Viewport (Qt) and flows to the domain context.
|
||||
1. `QViewport` emits `prop3dSelected(Prop3D*)` (Qt signal).
|
||||
2. `MainPanel` catches it and calls `contextPanel->selectObject(p->GetContent())`.
|
||||
3. `ContextPanel` updates the tree view and property editors.
|
||||
|
||||
### 3. Connection Hygiene
|
||||
- Use `uLib::Object::connect` for everything involving `uLib::Property` changes.
|
||||
- Use Qt `connect` for button clicks, menu actions, and window events.
|
||||
- Be careful with lambda captures; ensure the captured object is still alive or use weak pointers if necessary.
|
||||
|
||||
## Checklist
|
||||
- [ ] Is the correct signaling system being used for the task?
|
||||
- [ ] Are capture groups in lambdas safe?
|
||||
- [ ] Does selection flow correctly between the 3D view and the tree view?
|
||||
34
.agents/skills/testing_guide.md
Normal file
34
.agents/skills/testing_guide.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Skill: Standardized Testing & Validation
|
||||
|
||||
This skill provides the standard workflow for testing and validating changes in the `uLib` project.
|
||||
|
||||
## Context
|
||||
- **Tooling**: `ctest` and direct execution of test binaries in the `build/` directory.
|
||||
- **Location**: Test binaries are typically located in `build/src/*/testing/` or `build/Testing/`.
|
||||
|
||||
## Workflow
|
||||
|
||||
### 1. Running All Tests
|
||||
From the root directory:
|
||||
```bash
|
||||
ctest --test-dir build/clang-make --output-on-failure
|
||||
```
|
||||
|
||||
### 2. Running Component Tests
|
||||
Run specific categories of tests:
|
||||
- **Core**: `./build/clang-make/src/Core/testing/CoreTest`
|
||||
- **Math**: `./build/clang-make/src/Math/testing/MathVectorTest`
|
||||
- **Geant**: `./build/clang-make/src/HEP/Geant/testing/GeantApp`
|
||||
- **VTK**: `./build/clang-make/src/Vtk/testing/vtkViewerTest`
|
||||
|
||||
### 3. Debugging a Failing Test
|
||||
Run the binary directly through `gdb` or `valgrind` (if available):
|
||||
```bash
|
||||
gdb --args ./build/clang-make/src/Core/testing/ObjectWrapperTest
|
||||
```
|
||||
|
||||
## Validation Checklist for New Features
|
||||
- [ ] Does `ctest` pass globally?
|
||||
- [ ] If changing visualization, does `vtkViewerTest` show the correct results?
|
||||
- [ ] If changing Geant logic, does `GeantApp` run without memory aborts?
|
||||
- [ ] Are new tests added to the appropriate `CMakeLists.txt`?
|
||||
52
.agents/skills/vtk_visualization.md
Normal file
52
.agents/skills/vtk_visualization.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# Skill: VTK Visualization Pipeline
|
||||
|
||||
This skill defines how to bridge domain objects with the VTK 3D visualization layer.
|
||||
|
||||
## Context
|
||||
- **Wrapper**: `Prop3D` (wraps a `vtkProp`).
|
||||
- **Mapping**: `Viewport` maintains `m_ObjectToProp3D` for synchronization.
|
||||
- **GUI Integration**: `QViewport` handles Qt events and selection signals.
|
||||
|
||||
## Implementation Patterns
|
||||
|
||||
### 1. Creating a Prop3D
|
||||
A `Prop3D` should wrap a domain object and update its visual state when the object changes.
|
||||
```cpp
|
||||
class MyProp3D : public Prop3D {
|
||||
public:
|
||||
MyProp3D(MyObject* obj) : Prop3D(obj) {
|
||||
// Connect domain updates to visual refreshes
|
||||
uLib::Object::connect(obj, &Object::Updated, [this]() { this->SyncFromObject(); });
|
||||
|
||||
// Expose properties to the VTK side-panel
|
||||
ULIB_ACTIVATE_DISPLAY_PROPERTIES(*this)
|
||||
}
|
||||
|
||||
void SyncFromObject() {
|
||||
// Update VTK actors/mappers from MyObject's properties
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### 2. Display Properties
|
||||
Use `serialize_display` to choose which properties of the domain object or the `Prop3D` itself are visible in the sliding "Display Properties" panel in `gcompose`.
|
||||
```cpp
|
||||
void serialize_display(Archive::display_properties_archive &ar) {
|
||||
ar & boost::serialization::make_hrp("Opacity", m_Opacity);
|
||||
ar & boost::serialization::make_hrp("Wireframe", m_Wireframe);
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Transformation Sync (TRS)
|
||||
Always synchronize the object's `trs` (Translate, Rotate, Scale) with the VTK actor's user transform.
|
||||
```cpp
|
||||
void UpdateTransform() {
|
||||
auto matrix = GetContent()->GetTransform().GetMatrix();
|
||||
m_Actor->SetUserMatrix(uLib::ToVtkMatrix(matrix));
|
||||
}
|
||||
```
|
||||
|
||||
## Checklist
|
||||
- [ ] Does the `Prop3D` connect to the object's `Updated()` signal?
|
||||
- [ ] Are `ULIB_ACTIVATE_DISPLAY_PROPERTIES` and `serialize_display` implemented?
|
||||
- [ ] Is the transformation (TRS) correctly mapped to the VTK actor?
|
||||
Reference in New Issue
Block a user