From f042e07ee75dc72c615d0925023142c3f6f91f7a Mon Sep 17 00:00:00 2001 From: zongor Date: Wed, 23 Jul 2025 21:58:27 -0400 Subject: [PATCH] init --- .ccls | 6 +++ .gitignore | 105 ++++++++++++++++++++++++++++++++++++++ Makefile | 36 +++++++++++++ README.org | 123 +++++++++++++++++++++++++++++++++++++++++++++ src/main.cpp | 19 +++++++ src/ring_buffer.h | 51 +++++++++++++++++++ src/simulation.cpp | 36 +++++++++++++ src/simulation.h | 21 ++++++++ src/vec3.h | 45 +++++++++++++++++ 9 files changed, 442 insertions(+) create mode 100644 .ccls create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.org create mode 100644 src/main.cpp create mode 100644 src/ring_buffer.h create mode 100644 src/simulation.cpp create mode 100644 src/simulation.h create mode 100644 src/vec3.h diff --git a/.ccls b/.ccls new file mode 100644 index 0000000..203ba38 --- /dev/null +++ b/.ccls @@ -0,0 +1,6 @@ +%compile_flags +-Isrc +-std=c++23 +-Wall +-Wextra +-O2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..622b816 --- /dev/null +++ b/.gitignore @@ -0,0 +1,105 @@ +# -*- mode: gitignore; -*- +*~ +\#*\# +/.emacs.desktop +/.emacs.desktop.lock +*.elc +auto-save-list +tramp +.\#* + +# Org-mode +.org-id-locations +*_archive + +# flymake-mode +*_flymake.* + +# eshell files +/eshell/history +/eshell/lastdir + +# elpa packages +/elpa/ + +# reftex files +*.rel + +# AUCTeX auto folder +/auto/ + +# cask packages +.cask/ +dist/ + +# Flycheck +flycheck_*.el + +# server auth directory +/server/ + +# projectiles files +.projectile + +# directory configuration +.dir-locals.el +.ccls-cache/ + +# network security +/network-security.data + +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +build/ +.ccls-cache/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6afbe66 --- /dev/null +++ b/Makefile @@ -0,0 +1,36 @@ +CXX := g++ +SRC_DIR := src +BUILD_DIR := build +TARGET := $(BUILD_DIR)/holst +STD ?= c++23 + +CXXFLAGS := -std=$(STD) -Wall -Wextra -O2 -Iinclude +LDFLAGS := + +# Source files and object files +SRCS := $(shell find $(SRC_DIR) -name '*.cpp') +OBJS := $(patsubst $(SRC_DIR)/%.cpp,$(BUILD_DIR)/%.o,$(SRCS)) + +# Default target +all: $(TARGET) + +# Link final executable +$(TARGET): $(OBJS) + @mkdir -p $(dir $@) + $(CXX) $(OBJS) -o $@ $(LDFLAGS) + +# Compile source files +$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp + @mkdir -p $(dir $@) + $(CXX) $(CXXFLAGS) -c $< -o $@ + +# Clean build files +clean: + rm -rf $(BUILD_DIR) + +# Print configuration (debugging) +print: + @echo "Compiler: $(CXX)" + @echo "Standard: $(STD)" + @echo "Sources: $(SRCS)" + @echo "Objects: $(OBJS)" diff --git a/README.org b/README.org new file mode 100644 index 0000000..c22d38b --- /dev/null +++ b/README.org @@ -0,0 +1,123 @@ +#+TITLE: Holst +#+AUTHOR: Charles Kralapp +#+OPTIONS: toc:nil num:nil + +This project combines a raytracer and an N-body solar system simulation to learn modern C++ (C++03โ€“C++23) through practical implementation. + +* โœ… Project Goals +- [ ] Simulate solar system using an N-body gravitational algorithm. +- [ ] Implement a raytracer for rendering bodies and backgrounds. +- [ ] Learn and demonstrate features from every major C++ standard. +- [ ] Use open-source tooling: GNU Emacs, Org-mode, GCC, GNU Make. + +* ๐Ÿš€ Toolchain +- Editor: Emacs + Org Mode +- Compiler: GCC/g++ +- Build System: GNU Make (no CMake) +- Version Control: Git (optional but recommended) + +* ๐Ÿ“š C++ Learning Checklist + +** C++03 (Baseline) +- [ ] Classes & Constructors +- [ ] Operator Overloading (`+`, `*`, `[]`) +- [ ] Manual memory management (`new` / `delete`) +- [ ] STL containers: `std::vector`, `std::map` +- [ ] Function overloading +- [ ] Templates (vector math, utility classes) +- [ ] Pointers, references, and const correctness +- [ ] Namespaces +- [ ] RAII pattern with destructors +- [ ] `std::string`, `std::stringstream` + +** C++11 (Modern C++ begins) +- [ ] `auto` type deduction +- [ ] Range-based for loops +- [ ] Lambda expressions +- [ ] `nullptr` +- [ ] `enum class` +- [ ] Smart pointers: `std::unique_ptr`, `std::shared_ptr` +- [ ] `override`, `final` specifiers +- [ ] `move` semantics and rvalue references +- [ ] `std::array`, `std::tuple` +- [ ] Thread support: `std::thread` + +** C++14 (Polish & convenience) +- [ ] Generic lambdas (`auto` in lambda parameters) +- [ ] `decltype(auto)` and improved return type inference +- [ ] `std::make_unique` +- [ ] Binary literals and digit separators (`0b1010`, `1'000'000`) +- [ ] Relaxed constexpr functions +- [ ] Using `auto` in lambda captures + +** C++17 (Simpler and more expressive) +- [ ] Structured bindings (`auto [x, y] = foo();`) +- [ ] `if constexpr` +- [ ] `std::optional` +- [ ] `std::variant`, `std::any` +- [ ] Inline variables +- [ ] `std::string_view` +- [ ] Filesystem support (`std::filesystem`) +- [ ] Parallel algorithms (`std::execution`) + +** C++20 (Huge leap forward) +- [ ] Concepts (`template requires`) +- [ ] Ranges library: views, filters, transforms +- [ ] `consteval` / `constinit` +- [ ] Coroutines (`co_yield`, `co_return`) +- [ ] Calendar and time utilities (`std::chrono::year_month_day`) +- [ ] Modules (if supported by compiler/toolchain) +- [ ] Expanded constexpr support (e.g., STL algorithms) + +** C++23 (Final polish) +- [ ] `std::expected` (like Rust's Result) +- [ ] `std::mdspan` for multidimensional array views +- [ ] `explicit` lambdas +- [ ] More constexpr in the standard library +- [ ] `[[assume]]` attribute +- [ ] Improved ranges (e.g., `views::repeat`, `zip`) + +* ๐Ÿ›  Project Milestones (use standards progressively) + +** Milestone 1: Base Simulation Engine +- [ ] Build N-body simulation using raw pointers (C++03) +- [ ] Add `Vector3` class, `Body` class +- [ ] Use `std::vector` and manual memory management + +** Milestone 2: Modernization Pass 1 +- [ ] Convert raw pointers to smart pointers (C++11) +- [ ] Add lambda-driven physics update loop +- [ ] Use `enum class` for material types + +** Milestone 3: Raytracer Core +- [ ] Add ray-object intersection logic +- [ ] Use `std::optional` for hit results (C++17) +- [ ] Structured bindings for clean code + +** Milestone 4: Optimization Pass +- [ ] Parallel rendering with `std::execution::par` (C++17) +- [ ] Use ranges and views to process pixels (C++20) + +** Milestone 5: Error Handling & Final Touches +- [ ] Use `std::expected` for config file errors or simulation errors (C++23) +- [ ] Add diagnostics/metrics via coroutines or logging views +- [ ] Final cleanup using `consteval`, `mdspan`, or advanced features + +* ๐Ÿงช Testing Ideas +- [ ] Unit tests for vector math and physics (can use C++11 `assert`) +- [ ] Visual verification of orbits and raytraced scene +- [ ] Compare numerical stability over long time steps + +* ๐Ÿ“‚ Directory Layout (suggested) +#+BEGIN_SRC +project-root/ +โ”œโ”€โ”€ Makefile +โ”œโ”€โ”€ README.org (this file) +โ””โ”€โ”€โ”€ src/ + โ”œโ”€โ”€ main.cpp + โ”œโ”€โ”€ vec3.cpp / .h + โ”œโ”€โ”€ body.cpp / .h + โ””โ”€โ”€โ”€ raytracer/ + โ””โ”€โ”€ ray.cpp / .h ... +#+END_SRC + diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..fc8a8a8 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,19 @@ +#include "simulation.h" +#include +#include + +int main() { + auto state = std::make_shared(); + state->positions.push_back(Vec3(1.0, 2.0, 3.0)); + + std::thread sim(simulation_loop, state); + std::thread render(render_loop); + + std::this_thread::sleep_for(std::chrono::seconds(2)); + running = false; + + sim.join(); + render.join(); + + return 0; +} diff --git a/src/ring_buffer.h b/src/ring_buffer.h new file mode 100644 index 0000000..dfa0064 --- /dev/null +++ b/src/ring_buffer.h @@ -0,0 +1,51 @@ +#ifndef RING_BUFFER_H +#define RING_BUFFER_H + +#include +#include +#include + +template +class RingBuffer { + static_assert((Capacity & (Capacity - 1)) == 0, "Capacity must be power of 2"); + +private: + std::array buffer; + std::atomic head = 0; // write index + std::atomic tail = 0; // read index + +public: + bool push(const T& item) { + size_t current_head = head.load(std::memory_order_relaxed); + size_t next_head = (current_head + 1) & (Capacity - 1); + + if (next_head == tail.load(std::memory_order_acquire)) { + return false; // buffer full + } + + buffer[current_head] = item; + head.store(next_head, std::memory_order_release); + return true; + } + + bool pop(T& item) { + size_t current_tail = tail.load(std::memory_order_relaxed); + if (current_tail == head.load(std::memory_order_acquire)) { + return false; // buffer empty + } + + item = buffer[current_tail]; + tail.store((current_tail + 1) & (Capacity - 1), std::memory_order_release); + return true; + } + + bool empty() const { + return head.load() == tail.load(); + } + + bool full() const { + return ((head.load() + 1) & (Capacity - 1)) == tail.load(); + } +}; + +#endif diff --git a/src/simulation.cpp b/src/simulation.cpp new file mode 100644 index 0000000..29d4bd9 --- /dev/null +++ b/src/simulation.cpp @@ -0,0 +1,36 @@ +#include "simulation.h" +#include +#include +#include + +std::atomic running(true); +RingBuffer snapshot_buffer; + +void simulation_loop(std::shared_ptr state) { + Vec3 velocity(0.01, 0.02, 0.03); + + while (running) { + // Update position + for (auto &p : state->positions) { + p += velocity; + } + + // Push latest position to buffer + if (!snapshot_buffer.push(state->positions[0])) { + std::cerr << "Snapshot buffer full, dropping frame\n"; + } + } +} + +void render_loop() { + Vec3 latest; + + while (running) { + while (snapshot_buffer.pop(latest)) { + std::cout << "[Render] "; + latest.print(); + } + // Optional: add very short pause to avoid spinning too fast + std::this_thread::yield(); // cooperative multitasking + } +} diff --git a/src/simulation.h b/src/simulation.h new file mode 100644 index 0000000..953b24c --- /dev/null +++ b/src/simulation.h @@ -0,0 +1,21 @@ +#ifndef SIMULATION_H +#define SIMULATION_H + +#include +#include +#include +#include +#include "vec3.h" +#include "ring_buffer.h" + +struct SimulationState { + std::vector positions; +}; + +extern std::atomic running; +extern RingBuffer snapshot_buffer; + +void simulation_loop(std::shared_ptr state); +void render_loop(); + +#endif diff --git a/src/vec3.h b/src/vec3.h new file mode 100644 index 0000000..50caba2 --- /dev/null +++ b/src/vec3.h @@ -0,0 +1,45 @@ +#ifndef VEC3_H +#define VEC3_H + +#include +#include + +class Vec3 { + std::array data; + +public: + // Constructors + Vec3() = default; + Vec3(double x, double y, double z) : data{x, y, z} {} + + // Named accessors (mutable) + double& x() { return data[0]; } + double& y() { return data[1]; } + double& z() { return data[2]; } + + // Named accessors (const) + double x() const { return data[0]; } + double y() const { return data[1]; } + double z() const { return data[2]; } + + // Arithmetic operators + friend Vec3 operator+(const Vec3& a, const Vec3& b) { + return Vec3(a.x() + b.x(), + a.y() + b.y(), + a.z() + b.z()); + } + + Vec3& operator+=(const Vec3& other) { + x() += other.x(); + y() += other.y(); + z() += other.z(); + return *this; + } + + // Debug print + void print() const { + std::cout << "(" << x() << ", " << y() << ", " << z() << ")\n"; + } +}; + +#endif // VEC3_H