Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
Language: Cpp
BasedOnStyle: Google

IncludeBlocks: Preserve
IndentPPDirectives: AfterHash
InsertNewlineAtEOF: On
48 changes: 48 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
Checks:
- core*
- cppcoreguidelines-*
- modernize*
- bugprone-*
- performance-*
- readability-*
- portability-*
- clang-diagnostic-*
- misc-*
- google-build-namespaces
- google-build-using-namespace
- google-default-arguments
- google-explicit-constructor
- google-readability-casting
- -modernize-use-trailing-return-type
- -modernize-use-nodiscard
- -modernize-concat-nested-namespaces
- -modernize-use-default-member-init
- -modernize-use-ranges
- -modernize-use-designated-initializers
- -misc-non-private-member-variables-in-classes
- -misc-use-internal-linkage
- -misc-use-anonymous-namespace
- -misc-include-cleaner
- -misc-static-assert
- -cppcoreguidelines-pro-type-vararg
- -cppcoreguidelines-non-private-member-variables-in-classes
- -cppcoreguidelines-special-member-functions
- -cppcoreguidelines-pro-type-reinterpret-cast
- -cppcoreguidelines-pro-type-union-access
- -cppcoreguidelines-pro-bounds-pointer-arithmetic
- -cppcoreguidelines-pro-type-member-init
- -cppcoreguidelines-owning-memory
- -cppcoreguidelines-avoid-const-or-ref-data-members
- -cppcoreguidelines-avoid-c-arrays
- -cppcoreguidelines-macro-usage
- -cppcoreguidelines-pro-bounds-constant-array-index
- -cppcoreguidelines-pro-bounds-array-to-pointer-decay
- -cppcoreguidelines-pro-type-static-cast-downcast
- -bugprone-easily-swappable-parameters
- -bugprone-assert-side-effect
- -readability-named-parameter
- -readability-identifier-length

CheckOptions:
performance-move-const-arg.CheckTriviallyCopyableMove: false
cppcoreguidelines-avoid-do-while.IgnoreMacros: true
107 changes: 107 additions & 0 deletions .github/workflows/ci-cd-tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# This starter workflow is for a CMake project running on multiple platforms. There is a different starter workflow if you just want a single platform.
# See: https://github.com/actions/starter-workflows/blob/main/ci/cmake-single-platform.yml
name: CMake

on:
push:
branches: ["main"]
pull_request:
branches: ["main"]

#Allows you to start workflow manually from the actions tab in the interface github.com
workflow_dispatch:

jobs:
#CMake buildss
build:
name: ${{ matrix.config.name }}
runs-on: ${{ matrix.config.os }}
defaults:
run:
shell: ${{ matrix.config.shell }} {0}

strategy:
# Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable.
fail-fast: false

matrix:
config:
- {
name: "Windows MSVC x64",
os: windows-latest,
shell: "powershell",
cmake_args: '-G "Visual Studio 18 2026" -A x64',
}
- {
name: "Windows MSVC x86",
os: windows-latest,
shell: "powershell",
cmake_args: '-G "Visual Studio 18 2026" -A Win32',
}
- {
name: "Windows MinGW",
os: windows-latest,
shell: "msys2",
cmake_args: "-GNinja",
}
- {
name: "Ubuntu GCC",
os: ubuntu-latest,
shell: "bash",
cmake_args: '-G "Unix Makefiles" -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++',
jobs_count: 4,
}
- {
name: "Ubuntu Clang",
os: ubuntu-latest,
shell: "bash",
cmake_args: '-G "Unix Makefiles" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++',
jobs_count: 4,
}
- {
name: "macOS Clang",
os: macos-latest,
shell: "bash",
cmake_args: '-G "Unix Makefiles" -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++',
jobs_count: 4,
}

steps:
- name: Set Windows enviroment
if: ${{ (matrix.config.os == 'windows-latest' && matrix.config.shell == 'powershell') }}
uses: ilammy/msvc-dev-cmd@v1

- name: Set MinGW enviroment
if: ${{ (matrix.config.os == 'windows-latest' && matrix.config.shell == 'msys2') }}
uses: msys2/setup-msys2@v2
with:
msystem: MINGW64
install: >-
git
base-devel
pacboy: >-
cmake:p
ninja:p
gcc:p
update: true

- uses: actions/checkout@v4
with:
submodules: recursive

# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
- name: Configure CMake
run: >
cmake -B build
${{ matrix.config.cmake_args }}
-S ./

- name: Build
# Build your program with the given configuration. Note that --config is needed because the default Windows generator is a multi-config generator (Visual Studio generator).
run: cmake --build build --config Release --parallel ${{ matrix.config.jobs_count }}

- name: Test
# Execute tests defined by the CMake configuration. Note that --build-config is needed because the default Windows generator is a multi-config generator (Visual Studio generator).
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: ctest --test-dir build --build-config Release --output-on-failure --parallel
70 changes: 70 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Aether Objects Guide

## Library

`aether-objects` is a C++20 static library for persistent object graphs. It
provides object identities, domains, registration, serialization and persistence
interfaces, reference-counted pointers, and RAM or standard-filesystem storage.
Public headers are installed from `src/aether-objects`, and the library target is
`aether-objects` (alias `aether::objects`).

