Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 167 additions & 1 deletion src/FlyWithLua.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// FlyWithLua Plugin for X-Plane 11
// ----------------------------------

#define PLUGIN_VERSION_NO "2.7.38"
#define PLUGIN_VERSION_NO "2.7.39"
#define PLUGIN_VERSION_BUILD __DATE__ " " __TIME__
#define PLUGIN_VERSION PLUGIN_VERSION_NO " build " PLUGIN_VERSION_BUILD

Expand Down Expand Up @@ -157,6 +157,9 @@
* Thanks osprey-12
* v2.7.37 [added] Added support for the horizontal scrollbar in Imgui windows.
* v2.7.38 [added] Removed X-Plane LuaJIT alloc.
* v2.2.39 [Added] do_every_frame_after() callback to run in FlightLoop Phase 1 (after physics processing, thus eliminating
* graphic jitter
* [Added] do_every_frame_before() callback to run in FlightLoop Phase 1 (before physics processing)
*
* Markus (Teddii):
* v2.1.20 [changed] bug fixed in Luahid_open() and Luahid_open_path(), setting last HID device index back if no device was found
Expand Down Expand Up @@ -300,6 +303,7 @@
//#endif
// include the extern command provided by the LUA team
#include <lua.hpp>
using namespace flywithlua; // Resolve namespace issues when compiling

/// This symbol comes from statically linked LuaXML_lib library.
extern "C" int luaopen_LuaXML_lib(lua_State* L);
Expand Down Expand Up @@ -2873,6 +2877,146 @@ static int LuaDoEveryFrame(lua_State* L)
return 0;
}

// --- MULTI-CALLBACK VERSION OF: FlightLoop Callback BeforeFlightModel ---

static XPLMFlightLoopID g_DoEveryFrameBefore_ID = nullptr;
static std::vector<std::string> do_every_frame_before_code;

// Called every frame before flight model is updated
float Do_Every_Frame_Before(float inElapsedSinceLastCall, float inElapsedTimeSinceLastFlightLoop,
int inCounter, void* inRefcon)
{
if (!LuaIsRunning) return -1.0f;

CopyDataRefsToLua();

for (const auto& code : do_every_frame_before_code)
{
if (luaL_loadstring(FWLLua, code.c_str()) == LUA_OK)
{
if (lua_pcall(FWLLua, 0, 0, 0) != LUA_OK)
{
const char* err = lua_tostring(FWLLua, -1);
logMsg(logToDevCon, std::string("Error in do_every_frame_before(): ") + err);
lua_pop(FWLLua, 1);
}
}
else
{
const char* err = lua_tostring(FWLLua, -1);
logMsg(logToDevCon, std::string("Syntax error in do_every_frame_before(): ") + err);
lua_pop(FWLLua, 1);
}
}

CopyDataRefsToXPlane();

return -1.0f; // every frame
}

void Register_Do_Every_Frame_Before()
{
if (g_DoEveryFrameBefore_ID != nullptr)
return;

XPLMCreateFlightLoop_t loop_params{};
loop_params.structSize = sizeof(XPLMCreateFlightLoop_t);
loop_params.phase = xplm_FlightLoop_Phase_BeforeFlightModel;
loop_params.callbackFunc = Do_Every_Frame_Before;
loop_params.refcon = nullptr;

g_DoEveryFrameBefore_ID = XPLMCreateFlightLoop(&loop_params);
XPLMScheduleFlightLoop(g_DoEveryFrameBefore_ID, -1.0, 0);
}

static int LuaDoEveryFrameBefore(lua_State* L)
{
if (!lua_isstring(L, 1))
{
logMsg(logToDevCon, "FlyWithLua Error: do_every_frame_before() needs a string of Lua code.");
LuaIsRunning = false;
return 0;
}

std::string lua_code = lua_tostring(L, 1);
do_every_frame_before_code.push_back(lua_code);

return 0;
}

// --- End DoEveryFrameBefore routines


// --- MULTI-CALLBACK VERSION OF: FlightLoop Callback AfterFlightModel ---

static XPLMFlightLoopID g_DoEveryFrameAfter_ID = nullptr;
static std::vector<std::string> do_every_frame_after_code;

