From 99bfbeb7f32460acd2f2a2658d22431c39eb1f59 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 15 Mar 2024 19:39:05 -0400 Subject: [PATCH] pysimulator: initial commit --- .gitignore | 6 +++ CMakeLists.txt | 44 ++++++++++++++++++ README.md | 70 +++++++++++++++++++++++++++++ cmake/xo_pysimulatorConfig.cmake.in | 4 ++ include/README.md | 2 + src/pysimulator/CMakeLists.txt | 8 ++++ src/pysimulator/pysimulator.cpp | 66 +++++++++++++++++++++++++++ src/pysimulator/pysimulator.hpp.in | 25 +++++++++++ 8 files changed, 225 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 README.md create mode 100644 cmake/xo_pysimulatorConfig.cmake.in create mode 100644 include/README.md create mode 100644 src/pysimulator/CMakeLists.txt create mode 100644 src/pysimulator/pysimulator.cpp create mode 100644 src/pysimulator/pysimulator.hpp.in diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..53a9c92f --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +# lsp keeps state here +.cache +# typical build directory +.build* +# lsp: symlink to file in build directory (established manually) +compile_commands.json diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..25398891 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,44 @@ +# xo-pysimulator/CMakeLists.txt + +cmake_minimum_required(VERSION 3.10) + +project(xo_pysimulator VERSION 0.1) +enable_language(CXX) + +# common XO cmake macros (see https://github.com:rconybea/xo-cmake.git) +include(xo_macros/xo-project-macros) + +# ---------------------------------------------------------------- +# unit test setup + +enable_testing() +# activate code coverage for all executables + libraries (when configured with -DCODE_COVERAGE=ON) +add_code_coverage() +# 1. assuming that /nix/store/ prefixes .hpp files belonging to gcc, catch2 etc. +# we're not interested in code coverage for these sources. +# 2. exclude the utest/ subdir, we don't need coverage on the unit tests themselves; +# rather, want coverage on the code that the unit tests exercise. +# +# NOTE: this seems to work only with the 'ccov-all' target. In particular, doesn't seem to do anything with the 'ccov' target +# +add_code_coverage_all_targets(EXCLUDE /nix/store/* ${PROJECT_SOURCE_DIR}/utest/* ${PROJECT_BINARY_DIR}/local/* ${PROJECT_SOURCE_DIR}/repo/*) + +# ---------------------------------------------------------------- +# c++ settings (usually temporary) + +set(PROJECT_CXX_FLAGS "") +add_definitions(${PROJECT_CXX_FLAGS}) + +xo_toplevel_compile_options() + +# ---------------------------------------------------------------- +# sources + +add_subdirectory(src/pysimulator) +#add_subdirectory(utest) + +# ---------------------------------------------------------------- +# provide find_package() support + +xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets) + diff --git a/README.md b/README.md new file mode 100644 index 00000000..676fe720 --- /dev/null +++ b/README.md @@ -0,0 +1,70 @@ +# python bindings for c++ reflection library (xo-pysimulator) + +## Getting Started + +### build + install dependencies + +- [github/Rconybea/xo-simulator](https://github.com/Rconybea/xo-simulator) +- [github/Rconybea/xo-pyutil](https://github.com/Rconybea/xo-pyutil) +- [github/Rconybea/xo-pyreflect](https://github.com/Rconybea/xo-pyreflect) +- [github/Rconybea/xo-pyprintjson](https://github.com/Rconybea/xo-pyprintjson) +- [github/Rconybea/xo-pyreactor](https://github.com/Rconybea/xo-pyreactor) + +### build + install +``` +$ cd xo-pysimulator +$ mkdir build +$ cd build +$ INSTALL_PREFIX=/usr/local # or wherever you prefer, e.g. ~/local +$ cmake \ + -DCMAKE_MODULE_PATH=${INSTALL_PREFIX}/share/cmake \ + -DCMAKE_PREFIX_PATH=${INSTALL_PREFIX} \ + -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} .. +$ make +$ make install +``` +(also see .github/workflows/main.yml) + +## Examples + +Assumes `xo-pysimulator` installed to `~/local2/lib` +``` +PYTHONPATH=~/local2/lib:$PYTHONPATH python +>>> import xo_pysimulator +>>> dir(xo_pysimulator) +['Simulator', 'SourceTimestamp', 'TimeSlip', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'make_simulator'] +>>> + +## Development + +### build for unit test coverage +``` +$ cd xo-pysimulator +$ mkdir build-ccov +$ cd build-ccov +$ cmake \ + -DCMAKE_MODULE_PATH=${INSTALL_PREFIX}/share/cmake \ + -DCMAKE_PREFIX_PATH=${INSTALL_PREFIX} \ + -DCODE_COVERAGE=ON \ + -DCMAKE_BUILD_TYPE=Debug .. +``` + +### LSP (language server) support + +LSP looks for compile commands in the root of the source tree; +while `cmake` creates them in the root of its build directory. + +``` +$ cd xo-pysimulator +$ ln -s build/compile_commands.json # supply compile commands to LSP +``` + +## Examples + +Assumes `xo-pysimulator` installed to `~/local2/lib` + +``` +PYTHONPATH=~/local2/lib python +>>> import pysimulator +>>> dir(pysimulator) +``` diff --git a/cmake/xo_pysimulatorConfig.cmake.in b/cmake/xo_pysimulatorConfig.cmake.in new file mode 100644 index 00000000..9c15f36a --- /dev/null +++ b/cmake/xo_pysimulatorConfig.cmake.in @@ -0,0 +1,4 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") +check_required_components("@PROJECT_NAME@") diff --git a/include/README.md b/include/README.md new file mode 100644 index 00000000..12c02f54 --- /dev/null +++ b/include/README.md @@ -0,0 +1,2 @@ +placeholder for future pysimulator #include files + diff --git a/src/pysimulator/CMakeLists.txt b/src/pysimulator/CMakeLists.txt new file mode 100644 index 00000000..c88c44d0 --- /dev/null +++ b/src/pysimulator/CMakeLists.txt @@ -0,0 +1,8 @@ +# xo_pysimulator/src/pysimulator/CMakeLists.txt + +set(SELF_LIB xo_pysimulator) +set(SELF_SRCS pysimulator.cpp) + +xo_pybind11_library(${SELF_LIB} ${PROJECT_NAME}Targets ${SELF_SRCS}) +xo_pybind11_dependency(${SELF_LIB} simulator) +xo_pybind11_dependency(${SELF_LIB} xo_pyutil) diff --git a/src/pysimulator/pysimulator.cpp b/src/pysimulator/pysimulator.cpp new file mode 100644 index 00000000..c1077b0a --- /dev/null +++ b/src/pysimulator/pysimulator.cpp @@ -0,0 +1,66 @@ +/* @file pysimulator.cpp */ + +#include "pysimulator.hpp" +#include "xo/pyreactor/pyreactor.hpp" + +#include "xo/simulator/Simulator.hpp" +#include "xo/simulator/SourceTimestamp.hpp" +#include "xo/simulator/TimeSlip.hpp" +#include "xo/pyutil/pyutil.hpp" +//#include +//#include +//#include + +namespace xo { + using xo::reactor::Reactor; + //using xo::scope; + namespace py = pybind11; + + namespace sim { + PYBIND11_MODULE(PYSIMULATOR_MODULE_NAME(), m) { + /* e.g. for Reactor */ + PYREACTOR_IMPORT_MODULE(); //py::module_::import("pyreactor") + + /* module docstring */ + m.doc() = "pybind11 plugin for xo.simulator"; + + m.def("make_simulator", + []() { + return xo::sim::Simulator::make(xo::time::timeutil::epoch()); + }, + "create new Simulator instance"); + + py::class_(m, "TimeSlip") + .def_property_readonly("sim_tm", &TimeSlip::sim_tm) + .def_property_readonly("real_tm", &TimeSlip::real_tm) + // .def("__repr__", &TimeSlip::display_string) // TODO + ; + + py::class_>(m, "Simulator") + .def_static("make", []() { return xo::sim::Simulator::make(xo::time::timeutil::epoch()); }) + .def_property_readonly("start_tm", &Simulator::t0) + .def_property_readonly("last_tm", &Simulator::last_tm) + .def_property_readonly("n_event", &Simulator::n_event) + .def_property_readonly("is_exhausted", &Simulator::is_exhausted) + .def("next_tm", &Simulator::next_tm) + .def("next_src", &Simulator::next_src) + .def("timeslip", &Simulator::timeslip) + .def("throttled_event_dt", &Simulator::throttled_event_dt) + .def("heap_contents", &Simulator::heap_contents) + .def("log_heap_contents", + [](Simulator & self) { + scope log(XO_LITERAL(log_level::always, "pysimulator", ".log_heap_contents")); + self.log_heap_contents(&log); + }) + .def("__repr__", &Simulator::display_string); + + py::class_(m, "SourceTimestamp") + .def("__repr__", &SourceTimestamp::display_string); + + } /*pysimulator*/ + } /*namespace sim*/ +} /*namespace xo*/ + +/* end pysimulator.cpp */ diff --git a/src/pysimulator/pysimulator.hpp.in b/src/pysimulator/pysimulator.hpp.in new file mode 100644 index 00000000..db3656c5 --- /dev/null +++ b/src/pysimulator/pysimulator.hpp.in @@ -0,0 +1,25 @@ +/* @file pysimulator.hpp + * + * automatically generated from src/xo_pysimulator/pysimulator.hpp.in + * see src/xo_pysimulator/CMakeLists.txt + */ + +/* python requires module name = library name + * example: + * PYBIND11_MODULE(PYSIMULATOR_MODULE_NAME(), m) { ... } + */ +#define PYSIMULATOR_MODULE_NAME() @SELF_LIB@ + +/* example: + * py::module_::import(PYSIMULATOR_MODULE_NAME_STR) + */ +#define PYSIMULATOR_MODULE_NAME_STR "@SELF_LIB@" + +/* example: + * PYSIMULATOR_IMPORT_MODULE() + * replaces + * py::module_::import("pysimulator") + */ +#define PYSIMULATOR_IMPORT_MODULE() py::module_::import("@SELF_LIB@") + +/* end pysimulator.hpp */