## Coding Style and Contributor Agreement

- Follow the repository `.clang-format` configuration (Google C++ style) and
format repository-owned C++ sources and headers before submitting changes.
- Preserve the C++20 language level, dependency versions, public include root,
target identity, and installation layout unless a change explicitly requires
them.
- Public header guards use `AETHER_OBJECTS_<PATH>_H_`, derived from the path
beneath `src/aether-objects`; closing comments must match the guard.
- Keep includes minimal. Preserve intentional exported or transitive includes
with their IWYU annotations.
- Raw pointers express nullable or non-owning access, never ownership. Use
`Ptr<T>`, `PtrView<T>`, and `ObjPtr<T>` according to their established
lifetime contracts.
- Keep serialization formats, object IDs, ownership and reference tracking,
persistence behavior, and threading behavior compatible.
- Use `LOG_` macros for local debug logging.
- Manage dependencies through CPM; do not vendor, edit, or copy dependency
sources without explicit approval.

## Modules

### Pointer (`ptr`)

`Ptr<T>` supplies reference-counted ownership with reference-tree tracking to
reclaim cycles. `PtrView<T>` is a nullable non-owning view and must be locked or
loaded before retaining or dereferencing its object. Avoid unnecessary `Ptr`
copies because releasing one can traverse the reference graph.

### Objects and Domains (`obj`)

Objects provide durable IDs, versions, registration, typed object pointers, and
domain membership. Domains coordinate object lookup, loading, saving, and
registration through the persistence interface. A valid `ObjPtr` can designate
an unloaded object; load it and retain the loaded pointer while using it.

### Domain Storage (`domain_storage`)

`IDomainStorage` defines persistence operations used by domains. The available
implementations are in-memory RAM storage and standard-filesystem storage.
Preserve their serialized representation and error behavior.

### Logging (`log.h`)

`LOG_` is the local debug logging boundary. It writes formatted messages in
debug builds unless `AE_NO_DEBUG_LOG` disables it, and compiles away in release
builds. Preserve this behavior.

## Tests and Dependencies

- Tests use Unity and are organized under `tests/` by subsystem. Test suites
expose a global `int test_<suite>()` entry and use the existing naming style.
- Configure builds with CMake in a separate build directory. Build and run
configured tests with `cmake --build <build_dir> --parallel` and
`ctest --test-dir <build_dir> --output-on-failure`.
- Use the configured build's `compile_commands.json` for changed-file
clang-tidy analysis. Treat findings that require public API, ownership,
persistence, threading, or platform changes as requiring review.
- Generated files, build outputs, and third-party dependency sources are not
formatted or edited.
92 changes: 92 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Copyright 2026 Aethernet Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

cmake_minimum_required(VERSION 3.16)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

project(aether-objects VERSION 1.0.0 LANGUAGES CXX)

# define is the project is the current root project
# root project builds tests and defines installation targets by default
if( ${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME})
set(IS_ROOT_PROJECT ON)
else()
set(IS_ROOT_PROJECT OFF)
endif()

option(AE_BUILD_TESTS "Build tests" ${IS_ROOT_PROJECT} )
option(AE_INSTALL "Install aether-objects library" ${IS_ROOT_PROJECT} )
option(AE_NO_DEBUG_LOG "Do not print debug logs" !${IS_ROOT_PROJECT} )

include(cmake/CPM.cmake)

CPMAddPackage(
NAME aether-miscpp
GIT_REPOSITORY "https://github.com/aethernetio/aether-miscpp.git"
GIT_TAG "main"
OPTIONS "AE_INSTALL ${AE_INSTALL}" "AE_BUILD_TESTS ${AE_BUILD_TESTS}"
EXCLUDE_FROM_ALL FALSE
)


add_library(${PROJECT_NAME} STATIC)
add_library(aether::objects ALIAS ${PROJECT_NAME})

target_sources(${PROJECT_NAME} PRIVATE
src/aether-objects/ptr/ptr.cpp
src/aether-objects/ptr/ptr_view.cpp
src/aether-objects/ptr/ref_tree.cpp

src/aether-objects/obj/domain.cpp
src/aether-objects/obj/obj.cpp
src/aether-objects/obj/obj_id.cpp
src/aether-objects/obj/obj_ptr_base.cpp
src/aether-objects/obj/registry.cpp

src/aether-objects/domain_storage/file_system_std_storage.cpp
src/aether-objects/domain_storage/ram_domain_storage.cpp
)

target_include_directories(${PROJECT_NAME} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/src>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)

target_link_libraries(${PROJECT_NAME} PUBLIC aether::miscpp)

if(AE_NO_DEBUG_LOG)
target_compile_definitions(${PROJECT_NAME} PUBLIC "AE_NO_DEBUG_LOG=1")
endif()

if(AE_BUILD_TESTS)
enable_testing()
add_subdirectory("tests")
endif()

if(AE_INSTALL)
include(GNUInstallDirs)

# define the installation target, install lib headers and export cmake config
install(TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}Targets
)

install(DIRECTORY src/aether-objects DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

install(EXPORT ${PROJECT_NAME}Targets
FILE ${PROJECT_NAME}Targets.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
)
endif()
Loading
Loading