From 8e3a6609db74b47f1a542755a41f47d2617ac5c2 Mon Sep 17 00:00:00 2001 From: fusiled Date: Sun, 14 Jun 2026 20:38:13 -0500 Subject: [PATCH] Complete first example And other fixes. Adjust nix environment to build with clang --- .github/workflows/verify_guided_examples.yml | 40 ++++++++ .gitignore | 3 +- README.md | 3 +- .../1_FirstModule_and_SimoSim/CMakeLists.txt | 11 +-- .../1_FirstModule_and_SimoSim/README.md | 92 ++++++++++++++++--- .../1_FirstModule_and_SimoSim/flake.lock | 82 ----------------- docs/guided_examples/README.md | 3 + docs/guided_examples/build_all_examples.sh | 28 ++++++ .../{1_FirstModule_and_SimoSim => }/flake.nix | 3 +- flake.nix | 3 +- include/Simo/core/Time.h | 4 +- include/Simo/port/Port.h | 4 +- support/scripts/cpp-check-format.sh | 17 +++- 13 files changed, 181 insertions(+), 112 deletions(-) create mode 100644 .github/workflows/verify_guided_examples.yml delete mode 100644 docs/guided_examples/1_FirstModule_and_SimoSim/flake.lock create mode 100644 docs/guided_examples/README.md create mode 100755 docs/guided_examples/build_all_examples.sh rename docs/guided_examples/{1_FirstModule_and_SimoSim => }/flake.nix (96%) diff --git a/.github/workflows/verify_guided_examples.yml b/.github/workflows/verify_guided_examples.yml new file mode 100644 index 0000000..4f7f016 --- /dev/null +++ b/.github/workflows/verify_guided_examples.yml @@ -0,0 +1,40 @@ +# Copyright 2026 Matteo Fusi and Contributors +# +# 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. +name: "Build Guided Examples" +on: + push: + branches: [ "main" ] + paths: + - 'docs/guided_examples/**' + pull_request: + branches: [ "main" ] + paths: + - 'docs/guided_examples/**' +env: + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: Release +jobs: + Build-Guided-Examples: + strategy: + matrix: + os: [ ubuntu-latest ] + name: Build and test (${{ matrix.os }}) + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v5 + - uses: cachix/install-nix-action@v31 + with: + github_access_token: ${{ secrets.GITHUB_TOKEN }} + - name: Build Examples + run: cd docs/guided_examples && nix develop --command ./build_all_examples.sh diff --git a/.gitignore b/.gitignore index faf5f38..07d1fb4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /.idea /cmake-build-* -/docs/tutorial/build* +/docs/guided_examples/*/build* +/docs/guided_examples/flake.lock diff --git a/README.md b/README.md index 51590fb..bb40bb2 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ cd Simo Clone Simo and initialize the submodules: Build dependencies: +- Clang (recommended) - CMake >= 3.31.0 - Boost ([Boost.Test](https://www.boost.org/libs/test), [Boost.TypeIndex](https://www.boost.org/libs/type_index)) - [Glaze](https://github.com/stephenberry/glaze) @@ -42,7 +43,7 @@ The GitHub actions run entering the virtual environment of `nix develop`. ## First Steps -Look inside [docs/tutorial](./docs/tutorial) . +Look inside [docs/guided_examples](./docs/guided_examples) . ## Features diff --git a/docs/guided_examples/1_FirstModule_and_SimoSim/CMakeLists.txt b/docs/guided_examples/1_FirstModule_and_SimoSim/CMakeLists.txt index cedd6b9..dc2cfad 100644 --- a/docs/guided_examples/1_FirstModule_and_SimoSim/CMakeLists.txt +++ b/docs/guided_examples/1_FirstModule_and_SimoSim/CMakeLists.txt @@ -21,21 +21,16 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) # Look for Simo package find_package(Simo REQUIRED) -get_filename_component(SIMO_PACKAGE_PREFIX "${Simo_DIR}/../../.." ABSOLUTE) - # Create you collection of modules -add_library(TutorialCollection SHARED +add_library(FirstModuleCollection SHARED FirstModule.cc ) # Hide symbols by default -set_target_properties(TutorialCollection PROPERTIES +set_target_properties(FirstModuleCollection PROPERTIES CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN 1 ) # Use Simo::Simo_includes_only to only use the include files and avoid direct linking to Simo -target_link_libraries(TutorialCollection PRIVATE Simo::Simo_includes_only) -target_include_directories(TutorialCollection PRIVATE - "${SIMO_PACKAGE_PREFIX}/include" -) +target_link_libraries(FirstModuleCollection PRIVATE Simo::Simo_includes_only) diff --git a/docs/guided_examples/1_FirstModule_and_SimoSim/README.md b/docs/guided_examples/1_FirstModule_and_SimoSim/README.md index 450daa0..b1efe59 100644 --- a/docs/guided_examples/1_FirstModule_and_SimoSim/README.md +++ b/docs/guided_examples/1_FirstModule_and_SimoSim/README.md @@ -5,15 +5,17 @@ The documents highlights some location in the source of [FirstModule.cc](./First to better understand how to write your own `Module` class and how to use it in `SimoSim`, a general purpose executable to run simulations. +It is assumed that this example is executed inside the nix development environment +provided by [`../flake.nix`](../flake.nix). -### You first module +## You first module Modules are the basic block of the simulation. They have the ability to schedule events in the simulation loop. To create a new module, it is enough to inherit from `Simo::Module` class. -#### Module initialization +### Module initialization All the classed are declared in the include `Simo/Simo.h` and they are contained in the `Simo` namespace. @@ -56,21 +58,87 @@ Other interesting content in the `initialize` method: - a new statistic is created with `create_statistic` method. - logging is set up to save the log at `tutorial_module.log` -#### Module event +### Module event `event_log` runs first at time zero, and it re-schedules itself every `period` time units -using the simulation context. Look for `Simo/core/Context.h` for the difference between -`schedule_at` and `schedule_in` of . +using the simulation context. Look at `Simo/core/Context.h` for the difference between +`schedule_at` and `schedule_in` . Source of the method: - ```cpp void log_event() { -// schedule_in schedule and event at current_time + period -++(*num_events); -log(Log::LogLevel::INFO, [this]() { - return std::format("{}, Hello from TestModule!", num_events->value()); -}); -sim_ctx().schedule_in(period, [this]() { log_event(); }); + // schedule_in schedule and event at current_time + period + ++(*num_events); + log(Log::LogLevel::INFO, [this]() { + return std::format("{}, Hello from TestModule!", num_events->value()); + }); + sim_ctx().schedule_in(period, [this]() { log_event(); }); } ``` + +This function above increase the statistic, and it logs the event in the logger. + +### Parameters for the module + +`Parameters` class defines a set of parameters. Parameters are organized in a +trie-like structure. The easiest way to define parameters for a new module is to +extend the `Parameters` class, and add parameter definitions in the constructor. + +```cpp +class FirstModuleParameters : public Parameters { + public: + // Parameters describe inputs of a Module. + // Parameters with a default value are added with `trie.add<>` + // and without a default with `trie.add_unset<>` + FirstModuleParameters() { + // validator method is used to verify if a parameter is valid + trie.add_unset