// Called every frame after flight model is updated
float Do_Every_Frame_After(float inElapsedSinceLastCall, float inElapsedTimeSinceLastFlightLoop,
int inCounter, void* inRefcon)
{
if (!LuaIsRunning) return -1.0f;

CopyDataRefsToLua();

for (const auto& code : do_every_frame_after_code)
{
if (luaL_loadstring(FWLLua, code.c_str()) == LUA_OK)
{
if (lua_pcall(FWLLua, 0, 0, 0) != LUA_OK)
{
const char* err = lua_tostring(FWLLua, -1);
logMsg(logToDevCon, std::string("Error in do_every_frame_after(): ") + err);
lua_pop(FWLLua, 1);
}
}
else
{
const char* err = lua_tostring(FWLLua, -1);
logMsg(logToDevCon, std::string("Syntax error in do_every_frame_after(): ") + err);
lua_pop(FWLLua, 1);
}
}

CopyDataRefsToXPlane();

return -1.0f; // every frame
}

void Register_Do_Every_Frame_After()
{
if (g_DoEveryFrameAfter_ID != nullptr)
return;

XPLMCreateFlightLoop_t loop_params{};
loop_params.structSize = sizeof(XPLMCreateFlightLoop_t);
loop_params.phase = xplm_FlightLoop_Phase_AfterFlightModel;
loop_params.callbackFunc = Do_Every_Frame_After;
loop_params.refcon = nullptr;

g_DoEveryFrameAfter_ID = XPLMCreateFlightLoop(&loop_params);
XPLMScheduleFlightLoop(g_DoEveryFrameAfter_ID, -1.0, 0);
}

static int LuaDoEveryFrameAfter(lua_State* L)
{
if (!lua_isstring(L, 1))
{
logMsg(logToDevCon, "FlyWithLua Error: do_every_frame_after() needs a string of Lua code.");
LuaIsRunning = false;
return 0;
}

std::string lua_code = lua_tostring(L, 1);
do_every_frame_after_code.push_back(lua_code);

return 0;
}

// --- End DoEveryFrameAfter routines


static int LuaDoOften(lua_State* L)
{
if (!lua_isstring(L, 1))
Expand Down Expand Up @@ -5966,6 +6110,8 @@ void RegisterCoreCFunctionsToLua(lua_State* L)
lua_register(L, "do_on_mouse_wheel", LuaDoEveryMouseWheel);
lua_register(L, "do_every_draw", LuaDoEveryDrawCallback);
lua_register(L, "do_every_frame", LuaDoEveryFrame);
lua_register(L, "do_every_frame_before", LuaDoEveryFrameBefore); // Callback before FlightModel
lua_register(L, "do_every_frame_after", LuaDoEveryFrameAfter); // Callback after FlightModel
lua_register(L, "do_often", LuaDoOften);
lua_register(L, "do_sometimes", LuaDoSometimes);
lua_register(L, "add_macro", LuaAddMacro);
Expand Down Expand Up @@ -7316,6 +7462,22 @@ PLUGIN_API void XPluginDisable(void)
XPLMUnregisterFlightLoopCallback(MyFastLoopCallback, nullptr);
XPLMUnregisterFlightLoopCallback(MySlowLoopCallback, nullptr);
XPLMUnregisterFlightLoopCallback(MyEveryFrameLoopCallback, nullptr);

// Unregister and clean up the BeforeFlightModel flight loop
if (g_DoEveryFrameBefore_ID != nullptr)
{
XPLMDestroyFlightLoop(g_DoEveryFrameBefore_ID);
g_DoEveryFrameBefore_ID = nullptr;
do_every_frame_before_code.clear();
}

// Unregister and clean up the AfterFlightModel flight loop
if (g_DoEveryFrameAfter_ID != nullptr)
{
XPLMDestroyFlightLoop(g_DoEveryFrameAfter_ID);
g_DoEveryFrameAfter_ID = nullptr;
do_every_frame_after_code.clear();
}

// write to Log.txt
logMsg(logToDevCon, "FlyWithLua Info: FlyWithLua plugin disabled.");
Expand Down Expand Up @@ -7371,6 +7533,10 @@ PLUGIN_API int XPluginEnable(void)
nullptr); /* refcon not used. */

XPLMRegisterDrawCallback(FWLDrawWindowCallback, xplm_Phase_Window, 0, (void*) "FWLWindowDrawer");

Register_Do_Every_Frame_Before(); // Provide a callback that runs in FlightLoop Phase Before mode.

Register_Do_Every_Frame_After(); // Provide a callback that runs in FlightLoop Phase After mode.

// create the FlyWithLua menu inside the plugin menu
if (FlyWithLuaMenuItem < 0)
Expand Down
Loading