Created
April 12, 2018 18:39
-
-
Save JDeeth/60e87713583b25c20be7748cdb01cd3b to your computer and use it in GitHub Desktop.
Wrapper for X-Plane Command interface
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "command.h" | |
Command::Command(XPLMCommandRef ref, | |
std::function<Outcome(Phase)> cb, | |
bool run_before_sim) | |
: ref_(ref), before_(run_before_sim ? 1 : 0), callback_(cb) { | |
XPLMRegisterCommandHandler( | |
ref_, | |
[](XPLMCommandRef, XPLMCommandPhase phase, void* vp) { | |
auto cmd = reinterpret_cast<Command*>(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_(cmd->phase_); | |
return outcome == Outcome::Halt ? 0 : 1; | |
}, | |
before_, | |
this); | |
} | |
Command::Command(std::string cmd_to_replace, | |
std::function<Outcome(Phase)> callback, | |
bool run_before) | |
: Command(XPLMFindCommand(cmd_to_replace.c_str()), callback, run_before) {} | |
Command::Command(std::string new_cmd, | |
std::string description, | |
std::function<Outcome(Phase)> callback, | |
bool run_before) | |
: Command(XPLMCreateCommand(new_cmd.c_str(), description.c_str()), | |
callback, | |
run_before) {} | |
Command::~Command() { | |
XPLMUnregisterCommandHandler( | |
ref_, | |
[](XPLMCommandRef, XPLMCommandPhase, void*) { return 0; }, | |
before_, | |
this); | |
} | |
Command::Phase Command::phase() const { | |
return phase_; | |
} | |
void Command::begin() { | |
XPLMCommandBegin(ref_); | |
} | |
void Command::end() { | |
XPLMCommandEnd(ref_); | |
} | |
void Command::once() { | |
XPLMCommandOnce(ref_); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
/* This class registers and deregisters a command callback function | |
in an RAII way (as in, the destructor calls XPLMUnregisterCommandHandler | |
automatically when the object is destroyed) | |
Depending on how you call the constructor, it will either create a new | |
command, if you give it two strings for its name and description: | |
Command cmd{"YourName/YourProject/show_compile_msg", | |
"Shows the compilation date and time", | |
[](Command::Phase phase) { | |
if (phase == Command::Phase::Begin) { | |
std::stringstream desc; | |
desc << "Compiled " << __DATE__ << " " << __TIME__; | |
XPLMSpeakString(desc.str().c_str()); | |
} | |
return Command::Outcome::Halt; | |
}}; | |
Or it will register a new handler for an existing command, if you give it | |
either the command's name or its XPLMCommandRef. | |
Command brake_toggle_cmd{ | |
"sim/flight_controls/brakes_toggle_regular", | |
[&](Command::Phase phase) { | |
if (phase == Command::Phase::Begin) { | |
if (handbrake_lever_ratio_ < 0.5f) | |
handbrake_lever_ratio_ = 0.5f; | |
else | |
handbrake_lever_ratio_ = 0.f; | |
} | |
return Command::Outcome::Halt; | |
}}; | |
XPLMCommandPhase is replaced with an enum class: | |
Command::Phase::Begin | |
Command::Phase::Continue | |
Command::Phase::End | |
and the callback function returns an Outcome enum: | |
Command::Outcome::Halt (X-Plane stops processing the command) | |
Command::Outcome::Pass_On (X-Plane continues processing the command) | |
The default callback function immediately returns Halt, essentially | |
disabling that command: | |
Command left_brake_cmd_{"sim/flight_controls/left_brake"}; | |
*/ | |
#include <XPLMUtilities.h> | |
#include <functional> | |
#include <string> | |
class Command { | |
public: | |
enum class Outcome { Continue, Halt }; | |
enum class Phase { Begin, Continue, End }; | |
// Finds a command by reference and attaches a new callback to it | |
Command(XPLMCommandRef ref, | |
std::function<Outcome(Phase)> callback_ = | |
[](...) { return Outcome::Halt; }, | |
bool run_before = true); | |
// Finds a command by name and attaches a new callback to it | |
Command(std::string cmd_to_replace, | |
std::function<Outcome(Phase)> 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<Outcome(Phase)> callback_ = | |
[](...) { return Outcome::Halt; }, | |
bool run_before = true); | |
~Command(); | |
Phase phase() const; | |
// Call XPLMCommandBegin/End/Once | |
void begin(); | |
void end(); | |
void once(); | |
private: | |
XPLMCommandRef ref_; | |
int before_; | |
Phase phase_{Phase::End}; | |
std::function<Outcome(Phase)> callback_; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment