diff --git a/.github/workflows/ci-cd-multi-platforms.yml b/.github/workflows/ci-cd-multi-platforms.yml index fb95e9cf..87ab87e7 100644 --- a/.github/workflows/ci-cd-multi-platforms.yml +++ b/.github/workflows/ci-cd-multi-platforms.yml @@ -30,38 +30,28 @@ jobs: name: "Windows MSVC x64", os: windows-latest, shell: "powershell", - generator: "Visual Studio 18 2026", - arch: "x64", - cc: "cl", - cxx: "cl", + cmake_args: '-G "Visual Studio 18 2026" -A x64 -DCMAKE_TOOLCHAIN_FILE=./toolchain/optmization-options-msvc.toolchain', initial_cache: ".github/workflows/windows_msvc_x64_initial_cache.txt", } - { name: "Windows MSVC x86", os: windows-latest, shell: "powershell", - generator: "Visual Studio 18 2026", - arch: "Win32", - cc: "cl", - cxx: "cl", + cmake_args: '-G "Visual Studio 18 2026" -A Win32 -DCMAKE_TOOLCHAIN_FILE=./toolchain/optmization-options-msvc.toolchain', initial_cache: ".github/workflows/windows_msvc_x86_initial_cache.txt", } - { name: "Windows MinGW", os: windows-latest, shell: "msys2", - generator: "Ninja", - cc: "gcc", - cxx: "g++", + cmake_args: "-GNinja -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_TOOLCHAIN_FILE=./toolchain/optmization-options-mingw.toolchain", initial_cache: ".github/workflows/windows_mingw_initial_cache.txt", } - { name: "Ubuntu GCC", os: ubuntu-latest, shell: "bash", - generator: "Unix Makefiles", - cc: "gcc", - cxx: "g++", + cmake_args: '-G "Unix Makefiles" -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_TOOLCHAIN_FILE=./toolchain/optmization-options-gnu-clang.toolchain', jobs_count: 4, initial_cache: ".github/workflows/linux_initial_cache.txt", } @@ -69,9 +59,7 @@ jobs: name: "macOS Clang", os: macos-latest, shell: "bash", - generator: "Unix Makefiles", - cc: "clang", - cxx: "clang++", + cmake_args: '-G "Unix Makefiles" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_TOOLCHAIN_FILE=./toolchain/optmization-options-apple.toolchain', jobs_count: 4, initial_cache: ".github/workflows/macos_initial_cache.txt", } @@ -81,12 +69,12 @@ jobs: - { name: "Sodium", user_config: "./config/user_config_sodium.h" } steps: - - name: Set Windows enviroment - if: ${{ (matrix.config.os == 'windows-latest' && matrix.config.cc == 'cl') }} + - name: Set Windows environment + 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.cc == 'gcc') }} + - name: Set MinGW environment + if: ${{ (matrix.config.os == 'windows-latest' && matrix.config.shell == 'msys2') }} uses: msys2/setup-msys2@v2 with: msystem: MINGW64 @@ -108,10 +96,7 @@ jobs: - name: Configure CMake run: > cmake -B build - -G "${{ matrix.config.generator }}" - -A "${{ matrix.config.arch }}" - -DCMAKE_CXX_COMPILER=${{ matrix.config.cxx }} - -DCMAKE_C_COMPILER=${{ matrix.config.cc }} + ${{ matrix.config.cmake_args }} -DCMAKE_BUILD_TYPE=Release -DUSER_CONFIG="${{ matrix.platforms.user_config }}" -C "${{ matrix.config.initial_cache }}" diff --git a/CMakeLists.txt b/CMakeLists.txt index 691ec1a5..f8277cf9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,7 +63,6 @@ option(AE_BUILD_EXAMPLES "Build examples" ${AE_ROOT_PORJECT}) option(AE_BUILD_TESTS "Build tests" ${AE_ROOT_PORJECT}) option(AE_BUILD_ANDROID_SMOKE "Build Android NDK smoke shared library and runner" Off) option(AE_ADDRESS_SANITIZE "Enable address sanitizer" Off) -option(AE_NO_STRIP_ALL "Do not apply --strip_all, useful for bloaty and similar tools " Off) set(UTM_ID "0" CACHE STRING "User Tracking Measurement ID, must be a uint32 value") set(USER_CONFIG "" CACHE PATH "Path to user provided configuration header file") @@ -80,7 +79,6 @@ message(STATUS "Aether build options: AE_BUILD_TESTS=${AE_BUILD_TESTS} AE_BUILD_ANDROID_SMOKE=${AE_BUILD_ANDROID_SMOKE} AE_ADDRESS_SANITIZE=${AE_ADDRESS_SANITIZE} - AE_NO_STRIP_ALL=${AE_NO_STRIP_ALL} UTM_ID=${UTM_ID} USER_CONFIG=${USER_CONFIG} FS_INIT=${FS_INIT} @@ -155,6 +153,14 @@ CPMAddPackage( "AE_TELE_BUILD_TESTS ${AE_BUILD_TESTS}" EXCLUDE_FROM_ALL FALSE ) +CPMAddPackage( + NAME aether-objects + GIT_REPOSITORY "https://github.com/aethernetio/aether-objects.git" + GIT_TAG "main" + OPTIONS "AE_TELE_INSTALL ${AE_INSTALL}" + "AE_TELE_BUILD_TESTS ${AE_BUILD_TESTS}" + EXCLUDE_FROM_ALL FALSE +) CPMAddPackage( NAME etl GIT_REPOSITORY "https://github.com/ETLCPP/etl.git" @@ -189,7 +195,8 @@ target_link_libraries(${TARGET_NAME} PUBLIC etl stdexec ae-numeric - aether::miscpp) + aether::miscpp + aether::objects) message(STATUS "Aether build for CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}") if(CMAKE_SYSTEM_NAME STREQUAL "Linux" @@ -324,52 +331,6 @@ target_compile_options(${TARGET_NAME} PUBLIC > ) -# setup release build options -if (CMAKE_BUILD_TYPE STREQUAL "Release") - if (NOT MINGW AND - (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR - CMAKE_CXX_COMPILER_ID STREQUAL "Clang")) - - target_compile_options(${TARGET_NAME} PUBLIC - -ffast-math - -fno-math-errno - -funsafe-math-optimizations - -fassociative-math - -freciprocal-math - -ffinite-math-only - -fno-signed-zeros - -fno-trapping-math) - # clang does not support this - if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - target_compile_options(${TARGET_NAME} PUBLIC - -fsingle-precision-constant - -fno-fp-int-builtin-inexact) - endif() - - # TODO: make this options configurable from user side - target_compile_options(${TARGET_NAME} PRIVATE $<$:-fno-exceptions>) - target_compile_options(${TARGET_NAME} PUBLIC $<$:-fno-rtti>) - - - if (GCC_VERSION VERSION_GREATER 12.1 OR GCC_VERSION VERSION_EQUAL 12.1) - target_compile_options(${TARGET_NAME} PUBLIC -Oz -DNDEBUG) - else() - target_compile_options(${TARGET_NAME} PUBLIC -Os -DNDEBUG) - endif() - - # size optimizations - target_compile_options(${TARGET_NAME} PUBLIC -fdata-sections -ffunction-sections) - target_link_options(${TARGET_NAME} PUBLIC -fdata-sections -ffunction-sections) - target_compile_options(${TARGET_NAME} PUBLIC -flto=auto -ffat-lto-objects) - target_link_options(${TARGET_NAME} PUBLIC -flto=auto) - - if(NOT AE_NO_STRIP_ALL ) - target_link_options(${TARGET_NAME} PUBLIC -Wl,--gc-sections,--strip-all) - endif() - - endif() -endif() - if(AE_BUILD_TOOLS) message(STATUS "Aether builds tools!") add_subdirectory(tools/registrator) diff --git a/aether/CMakeLists.txt b/aether/CMakeLists.txt index d0fdc096..586300b8 100644 --- a/aether/CMakeLists.txt +++ b/aether/CMakeLists.txt @@ -52,20 +52,6 @@ list(APPEND aether_srcs "dns/dns_c_ares.cpp" "dns/esp32_dns_resolve.cpp") -list(APPEND aether_srcs - "obj/obj.cpp" - "obj/domain.cpp" - "obj/obj_id.cpp" - "obj/registry.cpp" - "obj/obj_ptr_base.cpp" - ) - -list(APPEND aether_srcs - "ptr/ptr.cpp" - "ptr/ptr_view.cpp" - "ptr/ref_tree.cpp" - ) - list(APPEND aether_srcs "ae_actions/get_servers.cpp" "ae_actions/ping.cpp" @@ -218,9 +204,7 @@ list(APPEND aether_srcs "domain_storage/domain_storage_factory.cpp" "domain_storage/registrar_domain_storage.cpp" "domain_storage/static_domain_storage.cpp" - "domain_storage/ram_domain_storage.cpp" "domain_storage/spifs_domain_storage.cpp" - "domain_storage/file_system_std_storage.cpp" "domain_storage/sync_domain_storage.cpp") list(APPEND aether_srcs diff --git a/aether/access_points/access_point.h b/aether/access_points/access_point.h index 630db749..3e1d51c0 100644 --- a/aether/access_points/access_point.h +++ b/aether/access_points/access_point.h @@ -19,8 +19,8 @@ #include -#include "aether/obj/obj.h" -#include "aether/obj/obj_ptr.h" +#include "aether-objects/obj/obj.h" +#include "aether-objects/obj/obj_ptr.h" namespace ae { class Channel; diff --git a/aether/access_points/ethernet_access_point.h b/aether/access_points/ethernet_access_point.h index 5e1f19c7..83dd82f9 100644 --- a/aether/access_points/ethernet_access_point.h +++ b/aether/access_points/ethernet_access_point.h @@ -19,8 +19,8 @@ #include "aether/access_points/access_point.h" -#include "aether/obj/obj.h" -#include "aether/obj/obj_ptr.h" +#include "aether-objects/obj/obj.h" +#include "aether-objects/obj/obj_ptr.h" namespace ae { class Aether; diff --git a/aether/access_points/lora_module_access_point.h b/aether/access_points/lora_module_access_point.h index 1cd3cc15..aa3440cf 100644 --- a/aether/access_points/lora_module_access_point.h +++ b/aether/access_points/lora_module_access_point.h @@ -20,13 +20,13 @@ #include "aether/config.h" #if AE_SUPPORT_LORA +# include "aether-objects/obj/obj.h" # include "aether/access_points/access_point.h" # include "aether/actions/action.h" # include "aether/actions/action_ptr.h" # include "aether/adapters/lora_module_adapter.h" # include "aether/events/event_subscription.h" # include "aether/lora_modules/ilora_module_driver.h" -# include "aether/obj/obj.h" # include "aether/types/state_machine.h" namespace ae { diff --git a/aether/access_points/modem_access_point.h b/aether/access_points/modem_access_point.h index d042645d..500b3963 100644 --- a/aether/access_points/modem_access_point.h +++ b/aether/access_points/modem_access_point.h @@ -20,13 +20,13 @@ #include "aether/config.h" #if AE_SUPPORT_MODEMS +# include "aether-objects/obj/obj.h" # include "aether/access_points/access_point.h" # include "aether/actions/action.h" # include "aether/adapters/modem_adapter.h" # include "aether/ae_context.h" # include "aether/events/event_subscription.h" # include "aether/events/events.h" -# include "aether/obj/obj.h" namespace ae { class Aether; diff --git a/aether/access_points/wifi_access_point.h b/aether/access_points/wifi_access_point.h index fc5902cb..f63c60a5 100644 --- a/aether/access_points/wifi_access_point.h +++ b/aether/access_points/wifi_access_point.h @@ -22,10 +22,10 @@ #include "aether/config.h" #if AE_SUPPORT_WIFIS +# include "aether-objects/obj/obj_ptr.h" # include "aether/actions/action.h" # include "aether/ae_context.h" # include "aether/events/events.h" -# include "aether/obj/obj_ptr.h" # include "aether/access_points/access_point.h" # include "aether/wifi/wifi_driver.h" diff --git a/aether/adapter_registry.h b/aether/adapter_registry.h index d83fcf4a..fb0e9107 100644 --- a/aether/adapter_registry.h +++ b/aether/adapter_registry.h @@ -17,7 +17,7 @@ #ifndef AETHER_ADAPTER_REGISTRY_H_ #define AETHER_ADAPTER_REGISTRY_H_ -#include "aether/obj/obj.h" +#include "aether-objects/obj/obj.h" #include "aether/adapters/adapter.h" diff --git a/aether/adapters/adapter.h b/aether/adapters/adapter.h index f36d9567..fa892352 100644 --- a/aether/adapters/adapter.h +++ b/aether/adapters/adapter.h @@ -19,7 +19,7 @@ #include -#include "aether/obj/obj.h" +#include "aether-objects/obj/obj.h" #include "aether/events/events.h" #include "aether/access_points/access_point.h" diff --git a/aether/adapters/ethernet.h b/aether/adapters/ethernet.h index 1c3d427a..b5b5621d 100644 --- a/aether/adapters/ethernet.h +++ b/aether/adapters/ethernet.h @@ -17,10 +17,10 @@ #ifndef AETHER_ADAPTERS_ETHERNET_H_ #define AETHER_ADAPTERS_ETHERNET_H_ -#include "aether/poller/poller.h" -#include "aether/obj/dummy_obj.h" // IWYU pragma: keep -#include "aether/dns/dns_resolve.h" // IWYU pragma: keep +#include "aether-objects/obj/dummy_obj.h" // IWYU pragma: keep #include "aether/adapters/adapter.h" +#include "aether/dns/dns_resolve.h" // IWYU pragma: keep +#include "aether/poller/poller.h" #include "aether/access_points/ethernet_access_point.h" diff --git a/aether/adapters/proxy.h b/aether/adapters/proxy.h index eeab5d0f..3f37c884 100644 --- a/aether/adapters/proxy.h +++ b/aether/adapters/proxy.h @@ -17,7 +17,7 @@ #ifndef AETHER_ADAPTERS_PROXY_H_ #define AETHER_ADAPTERS_PROXY_H_ -#include "aether/obj/obj.h" +#include "aether-objects/obj/obj.h" #include "aether/types/address.h" namespace ae { diff --git a/aether/ae_actions/select_client.h b/aether/ae_actions/select_client.h index 79efc796..65c3827b 100644 --- a/aether/ae_actions/select_client.h +++ b/aether/ae_actions/select_client.h @@ -19,12 +19,12 @@ #include "aether-miscpp/types/result.h" +#include "aether-objects/obj/obj_ptr.h" #include "aether/actions/action.h" #include "aether/ae_context.h" #include "aether/config.h" #include "aether/events/event_subscription.h" #include "aether/events/events.h" -#include "aether/obj/obj_ptr.h" namespace ae { class Aether; diff --git a/aether/aether.cpp b/aether/aether.cpp index b75a866b..98f11bd5 100644 --- a/aether/aether.cpp +++ b/aether/aether.cpp @@ -18,8 +18,8 @@ #include +#include "aether-objects/obj/obj_ptr.h" #include "aether/client.h" -#include "aether/obj/obj_ptr.h" #include "aether/registration_cloud.h" #include "aether/server.h" diff --git a/aether/aether.h b/aether/aether.h index 9fee1b5a..f5d72b9a 100644 --- a/aether/aether.h +++ b/aether/aether.h @@ -20,9 +20,9 @@ #include #include +#include "aether-objects/obj/obj.h" #include "aether/clock.h" #include "aether/memory.h" -#include "aether/obj/obj.h" #include "aether/types/client_config.h" #include "aether/ae_actions/select_client.h" diff --git a/aether/aether_app.cpp b/aether/aether_app.cpp index fa8f9ad4..1d5bd288 100644 --- a/aether/aether_app.cpp +++ b/aether/aether_app.cpp @@ -299,7 +299,7 @@ void AetherAppContext::InitComponentContext() { domain_storage.CleanUp(); #endif // AE_DISTILLATION - return std::make_unique(Now(), domain_storage); + return std::make_unique(domain_storage); }); if (!aether_) { diff --git a/aether/aether_app.h b/aether/aether_app.h index 976d3642..4f509313 100644 --- a/aether/aether_app.h +++ b/aether/aether_app.h @@ -22,11 +22,11 @@ #include #include +#include "aether-objects/obj/domain.h" +#include "aether-objects/ptr/ptr.h" #include "aether/common.h" #include "aether/config.h" #include "aether/memory.h" -#include "aether/obj/domain.h" -#include "aether/ptr/ptr.h" #include "aether/actions/action.h" // IWYU pragma: keep #include "aether/events/events.h" // IWYU pragma: keep diff --git a/aether/aether_c/aether_capi.cpp b/aether/aether_c/aether_capi.cpp index f5d6ca80..79f4001d 100644 --- a/aether/aether_c/aether_capi.cpp +++ b/aether/aether_c/aether_capi.cpp @@ -24,10 +24,10 @@ #include "aether/aether_c/c_errors.h" #include "aether/aether_c/extern_c.h" +#include "aether-objects/obj/obj_ptr.h" +#include "aether-objects/ptr/ptr.h" #include "aether/actions/actions_queue.h" #include "aether/memory.h" -#include "aether/obj/obj_ptr.h" -#include "aether/ptr/ptr.h" #include "aether/types/data_buffer.h" #include "aether/aether_app.h" @@ -36,9 +36,9 @@ // IWYU pragma: begin_keeps #include "aether/wifi/wifi_driver_types.h" +#include "aether-objects/domain_storage/file_system_std_storage.h" +#include "aether-objects/domain_storage/ram_domain_storage.h" #include "aether/domain_storage/domain_storage_factory.h" -#include "aether/domain_storage/file_system_std_storage.h" -#include "aether/domain_storage/ram_domain_storage.h" #include "aether/domain_storage/spifs_domain_storage.h" #include "aether/adapter_registry.h" diff --git a/aether/all.h b/aether/all.h index 9b305ed6..582c9937 100644 --- a/aether/all.h +++ b/aether/all.h @@ -35,17 +35,17 @@ #include "aether-miscpp/format/format.h" #include "aether-miscpp/reflect/reflect.h" -#include "aether/obj/domain.h" -#include "aether/obj/obj.h" -#include "aether/obj/obj_id.h" -#include "aether/obj/obj_ptr.h" -#include "aether/obj/registry.h" -#include "aether/ptr/ptr.h" -#include "aether/ptr/ptr_view.h" - +#include "aether-objects/obj/domain.h" +#include "aether-objects/obj/obj.h" +#include "aether-objects/obj/obj_id.h" +#include "aether-objects/obj/obj_ptr.h" +#include "aether-objects/obj/registry.h" +#include "aether-objects/ptr/ptr.h" +#include "aether-objects/ptr/ptr_view.h" + +#include "aether-objects/domain_storage/file_system_std_storage.h" +#include "aether-objects/domain_storage/ram_domain_storage.h" #include "aether/domain_storage/domain_storage_factory.h" -#include "aether/domain_storage/file_system_std_storage.h" -#include "aether/domain_storage/ram_domain_storage.h" #include "aether/domain_storage/registrar_domain_storage.h" #include "aether/domain_storage/spifs_domain_storage.h" #include "aether/domain_storage/static_domain_storage.h" diff --git a/aether/channels/channel.h b/aether/channels/channel.h index 7ae7082e..1411efe6 100644 --- a/aether/channels/channel.h +++ b/aether/channels/channel.h @@ -19,11 +19,11 @@ #include +#include "aether-objects/obj/obj.h" #include "aether/channels/channel_statistics.h" #include "aether/channels/channels_types.h" #include "aether/executors/executors.h" #include "aether/memory.h" -#include "aether/obj/obj.h" #include "aether/stream_api/istream.h" #include "aether/types/address.h" diff --git a/aether/channels/channel_statistics.h b/aether/channels/channel_statistics.h index fef826de..bea68d6d 100644 --- a/aether/channels/channel_statistics.h +++ b/aether/channels/channel_statistics.h @@ -17,9 +17,10 @@ #ifndef AETHER_CHANNELS_CHANNEL_STATISTICS_H_ #define AETHER_CHANNELS_CHANNEL_STATISTICS_H_ +#include "aether-objects/obj/obj.h" + +#include "aether/clock.h" #include "aether/config.h" -#include "aether/common.h" -#include "aether/obj/obj.h" #include "aether/types/statistic_counter.h" diff --git a/aether/channels/ethernet_transport_factory.h b/aether/channels/ethernet_transport_factory.h index 35e38424..f21848ca 100644 --- a/aether/channels/ethernet_transport_factory.h +++ b/aether/channels/ethernet_transport_factory.h @@ -18,10 +18,10 @@ #include -#include "aether/ptr/ptr.h" +#include "aether-objects/ptr/ptr.h" #include "aether/ae_context.h" -#include "aether/types/address.h" #include "aether/stream_api/istream.h" +#include "aether/types/address.h" namespace ae { class IPoller; diff --git a/aether/channels/wifi_channel.cpp b/aether/channels/wifi_channel.cpp index 7eb095a7..5421253c 100644 --- a/aether/channels/wifi_channel.cpp +++ b/aether/channels/wifi_channel.cpp @@ -21,9 +21,9 @@ # include # include +# include "aether-objects/ptr/ptr_view.h" # include "aether/events/event_subscription.h" # include "aether/executors/executors.h" -# include "aether/ptr/ptr_view.h" # include "aether/aether.h" # include "aether/dns/dns_resolve.h" diff --git a/aether/client.h b/aether/client.h index fe8206c5..dbf5e6f1 100644 --- a/aether/client.h +++ b/aether/client.h @@ -21,10 +21,10 @@ #include #include +#include "aether-objects/obj/obj.h" #include "aether/client_connectivity_policy.h" #include "aether/cloud.h" #include "aether/memory.h" -#include "aether/obj/obj.h" #include "aether/server_keys.h" #include "aether/types/uid.h" diff --git a/aether/client_connectivity_policy.h b/aether/client_connectivity_policy.h index d038af72..53c063b7 100644 --- a/aether/client_connectivity_policy.h +++ b/aether/client_connectivity_policy.h @@ -22,9 +22,11 @@ #include #include +#include "aether-objects/obj/obj.h" + +#include "aether/clock.h" #include "aether/config.h" #include "aether/events/events.h" -#include "aether/obj/obj.h" #include "aether/cloud_connections/request_policy.h" diff --git a/aether/client_messages/p2p_message_stream.h b/aether/client_messages/p2p_message_stream.h index f52f78f6..8fdb5eaa 100644 --- a/aether/client_messages/p2p_message_stream.h +++ b/aether/client_messages/p2p_message_stream.h @@ -22,8 +22,8 @@ #include "aether/common.h" +#include "aether-objects/ptr/ptr_view.h" #include "aether/ae_context.h" -#include "aether/ptr/ptr_view.h" #include "aether/types/uid.h" #include "aether/write_action/buffer_write.h" diff --git a/aether/client_messages/p2p_message_stream_manager.h b/aether/client_messages/p2p_message_stream_manager.h index ee2c0415..9dc1a1a1 100644 --- a/aether/client_messages/p2p_message_stream_manager.h +++ b/aether/client_messages/p2p_message_stream_manager.h @@ -20,13 +20,13 @@ #include #include -#include "aether/ptr/ptr.h" -#include "aether/ptr/ptr_view.h" -#include "aether/types/uid.h" +#include "aether-objects/ptr/ptr.h" +#include "aether-objects/ptr/ptr_view.h" #include "aether/ae_context.h" -#include "aether/events/events.h" -#include "aether/cloud_connections/cloud_subscription.h" #include "aether/client_messages/p2p_port_handle.h" +#include "aether/cloud_connections/cloud_subscription.h" +#include "aether/events/events.h" +#include "aether/types/uid.h" namespace ae { diff --git a/aether/cloud.h b/aether/cloud.h index f5681751..06fe059b 100644 --- a/aether/cloud.h +++ b/aether/cloud.h @@ -23,7 +23,7 @@ #include "aether/events/events.h" -#include "aether/obj/obj.h" +#include "aether-objects/obj/obj.h" #include "aether/server.h" namespace ae { diff --git a/aether/cloud_connections/cloud_server_connection.h b/aether/cloud_connections/cloud_server_connection.h index 3461b878..cb761a71 100644 --- a/aether/cloud_connections/cloud_server_connection.h +++ b/aether/cloud_connections/cloud_server_connection.h @@ -20,7 +20,7 @@ #include #include -#include "aether/ptr/ptr_view.h" +#include "aether-objects/ptr/ptr_view.h" #include "aether/cloud.h" #include "aether/server.h" diff --git a/aether/cloud_connections/cloud_server_connections.h b/aether/cloud_connections/cloud_server_connections.h index 7b7dc56f..c0bf1acf 100644 --- a/aether/cloud_connections/cloud_server_connections.h +++ b/aether/cloud_connections/cloud_server_connections.h @@ -21,11 +21,11 @@ #include #include +#include "aether-objects/ptr/ptr.h" +#include "aether-objects/ptr/ptr_view.h" #include "aether/ae_context.h" #include "aether/events/events.h" #include "aether/events/multi_subscription.h" -#include "aether/ptr/ptr.h" -#include "aether/ptr/ptr_view.h" #include "aether/write_action/write_action.h" #include "aether/cloud.h" diff --git a/aether/connection_manager/client_cloud_manager.h b/aether/connection_manager/client_cloud_manager.h index 782aff13..e1755032 100644 --- a/aether/connection_manager/client_cloud_manager.h +++ b/aether/connection_manager/client_cloud_manager.h @@ -20,12 +20,12 @@ #include #include +#include "aether-objects/obj/obj.h" +#include "aether-objects/ptr/ptr.h" #include "aether/actions/action_pool.h" #include "aether/cloud.h" #include "aether/events/events.h" #include "aether/executors/executors.h" -#include "aether/obj/obj.h" -#include "aether/ptr/ptr.h" #include "aether/types/uid.h" #include "aether/ae_actions/get_servers.h" diff --git a/aether/connection_manager/server_connection_manager.h b/aether/connection_manager/server_connection_manager.h index 53d8a816..a0e76245 100644 --- a/aether/connection_manager/server_connection_manager.h +++ b/aether/connection_manager/server_connection_manager.h @@ -20,9 +20,9 @@ #include #include +#include "aether-objects/ptr/ptr.h" +#include "aether-objects/ptr/ptr_view.h" #include "aether/ae_context.h" -#include "aether/ptr/ptr.h" -#include "aether/ptr/ptr_view.h" #include "aether/server_connections/client_server_connection.h" #include "aether/server_connections/iserver_connection_factory.h" diff --git a/aether/crypto.h b/aether/crypto.h index 838a5bfa..b6b6d018 100644 --- a/aether/crypto.h +++ b/aether/crypto.h @@ -19,9 +19,9 @@ #include -#include "aether/obj/obj.h" -#include "aether/crypto/sign.h" +#include "aether-objects/obj/obj.h" #include "aether/crypto/key.h" +#include "aether/crypto/sign.h" namespace ae { diff --git a/aether/dns/dns_resolve.h b/aether/dns/dns_resolve.h index 98be40b5..f0f318aa 100644 --- a/aether/dns/dns_resolve.h +++ b/aether/dns/dns_resolve.h @@ -17,15 +17,15 @@ #ifndef AETHER_DNS_DNS_RESOLVE_H_ #define AETHER_DNS_DNS_RESOLVE_H_ -#include // IWYU pragma: keep #include +#include // IWYU pragma: keep +#include "aether-objects/obj/dummy_obj.h" // IWYU pragma: keep #include "aether/config.h" -#include "aether/obj/dummy_obj.h" // IWYU pragma: keep #if AE_SUPPORT_CLOUD_DNS -# include "aether/obj/obj.h" -# include "aether/types/address.h" +# include "aether-objects/obj/obj.h" # include "aether/executors/executors.h" +# include "aether/types/address.h" namespace ae { diff --git a/aether/dns/esp32_dns_resolve.h b/aether/dns/esp32_dns_resolve.h index a0f32726..4d38d157 100644 --- a/aether/dns/esp32_dns_resolve.h +++ b/aether/dns/esp32_dns_resolve.h @@ -24,8 +24,8 @@ # if (defined(ESP_PLATFORM)) # define ESP32_DNS_RESOLVER_ENABLED 1 +# include "aether-objects/obj/obj.h" # include "aether/dns/dns_resolve.h" -# include "aether/obj/obj.h" namespace ae { class Aether; diff --git a/aether/domain_storage/domain_storage_factory.cpp b/aether/domain_storage/domain_storage_factory.cpp index eab77dcf..0a8c4bff 100644 --- a/aether/domain_storage/domain_storage_factory.cpp +++ b/aether/domain_storage/domain_storage_factory.cpp @@ -17,11 +17,12 @@ #include "aether/domain_storage/domain_storage_factory.h" // IWYU pragma: begin_keeps -#include "aether/domain_storage/ram_domain_storage.h" -#include "aether/domain_storage/sync_domain_storage.h" +#include "aether-objects/domain_storage/file_system_std_storage.h" +#include "aether-objects/domain_storage/ram_domain_storage.h" + #include "aether/domain_storage/spifs_domain_storage.h" #include "aether/domain_storage/static_domain_storage.h" -#include "aether/domain_storage/file_system_std_storage.h" +#include "aether/domain_storage/sync_domain_storage.h" #if defined FS_INIT # define STATIC_DOMAIN_STORAGE_ENABLED 1 @@ -32,7 +33,7 @@ namespace ae { std::unique_ptr DomainStorageFactory::Create() { -#if defined STATIC_DOMAIN_STORAGE_ENABLED +#if STATIC_DOMAIN_STORAGE_ENABLED auto ro_storage = make_unique(static_domain_data); auto rw_storage = CreateRwStorage(); return make_unique(std::move(ro_storage), @@ -43,11 +44,11 @@ std::unique_ptr DomainStorageFactory::Create() { } std::unique_ptr DomainStorageFactory::CreateRwStorage() { -#if defined AE_FILE_SYSTEM_STD_ENABLED +#if AE_FILE_SYSTEM_STD_ENABLED return make_unique(); -#elif defined AE_SPIFS_DOMAIN_STORAGE_ENABLED +#elif AE_SPIFS_DOMAIN_STORAGE_ENABLED return make_unique(); -#elif defined AE_FILE_SYSTEM_RAM_ENABLED +#else return make_unique(); #endif } diff --git a/aether/domain_storage/domain_storage_factory.h b/aether/domain_storage/domain_storage_factory.h index 6b56d8dd..cb4bc47e 100644 --- a/aether/domain_storage/domain_storage_factory.h +++ b/aether/domain_storage/domain_storage_factory.h @@ -17,8 +17,8 @@ #ifndef AETHER_DOMAIN_STORAGE_DOMAIN_STORAGE_FACTORY_H_ #define AETHER_DOMAIN_STORAGE_DOMAIN_STORAGE_FACTORY_H_ +#include "aether-objects/obj/idomain_storage.h" #include "aether/memory.h" -#include "aether/obj/idomain_storage.h" namespace ae { class DomainStorageFactory { diff --git a/aether/domain_storage/domain_storage_tele.h b/aether/domain_storage/domain_storage_tele.h index 66d11c17..a5912052 100644 --- a/aether/domain_storage/domain_storage_tele.h +++ b/aether/domain_storage/domain_storage_tele.h @@ -17,31 +17,11 @@ #ifndef AETHER_DOMAIN_STORAGE_DOMAIN_STORAGE_TELE_H_ #define AETHER_DOMAIN_STORAGE_DOMAIN_STORAGE_TELE_H_ -#include "aether/tele.h" +#include "aether/tele.h" // IWYU pragma: exports AE_TELE_MODULE(kDomainStorage, 9, 171, 185); AE_TELE_MODULE(kDomainStorageDebug, 109, 300, 320); -AE_TAG(kFileSystemDsLoadObjClassIdNotFound, kDomainStorage) -AE_TAG(kFileSystemDsEnumObjIdNotFound, kDomainStorage) -AE_TAG(kFileSystemDsRemoveObjError, kDomainStorage) - -AE_TAG(kFileSystemDsEnumerated, kDomainStorageDebug) -AE_TAG(kFileSystemDsObjSaved, kDomainStorageDebug) -AE_TAG(kFileSystemDsObjLoaded, kDomainStorageDebug) -AE_TAG(kFileSystemDsObjRemoved, kDomainStorageDebug) - -AE_TAG(kRamDsLoadObjVersionNotFound, kDomainStorage) -AE_TAG(kRamDsLoadObjIdNoFound, kDomainStorage) -AE_TAG(kRamDsLoadObjClassIdNotFound, kDomainStorage) -AE_TAG(kRamDsEnumObjIdNotFound, kDomainStorage) -AE_TAG(kRamDsRemoveObjError, kDomainStorage) - -AE_TAG(kRamDsEnumerated, kDomainStorageDebug) -AE_TAG(kRamDsObjSaved, kDomainStorageDebug) -AE_TAG(kRamDsObjLoaded, kDomainStorageDebug) -AE_TAG(kRamDsObjRemoved, kDomainStorageDebug) - AE_TAG(kSpifsDsLoadObjVersionNotFound, kDomainStorage) AE_TAG(kSpifsDsLoadObjIdNoFound, kDomainStorage) AE_TAG(kSpifsDsLoadObjClassIdNotFound, kDomainStorage) diff --git a/aether/domain_storage/file_system_std_storage.cpp b/aether/domain_storage/file_system_std_storage.cpp deleted file mode 100644 index cbb66f59..00000000 --- a/aether/domain_storage/file_system_std_storage.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright 2024 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. - */ - -#include "aether/domain_storage/file_system_std_storage.h" - -#if defined AE_FILE_SYSTEM_STD_ENABLED - -# include -# include -# include -# include -# include -# include - -# include "aether/domain_storage/domain_storage_tele.h" - -namespace ae { - -class FstreamStorageWriter final : public IDomainStorageWriter { - public: - FstreamStorageWriter(DomainQuery q, std::ofstream&& f) - : query{std::move(q)}, file{std::move(f)} {} - - ~FstreamStorageWriter() override { - file.close(); - AE_TELE_DEBUG(kFileSystemDsObjSaved, - "Saved object id={}, class id={}, version={}, size={}", - query.id, query.class_id, static_cast(query.version), - written_size); - } - - seri::SeriResult Write(seri::SizeWriteTag data) override { - auto const u_size = static_cast(data.size); - return Write(seri::DataTag{u_size}); - } - - seri::SeriResult Write(seri::DataWriteTag data) override { - file.write(reinterpret_cast(data.data), - static_cast(data.size)); - if (file.fail()) { - return Error{seri::write_error}; - } - written_size += data.size; - return Ok{seri::good}; - } - - private: - DomainQuery query; - std::ofstream file; - std::size_t written_size{}; -}; - -class FstreamStorageReader final : public IDomainStorageReader { - public: - explicit FstreamStorageReader(std::ifstream&& f) : file{std::move(f)} {} - ~FstreamStorageReader() override { file.close(); } - - seri::SeriResult Read(seri::SizeReadTag data) override { - std::uint32_t u_size{}; - TRY_RESULT(Read(seri::DataTag{u_size})); - data.size = static_cast(u_size); - return Ok{seri::good}; - } - - seri::SeriResult Read(seri::DataReadTag data) override { - if (file.eof()) { - return Error{seri::read_eof}; - } - - file.read(reinterpret_cast(data.data), - static_cast(data.size)); - if (file.bad()) { - return Error{seri::read_error}; - } - if (file.gcount() != static_cast(data.size)) { - return Error{file.eof() ? seri::read_eof : seri::read_error}; - } - return Ok{seri::good}; - } - - private: - std::ifstream file; -}; - -FileSystemStdStorage::FileSystemStdStorage() = default; - -FileSystemStdStorage::~FileSystemStdStorage() = default; - -std::unique_ptr FileSystemStdStorage::Store( - DomainQuery const& query) { - auto class_dir = std::filesystem::path("state") / - std::to_string(query.id.id()) / - std::to_string(query.class_id); - - std::filesystem::create_directories(class_dir); - auto version_data_path = class_dir / std::to_string(query.version); - std::ofstream f(version_data_path, - std::ios::out | std::ios::binary | std::ios::trunc); - - return std::make_unique(query, std::move(f)); -} - -ClassList FileSystemStdStorage::Enumerate(const ae::ObjId& obj_id) { - // collect unique classes - std::set classes; - - auto state_dir = std::filesystem::path{"state"}; - auto ec = std::error_code{}; - auto obj_dir = state_dir / std::to_string(obj_id.id()); - for (auto const& class_dir : - std::filesystem::directory_iterator(obj_dir, ec)) { - auto file_name = class_dir.path().filename().string(); - classes.insert(static_cast(std::stoul(file_name))); - } - AE_TELE_DEBUG(kFileSystemDsEnumerated, "Enumerated classes {}", classes); - - if (ec) { - AE_TELE_INFO(kFileSystemDsEnumObjIdNotFound, - "Unable to open directory with error {}", ec.message()); - } - - return ClassList{classes.begin(), classes.end()}; -} - -DomainLoad FileSystemStdStorage::Load(DomainQuery const& query) { - auto object_dir = - std::filesystem::path("state") / std::to_string(query.id.id()); - auto ec = std::error_code{}; - if (!std::filesystem::exists(object_dir, ec)) { - return {DomainLoadResult::kEmpty, {}}; - } - - auto is_dir_empty = [&]() { - auto iter = std::filesystem::directory_iterator{object_dir}; - return std::filesystem::begin(iter) == std::filesystem::end(iter); - }; - if (is_dir_empty()) { - return {DomainLoadResult::kRemoved, {}}; - } - - auto class_dir = object_dir / std::to_string(query.class_id); - auto version_data_path = class_dir / std::to_string(query.version); - std::ifstream f(version_data_path, std::ios::in | std::ios::binary); - if (!f.good()) { - AE_TELE_INFO(kFileSystemDsLoadObjClassIdNotFound, "Unable to open file {}", - version_data_path.string()); - return DomainLoad{DomainLoadResult::kEmpty, {}}; - } - - AE_TELE_DEBUG(kFileSystemDsObjLoaded, - "Loaded object id={}, class id={}, version={}", query.id, - query.class_id, static_cast(query.version)); - - return {DomainLoadResult::kLoaded, - std::make_unique(std::move(f))}; -} - -void FileSystemStdStorage::Remove(ae::ObjId const& obj_id) { - auto object_dir = - std::filesystem::path("state") / std::to_string(obj_id.id()); - auto ec = std::error_code{}; - if (!std::filesystem::exists(object_dir, ec)) { - std::filesystem::create_directory(object_dir); - return; - } - if (ec) { - AE_TELED_ERROR("Unable to check if dir exists {} error {}", - object_dir.string(), ec.message()); - return; - } - - for (auto const& class_dir : - std::filesystem::directory_iterator(object_dir, ec)) { - auto ec2 = std::error_code{}; - std::filesystem::remove_all(class_dir.path(), ec2); - if (ec2) { - AE_TELED_ERROR("Unable to remove dir {}, error {}", - class_dir.path().string(), ec2.message()); - continue; - } - AE_TELE_DEBUG(kFileSystemDsObjRemoved, "Object removed {}", obj_id); - } - if (ec) { - AE_TELE_ERROR(kFileSystemDsRemoveObjError, - "Unable to open directory with error {}", ec.message()); - } -} - -void FileSystemStdStorage::CleanUp() { - std::filesystem::remove_all("state"); - AE_TELED_DEBUG("Removed all!", 0); -} -} // namespace ae - -#endif // AE_FILE_SYSTEM_STD_ENABLED diff --git a/aether/domain_storage/file_system_std_storage.h b/aether/domain_storage/file_system_std_storage.h deleted file mode 100644 index bb863a27..00000000 --- a/aether/domain_storage/file_system_std_storage.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2024 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. - */ - -#ifndef AETHER_DOMAIN_STORAGE_FILE_SYSTEM_STD_STORAGE_H_ -#define AETHER_DOMAIN_STORAGE_FILE_SYSTEM_STD_STORAGE_H_ - -#include - -#if (defined(__linux__) || defined(__unix__) || defined(__APPLE__) || \ - defined(__FreeBSD__) || defined(_WIN64) || defined(_WIN32)) - -# define AE_FILE_SYSTEM_STD_ENABLED 1 - -# include "aether/obj/idomain_storage.h" - -namespace ae { -class FileSystemStdStorage : public IDomainStorage { - public: - FileSystemStdStorage(); - ~FileSystemStdStorage() override; - - std::unique_ptr Store( - DomainQuery const& query) override; - ClassList Enumerate(ObjId const& obj_id) override; - DomainLoad Load(DomainQuery const& query) override; - void Remove(ObjId const& obj_id) override; - void CleanUp() override; -}; -} // namespace ae - -#endif -#endif // AETHER_DOMAIN_STORAGE_FILE_SYSTEM_STD_STORAGE_H_ */ diff --git a/aether/domain_storage/ram_domain_storage.cpp b/aether/domain_storage/ram_domain_storage.cpp deleted file mode 100644 index 788f6871..00000000 --- a/aether/domain_storage/ram_domain_storage.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2024 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. - */ - -#include "aether/domain_storage/ram_domain_storage.h" - -#if defined AE_FILE_SYSTEM_RAM_ENABLED - -# include -# include -# include -# include - -# include "aether/domain_storage/domain_storage_tele.h" - -namespace ae { -class RamDomainStorageWriter final : public IDomainStorageWriter { - public: - RamDomainStorageWriter(DomainQuery q, RamDomainStorage& s) - : query{std::move(q)}, storage{&s} { - assert(!storage->write_lock); - } - ~RamDomainStorageWriter() override { - storage->SaveData(query, std::move(data_buffer)); - } - - seri::SeriResult Write(seri::SizeWriteTag data) override { - auto const u_size = static_cast(data.size); - return Write(seri::DataTag{u_size}); - } - - seri::SeriResult Write(seri::DataWriteTag data) override { - data_buffer.insert(std::end(data_buffer), - static_cast(data.data), - static_cast(data.data) + data.size); - return Ok{seri::good}; - } - - DomainQuery query; - RamDomainStorage* storage; - ObjectData data_buffer; -}; - -class RamDomainStorageReader final : public IDomainStorageReader { - public: - RamDomainStorageReader(ObjectData const& d, RamDomainStorage& s) - : storage{&s}, data_buffer{d.data(), d.size()} { - storage->write_lock = true; - } - ~RamDomainStorageReader() override { storage->write_lock = false; } - - seri::SeriResult Read(seri::SizeReadTag data) override { - std::uint32_t u_size{}; - TRY_RESULT(Read(seri::DataTag{u_size})); - data.size = static_cast(u_size); - return Ok{seri::good}; - } - - seri::SeriResult Read(seri::DataReadTag data) override { - if (data_buffer.size() < data.size) { - return Error{seri::read_eof}; - } - std::memcpy(data.data, data_buffer.data(), data.size); - data_buffer = data_buffer.subspan(data.size); - return Ok{seri::good}; - } - - RamDomainStorage* storage; - std::span data_buffer; -}; - -RamDomainStorage::RamDomainStorage() = default; - -RamDomainStorage::~RamDomainStorage() = default; - -std::unique_ptr RamDomainStorage::Store( - DomainQuery const& query) { - return std::make_unique(query, *this); -} - -ClassList RamDomainStorage::Enumerate(ObjId const& obj_id) { - auto obj_map_it = state.find(obj_id); - if (obj_map_it == std::end(state)) { - AE_TELE_INFO(kRamDsEnumObjIdNotFound, "Obj not found {}", obj_id); - return {}; - } - if (!obj_map_it->second) { - return {}; - } - - ClassList classes; - classes.reserve(obj_map_it->second->size()); - for (auto& [cls, _] : *obj_map_it->second) { - classes.emplace_back(cls); - } - AE_TELE_DEBUG(kRamDsEnumerated, "Enumerated for obj {} classes {}", obj_id, - classes); - return classes; -} - -DomainLoad RamDomainStorage::Load(DomainQuery const& query) { - auto obj_map_it = state.find(query.id); - if (obj_map_it == std::end(state)) { - AE_TELE_INFO(kRamDsLoadObjIdNoFound, - "Unable to find object id={}, class id={}, version={}", - query.id, query.class_id, static_cast(query.version)); - return {DomainLoadResult::kEmpty, {}}; - } - if (!obj_map_it->second) { - return {DomainLoadResult::kRemoved, {}}; - } - - auto class_map_it = obj_map_it->second->find(query.class_id); - if (class_map_it == std::end(*obj_map_it->second)) { - AE_TELE_INFO(kRamDsLoadObjClassIdNotFound, - "Unable to find object id={}, class id={}, version={}", - query.id, query.class_id, static_cast(query.version)); - return {DomainLoadResult::kEmpty, {}}; - } - auto version_it = class_map_it->second.find(query.version); - if (version_it == std::end(class_map_it->second)) { - AE_TELE_INFO(kRamDsLoadObjVersionNotFound, - "Unable to find object id={}, class id={}, version={}", - query.id, query.class_id, static_cast(query.version)); - return {DomainLoadResult::kEmpty, {}}; - } - - AE_TELE_DEBUG(kRamDsObjLoaded, - "Loaded object id={}, class id={}, version={}, size={}", - query.id, query.class_id, static_cast(query.version), - version_it->second.size()); - - return {DomainLoadResult::kLoaded, - std::make_unique(version_it->second, *this)}; -} - -void RamDomainStorage::Remove(ObjId const& obj_id) { - auto obj_map_it = state.find(obj_id); - if (obj_map_it == std::end(state)) { - state.emplace(obj_id, std::nullopt); - return; - } - - obj_map_it->second.reset(); - AE_TELE_DEBUG(kRamDsObjRemoved, "Removed object {}", obj_id); -} - -void RamDomainStorage::CleanUp() { state.clear(); } - -void RamDomainStorage::SaveData(DomainQuery const& query, ObjectData&& data) { - auto& objcect_classes = state[query.id]; - if (!objcect_classes) { - objcect_classes.emplace(); - } - auto& saved = (*objcect_classes)[query.class_id][query.version]; - saved = std::move(data); - AE_TELE_DEBUG( - kRamDsObjSaved, "Saved object id={}, class id={}, version={}, size={}", - query.id, query.class_id, std::to_string(query.version), saved.size()); -} - -} // namespace ae - -#endif // AE_FILE_SYSTEM_RAM_ENABLED diff --git a/aether/domain_storage/ram_domain_storage.h b/aether/domain_storage/ram_domain_storage.h deleted file mode 100644 index 893c3d60..00000000 --- a/aether/domain_storage/ram_domain_storage.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2024 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. - */ - -#ifndef AETHER_DOMAIN_STORAGE_RAM_DOMAIN_STORAGE_H_ -#define AETHER_DOMAIN_STORAGE_RAM_DOMAIN_STORAGE_H_ - -#define AE_FILE_SYSTEM_RAM_ENABLED 0 - -#include -#include -#include - -#include "aether/obj/idomain_storage.h" - -namespace ae { -class RamDomainStorage : public IDomainStorage { - public: - using Data = ObjectData; - using VersionData = std::map; - using ClassData = std::map; - using ObjClassData = std::map>; - - RamDomainStorage(); - ~RamDomainStorage() override; - - std::unique_ptr Store( - DomainQuery const& query) override; - - ClassList Enumerate(ObjId const& obj_id) override; - DomainLoad Load(DomainQuery const& query) override; - void Remove(ObjId const& obj_id) override; - void CleanUp() override; - - void SaveData(DomainQuery const& query, ObjectData&& data); - - ObjClassData state; - bool write_lock = false; -}; -} // namespace ae -#endif // AETHER_DOMAIN_STORAGE_RAM_DOMAIN_STORAGE_H_ */ diff --git a/aether/domain_storage/registrar_domain_storage.h b/aether/domain_storage/registrar_domain_storage.h index 7e58e262..aa0ead01 100644 --- a/aether/domain_storage/registrar_domain_storage.h +++ b/aether/domain_storage/registrar_domain_storage.h @@ -21,8 +21,8 @@ #include -#include "aether/obj/idomain_storage.h" -#include "aether/domain_storage/ram_domain_storage.h" +#include "aether-objects/domain_storage/ram_domain_storage.h" +#include "aether-objects/obj/idomain_storage.h" namespace ae { class RegistrarDomainStorage : public IDomainStorage { diff --git a/aether/domain_storage/spifs_domain_storage.h b/aether/domain_storage/spifs_domain_storage.h index dc01bf6e..33cc2eb2 100644 --- a/aether/domain_storage/spifs_domain_storage.h +++ b/aether/domain_storage/spifs_domain_storage.h @@ -26,7 +26,7 @@ # include # include -# include "aether/obj/idomain_storage.h" +# include "aether-objects/obj/idomain_storage.h" namespace ae { class SpiFsDomainStorage : public IDomainStorage { diff --git a/aether/domain_storage/static_domain_storage.h b/aether/domain_storage/static_domain_storage.h index 3ae50bfa..bf98ba24 100644 --- a/aether/domain_storage/static_domain_storage.h +++ b/aether/domain_storage/static_domain_storage.h @@ -19,8 +19,8 @@ #include +#include "aether-objects/obj/idomain_storage.h" #include "aether/domain_storage/static_object_types.h" -#include "aether/obj/idomain_storage.h" #include "aether/tele.h" // IWYU pragma: keep diff --git a/aether/domain_storage/sync_domain_storage.h b/aether/domain_storage/sync_domain_storage.h index 25855654..4008a57c 100644 --- a/aether/domain_storage/sync_domain_storage.h +++ b/aether/domain_storage/sync_domain_storage.h @@ -19,7 +19,7 @@ #include -#include "aether/obj/idomain_storage.h" +#include "aether-objects/obj/idomain_storage.h" namespace ae { class SyncDomainStorage final : public IDomainStorage { diff --git a/aether/global_ids.h b/aether/global_ids.h index 28591217..904e5038 100644 --- a/aether/global_ids.h +++ b/aether/global_ids.h @@ -17,7 +17,7 @@ #ifndef AETHER_GLOBAL_IDS_H_ #define AETHER_GLOBAL_IDS_H_ -#include "aether/obj/obj_id.h" +#include "aether-objects/obj/obj_id.h" namespace ae { static constexpr ObjId kGlobalIdAdaptersOffset{1000}; diff --git a/aether/obj/domain.cpp b/aether/obj/domain.cpp deleted file mode 100644 index 54bdff6b..00000000 --- a/aether/obj/domain.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright 2024 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. - */ - -#include "aether/obj/domain.h" - -#include - -#include "aether/obj/obj.h" -#include "aether/obj/obj_tele.h" - -namespace ae { - -DomainGraph::DomainGraph(Domain* domain) : domain(domain) { assert(domain); } - -Ptr DomainGraph::LoadRoot(ObjId obj_id) { - if (!obj_id.is_valid()) { - return {}; - } - // if already loaded - if (auto obj = domain->Find(obj_id); obj) { - return obj; - } - - auto* factory = domain->GetMostRelatedFactory(obj_id); - if (factory == nullptr) { - return {}; - } - - auto ptr = domain->ConstructObj(*factory, obj_id); - factory->load(this, ptr, obj_id); - return ptr; -} - -Ptr DomainGraph::LoadCopyImpl(ObjId ref_id, ObjId copy_id) { - if (!ref_id.is_valid() || !copy_id.is_valid()) { - return {}; - } - // if already loaded - if (auto obj = domain->Find(copy_id); obj) { - return obj; - } - - auto* factory = domain->GetMostRelatedFactory(ref_id); - if (factory == nullptr) { - assert(false); - return {}; - } - - auto ptr = domain->ConstructObj(*factory, copy_id); - // load new object with ref_id - factory->load(this, ptr, ref_id); - return ptr; -} - -void DomainGraph::SaveRoot(Ptr const& ptr, ObjId obj_id) { - if (!ptr) { - return; - } - if (auto* factory = domain->FindClassFactory(ptr->GetClassId()); - factory != nullptr) { - factory->save(this, ptr, obj_id); - } -} - -DomainLoad DomainGraph::GetReader(DomainQuery const& query) { - return domain->storage_->Load(query); -} - -std::unique_ptr DomainGraph::GetWriter( - DomainQuery const& query) { - auto writer = domain->storage_->Store(query); - assert(writer && "Writer must be created!"); - return writer; -} - -Domain::Domain(TimePoint p, IDomainStorage& storage) - : update_time_{p}, - storage_(&storage), - registry_{&Registry::GetRegistry()} {} - -Ptr Domain::ConstructObj(Factory const& factory, ObjId obj_id) { - Ptr o = factory.create(); - AddObject(obj_id, o); - o->domain = this; - o->obj_id = obj_id; - return o; -} - -bool Domain::IsLast(uint32_t class_id) const { - return registry_->relations.find(class_id) == registry_->relations.end(); -} - -bool Domain::IsExisting(uint32_t class_id) const { - return registry_->IsExisting(class_id); -} - -Ptr Domain::Find(ObjId obj_id) const { - if (auto it = id_objects_.find(obj_id.id()); it != id_objects_.end()) { - return it->second.Lock(); - } - return {}; -} - -void Domain::AddObject(ObjId id, Ptr const& obj) { - id_objects_[id.id()] = obj; -} - -void Domain::RemoveObject(Obj* ptr) { id_objects_.erase(ptr->obj_id.id()); } - -Factory* Domain::GetMostRelatedFactory(ObjId id) { - auto classes = storage_->Enumerate(id); -#if DEBUG - auto class_names = std::vector{}; - class_names.reserve(classes.size()); - for (auto cid : classes) { - class_names.emplace_back(registry_->ClassName(cid)); - } - - AE_TELED_DEBUG("For obj {} enumerated classes [{}]", id.id(), class_names); -#else - AE_TELED_DEBUG("For obj {} enumerated classes [{}]", id.id(), classes); -#endif - - // Remove all unsupported classes. - classes.erase( - std::remove_if(std::begin(classes), std::end(classes), - [this](auto const& c) { return !IsExisting(c); }), - std::end(classes)); - - if (classes.empty()) { - return nullptr; - } - - // Build inheritance chain. - // from base to derived. - std::sort(std::begin(classes), std::end(classes), - [this](auto left, auto right) { - if (registry_->GenerationDistance(right, left) > 0) { - return false; - } - if (registry_->GenerationDistance(left, right) >= 0) { - return true; - } - // All classes must be in one inheritance chain. - assert(false); - return false; - }); - - // Find the Final class for the most derived class provided and create it. - for (auto& f : registry_->factories) { - if (IsLast(f.first)) { - // check with most derived class - int distance = registry_->GenerationDistance(classes.back(), f.first); - if (distance >= 0) { - return &f.second; - } - } - } - - return nullptr; -} - -Factory* Domain::FindClassFactory(std::uint32_t class_id) { - return registry_->FindFactory(class_id); -} - -namespace seri { -SeriResult Serializer, std::string>::Deseri( - BinaryArchive& archive, Meta val) const { - std::size_t size{}; - TRY_RESULT(archive.buffer().Read(SizeTag{size})); - if (size > archive.max_container_load_size()) { - return Error{container_too_large}; - } - val.value.resize(size); - auto* data = reinterpret_cast(val.value.data()); - return archive.buffer().Read(DataReadTag{data, size}); -} - -SeriResult Serializer, std::string>::Seri( - BinaryArchive& archive, Meta val) const { - auto const size = val.value.size(); - TRY_RESULT(archive.buffer().Write(SizeTag{size})); - auto const* data = reinterpret_cast(val.value.data()); - TRY_RESULT(archive.buffer().Write(DataWriteTag{data, size})); - return Ok{good}; -} - -SeriResult -Serializer, std::vector>::Deseri( - BinaryArchive& archive, - Meta> val) const { - std::size_t size{}; - TRY_RESULT(archive.buffer().Read(SizeTag{size})); - if (size > archive.max_container_load_size()) { - return Error{container_too_large}; - } - val.value.resize(size); - auto* data = reinterpret_cast(val.value.data()); - return archive.buffer().Read(DataReadTag{data, size}); -} - -SeriResult -Serializer, std::vector>::Seri( - BinaryArchive& archive, - Meta const> val) const { - auto const size = val.value.size(); - TRY_RESULT(archive.buffer().Write(SizeTag{size})); - auto const* data = reinterpret_cast(val.value.data()); - TRY_RESULT(archive.buffer().Write(DataWriteTag{data, size})); - return Ok{good}; -} -} // namespace seri -} // namespace ae diff --git a/aether/obj/domain.h b/aether/obj/domain.h deleted file mode 100644 index e85e4255..00000000 --- a/aether/obj/domain.h +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright 2024 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. - */ - -#ifndef AETHER_OBJ_DOMAIN_H_ -#define AETHER_OBJ_DOMAIN_H_ - -#include -#include -#include -#include -#include -#include - -#include "aether/clock.h" - -#include "aether-miscpp/domain_visitor/domain_visitor.h" -#include "aether-miscpp/reflect/reflect.h" -#include "aether-miscpp/serialization/binary_archive.h" -#include "aether-miscpp/serialization/serialization.h" -#include "aether/ptr/ptr_view.h" -#include "aether/types/packed_size.h" - -#include "aether/obj/idomain_storage.h" -#include "aether/obj/obj_id.h" -#include "aether/obj/registry.h" -#include "aether/obj/version_iterator.h" - -namespace ae { -class Obj; -class Domain; -class DomainGraph; - -struct DomainCycleDetector { - struct Node { - bool operator==(const Node& other) const { - return id == other.id && class_id == other.class_id; - } - bool operator<(const Node& other) const { - return id < other.id || (id == other.id && class_id < other.class_id); - } - - ObjId id; - std::uint32_t class_id; - }; - - bool Add(std::uint32_t class_id, ObjId obj_id) { - auto [_, ok] = visited_nodes.insert(Node{obj_id, class_id}); - return ok; - } - - std::set visited_nodes; -}; - -struct DomainBuffer { - seri::SeriResult Write(seri::SizeWriteTag data) const { - if (writer == nullptr) { - return Error{seri::write_eof}; - } - return writer->Write(data); - } - - seri::SeriResult Write(seri::DataWriteTag data) const { - if (writer == nullptr) { - return Error{seri::write_eof}; - } - return writer->Write(data); - } - - seri::SeriResult Read(seri::SizeReadTag data) const { - if (reader == nullptr) { - return Error{seri::read_eof}; - } - return reader->Read(data); - } - seri::SeriResult Read(seri::DataReadTag data) const { - if (reader == nullptr) { - return Error{seri::read_eof}; - } - return reader->Read(data); - } - - ObjId id; - DomainGraph* domain_graph{}; - IDomainStorageWriter* writer{nullptr}; - IDomainStorageReader* reader{nullptr}; -}; - -/** - * \brief Operations on graph of objects in domain. - * For load/save a new graph create a new DomainGraph. - */ -class DomainGraph { - public: - explicit DomainGraph(Domain* domain); - - // Load saved state of object. - Ptr LoadRoot(ObjId obj_id); - // Save state of object. - void SaveRoot(Ptr const& ptr, ObjId obj_id); - // Load a copy of object - template - Ptr LoadCopy(ObjId ref_id, ObjId copy_id); - - Ptr LoadCopyImpl(ObjId ref_id, ObjId copy_id); - - template - seri::SeriResult Load(T& obj, ObjId obj_id); - template - seri::SeriResult LoadVersion(Version version, T& obj, ObjId obj_id); - - template - seri::SeriResult Save(T const& obj, ObjId obj_id); - template - seri::SeriResult SaveVersion(Version version, T const& obj, ObjId obj_id); - - Domain* domain{}; - DomainCycleDetector cycle_detector{}; - - private: - DomainLoad GetReader(DomainQuery const& query); - std::unique_ptr GetWriter(DomainQuery const& query); -}; - -class Domain { - friend class DomainGraph; - - public: - Domain(TimePoint p, IDomainStorage& storage); - - // Search for the object by obj_id. - Ptr Find(ObjId obj_id) const; - - void AddObject(ObjId id, Ptr const& obj); - void RemoveObject(Obj* obj); - - private: - Ptr ConstructObj(Factory const& factory, ObjId id); - - bool IsLast(uint32_t class_id) const; - bool IsExisting(uint32_t class_id) const; - - Factory* FindClassFactory(std::uint32_t class_id); - Factory* GetMostRelatedFactory(ObjId id); - - TimePoint update_time_; - IDomainStorage* storage_; - Registry* registry_; - - std::map> id_objects_; -}; - -template -Ptr DomainGraph::LoadCopy(ObjId ref_id, ObjId copy_id) { - return Ptr{LoadCopyImpl(ref_id, copy_id)}; -} - -template -seri::SeriResult DomainGraph::Load(T& obj, ObjId obj_id) { - if (!cycle_detector.Add(T::kClassId, obj_id)) { - return Ok{seri::good}; - } - - if constexpr (HasAnyVersionedLoad::value) { - auto result = seri::SeriResult{Ok{seri::good}}; - version_iterator( - obj, [this, obj_id, &result](auto version, auto& obj) { - if (result.IsErr()) { - return; - } - result = this->LoadVersion(version, obj, obj_id); - }); - return result; - } else { - return LoadVersion(T::kCurrentVersion, obj, obj_id); - } -} - -struct LoadVisitor { - void operator()(auto& v) { - if (res) { - res = bin_archive.Load(v); - } - } - - seri::BinaryArchive& bin_archive; - seri::SeriResult res{Ok{seri::good}}; -}; - -template -seri::SeriResult DomainGraph::LoadVersion(Version version, T& obj, - ObjId obj_id) { - auto load = GetReader({obj_id, T::kClassId, V}); - if (load.result != DomainLoadResult::kLoaded) { - return Ok{seri::good}; - } - - auto bin_archive = - seri::BinaryArchive{DomainBuffer{.id = obj_id, - .domain_graph = this, - .writer = {}, - .reader = load.reader.get()}}; - - auto load_visitor = LoadVisitor{bin_archive}; - - // if T has any versioned, it also must have Load for this version - if constexpr (HasAnyVersionedLoad::value) { - auto visitor = VersionNodeVisitor{load_visitor}; - obj.Load(version, visitor); - } else { - // load or deserialize object - domain_visitor::DomainVisit(obj, load_visitor); - } - return load_visitor.res; -} - -template -seri::SeriResult DomainGraph::Save(T const& obj, ObjId obj_id) { - if (!cycle_detector.Add(T::kClassId, obj_id)) { - return Ok{seri::good}; - } - - if constexpr (HasAnyVersionedSave::value) { - auto result = seri::SeriResult{Ok{seri::good}}; - version_iterator( - obj, [this, obj_id, &result](auto version, auto& obj) { - if (result.IsErr()) { - return; - } - result = this->SaveVersion(version, obj, obj_id); - }); - return result; - } else { - return SaveVersion(T::kCurrentVersion, obj, obj_id); - } -} - -struct SaveVisitor { - void operator()(auto const& v) { - if (res) { - res = bin_archive.Save(v); - } - } - - seri::BinaryArchive& bin_archive; - seri::SeriResult res{Ok{seri::good}}; -}; - -template -seri::SeriResult DomainGraph::SaveVersion(Version version, T const& obj, - ObjId obj_id) { - auto storage_writer = GetWriter({obj_id, T::kClassId, V}); - - auto bin_archive = - seri::BinaryArchive{DomainBuffer{.id = obj_id, - .domain_graph = this, - .writer = storage_writer.get(), - .reader = {}}}; - - auto save_visitor = SaveVisitor{bin_archive}; - - if constexpr (HasAnyVersionedSave::value) { - auto visitor = VersionNodeVisitor{save_visitor}; - obj.Save(version, visitor); - } else { - // load or deserialize object - domain_visitor::DomainVisit( - obj, save_visitor, - domain_visitor::PolicyConst{}); - } - return save_visitor.res; -} - -namespace seri { -template - requires(std::is_base_of_v) -struct Serializer, T> { - using Archive = BinaryArchive; - - SeriResult Seri(Archive& arch, Meta meta_val) const { - return arch.buffer().domain_graph->Save(meta_val.value, arch.buffer().id); - } - - SeriResult Deseri(Archive& arch, Meta meta_val) const { - return arch.buffer().domain_graph->Load(meta_val.value, arch.buffer().id); - } -}; - -template <> -struct Serializer, std::string> { - SeriResult Deseri(BinaryArchive& archive, - Meta val) const; - SeriResult Seri(BinaryArchive& archive, - Meta val) const; -}; - -template <> -struct Serializer, std::vector> { - SeriResult Deseri(BinaryArchive& archive, - Meta> val) const; - SeriResult Seri(BinaryArchive& archive, - Meta const> val) const; -}; - -} // namespace seri -} // namespace ae - -#endif // AETHER_OBJ_DOMAIN_H_ diff --git a/aether/obj/dummy_obj.h b/aether/obj/dummy_obj.h deleted file mode 100644 index 12abde9d..00000000 --- a/aether/obj/dummy_obj.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2024 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. - */ - -#ifndef AETHER_OBJ_DUMMY_OBJ_H_ -#define AETHER_OBJ_DUMMY_OBJ_H_ - -#include "aether/common.h" -#include "aether/obj/obj.h" - -namespace ae { -/** - * \brief Use it to fill the holes in object states configured with different - * preprocessor directives - */ -class DummyObj : public Obj { - AE_OBJECT(DummyObj, Obj, 0) - - using Obj::Obj; - - public: - AE_OBJECT_REFLECT() -}; - -#define AE_DUMMY_OBJ(DERIVED) \ - protected: \ - friend class ae::Registrar; \ - friend ae::Ptr ae::MakePtr(); \ - \ - public: \ - _AE_OBJECT_FIELDS(crc32::from_literal(STR(DERIVED##dummy)).value, \ - DummyObj::kClassId, 0) \ - inline static auto registrar_ = \ - ae::Registrar(kClassId, kBaseClassId); \ - using Base = DummyObj; \ - using ptr = ae::ObjPtr; \ - Base& base_{*this}; \ - std::uint32_t GetClassId() const override { return kClassId; } \ - \ - public: \ - using DummyObj::DummyObj; \ - AE_OBJECT_REFLECT() \ - private: - -} // namespace ae - -#endif // AETHER_OBJ_DUMMY_OBJ_H_ diff --git a/aether/obj/idomain_storage.h b/aether/obj/idomain_storage.h deleted file mode 100644 index befce8fc..00000000 --- a/aether/obj/idomain_storage.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2025 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. - */ - -#ifndef AETHER_OBJ_IDOMAIN_STORAGE_H_ -#define AETHER_OBJ_IDOMAIN_STORAGE_H_ - -#include -#include -#include - -#include "aether-miscpp/serialization/binary_archive.h" - -#include "aether/obj/obj_id.h" - -namespace ae { - -enum class DomainLoadResult : std::uint8_t { - kEmpty, //< There is not data for queury - kRemoved, //< Data for query was removed - kLoaded, //< Data loaded successfully -}; - -using ObjectData = std::vector; -using ClassList = std::vector; - -struct DomainQuery { - ObjId id; - std::uint32_t class_id; - std::uint8_t version; -}; - -// BinaryBuffer implementation for storage writer -class IDomainStorageWriter { - public: - virtual ~IDomainStorageWriter() = default; - - virtual seri::SeriResult Write(seri::SizeWriteTag data) = 0; - virtual seri::SeriResult Write(seri::DataWriteTag data) = 0; -}; - -// BinaryBuffer implementation for storage reader -class IDomainStorageReader { - public: - virtual ~IDomainStorageReader() = default; - - virtual seri::SeriResult Read(seri::SizeReadTag data) = 0; - virtual seri::SeriResult Read(seri::DataReadTag data) = 0; -}; - -struct DomainLoad { - DomainLoadResult result; - std::unique_ptr reader; -}; - -/** - * \brief IDomainFacility to store object's data. - */ -class IDomainStorage { - public: - virtual ~IDomainStorage() = default; - /** - * \brief Store an ObjectData by query. - */ - virtual std::unique_ptr Store( - DomainQuery const& query) = 0; - /** - * \brief Enumerate all classes for object. - */ - virtual ClassList Enumerate(ObjId const& obj_id) = 0; - /** - * \brief Load object data by query. - */ - virtual DomainLoad Load(DomainQuery const& query) = 0; - - /** - * \brief Remove object data by query - */ - virtual void Remove(ObjId const& obj_id) = 0; - /** - * \brief Clean up the whole storage. - */ - virtual void CleanUp() = 0; -}; -} // namespace ae - -#endif // AETHER_OBJ_IDOMAIN_STORAGE_H_ diff --git a/aether/obj/obj.cpp b/aether/obj/obj.cpp deleted file mode 100644 index 4a2e450c..00000000 --- a/aether/obj/obj.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2024 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. - */ - -#include "aether/obj/obj.h" - -namespace ae { -Obj::Obj() = default; - -Obj::Obj(ObjProp prop) : domain{prop.domain}, obj_id{prop.id} {} - -Obj::~Obj() { - if (domain != nullptr) { - domain->RemoveObject(this); - } -} - -uint32_t Obj::GetClassId() const { return kClassId; } - -namespace domain_visitor { -std::size_t GetObjIndexImpl(Obj const* obj, std::uint32_t class_id) { - auto res = crc32::from_buffer( - reinterpret_cast(&class_id), sizeof(class_id)); - auto id = obj->obj_id.id(); - res = crc32::from_buffer(reinterpret_cast(&id), - sizeof(id), res); - return res.value; -} -} // namespace domain_visitor -} // namespace ae diff --git a/aether/obj/obj.h b/aether/obj/obj.h deleted file mode 100644 index 2fff4f8b..00000000 --- a/aether/obj/obj.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2024 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. - */ - -// Copyright 2016 Aether authors. All Rights Reserved. -// 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. -// ============================================================================= - -#ifndef AETHER_OBJ_OBJ_H_ -#define AETHER_OBJ_OBJ_H_ - -#include "aether/config.h" - -#include "aether-miscpp/crc.h" -#include "aether-miscpp/reflect/reflect.h" -#include "aether/obj/domain.h" -#include "aether/obj/obj_id.h" -#include "aether/obj/obj_ptr.h" -#include "aether/obj/registrar.h" // IWYU pragma: export -#include "aether/obj/registry.h" - -namespace ae { -/** - * \brief Base class for all objects. - */ -class Obj { - friend class ObjectPtrBase; - - public: - using CurrentVersion = Version<0>; - using ptr = ObjPtr; - - static constexpr std::uint32_t kClassId = crc32::from_literal("Obj").value; - static constexpr std::uint32_t kBaseClassId = - crc32::from_literal("Obj").value; - - static constexpr CurrentVersion kCurrentVersion{}; - - Obj(); - explicit Obj(ObjProp prop); - virtual ~Obj(); - - virtual std::uint32_t GetClassId() const; - - AE_REFLECT(); - - Domain* domain{}; - ObjId obj_id; -}; - -namespace domain_visitor { -extern std::size_t GetObjIndexImpl(Obj const* obj, std::uint32_t class_id); - -template -struct ObjectIndex>> { - static std::size_t GetIndex(Obj const* obj) { - return GetObjIndexImpl(obj, T::kClassId); - } -}; -} // namespace domain_visitor -} // namespace ae - -#define _AE_OBJECT_FIELDS(CLASS_ID, BASE_CLASS_ID, VERSION) \ - static constexpr std::uint32_t kClassId = CLASS_ID; \ - static constexpr std::uint32_t kBaseClassId = BASE_CLASS_ID; \ - static constexpr std::uint32_t kVersion = VERSION; \ - using CurrentVersion = ::ae::Version; \ - static constexpr CurrentVersion kCurrentVersion{}; - -/** - * \brief Use it inside each derived class to register it with the object system - */ -#define AE_OBJECT(DERIVED, BASE, VERSION) \ - protected: \ - friend class ::ae::Registrar; \ - friend ae::Ptr ae::MakePtr(); \ - \ - public: \ - _AE_OBJECT_FIELDS(crc32::from_literal(#DERIVED).value, BASE::kClassId, \ - VERSION) \ - inline static auto registrar_ = \ - ::ae::Registrar(kClassId, kBaseClassId); \ - \ - using Base = BASE; \ - using ptr = ::ae::ObjPtr; \ - \ - Base& base_{*this}; \ - \ - std::uint32_t GetClassId() const override { return kClassId; } \ - \ - private: \ - /* add rest class's staff after */ - -/** - * \brief Obj class reflection - */ -#define AE_OBJECT_REFLECT(...) \ - AE_REFLECT(AE_REF_BASE(std::decay_t), __VA_ARGS__) - -#endif // AETHER_OBJ_OBJ_H_ diff --git a/aether/obj/obj_id.cpp b/aether/obj/obj_id.cpp deleted file mode 100644 index 7f07948c..00000000 --- a/aether/obj/obj_id.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2024 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. - */ - -#include "aether/obj/obj_id.h" - -#include -#include - -namespace ae { -ObjId ObjId::GenerateUnique() { - static std::random_device dev; - static std::mt19937 rng(dev()); - static std::uniform_int_distribution dist6( - 10000, std::numeric_limits::max()); - return ObjId{static_cast(dist6(rng))}; -} -} // namespace ae diff --git a/aether/obj/obj_id.h b/aether/obj/obj_id.h deleted file mode 100644 index 3754f806..00000000 --- a/aether/obj/obj_id.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2024 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. - */ - -#ifndef AETHER_OBJ_OBJ_ID_H_ -#define AETHER_OBJ_OBJ_ID_H_ - -#include - -#include "aether-miscpp/format/format.h" -#include "aether-miscpp/reflect/reflect.h" -#include "aether-miscpp/serialization/serialization.h" - -namespace ae { - -class ObjId { - public: - using Type = std::uint32_t; - - static ObjId GenerateUnique(); - - constexpr ObjId() noexcept = default; - // NOLINTNEXTLINE(*explicit*) - constexpr ObjId(Type i) noexcept : id_{i} {} - - AE_REFLECT_MEMBERS(id_) - - constexpr Type id() const noexcept { return id_; } - constexpr bool is_valid() const noexcept { return id_ != 0; } - - constexpr bool operator<(ObjId const& i) const noexcept { - return id_ < i.id_; - } - constexpr bool operator!=(ObjId const& i) const noexcept { - return id_ != i.id_; - } - constexpr bool operator==(ObjId const& i) const noexcept { - return id_ == i.id_; - } - - constexpr ObjId& operator+=(Type i) noexcept { - id_ += i; - return *this; - } - constexpr ObjId operator+(Type i) const noexcept { return ObjId{id_ + i}; } - - private: - Type id_{0}; -}; - -template <> -struct Formatter : public Formatter { - template - void Format(ObjId value, FormatContext& ctx) const { - Formatter::Format(value.id(), ctx); - } -}; - -namespace seri { -template -struct Serializer { - SeriResult Seri(A& archive, Meta meta) const { - auto const id = meta.value.id(); - return archive.Save(Meta{id, meta.name}); - } - - SeriResult Deseri(A& archive, Meta meta) const { - ObjId::Type id{}; - TRY_RESULT((archive.Load(Meta{id, meta.name}))); - meta.value = ObjId{id}; - return Ok{good}; - } -}; -} // namespace seri - -class ObjFlags { - public: - using Type = std::uint8_t; - // defines for flag values - // none value - static constexpr Type kNone = 0x0; - // The object is not loaded with deserialization. Load method must be - // used for loading. - static constexpr Type kUnloadedByDefault = 0x1; - // current state the object is unloaded - static constexpr Type kUnloaded = 0x2; - - constexpr ObjFlags() noexcept = default; - // NOLINTNEXTLINE(*explicit*) - constexpr ObjFlags(Type v) noexcept : value_(v) {} - - AE_REFLECT_MEMBERS(value_) - - ObjFlags& operator=(Type v) noexcept { - value_ = v; - return *this; - } - - // NOLINTNEXTLINE(*explicit*) - constexpr operator Type() const noexcept { return value_; } - - private: - Type value_ = kNone; -}; - -template <> -struct Formatter : public Formatter { - template - void Format(ObjFlags value, FormatContext& ctx) const { - Formatter::Format( - static_cast(value), ctx); - } -}; - -namespace seri { -template -struct Serializer { - SeriResult Seri(A& archive, Meta meta) const { - ObjFlags::Type const flag = meta.value; - return archive.Save(Meta{flag, meta.name}); - } - - SeriResult Deseri(A& archive, Meta meta) const { - ObjFlags::Type flag{}; - TRY_RESULT((archive.Load(Meta{flag, meta.name}))); - meta.value = ObjFlags{flag}; - return Ok{good}; - } -}; -} // namespace seri - -} // namespace ae - -#endif // AETHER_OBJ_OBJ_ID_H_ */ diff --git a/aether/obj/obj_ptr.h b/aether/obj/obj_ptr.h deleted file mode 100644 index 39e8d530..00000000 --- a/aether/obj/obj_ptr.h +++ /dev/null @@ -1,412 +0,0 @@ -/* - * Copyright 2024 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. - */ - -#ifndef AETHER_OBJ_OBJ_PTR_H_ -#define AETHER_OBJ_OBJ_PTR_H_ - -#include -#include -#include -#include - -#include "aether-miscpp/domain_visitor/domain_visitor.h" // IWYU pragma: keep -#include "aether-miscpp/serialization/binary_archive.h" -#include "aether-miscpp/serialization/serialization.h" - -#include "aether/obj/domain.h" -#include "aether/obj/obj_id.h" -#include "aether/obj/obj_ptr_base.h" -#include "aether/obj/registry.h" -#include "aether/ptr/ptr.h" - -namespace ae { - -namespace obj_ptr_internal { -template -struct IsObjType : std::false_type {}; - -template -struct IsObjType> : std::true_type {}; -} // namespace obj_ptr_internal - -struct ObjProp { - Domain* domain; - ObjId id; -}; - -struct CreateWith { - CreateWith(Domain* d) : domain{d} { // NOLINT(*explicit*) - assert(d != nullptr); - } - CreateWith(Domain& d) : domain{&d} {} // NOLINT(*explicit*) - - CreateWith&& with_id(ObjId id) && { - obj_id = id; - return std::move(*this); - } - - CreateWith&& with_flags(ObjFlags f) && { - flags = f; - return std::move(*this); - } - - Domain* domain; - std::optional obj_id; - std::optional flags; -}; - -/** - * \brief A typed, non-owning view of an ObjectPtrBase cache. - * - * The referenced cache and its ObjPtr owner must outlive this view and must not - * be reset or replaced while the view is used. - */ -template -class ProxyPtr { - public: - explicit ProxyPtr(Ptr const& ptr) noexcept : ptr_{ptr} {} - ProxyPtr(Ptr&&) = delete; - ProxyPtr(Ptr const&&) = delete; - - [[nodiscard]] explicit operator bool() const noexcept { - return static_cast(ptr_); - } - - [[nodiscard]] T* get() const noexcept { return static_cast(ptr_.get()); } - - [[nodiscard]] T* operator->() const noexcept { - assert(ptr_ && "Dereferencing uninitialized ProxyPtr"); - return get(); - } - - [[nodiscard]] T& operator*() const noexcept { - assert(ptr_ && "Dereferencing uninitialized ProxyPtr"); - return *get(); - } - - // Materializing Ptr is intentional when the caller needs ownership. - template - requires(std::is_convertible_v) - // NOLINTNEXTLINE(*explicit*) - operator Ptr() const noexcept { - return Ptr{ptr_}; - } - - private: - Ptr const& ptr_; -}; - -template -class ObjPtr : public ObjectPtrBase { - template - friend class ObjPtr; - - friend struct seri::Serializer, ObjPtr>; - - public: - /** - * \brief Create new object with given arguments. - */ - template - static ObjPtr Create(CreateWith create_arg, TArgs&&... args); - - /** - * \brief Create new object ptr, but leave it in unloaded state. - */ - static ObjPtr Declare(CreateWith create_arg); - - /** - * \brief Make an obj ptr from the pointer to the object itself. - */ - static ObjPtr MakeFromThis(T* self); - - ObjPtr() noexcept : ObjectPtrBase{} {} - - ObjPtr(Domain* domain, ObjId obj_id, ObjFlags flags) - : ObjectPtrBase{domain, obj_id, flags} {} - - ObjPtr(Domain* domain, ObjId obj_id, ObjFlags flags, Ptr&& ptr) noexcept - : ObjectPtrBase{domain, obj_id, flags, std::move(ptr)} {} - - ObjPtr(Domain* domain, ObjId obj_id, ObjFlags flags, - Ptr const& ptr) noexcept - : ObjectPtrBase{domain, obj_id, flags, ptr} {} - - ObjPtr(ObjPtr const& ptr) noexcept = default; - ObjPtr(ObjPtr&& ptr) noexcept = default; - - template - requires(IsAbleToCast::value) - ObjPtr(ObjPtr ptr) noexcept // NOLINT(*explicit*) - : ObjectPtrBase{std::move(static_cast(ptr))} {} - - ObjPtr& operator=(ObjPtr const& ptr) noexcept = default; - ObjPtr& operator=(ObjPtr&& ptr) noexcept = default; - - template - requires(IsAbleToCast::value) - ObjPtr& operator=(ObjPtr ptr) noexcept { - ObjectPtrBase::operator=(std::move(static_cast(ptr))); - return *this; - } - - using ObjectPtrBase::domain; - using ObjectPtrBase::flags; - using ObjectPtrBase::id; - using ObjectPtrBase::is_loaded; - using ObjectPtrBase::is_valid; - using ObjectPtrBase::Reset; - using ObjectPtrBase::Save; - using ObjectPtrBase::SetFlags; - - T* operator->() &; - T* operator->() const&; - T* operator->() &&; - T* operator->() const&&; - T& operator*(); - T& operator*() const; - - explicit operator bool() const { return is_valid() && is_loaded(); } - - /** - * \brief Load current object to Ptr - */ - ProxyPtr Load() &; // NOLINT(*shadowing*) - ProxyPtr Load() const&; // NOLINT(*shadowing*) - Ptr Load() &&; // NOLINT(*shadowing*) - Ptr Load() const&&; // NOLINT(*shadowing*) - /** - * \brief Clone current object into new object - * \param obj_id Optional object ID to use for the new object, if not provided - * will be generated. - */ - ObjPtr Clone() const; - ObjPtr Clone(ObjId obj_id) const; - - template - auto WithLoaded(Func&& func) -> decltype(auto); - template - auto WithLoaded(Func&& func) const -> decltype(auto); -}; - -template -template -ObjPtr ObjPtr::Create(CreateWith create_arg, TArgs&&... args) { - static_assert(obj_ptr_internal::IsObjType::value, - "T Must be an object type"); - auto* domain = create_arg.domain; - auto obj_id = create_arg.obj_id.value_or(ObjId::GenerateUnique()); - auto flags = create_arg.flags.value_or(ObjFlags{}); - static_assert( - std::is_constructible_v, - "Class must be constructible with passed arguments and Domain*"); - auto ptr = MakePtr(ObjProp{domain, obj_id}, std::forward(args)...); - domain->AddObject(obj_id, ptr); - - return ObjPtr(domain, obj_id, flags, std::move(ptr)); -} - -template -ObjPtr ObjPtr::Declare(CreateWith create_arg) { - static_assert(obj_ptr_internal::IsObjType::value, - "T Must be an object type"); - auto* domain = create_arg.domain; - auto obj_id = create_arg.obj_id.value_or(ObjId::GenerateUnique()); - auto flags = create_arg.flags.value_or(ObjFlags::kUnloaded); - return ObjPtr(domain, obj_id, flags); -} - -template -ObjPtr ObjPtr::MakeFromThis(T* self) { - static_assert(obj_ptr_internal::IsObjType::value, - "T Must be an object type"); - auto id = self->obj_id; - auto* domain = self->domain; - assert(id.is_valid() && (domain != nullptr) && "Object must be in domain"); - auto ptr = MakePtrFromThis(self); - assert(ptr && "Object must be valid"); - return ObjPtr(domain, id, {}, std::move(ptr)); -} - -template -T* ObjPtr::operator->() & { - auto ptr = Load(); - assert(ptr && "Dereferencing invalid object"); - return ptr.get(); -} - -template -T* ObjPtr::operator->() const& { - auto ptr = Load(); - assert(ptr && "Dereferencing invalid object"); - return ptr.get(); -} - -template -T* ObjPtr::operator->() && { - auto ptr = std::move(*this).Load(); - assert(ptr && "Dereferencing invalid object"); - return ptr.get(); -} - -template -T* ObjPtr::operator->() const&& { - auto ptr = std::move(*this).Load(); - assert(ptr && "Dereferencing invalid object"); - return ptr.get(); -} - -template -T& ObjPtr::operator*() { - auto ptr = Load(); - assert(ptr && "Dereferencing invalid object"); - return *ptr; -} - -template -T& ObjPtr::operator*() const { - auto ptr = Load(); - assert(ptr && "Dereferencing invalid object"); - return *ptr; -} - -template -ProxyPtr ObjPtr::Load() & { - return ProxyPtr{ObjectPtrBase::LoadCached()}; -} - -template -ProxyPtr ObjPtr::Load() const& { - return ProxyPtr{ObjectPtrBase::LoadCached()}; -} - -template -Ptr ObjPtr::Load() && { - return Ptr{ObjectPtrBase::LoadCached()}; -} - -template -Ptr ObjPtr::Load() const&& { - return Ptr{ObjectPtrBase::LoadCached()}; -} - -template -ObjPtr ObjPtr::Clone() const { - return Clone(ObjId::GenerateUnique()); -} - -template -ObjPtr ObjPtr::Clone(ObjId obj_id) const { - assert(is_valid() && "Invalid clone ptr"); - assert(obj_id.is_valid() && "Invalid object ID"); - auto ptr = DomainGraph{domain()}.template LoadCopy(id(), obj_id); - return ObjPtr{domain(), obj_id, - static_cast(flags() & ~ObjFlags::kUnloaded), - std::move(ptr)}; -} - -template -auto WithLoadedImpl(U&& obj_ptr, Func&& func) -> decltype(auto) { - auto ptr = std::forward(obj_ptr).Load(); - using InvokeRes = decltype(std::invoke(std::forward(func), ptr)); - using ReturnType = std::conditional_t, bool, - std::optional>; - if (!ptr) { - return ReturnType{}; - } - if constexpr (std::is_void_v) { - std::invoke(std::forward(func), ptr); - return true; - } else { - return ReturnType{std::invoke(std::forward(func), ptr)}; - } -} - -template -template -auto ObjPtr::WithLoaded(Func&& func) -> decltype(auto) { - return WithLoadedImpl(*this, std::forward(func)); -} - -template -template -auto ObjPtr::WithLoaded(Func&& func) const -> decltype(auto) { - return WithLoadedImpl(*this, std::forward(func)); -} - -} // namespace ae - -namespace ae::seri { -template -struct Serializer, ObjPtr> { - using Archive = BinaryArchive; - - SeriResult Seri(Archive& archive, Meta const> meta) const { - return archive.Save(static_cast(meta.value)); - } - - SeriResult Deseri(Archive& archive, Meta> meta) const { - return archive.Load(static_cast(meta.value)); - } -}; -} // namespace ae::seri - -namespace ae::domain_visitor { -template -struct NodeVisitor> : NodeVisitor> { - using Policy = PolicyMatch; - using Base = NodeVisitor>; - void Visit(ae::ObjPtr& obj_ptr, CycleDetector& cycle_detector, - PtrRefDnv const& visitor) const { - Base::Visit(obj_ptr.cached(), cycle_detector, visitor); - } - - void Visit(ae::ObjPtr const& obj_ptr, CycleDetector& cycle_detector, - PtrRefDnv const& visitor) const { - Base::Visit(obj_ptr.cached(), cycle_detector, visitor); - } - - template - requires(!std::is_same_v>) - void Visit(ae::ObjPtr& obj_ptr, CycleDetector& cycle_detector, - Visitor&& visitor) const { - auto proxy = ae::ProxyPtr{obj_ptr.cached()}; - if (proxy) { - ApplyVisit(*proxy, cycle_detector, std::forward(visitor)); - } - } - - template - requires(!std::is_same_v>) - void Visit(ae::ObjPtr const& obj_ptr, CycleDetector& cycle_detector, - Visitor&& visitor) const { - auto proxy = ae::ProxyPtr{obj_ptr.cached()}; - if (proxy) { - ApplyVisit(*proxy, cycle_detector, std::forward(visitor)); - } - } - - private: - template - void ApplyVisit(U&& obj, CycleDetector& cycle_detector, - Visitor&& visitor) const { - domain_visitor::ApplyVisitor(std::forward(obj), cycle_detector, - std::forward(visitor)); - } -}; -} // namespace ae::domain_visitor - -#endif // AETHER_OBJ_OBJ_PTR_H_ diff --git a/aether/obj/obj_ptr_base.cpp b/aether/obj/obj_ptr_base.cpp deleted file mode 100644 index feede2e9..00000000 --- a/aether/obj/obj_ptr_base.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright 2024 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. - */ - -#include "aether/obj/obj_ptr_base.h" - -#include "aether/obj/domain.h" -#include "aether/obj/obj.h" -#include "aether/obj/obj_id.h" - -namespace ae { - -ObjectPtrBase::ObjectPtrBase() - : domain_{nullptr}, flags_{ObjFlags::kUnloaded} {} - -ObjectPtrBase::ObjectPtrBase(Domain* domain, ObjId obj_id, ObjFlags flags) - : domain_{domain}, id_{obj_id}, flags_{flags} {} - -ObjectPtrBase::ObjectPtrBase(Domain* domain, ObjId obj_id, ObjFlags flags, - Ptr ptr) noexcept - : domain_{domain}, id_{obj_id}, flags_{flags}, cached_{std::move(ptr)} {} - -ObjectPtrBase::ObjectPtrBase(ObjectPtrBase const& ptr) noexcept - : domain_{ptr.domain_}, id_{ptr.id_}, flags_{ptr.flags_} { - if (ptr.cached_) { - cached_ = ptr.cached_; - } -} - -ObjectPtrBase::ObjectPtrBase(ObjectPtrBase&& ptr) noexcept - : domain_{ptr.domain_}, id_{ptr.id_}, flags_{ptr.flags_} { - if (ptr.cached_) { - cached_ = std::move(ptr.cached_); - } -} - -ObjectPtrBase::~ObjectPtrBase() = default; - -ObjId ObjectPtrBase::id() const { return id_; } -ObjFlags ObjectPtrBase::flags() const { return flags_; } -Domain* ObjectPtrBase::domain() const { return domain_; } - -void ObjectPtrBase::SetFlags(ObjFlags flags) { flags_ = flags; } - -bool ObjectPtrBase::is_valid() const { return id_.is_valid(); } - -bool ObjectPtrBase::is_loaded() const { return static_cast(cached_); } - -Ptr const& ObjectPtrBase::LoadCached() { - if (cached_) { - return cached_; - } - if (!is_valid()) { - return cached_; - } - cached_ = DomainGraph{domain_}.LoadRoot(id_); - if (cached_) { - flags_ = flags_ & ~ObjFlags::kUnloaded; - } - return cached_; -} - -Ptr const& ObjectPtrBase::LoadCached() const { - return const_cast(this)->LoadCached(); // NOLINT(*const-cast) -} - -void ObjectPtrBase::Save() const { - if (cached_) { - DomainGraph{domain_}.SaveRoot(cached_, id_); - } -} - -void ObjectPtrBase::Reset() { - cached_.Reset(); - flags_ = flags_ & ObjFlags::kUnloaded; -} - -Ptr const& ObjectPtrBase::cached() const { return cached_; } -Ptr& ObjectPtrBase::cached() { return cached_; } - -ObjectPtrBase& ObjectPtrBase::operator=(ObjectPtrBase const& ptr) noexcept { - if (this != &ptr) { - domain_ = ptr.domain_; - id_ = ptr.id_; - flags_ = ptr.flags_; - if (ptr.cached_) { - cached_ = ptr.cached_; - } else { - cached_.Reset(); - } - } - return *this; -} - -ObjectPtrBase& ObjectPtrBase::operator=(ObjectPtrBase&& ptr) noexcept { - if (this != &ptr) { - domain_ = ptr.domain_; - id_ = ptr.id_; - flags_ = ptr.flags_; - - // Ptr move assignment swaps storage after resetting its destination. Move - // through a temporary and clear this cache first so ptr cannot receive the - // cache previously held by this ObjectPtrBase. - auto cache = std::move(ptr.cached_); - cached_ = Ptr{}; - cached_ = std::move(cache); - } - return *this; -} - -namespace seri { -using ObjPtrBaseSerializer = - Serializer, ObjectPtrBase>; - -SeriResult ObjPtrBaseSerializer::Seri(Archive& archive, - Meta meta) { - TRY_RESULT((archive.buffer().Write(DataTag{meta.value.id_}))); - TRY_RESULT((archive.buffer().Write(DataTag{meta.value.flags_}))); - if (meta.value.cached_) { - archive.buffer().domain_graph->SaveRoot(meta.value.cached_, meta.value.id_); - } - return Ok{seri::good}; -} - -SeriResult ObjPtrBaseSerializer::Deseri(Archive& archive, - Meta meta) { - meta.value.domain_ = archive.buffer().domain_graph->domain; - TRY_RESULT((archive.buffer().Read(DataTag{meta.value.id_}))); - TRY_RESULT((archive.buffer().Read(DataTag{meta.value.flags_}))); - meta.value.cached_.Reset(); - if (meta.value.is_valid() && - (meta.value.flags_ & ObjFlags::kUnloadedByDefault) == 0 && - (meta.value.flags_ & ObjFlags::kUnloaded) == 0) { - meta.value.cached_ = - archive.buffer().domain_graph->LoadRoot(meta.value.id_); - } - return Ok{seri::good}; -} -} // namespace seri -} // namespace ae diff --git a/aether/obj/obj_ptr_base.h b/aether/obj/obj_ptr_base.h deleted file mode 100644 index ae4b063b..00000000 --- a/aether/obj/obj_ptr_base.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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. - */ - -#ifndef AETHER_OBJ_OBJ_PTR_BASE_H_ -#define AETHER_OBJ_OBJ_PTR_BASE_H_ - -#include "aether-miscpp/serialization/serialization.h" - -#include "aether/obj/domain.h" -#include "aether/obj/obj_id.h" -#include "aether/ptr/ptr.h" - -namespace ae { - -class Obj; - -class ObjectPtrBase { - friend struct seri::Serializer, - ObjectPtrBase>; - - public: - ObjectPtrBase(); - ObjectPtrBase(Domain* domain, ObjId obj_id, ObjFlags flags); - ObjectPtrBase(Domain* domain, ObjId obj_id, ObjFlags flags, - Ptr ptr) noexcept; - - ObjectPtrBase(ObjectPtrBase const& ptr) noexcept; - ObjectPtrBase(ObjectPtrBase&& ptr) noexcept; - ObjectPtrBase& operator=(ObjectPtrBase const& ptr) noexcept; - ObjectPtrBase& operator=(ObjectPtrBase&& ptr) noexcept; - ~ObjectPtrBase(); - - ObjId id() const; - ObjFlags flags() const; - Domain* domain() const; - - void SetFlags(ObjFlags flags); - - bool is_valid() const; - bool is_loaded() const; - Ptr const& LoadCached(); - Ptr const& LoadCached() const; - void Save() const; - void Reset(); - - Ptr const& cached() const; - Ptr& cached(); - - protected: - Domain* domain_; - ObjId id_; - ObjFlags flags_; - Ptr cached_; -}; - -namespace seri { -template <> -struct Serializer, ObjectPtrBase> { - using Archive = BinaryArchive; - - static SeriResult Seri(Archive& archive, Meta meta); - - static SeriResult Deseri(Archive& archive, Meta meta); -}; -} // namespace seri -} // namespace ae - -#endif // AETHER_OBJ_OBJ_PTR_BASE_H_ diff --git a/aether/obj/obj_tele.h b/aether/obj/obj_tele.h deleted file mode 100644 index 5e9e68c7..00000000 --- a/aether/obj/obj_tele.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2024 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. - */ - -#ifndef AETHER_OBJ_OBJ_TELE_H_ -#define AETHER_OBJ_OBJ_TELE_H_ - -#include "aether/tele.h" - -AE_TELE_MODULE(kObj, 1, 1, 2); -AE_TAG(ObjectDomainUpdatePastTime, kObj); -AE_TAG(ObjectRegistryLog, kObj); - -#endif // AETHER_OBJ_OBJ_TELE_H_ diff --git a/aether/obj/registrar.h b/aether/obj/registrar.h deleted file mode 100644 index 932be7de..00000000 --- a/aether/obj/registrar.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2024 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. - */ - -#ifndef AETHER_OBJ_REGISTRAR_H_ -#define AETHER_OBJ_REGISTRAR_H_ - -#include - -#include "aether-miscpp/meta/type_index.h" - -#include "aether/ptr/ptr.h" -#include "aether/obj/domain.h" -#include "aether/obj/registry.h" - -namespace ae { -template -class Registrar { - public: - Registrar(std::uint32_t cls_id, std::uint32_t base_id) noexcept { - Registry::GetRegistry().RegisterClass( - cls_id, base_id, - { - Factory::CreateFunc(&Create), - Factory::LoadFunc(&Load), - Factory::SaveFunc(&Save), -#ifdef DEBUG - std::string{GetTypeName()}, - cls_id, - base_id, -#endif // DEBUG - }); - } - - private: - // like std::is_default_constructible but with respect to Registrar<-Ojb - // friendship - template - struct IsDefaultConstructible : std::false_type {}; - template - struct IsDefaultConstructible> - : std::true_type {}; - - static Ptr Create() { - if constexpr (std::is_abstract_v) { - assert(false && "Create called on abstract class"); - return {}; - } else { - static_assert(IsDefaultConstructible::value, - "AE_OBJECT class should be default constructible"); - return MakePtr(); - } - } - - static void Load(DomainGraph* domain_graph, Ptr& obj, ObjId obj_id) { - auto* self_ptr = static_cast(obj.get()); - domain_graph->Load(*self_ptr, obj_id); - } - - static void Save(DomainGraph* domain_graph, Ptr const& obj, ObjId id) { - auto const* self_ptr = static_cast(obj.get()); - domain_graph->Save(*self_ptr, id); - } -}; -} // namespace ae -#endif // AETHER_OBJ_REGISTRAR_H_ diff --git a/aether/obj/registry.cpp b/aether/obj/registry.cpp deleted file mode 100644 index 6f4cf980..00000000 --- a/aether/obj/registry.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2024 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. - */ - -#include "aether/obj/registry.h" - -#include - -#include "aether-miscpp/crc.h" -#include "aether/obj/obj_tele.h" - -namespace ae { -Registry& Registry::GetRegistry() { - static Registry registry; - return registry; -} - -void Registry::RegisterClass(uint32_t cls_id, std::uint32_t base_id, - Factory&& factory) { -#if DEBUG - // Fixme: Commented out to fix the build crash in MinGW - /*std::cout << "Registering class " << factory.class_name << " id " << cls_id - << " with base " << base_id << std::endl;*/ - - // TODO: move into compil-time. - // TODO: check at compile-time that the base_id to be existing class. - // Visual Studio 2017 has a bug with multiple static inline members - // initialization - // https://developercommunity.visualstudio.com/t/multiple-initializations-of-inline-static-data-mem/261624 - // Refer to - // https://learn.microsoft.com/en-us/cpp/overview/compiler-versions?view=msvc-170 -# if !defined(_MSC_VER) || _MSC_VER >= 1920 - auto no_duplication = factories.find(cls_id) == factories.end(); - assert(no_duplication && "Duplicate class id in registry"); -# endif // !defined(_MSC_VER) || _MSC_VER >= 1920 -#endif // DEBUG - factories.emplace(cls_id, std::move(factory)); - // TODO: maybe remove this check - if (base_id != crc32::from_literal("Obj").value) { - relations[base_id].push_back(cls_id); - } -} - -bool Registry::IsExisting(uint32_t class_id) { - return factories.find(class_id) != factories.end(); -} - -int Registry::GenerationDistanceInternal(std::uint32_t base_id, - std::uint32_t derived_id) { - auto d = relations.find(base_id); - // The base class is final. - if (d == relations.end()) { - return -1; - } - - for (auto& c : d->second) { - if (derived_id == c) { - return 1; - } - - int distance = GenerationDistanceInternal(c, derived_id); - if (distance >= 0) { - return distance + 1; - } - } - - return -1; -} - -int Registry::GenerationDistance(std::uint32_t base_id, - std::uint32_t derived_id) { - if (!IsExisting(base_id) || !IsExisting(derived_id)) { - return -1; - } - - if (base_id == derived_id) { - return 0; - } - - return GenerationDistanceInternal(base_id, derived_id); -} - -Factory* Registry::FindFactory(std::uint32_t base_id) { - auto it = factories.find(base_id); - if (it == factories.end()) { - return nullptr; - } - return &it->second; -} - -#if DEBUG -std::string_view Registry::ClassName(std::uint32_t class_id) { - if (class_id == crc32::from_literal("Obj").value) { - return "ae::Obj"; - } - auto* f = FindFactory(class_id); - if (f == nullptr) { - return "Unknown"; - } - return f->class_name; -} -#endif // DEBUG - -void Registry::Log() { -#if DEBUG - for (const auto& c : factories) { - AE_TELE_DEBUG(ObjectRegistryLog, "name {}, id {}, base_id {}", - c.second.class_name, c.second.cls_id, c.second.base_id); - } -#endif // DEBUG -} - -} // namespace ae diff --git a/aether/obj/registry.h b/aether/obj/registry.h deleted file mode 100644 index c44e654d..00000000 --- a/aether/obj/registry.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2024 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. - */ - -#ifndef AETHER_OBJ_REGISTRY_H_ -#define AETHER_OBJ_REGISTRY_H_ - -#include -#include -#include -#include - -#include "aether/config.h" -#include "aether/ptr/ptr.h" -#include "aether/obj/obj_id.h" - -namespace ae { -class Obj; -class Domain; -class DomainGraph; - -struct Factory { - using CreateFunc = Ptr (*)(); - using LoadFunc = void (*)(DomainGraph* domain_graph, Ptr& obj, ObjId id); - using SaveFunc = void (*)(DomainGraph* domain_graph, Ptr const& obj, - ObjId id); - - CreateFunc create; - LoadFunc load; - SaveFunc save; -#if DEBUG - std::string class_name{}; - std::uint32_t cls_id{}; - std::uint32_t base_id{}; -#endif // DEBUG -}; - -class Registry { - public: - using Relations = std::unordered_map>; - using Factories = std::unordered_map; - - static Registry& GetRegistry(); - - void RegisterClass(std::uint32_t cls_id, std::uint32_t base_id, Factory&& factory); - void Log(); - bool IsExisting(std::uint32_t class_id); - - int GenerationDistanceInternal(std::uint32_t base_id, - std::uint32_t derived_id); - - // Calculates distance from base to derived in generations: - // -1 - derived is not inherited directly or indirectly from base or any - // class doesn't exist. - int GenerationDistance(std::uint32_t base_id, std::uint32_t derived_id); - - Factory* FindFactory(std::uint32_t base_id); - -#if DEBUG - std::string_view ClassName(std::uint32_t class_id); -#endif // DEBUG - - Relations relations; - Factories factories; -}; -} // namespace ae - -#endif // AETHER_OBJ_REGISTRY_H_ */ diff --git a/aether/obj/version_iterator.h b/aether/obj/version_iterator.h deleted file mode 100644 index 1cb71847..00000000 --- a/aether/obj/version_iterator.h +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright 2024 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. - */ - -#ifndef AETHER_OBJ_VERSION_ITERATOR_H_ -#define AETHER_OBJ_VERSION_ITERATOR_H_ - -#include -#include -#include -#include - -#include "aether-miscpp/meta/index_sequence.h" - -namespace ae { -using VersionValueType = std::uint8_t; - -// use max version for compilation time optimization -// increase max version count if required -#ifdef MAX_OBJECT_VERSION -inline constexpr VersionValueType kMaxVersion = MAX_OBJECT_VERSION; -#else -inline constexpr VersionValueType kMaxVersion = 24; -#endif - -// Helper version tag for versioned function overloading -template - requires(V <= kMaxVersion) -struct Version : public std::integral_constant {}; - -// Traits for check supported versioned functionality - -struct Dnv; - -template -struct VersionLoadTrait { - template - struct Has : std::false_type {}; - template - struct Has().Load( - Version{}, std::declval()))>> : std::true_type {}; - - static constexpr bool value = Has::value; -}; - -template -struct VersionSaveTrait { - template - struct Has : std::false_type {}; - template - struct Has().Save( - Version{}, std::declval()))>> : std::true_type {}; - - static constexpr bool value = Has::value; -}; - -/** - * \brief Calculate min and max version supported by T and tested with - * VersionTrait - */ -template typename VersionTrait> -struct VersionBounds { - template - using i_seq = std::integer_sequence; - - template - static consteval auto CalcVersionBounds(i_seq) - -> std::pair { - constexpr auto arr = std::array{VersionTrait::value...}; - VersionValueType min{}; - VersionValueType max{}; - std::size_t i = 0; - for (; i < arr.size(); ++i) { - if (arr[i]) { - break; - } - } - if (i == arr.size()) { - return {0, 0}; - } - - min = static_cast(i); - - for (; i < arr.size(); ++i) { - if (!arr[i]) { - break; - } - } - max = static_cast(i - 1); - return {min, max}; - } - - static constexpr auto value = CalcVersionBounds( - std::make_integer_sequence()); -}; - -template typename VersionTrait> -struct HasAnyVersioned { - template - static consteval bool TestAny( - std::integer_sequence const&) { - return (VersionTrait::value || ...); - } - - static constexpr auto version_bounds = VersionBounds::value; - static constexpr bool value = - TestAny(make_range_sequence()); -}; - -template -struct HasAnyVersionedLoad : public HasAnyVersioned {}; -template -static constexpr inline bool HasAnyVersionedLoad_v = - HasAnyVersionedLoad::value; - -template -struct HasAnyVersionedSave : public HasAnyVersioned {}; -template -static constexpr inline bool HasAnyVersionedSave_v = - HasAnyVersionedSave::value; - -/** - * \brief Iterate for each version of the object for that VersionTrait returns - * true - * \tparam VersionTrait Trait to check if version is supported - * \tparam T Object type - * \tparam TFunc Function to call for each version with signature - * void(Version, T&) - * \param t Object to iterate - * \param func Function to call for each version - */ -template