From c9acb5dab84d0afbe70e78677579875eec1c4db7 Mon Sep 17 00:00:00 2001 From: Julia DeMille Date: Thu, 9 Nov 2023 09:20:12 -0600 Subject: [PATCH 1/3] Implement FlightLoop with XPLMCreateFlightLoop. Requires C++20. Handler kept as a member of the flight loop to ensure memory safety. Using templates with concepts rather than casting to abstract class, so that sizes are absolute. Marked abstract class Processor deprecated. Signed-off-by: Julia DeMille --- src/flightloop.cpp | 51 +++++++++++++++++++++ src/flightloop.h | 110 +++++++++++++++++++++++++++++++++++++++++++++ src/processor.h | 2 +- 3 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 src/flightloop.cpp create mode 100644 src/flightloop.h diff --git a/src/flightloop.cpp b/src/flightloop.cpp new file mode 100644 index 0000000..57f6f2f --- /dev/null +++ b/src/flightloop.cpp @@ -0,0 +1,51 @@ +#include "flightloop.h" +#include "XPLMProcessing.h" + +namespace PPL { + +template + requires impl_FlightLoopHandler +FlightLoop::FlightLoop(FlightLoopPhase phase, T handler_) + : handler(handler_) +{ + XPLMFlightLoopPhaseType x_phase; + switch (phase) { + case FlightLoopPhase::BeforeFlightModel: + x_phase = xplm_FlightLoop_Phase_BeforeFlightModel; + break; + case FlightLoopPhase::AfterFlightModel: + x_phase = xplm_FlightLoop_Phase_AfterFlightModel; + break; + } + XPLMCreateFlightLoop_t create_fl = { + sizeof(XPLMCreateFlightLoop_t), + x_phase, + FlightLoop::do_flight_loop, + &handler + }; + loop_id = XPLMCreateFlightLoop(&create_fl); +} + +template + requires impl_FlightLoopHandler +void FlightLoop::schedule(float when, bool relative_to_now) +{ + XPLMScheduleFlightLoop(loop_id, when, relative_to_now); +} + +template + requires impl_FlightLoopHandler +FlightLoop::~FlightLoop() +{ + XPLMDestroyFlightLoop(loop_id); +} + +template + requires impl_FlightLoopHandler +float FlightLoop::do_flight_loop(float time_since_last_call, float time_since_last_loop, int counter, void* refcon) +{ + T* handler = static_cast(refcon); + handler->do_flight_loop(time_since_last_call, time_since_last_loop, counter); +} + +} \ No newline at end of file diff --git a/src/flightloop.h b/src/flightloop.h new file mode 100644 index 0000000..f2d985d --- /dev/null +++ b/src/flightloop.h @@ -0,0 +1,110 @@ +// Copyright (c) 2023 Julia DeMille +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors +// may be used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#ifndef PPL_FLIGHTLOOP_H +#define PPL_FLIGHTLOOP_H + +#include "XPLMProcessing.h" +#include + +namespace PPL { + +/** + * @brief Phase to run a @ref PPL::FlightLoop in. + */ +enum class FlightLoopPhase { + /** + * @brief Run the @ref PPL::FlightLoop before the flight model. + */ + BeforeFlightModel, + /** + * @brief Run the @red PPL::FlightLoop after the flight model. + */ + AfterFlightModel +}; + +/** + * @brief Abstract class to be inherited by flight loop handlers. + */ +class FlightLoopHandler { +public: + FlightLoopHandler(); + virtual ~FlightLoopHandler() = 0; + /** + * @brief Handler function for the flight loop. + * + * @param time_since_last_call Time in seconds since this loop was last called. + * @param time_since_last_loop Time in seconds since any flight loop was last called. + * @param counter A counter that the simulator increases each time it dispatches a flight loop. + * @return float When to next run this function: + * Positive values: N seconds. + * Negative values (must be integer): N simulation frames. + * Zero: Deactivate this callback. It will remain registered. + */ + virtual float do_flight_loop(float time_since_last_call, float time_since_last_loop, int counter) = 0; +}; + +template +concept impl_FlightLoopHandler = std::derived_from && (!std::same_as); + +/** + * @brief A flight loop object. + * + * @tparam T The handler type for the flight loop. Must implement @ref PPL::FlightLoopHandler. + */ +template + requires impl_FlightLoopHandler +class FlightLoop { +public: + /** + * @brief Construct a new flight loop object. + * + * @param phase The phase in which to execute this flight loop. + * @param handler The handler for the flight loop. + */ + FlightLoop(FlightLoopPhase phase, T handler); + /** + * @brief Schedule this flight loop. + * + * @param when When to run this flight loop next. A positive value indicates seconds. + * A negative value (must be an integer) indicates number of simulation frames. + * @param relative_to_now Interpret `when` as relative to now. If `false`, it will be interpreted as + * relative to the time the callback was last called (or when it was registered, if never called). + */ + void schedule(float when, bool relative_to_now); + ~FlightLoop(); + +private: + static float do_flight_loop(float time_since_last_call, float time_since_last_loop, int counter, void* refcon); + XPLMFlightLoopID loop_id; + T handler; +}; + +} // namespace PPL + +#endif // PPL_FLIGHTLOOP_H \ No newline at end of file diff --git a/src/processor.h b/src/processor.h index 3d253d7..c131f01 100644 --- a/src/processor.h +++ b/src/processor.h @@ -30,7 +30,7 @@ namespace PPL { -class Processor +class [[deprecated("Replaced by PPL::FlightLoop.")]] Processor { public: Processor(float time_to_start = -1.f); From 2d8d0ed0b8850fa8d315d267eea16a8d46b1a179 Mon Sep 17 00:00:00 2001 From: Julia DeMille Date: Thu, 9 Nov 2023 09:29:30 -0600 Subject: [PATCH 2/3] Add forgotten license header. Signed-off-by: Julia DeMille --- src/flightloop.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/flightloop.cpp b/src/flightloop.cpp index 57f6f2f..d73a5b0 100644 --- a/src/flightloop.cpp +++ b/src/flightloop.cpp @@ -1,3 +1,31 @@ +// Copyright (c) 2023 Julia DeMille +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors +// may be used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + #include "flightloop.h" #include "XPLMProcessing.h" From 265aaeb3f3cfede4d12c58bc50dbd1d28f213cf7 Mon Sep 17 00:00:00 2001 From: Julia DeMille Date: Thu, 9 Nov 2023 09:33:35 -0600 Subject: [PATCH 3/3] Set CXX standard and bump version. Signed-off-by: Julia DeMille --- CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3d3b66a..bed174b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required (VERSION 3.0) -project(PPL VERSION 2.0.0 DESCRIPTION "Plugin Patterns Library for X-Plane 11/12") +project(PPL VERSION 2.1.0 DESCRIPTION "Plugin Patterns Library for X-Plane 11/12") -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_VERBOSE_MAKEFILE ON) @@ -65,8 +65,8 @@ set(DEFINITIONS XPLM301=1 ${PLATFORM_CORE_DEFINITIONS}) -include_directories(${CMAKE_SOURCE_DIR}/../SDK/CHeaders/XPLM - ${CMAKE_SOURCE_DIR}/../SDK/CHeaders/Widgets +include_directories(${CMAKE_SOURCE_DIR}/include/SDK/CHeaders/XPLM + ${CMAKE_SOURCE_DIR}/include/SDK/CHeaders/Widgets ${CMAKE_SOURCE_DIR}/include/simpleini ${PLATFORM_INCLUDE_DIRECTORIES})