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}) diff --git a/src/flightloop.cpp b/src/flightloop.cpp new file mode 100644 index 0000000..d73a5b0 --- /dev/null +++ b/src/flightloop.cpp @@ -0,0 +1,79 @@ +// 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" + +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);