From 342c5f03d80ca9403f914c7274de96bb8570b74d Mon Sep 17 00:00:00 2001 From: Jack Deeth Date: Sat, 31 Mar 2018 05:01:29 +0100 Subject: [PATCH 1/3] Add Command class --- ppl.pro | 6 ++- src/command.cpp | 64 +++++++++++++++++++++++++ src/command.h | 121 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 189 insertions(+), 2 deletions(-) create mode 100644 src/command.cpp create mode 100644 src/command.h diff --git a/ppl.pro b/ppl.pro index 214d87a..5569543 100644 --- a/ppl.pro +++ b/ppl.pro @@ -80,7 +80,8 @@ HEADERS += \ src/action.h \ src/smoothed.h \ src/processor.h \ - src/vertexbuffer.hpp + src/vertexbuffer.hpp \ + src/command.h SOURCES += \ src/pluginpath.cpp \ @@ -96,7 +97,8 @@ SOURCES += \ src/logwriter.cpp \ src/menuitem.cpp \ src/processor.cpp \ - src/vertexbuffer.cpp + src/vertexbuffer.cpp \ + src/command.cpp withsound { win32 { diff --git a/src/command.cpp b/src/command.cpp new file mode 100644 index 0000000..cdfb68a --- /dev/null +++ b/src/command.cpp @@ -0,0 +1,64 @@ +#include "command.h" + +/* Copyright (c) 2018, Jack Deeth github@jackdeeth.org.uk +// All rights reserved +// +// 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. +// +// 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 OWNER 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. +// +// The views and conclusions contained in the software and documentation are those +// of the authors and should not be interpreted as representing official policies, +// either expressed or implied, of the FreeBSD Project. +*/ + +PPL::Command::Command(XPLMCommandRef ref, + std::function cb, + bool run_before_sim) + : callback(cb), ref_(ref), before_(run_before_sim ? 1 : 0) { + XPLMRegisterCommandHandler(ref_, scb, before_, this); +} + +PPL::Command::Command(std::string cmd_to_replace, + std::function callback, + bool run_before) + : Command(XPLMFindCommand(cmd_to_replace.c_str()), callback, run_before) {} + +PPL::Command::Command(std::string new_cmd, + std::string description, + std::function callback, + bool run_before) + : Command(XPLMCreateCommand(new_cmd.c_str(), description.c_str()), + callback, + run_before) {} + +PPL::Command::~Command() { + XPLMUnregisterCommandHandler(ref_, scb, before_, this); +} + +PPL::Command::Phase PPL::Command::phase() const { return phase_; } + +int PPL::Command::scb(XPLMCommandRef ref, XPLMCommandPhase phase, void *vp) { + auto cmd = reinterpret_cast(vp); + if (phase == xplm_CommandBegin) cmd->phase_ = Phase::Begin; + if (phase == xplm_CommandContinue) cmd->phase_ = Phase::Continue; + if (phase == xplm_CommandEnd) cmd->phase_ = Phase::End; + auto outcome = cmd->callback(ref, cmd->phase_); + return outcome == Outcome::Halt ? 1 : 0; +} diff --git a/src/command.h b/src/command.h new file mode 100644 index 0000000..4ad46f6 --- /dev/null +++ b/src/command.h @@ -0,0 +1,121 @@ +#pragma once + +/* Copyright (c) 2018, Jack Deeth github@jackdeeth.org.uk +// All rights reserved +// +// 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. +// +// 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 OWNER 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. +// +// The views and conclusions contained in the software and documentation are those +// of the authors and should not be interpreted as representing official policies, +// either expressed or implied, of the FreeBSD Project. +*/ + +/* Example usage: + +// disable an existing command +PPL::Command left_brake_cmd_{"sim/flight_controls/left_brake"}; + +// hijack an existing command +const auto End{PPL::Command::Phase::End}; +const auto Halt{PPL::Command::Outcome::Halt}; +PPL::Command brake_toggle_cmd_{ + "sim/flight_controls/brakes_toggle_regular", + [&](XPLMCommandRef, PPL::Command::Phase phase) { + if (phase == End) { + if (handbrake_lever_ratio_ < 0.5f) + handbrake_lever_ratio_ = 0.5f; + else + handbrake_lever_ratio_ = 0.f; + } + return Halt; + }}; + +// create a new command +class CompileMessage { +public: + CompileMessage(std::string command_name = "YourName/YourProject/show_compile_msg", + std::string desc = "Announces compilation date/time of plugin" + : cmd_{command_name, desc, [](XPLMCommandRef, PPL::Command::Phase phase) { + if (phase == PPL::Command::Phase::Begin) + XPLMSpeakString(compile_message().c_str()); + return PPL::Command::Outcome::Halt; + }} {} + + static std::string compile_message() { + std::stringstream msg; + msg << "Compiled " << __DATE__ << " at " << __TIME__; + return msg.str(); + } +private: + PPL::Command cmd_; +}; + +*/ + +#include + +#include +#include + +// RAII wrapper for X-Plane Commands API + +namespace PPL { + +class Command { +public: + enum class Outcome { Pass_On, Halt }; + enum class Phase { Begin, Continue, End }; + + // Finds a command by reference and attaches a new callback to it + Command(XPLMCommandRef ref, + std::function callback = + [](...) { return Outcome::Halt; }, + bool run_before = true); + + // Finds a command by name and attaches a new callback to it + // (useful for hijacking and/or blocking existing commands) + Command(std::string cmd_to_replace, + std::function callback = + [](...) { return Outcome::Halt; }, + bool run_before = true); + + // Creates a new command and attaches a callback to it + Command(std::string new_cmd, + std::string description, + std::function callback = + [](...) { return Outcome::Halt; }, + bool run_before = true); + + ~Command(); + + Phase phase() const; + + std::function callback; + + static int scb(XPLMCommandRef ref, XPLMCommandPhase phase, void *vp); + +private: + XPLMCommandRef ref_; + int before_; + Phase phase_{Phase::End}; +}; + +} // namespace From 171522b1a5571cee5ea03a0dea95f1a49a333518 Mon Sep 17 00:00:00 2001 From: Jack Deeth Date: Sat, 31 Mar 2018 05:27:02 +0100 Subject: [PATCH 2/3] Add Begin, End and Once to Command Command now 100% covers the SDK API for commands. --- src/command.cpp | 26 ++++++++++++++++++++------ src/command.h | 27 +++++++++++++++++++-------- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/command.cpp b/src/command.cpp index cdfb68a..129cb3a 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -6,25 +6,31 @@ // 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 +// 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. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// 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 OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. // -// The views and conclusions contained in the software and documentation are those -// of the authors and should not be interpreted as representing official policies, +// The views and conclusions contained in the software and documentation are +those +// of the authors and should not be interpreted as representing official +policies, // either expressed or implied, of the FreeBSD Project. */ @@ -54,7 +60,15 @@ PPL::Command::~Command() { PPL::Command::Phase PPL::Command::phase() const { return phase_; } +void PPL::Command::begin() { XPLMCommandBegin(ref_); } + +void PPL::Command::end() { XPLMCommandEnd(ref_); } + +void PPL::Command::once() { XPLMCommandOnce(ref_); } + int PPL::Command::scb(XPLMCommandRef ref, XPLMCommandPhase phase, void *vp) { + // scb = shared/static call-back + // converts C conventions with (post?)modern C++ auto cmd = reinterpret_cast(vp); if (phase == xplm_CommandBegin) cmd->phase_ = Phase::Begin; if (phase == xplm_CommandContinue) cmd->phase_ = Phase::Continue; diff --git a/src/command.h b/src/command.h index 4ad46f6..c0b0b23 100644 --- a/src/command.h +++ b/src/command.h @@ -6,25 +6,31 @@ // 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 +// 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. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// 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 OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. // -// The views and conclusions contained in the software and documentation are those -// of the authors and should not be interpreted as representing official policies, +// The views and conclusions contained in the software and documentation are +those +// of the authors and should not be interpreted as representing official +policies, // either expressed or implied, of the FreeBSD Project. */ @@ -51,7 +57,8 @@ PPL::Command brake_toggle_cmd_{ // create a new command class CompileMessage { public: - CompileMessage(std::string command_name = "YourName/YourProject/show_compile_msg", + CompileMessage(std::string command_name = +"YourName/YourProject/show_compile_msg", std::string desc = "Announces compilation date/time of plugin" : cmd_{command_name, desc, [](XPLMCommandRef, PPL::Command::Phase phase) { if (phase == PPL::Command::Phase::Begin) @@ -81,7 +88,7 @@ namespace PPL { class Command { public: - enum class Outcome { Pass_On, Halt }; + enum class Outcome { Continue, Halt }; enum class Phase { Begin, Continue, End }; // Finds a command by reference and attaches a new callback to it @@ -108,6 +115,10 @@ class Command { Phase phase() const; + void begin(); + void end(); + void once(); + std::function callback; static int scb(XPLMCommandRef ref, XPLMCommandPhase phase, void *vp); From 22960bcbec1ce8f1a5707e054a5cd54b0cc1eb01 Mon Sep 17 00:00:00 2001 From: Jack Deeth Date: Sun, 1 Apr 2018 19:36:42 +0100 Subject: [PATCH 3/3] YOU SAW NOTHING --- src/command.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/command.cpp b/src/command.cpp index 129cb3a..527d2dd 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -74,5 +74,5 @@ int PPL::Command::scb(XPLMCommandRef ref, XPLMCommandPhase phase, void *vp) { if (phase == xplm_CommandContinue) cmd->phase_ = Phase::Continue; if (phase == xplm_CommandEnd) cmd->phase_ = Phase::End; auto outcome = cmd->callback(ref, cmd->phase_); - return outcome == Outcome::Halt ? 1 : 0; + return outcome == Outcome::Halt ? 0 : 1; }