feat(color): telemetry queues for Lua, enhance default widget options (#5926)
This commit is contained in:
@@ -109,7 +109,7 @@ void InputMixButtonBase::setSource(mixsrc_t idx)
|
||||
else
|
||||
lv_obj_clear_state(source, LV_STATE_USER_1);
|
||||
|
||||
lv_label_set_text(source, s);
|
||||
lv_label_set_text(source, s);
|
||||
}
|
||||
|
||||
void InputMixButtonBase::setOpts(const char* s)
|
||||
|
||||
@@ -49,7 +49,7 @@ class LayoutFactory
|
||||
|
||||
virtual const uint8_t* getBitmap() const = 0;
|
||||
|
||||
virtual const ZoneOption* getOptions() const = 0;
|
||||
virtual const ZoneOption* getLayoutOptions() const = 0;
|
||||
|
||||
virtual WidgetsContainer* create(
|
||||
Window* parent, LayoutPersistentData* persistentData) const = 0;
|
||||
|
||||
@@ -98,8 +98,6 @@ class Layout: public LayoutBase
|
||||
return getOptionValue(LAYOUT_OPTION_MIRRORED)->boolValue;
|
||||
}
|
||||
|
||||
virtual bool isAppMode() const { return false; }
|
||||
|
||||
// Set decoration visibility
|
||||
void setTrimsVisible(bool visible);
|
||||
void setSlidersVisible(bool visible);
|
||||
@@ -182,7 +180,7 @@ class BaseLayoutFactory: public LayoutFactory
|
||||
|
||||
const uint8_t* getBitmap() const override { return bitmap; }
|
||||
|
||||
const ZoneOption * getOptions() const override
|
||||
const ZoneOption * getLayoutOptions() const override
|
||||
{
|
||||
return options;
|
||||
}
|
||||
|
||||
@@ -327,7 +327,7 @@ void ScreenSetupPage::buildLayoutOptions()
|
||||
if (!factory) return;
|
||||
|
||||
int index = 0;
|
||||
for (auto* option = factory->getOptions(); option->name; option++, index++) {
|
||||
for (auto* option = factory->getLayoutOptions(); option->name; option++, index++) {
|
||||
auto layoutData = &g_model.screenData[customScreenIndex].layoutData;
|
||||
ZoneOptionValue* value = &layoutData->options[index].value;
|
||||
|
||||
|
||||
@@ -57,13 +57,13 @@ void Widget::openMenu()
|
||||
return;
|
||||
}
|
||||
|
||||
if (getOptions() || fsAllowed) {
|
||||
if (hasOptions() || fsAllowed) {
|
||||
Menu* menu = new Menu();
|
||||
menu->setTitle(getFactory()->getDisplayName());
|
||||
if (fsAllowed) {
|
||||
menu->addLine(STR_WIDGET_FULLSCREEN, [&]() { setFullscreen(true); });
|
||||
}
|
||||
if (getOptions() && getOptions()->name) {
|
||||
if (hasOptions()) {
|
||||
menu->addLine(STR_WIDGET_SETTINGS,
|
||||
[=]() { new WidgetSettings(this); });
|
||||
}
|
||||
@@ -146,9 +146,9 @@ bool Widget::onLongPress()
|
||||
return true;
|
||||
}
|
||||
|
||||
const ZoneOption* Widget::getOptions() const
|
||||
const ZoneOption* Widget::getOptionDefinitions() const
|
||||
{
|
||||
return getFactory()->getOptions();
|
||||
return getFactory()->getDefaultOptions();
|
||||
}
|
||||
|
||||
void Widget::enableFocus(bool enable)
|
||||
@@ -253,6 +253,7 @@ void WidgetFactory::initPersistentData(Widget::PersistentData* persistentData,
|
||||
{
|
||||
if (setDefault) {
|
||||
memset(persistentData, 0, sizeof(Widget::PersistentData));
|
||||
parseOptionDefaults();
|
||||
}
|
||||
if (options) {
|
||||
int i = 0;
|
||||
|
||||
@@ -42,7 +42,8 @@ class Widget : public ButtonBase
|
||||
|
||||
const WidgetFactory* getFactory() const { return factory; }
|
||||
|
||||
const ZoneOption* getOptions() const;
|
||||
const ZoneOption* getOptionDefinitions() const;
|
||||
bool hasOptions() const { return getOptionDefinitions() && getOptionDefinitions()->name; }
|
||||
|
||||
virtual const char* getErrorMessage() const { return nullptr; }
|
||||
|
||||
@@ -117,7 +118,8 @@ class WidgetFactory
|
||||
|
||||
const char* getName() const { return name; }
|
||||
|
||||
const ZoneOption* getOptions() const { return options; }
|
||||
const ZoneOption* getDefaultOptions() const { return options; }
|
||||
virtual const void parseOptionDefaults() const {}
|
||||
|
||||
const char* getDisplayName() const
|
||||
{
|
||||
|
||||
@@ -49,7 +49,8 @@ WidgetSettings::WidgetSettings(Widget* w) :
|
||||
FlexGridLayout grid(line_col_dsc, line_row_dsc, PAD_TINY);
|
||||
|
||||
uint8_t optIdx = 0;
|
||||
auto opt = widget->getOptions();
|
||||
auto opt = widget->getOptionDefinitions();
|
||||
|
||||
while (opt && opt->name != nullptr) {
|
||||
auto line = form->newLine(grid);
|
||||
|
||||
|
||||
@@ -85,5 +85,6 @@ class WidgetsContainer: public Window
|
||||
virtual void runBackground() = 0;
|
||||
|
||||
virtual bool isLayout() { return false; }
|
||||
virtual bool isAppMode() const { return false; }
|
||||
bool isWidgetsContainer() override { return true; }
|
||||
};
|
||||
|
||||
@@ -41,7 +41,7 @@ SetupWidgetsPageSlot::SetupWidgetsPageSlot(Window* parent, const rect_t& rect,
|
||||
menu->addLine(STR_SELECT_WIDGET,
|
||||
[=]() { addNewWidget(container, slotIndex); });
|
||||
auto widget = container->getWidget(slotIndex);
|
||||
if (widget->getOptions() && widget->getOptions()->name)
|
||||
if (widget->hasOptions())
|
||||
menu->addLine(STR_WIDGET_SETTINGS,
|
||||
[=]() { new WidgetSettings(widget); });
|
||||
menu->addLine(STR_REMOVE_WIDGET,
|
||||
@@ -103,7 +103,7 @@ void SetupWidgetsPageSlot::addNewWidget(WidgetsContainer* container,
|
||||
menu->addLine(factory->getDisplayName(), [=]() {
|
||||
container->createWidget(slotIndex, factory);
|
||||
auto widget = container->getWidget(slotIndex);
|
||||
if (widget->getOptions() && widget->getOptions()->name)
|
||||
if (widget->hasOptions())
|
||||
new WidgetSettings(widget);
|
||||
});
|
||||
if (cur && strcmp(cur, factory->getDisplayName()) == 0)
|
||||
|
||||
@@ -133,6 +133,8 @@ StandaloneLuaWindow::StandaloneLuaWindow(bool useLvgl, int initFn, int runFn) :
|
||||
|
||||
etx_solid_bg(lvobj);
|
||||
|
||||
luaScriptManager = this;
|
||||
|
||||
if (useLvglLayout()) {
|
||||
padAll(PAD_ZERO);
|
||||
etx_scrollbar(lvobj);
|
||||
@@ -146,8 +148,6 @@ StandaloneLuaWindow::StandaloneLuaWindow(bool useLvgl, int initFn, int runFn) :
|
||||
lv_obj_set_style_text_align(lbl, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN);
|
||||
lv_obj_set_style_pad_top(lbl, (LCD_H - EdgeTxStyles::PAGE_LINE_HEIGHT) / 2, LV_PART_MAIN);
|
||||
lv_label_set_text(lbl, STR_LOADING);
|
||||
|
||||
luaLvglManager = this;
|
||||
} else {
|
||||
lcdBuffer = new BitmapBuffer(BMP_RGB565, LCD_W, LCD_H);
|
||||
|
||||
@@ -218,7 +218,7 @@ void StandaloneLuaWindow::deleteLater(bool detach, bool trash)
|
||||
if (lcdBuffer) delete lcdBuffer;
|
||||
lcdBuffer = nullptr;
|
||||
|
||||
luaLvglManager = nullptr;
|
||||
luaScriptManager = nullptr;
|
||||
|
||||
Layer::pop(this);
|
||||
Layer::back()->show();
|
||||
@@ -320,13 +320,13 @@ void StandaloneLuaWindow::checkEvents()
|
||||
luaLcdAllowed = false;
|
||||
}
|
||||
|
||||
void StandaloneLuaWindow::onClicked() { Keyboard::hide(false); LuaEventHandler::onClicked(); }
|
||||
void StandaloneLuaWindow::onClicked() { Keyboard::hide(false); LuaScriptManager::onClickedEvent(); }
|
||||
|
||||
void StandaloneLuaWindow::onCancel() { LuaEventHandler::onCancel(); }
|
||||
void StandaloneLuaWindow::onCancel() { LuaScriptManager::onCancelEvent(); }
|
||||
|
||||
void StandaloneLuaWindow::onEvent(event_t evt)
|
||||
{
|
||||
LuaEventHandler::onLuaEvent(evt);
|
||||
LuaScriptManager::onLuaEvent(evt);
|
||||
}
|
||||
|
||||
void StandaloneLuaWindow::popupPaint(BitmapBuffer* dc, coord_t x, coord_t y, coord_t w, coord_t h,
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
extern void luaExecStandalone(const char * filename);
|
||||
|
||||
class StandaloneLuaWindow : public Window, public LuaEventHandler, public LuaLvglManager
|
||||
class StandaloneLuaWindow : public Window, public LuaScriptManager
|
||||
{
|
||||
static StandaloneLuaWindow* _instance;
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#define BITMAP_METATABLE "BITMAP*"
|
||||
|
||||
BitmapBuffer* luaLcdBuffer = nullptr;
|
||||
LuaWidget *runningFS = nullptr;
|
||||
|
||||
/*luadoc
|
||||
@function lcd.refresh()
|
||||
@@ -1386,8 +1385,8 @@ Exit full screen widget mode.
|
||||
*/
|
||||
static int luaLcdExitFullScreen(lua_State *L)
|
||||
{
|
||||
if (runningFS)
|
||||
runningFS->closeFullscreen();
|
||||
if (luaScriptManager)
|
||||
luaScriptManager->exitFullscreen();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,14 +28,11 @@
|
||||
|
||||
#include "api_colorlcd.h"
|
||||
|
||||
LuaLvglManager *luaLvglManager = nullptr;
|
||||
|
||||
static int luaLvglObj(lua_State *L, std::function<LvglWidgetObject*()> create, bool fullscreenOnly = false)
|
||||
{
|
||||
if (luaLvglManager && (!fullscreenOnly || luaLvglManager->isFullscreen())) {
|
||||
if (luaScriptManager && (!fullscreenOnly || luaScriptManager->isFullscreen())) {
|
||||
auto obj = create();
|
||||
obj->getParams(L, 1);
|
||||
obj->build(L);
|
||||
obj->create(L, 1);
|
||||
obj->push(L);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
@@ -46,24 +43,23 @@ static int luaLvglObj(lua_State *L, std::function<LvglWidgetObject*()> create, b
|
||||
|
||||
static int luaLvglObjEx(lua_State *L, std::function<LvglWidgetObjectBase*()> create, bool fullscreenOnly = false)
|
||||
{
|
||||
if (luaLvglManager && (!fullscreenOnly || luaLvglManager->isFullscreen())) {
|
||||
if (luaScriptManager && (!fullscreenOnly || luaScriptManager->isFullscreen())) {
|
||||
LvglWidgetObjectBase* p = nullptr;
|
||||
LvglWidgetObjectBase* prevParent = nullptr;
|
||||
if (lua_gettop(L) == 2) {
|
||||
p = LvglWidgetObjectBase::checkLvgl(L, 1);
|
||||
if (p) {
|
||||
prevParent = luaLvglManager->getTempParent();
|
||||
luaLvglManager->setTempParent(p);
|
||||
prevParent = luaScriptManager->getTempParent();
|
||||
luaScriptManager->setTempParent(p);
|
||||
}
|
||||
}
|
||||
|
||||
auto obj = create();
|
||||
obj->getParams(L, -1);
|
||||
obj->build(L);
|
||||
obj->create(L, -1);
|
||||
obj->push(L);
|
||||
|
||||
if (p)
|
||||
luaLvglManager->setTempParent((prevParent));
|
||||
luaScriptManager->setTempParent((prevParent));
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
@@ -74,8 +70,7 @@ static int luaLvglObjEx(lua_State *L, std::function<LvglWidgetObjectBase*()> cre
|
||||
static int luaLvglPopup(lua_State *L, std::function<LvglWidgetObjectBase*()> create)
|
||||
{
|
||||
auto obj = create();
|
||||
obj->getParams(L, 1);
|
||||
obj->build(L);
|
||||
obj->create(L, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -100,14 +95,14 @@ static int luaLvglSet(lua_State *L)
|
||||
|
||||
static int luaLvglClear(lua_State *L)
|
||||
{
|
||||
if (luaLvglManager) {
|
||||
if (luaScriptManager) {
|
||||
if (lua_gettop(L) == 1) {
|
||||
auto p = LvglWidgetObjectBase::checkLvgl(L, 1);
|
||||
if (p) {
|
||||
p->clear();
|
||||
}
|
||||
} else {
|
||||
luaLvglManager->clear();
|
||||
luaScriptManager->clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,6 +145,15 @@ static int luaLvglDisable(lua_State *L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int luaLvglClose(lua_State *L)
|
||||
{
|
||||
auto p = LvglWidgetObjectBase::checkLvgl(L, 1);
|
||||
if (p) {
|
||||
p->close();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
class LvglWidgetParams
|
||||
{
|
||||
public:
|
||||
@@ -177,6 +181,7 @@ static void buildLvgl(lua_State *L, int srcIndex, int refIndex)
|
||||
{
|
||||
luaL_checktype(L, srcIndex, LUA_TTABLE);
|
||||
for (lua_pushnil(L); lua_next(L, srcIndex - 1); lua_pop(L, 1)) {
|
||||
auto t = lua_gettop(L);
|
||||
LvglWidgetParams p(L, -1);
|
||||
LvglWidgetObjectBase *obj = nullptr;
|
||||
if (strcasecmp(p.type, "label") == 0)
|
||||
@@ -201,7 +206,7 @@ static void buildLvgl(lua_State *L, int srcIndex, int refIndex)
|
||||
obj = new LvglWidgetQRCode();
|
||||
else if (strcasecmp(p.type, "box") == 0)
|
||||
obj = new LvglWidgetBox();
|
||||
else if (luaLvglManager->isFullscreen()) {
|
||||
else if (luaScriptManager->isFullscreen()) {
|
||||
if (strcasecmp(p.type, "button") == 0)
|
||||
obj = new LvglWidgetTextButton();
|
||||
if (strcasecmp(p.type, "momentaryButton") == 0)
|
||||
@@ -236,8 +241,7 @@ static void buildLvgl(lua_State *L, int srcIndex, int refIndex)
|
||||
obj = new LvglWidgetSetting();
|
||||
}
|
||||
if (obj) {
|
||||
obj->getParams(L, -1);
|
||||
obj->build(L);
|
||||
obj->create(L, -1);
|
||||
auto ref = obj->getRef(L);
|
||||
if (p.name) {
|
||||
lua_pushstring(L, p.name);
|
||||
@@ -246,26 +250,27 @@ static void buildLvgl(lua_State *L, int srcIndex, int refIndex)
|
||||
}
|
||||
if (p.hasChildren && obj->getWindow()) {
|
||||
lua_getfield(L, -1, "children");
|
||||
auto prevParent = luaLvglManager->getTempParent();
|
||||
luaLvglManager->setTempParent(obj);
|
||||
auto prevParent = luaScriptManager->getTempParent();
|
||||
luaScriptManager->setTempParent(obj);
|
||||
buildLvgl(L, -1, refIndex - 3);
|
||||
lua_pop(L, 1);
|
||||
luaLvglManager->setTempParent(prevParent);
|
||||
luaScriptManager->setTempParent(prevParent);
|
||||
}
|
||||
}
|
||||
lua_settop(L, t); // In case of errors in build functions
|
||||
}
|
||||
}
|
||||
|
||||
static int luaLvglBuild(lua_State *L)
|
||||
{
|
||||
if (luaLvglManager) {
|
||||
if (luaScriptManager) {
|
||||
LvglWidgetObjectBase* p = nullptr;
|
||||
LvglWidgetObjectBase* prevParent = nullptr;
|
||||
if (lua_gettop(L) == 2) {
|
||||
p = LvglWidgetObjectBase::checkLvgl(L, 1);
|
||||
if (p) {
|
||||
prevParent = luaLvglManager->getTempParent();
|
||||
luaLvglManager->setTempParent(p);
|
||||
prevParent = luaScriptManager->getTempParent();
|
||||
luaScriptManager->setTempParent(p);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,7 +279,7 @@ static int luaLvglBuild(lua_State *L)
|
||||
buildLvgl(L, -2, -1);
|
||||
|
||||
if (p)
|
||||
luaLvglManager->setTempParent((prevParent));
|
||||
luaScriptManager->setTempParent((prevParent));
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
@@ -283,8 +288,8 @@ static int luaLvglBuild(lua_State *L)
|
||||
|
||||
static int luaLvglIsAppMode(lua_State *L)
|
||||
{
|
||||
if (luaLvglManager) {
|
||||
lua_pushboolean(L, luaLvglManager->isAppMode());
|
||||
if (luaScriptManager) {
|
||||
lua_pushboolean(L, luaScriptManager->isAppMode());
|
||||
} else {
|
||||
lua_pushboolean(L, false);
|
||||
}
|
||||
@@ -293,8 +298,8 @@ static int luaLvglIsAppMode(lua_State *L)
|
||||
|
||||
static int luaLvglIsFullscreen(lua_State *L)
|
||||
{
|
||||
if (luaLvglManager) {
|
||||
lua_pushboolean(L, luaLvglManager->isFullscreen());
|
||||
if (luaScriptManager) {
|
||||
lua_pushboolean(L, luaScriptManager->isFullscreen());
|
||||
} else {
|
||||
lua_pushboolean(L, false);
|
||||
}
|
||||
@@ -303,16 +308,16 @@ static int luaLvglIsFullscreen(lua_State *L)
|
||||
|
||||
static int luaLvglExitFullscreen(lua_State *L)
|
||||
{
|
||||
if (luaLvglManager)
|
||||
luaLvglManager->exitFullscreen();
|
||||
if (luaScriptManager)
|
||||
luaScriptManager->exitFullscreen();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int luaLvglGetContext(lua_State *L)
|
||||
{
|
||||
if (luaLvglManager && luaLvglManager->getContext() != LUA_REFNIL) {
|
||||
if (luaScriptManager && luaScriptManager->getContext() != LUA_REFNIL) {
|
||||
// Push context tanle onto Lua stack (return object)
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, luaLvglManager->getContext());
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, luaScriptManager->getContext());
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
@@ -354,8 +359,8 @@ LROT_BEGIN(lvgllib, NULL, 0)
|
||||
LROT_FUNCENTRY(switch, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetSwitchPicker(); }, true); })
|
||||
LROT_FUNCENTRY(source, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetSourcePicker(); }, true); })
|
||||
// Containers
|
||||
LROT_FUNCENTRY(box, [](lua_State* L) { return luaLvglObj(L, []() { return new LvglWidgetBox(); }, true); })
|
||||
LROT_FUNCENTRY(setting, [](lua_State* L) { return luaLvglObj(L, []() { return new LvglWidgetSetting(); }, true); })
|
||||
LROT_FUNCENTRY(box, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetBox(); }); })
|
||||
LROT_FUNCENTRY(setting, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetSetting(); }, true); })
|
||||
LROT_FUNCENTRY(page, [](lua_State* L) { return luaLvglObj(L, []() { return new LvglWidgetPage(); }, true); })
|
||||
LROT_FUNCENTRY(dialog, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetDialog(); }, true); })
|
||||
// Dialogs
|
||||
@@ -367,6 +372,7 @@ LROT_BEGIN(lvgllib, NULL, 0)
|
||||
LROT_FUNCENTRY(hide, luaLvglHide)
|
||||
LROT_FUNCENTRY(enable, luaLvglEnable)
|
||||
LROT_FUNCENTRY(disable, luaLvglDisable)
|
||||
LROT_FUNCENTRY(close, luaLvglClose)
|
||||
LROT_NUMENTRY(FLOW_ROW, LV_FLEX_FLOW_ROW)
|
||||
LROT_NUMENTRY(FLOW_COLUMN, LV_FLEX_FLOW_COLUMN)
|
||||
LROT_NUMENTRY(PAD_TINY, PAD_TINY)
|
||||
@@ -440,12 +446,16 @@ LROT_BEGIN(lvgl_mt, NULL, LROT_MASK_GC_INDEX)
|
||||
LROT_FUNCENTRY(timer, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetTimerPicker(); }, true); })
|
||||
LROT_FUNCENTRY(switch, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetSwitchPicker(); }, true); })
|
||||
LROT_FUNCENTRY(source, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetSourcePicker(); }, true); })
|
||||
// Containers
|
||||
LROT_FUNCENTRY(box, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetBox(); }); })
|
||||
LROT_FUNCENTRY(setting, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetSetting(); }, true); })
|
||||
// Object manipulation functions
|
||||
LROT_FUNCENTRY(set, luaLvglSet)
|
||||
LROT_FUNCENTRY(show, luaLvglShow)
|
||||
LROT_FUNCENTRY(hide, luaLvglHide)
|
||||
LROT_FUNCENTRY(enable, luaLvglEnable)
|
||||
LROT_FUNCENTRY(disable, luaLvglDisable)
|
||||
LROT_FUNCENTRY(close, luaLvglClose)
|
||||
LROT_END(lvgl_mt, NULL, LROT_MASK_GC_INDEX)
|
||||
|
||||
extern "C" {
|
||||
|
||||
@@ -898,6 +898,24 @@ static int luaGetRotEncMode(lua_State * L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static TelemetryQueue* getTelemetryQueue()
|
||||
{
|
||||
#if defined(COLORLCD)
|
||||
if (luaScriptManager) {
|
||||
luaScriptManager->createTelemetryQueue();
|
||||
return luaScriptManager->telemetryQueue();
|
||||
} else {
|
||||
if (!luaInputTelemetryFifo)
|
||||
luaInputTelemetryFifo = new TelemetryQueue();
|
||||
return luaInputTelemetryFifo;
|
||||
}
|
||||
#else
|
||||
if (!luaInputTelemetryFifo)
|
||||
luaInputTelemetryFifo = new TelemetryQueue();
|
||||
return luaInputTelemetryFifo;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*luadoc
|
||||
@function sportTelemetryPop()
|
||||
|
||||
@@ -917,23 +935,20 @@ the LUA telemetry receive queue.
|
||||
*/
|
||||
static int luaSportTelemetryPop(lua_State * L)
|
||||
{
|
||||
if (!luaInputTelemetryFifo) {
|
||||
luaInputTelemetryFifo = new Fifo<uint8_t, LUA_TELEMETRY_INPUT_FIFO_SIZE>();
|
||||
if (!luaInputTelemetryFifo) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
auto queue = getTelemetryQueue();
|
||||
|
||||
if (luaInputTelemetryFifo->size() >= sizeof(SportTelemetryPacket)) {
|
||||
SportTelemetryPacket packet;
|
||||
for (uint8_t i=0; i<sizeof(packet); i++) {
|
||||
luaInputTelemetryFifo->pop(packet.raw[i]);
|
||||
if (queue) {
|
||||
if (queue->size() >= sizeof(SportTelemetryPacket)) {
|
||||
SportTelemetryPacket packet;
|
||||
for (uint8_t i=0; i<sizeof(packet); i++) {
|
||||
queue->pop(packet.raw[i]);
|
||||
}
|
||||
lua_pushinteger(L, packet.physicalId);
|
||||
lua_pushinteger(L, packet.primId);
|
||||
lua_pushinteger(L, packet.dataId);
|
||||
lua_pushinteger(L, packet.value);
|
||||
return 4;
|
||||
}
|
||||
lua_pushinteger(L, packet.physicalId);
|
||||
lua_pushinteger(L, packet.primId);
|
||||
lua_pushinteger(L, packet.dataId);
|
||||
lua_pushinteger(L, packet.value);
|
||||
return 4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1144,27 +1159,24 @@ Pops a received Crossfire Telemetry packet from the queue.
|
||||
*/
|
||||
static int luaCrossfireTelemetryPop(lua_State * L)
|
||||
{
|
||||
if (!luaInputTelemetryFifo) {
|
||||
luaInputTelemetryFifo = new Fifo<uint8_t, LUA_TELEMETRY_INPUT_FIFO_SIZE>();
|
||||
if (!luaInputTelemetryFifo) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
auto queue = getTelemetryQueue();
|
||||
|
||||
uint8_t length = 0, data = 0;
|
||||
if (luaInputTelemetryFifo->probe(length) && luaInputTelemetryFifo->size() >= uint32_t(length)) {
|
||||
// length value includes the length field
|
||||
luaInputTelemetryFifo->pop(length);
|
||||
luaInputTelemetryFifo->pop(data); // command
|
||||
lua_pushinteger(L, data);
|
||||
lua_newtable(L);
|
||||
for (uint8_t i=1; i<length-1; i++) {
|
||||
luaInputTelemetryFifo->pop(data);
|
||||
lua_pushinteger(L, i);
|
||||
if (queue) {
|
||||
uint8_t length = 0, data = 0;
|
||||
if (queue->probe(length) && queue->size() >= uint32_t(length)) {
|
||||
// length value includes the length field
|
||||
queue->pop(length);
|
||||
queue->pop(data); // command
|
||||
lua_pushinteger(L, data);
|
||||
lua_settable(L, -3);
|
||||
lua_newtable(L);
|
||||
for (uint8_t i=1; i<length-1; i++) {
|
||||
queue->pop(data);
|
||||
lua_pushinteger(L, i);
|
||||
lua_pushinteger(L, data);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1268,27 +1280,24 @@ Pops a received Ghost Telemetry packet from the queue.
|
||||
*/
|
||||
static int luaGhostTelemetryPop(lua_State * L)
|
||||
{
|
||||
if (!luaInputTelemetryFifo) {
|
||||
luaInputTelemetryFifo = new Fifo<uint8_t, LUA_TELEMETRY_INPUT_FIFO_SIZE>();
|
||||
if (!luaInputTelemetryFifo) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
auto queue = getTelemetryQueue();
|
||||
|
||||
uint8_t length = 0, data = 0;
|
||||
if (luaInputTelemetryFifo->probe(length) && luaInputTelemetryFifo->size() >= uint32_t(length)) {
|
||||
// length value includes type(1B), payload, crc(1B)
|
||||
luaInputTelemetryFifo->pop(length);
|
||||
luaInputTelemetryFifo->pop(data); // type
|
||||
lua_pushinteger(L, data); // return type
|
||||
lua_newtable(L);
|
||||
for (uint8_t i=0; i<length-2; i++) {
|
||||
luaInputTelemetryFifo->pop(data);
|
||||
lua_pushinteger(L, i + 1);
|
||||
lua_pushinteger(L, data);
|
||||
lua_settable(L, -3);
|
||||
if (queue) {
|
||||
uint8_t length = 0, data = 0;
|
||||
if (queue->probe(length) && queue->size() >= uint32_t(length)) {
|
||||
// length value includes type(1B), payload, crc(1B)
|
||||
queue->pop(length);
|
||||
queue->pop(data); // type
|
||||
lua_pushinteger(L, data); // return type
|
||||
lua_newtable(L);
|
||||
for (uint8_t i=0; i<length-2; i++) {
|
||||
queue->pop(data);
|
||||
lua_pushinteger(L, i + 1);
|
||||
lua_pushinteger(L, data);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -2193,8 +2202,8 @@ Get percent of already used Lua instructions in current script execution cycle.
|
||||
static int luaGetUsage(lua_State * L)
|
||||
{
|
||||
#if defined(COLORLCD)
|
||||
if (luaLvglManager && luaLvglManager->useLvglLayout()) {
|
||||
lua_pushinteger(L, luaLvglManager->refreshInstructionsPercent);
|
||||
if (luaScriptManager && luaScriptManager->useLvglLayout()) {
|
||||
lua_pushinteger(L, luaScriptManager->refreshInstructionsPercent);
|
||||
} else {
|
||||
lua_pushinteger(L, instructionsPercent);
|
||||
}
|
||||
@@ -2592,30 +2601,10 @@ to the fields in the table returned by `model.getLogicalSwitch(switch)` identify
|
||||
static int luaGetSwitchIndex(lua_State * L)
|
||||
{
|
||||
const char * name = luaL_checkstring(L, 1);
|
||||
bool negate = false;
|
||||
bool found = false;
|
||||
swsrc_t idx;
|
||||
swsrc_t idx = getSwitchIndex(name, true);
|
||||
|
||||
if (name[0] == '!') {
|
||||
name++;
|
||||
negate = true;
|
||||
}
|
||||
|
||||
for (idx = SWSRC_NONE; idx < SWSRC_COUNT; idx++) {
|
||||
if (isSwitchAvailable(idx, ModelCustomFunctionsContext)) {
|
||||
char* s = getSwitchPositionName(idx);
|
||||
if (!strncasecmp(s, name, 31)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
if (negate)
|
||||
idx = -idx;
|
||||
if (idx != SWSRC_INVERT)
|
||||
lua_pushinteger(L, idx);
|
||||
}
|
||||
else
|
||||
lua_pushnil(L);
|
||||
|
||||
@@ -2715,8 +2704,7 @@ static int luaSwitches(lua_State * L)
|
||||
} else
|
||||
last = SWSRC_LAST;
|
||||
|
||||
lua_pushcfunction(L, luaNextSwitch);
|
||||
lua_pushinteger(L, last);
|
||||
lua_pushcfunction(L, luaNextSwitch); lua_pushinteger(L, last);
|
||||
lua_pushinteger(L, first);
|
||||
return 3;
|
||||
}
|
||||
@@ -2737,21 +2725,9 @@ This function is rather time consuming, and should not be used repeatedly in a s
|
||||
static int luaGetSourceIndex(lua_State* const L)
|
||||
{
|
||||
const char* const name = luaL_checkstring(L, 1);
|
||||
bool found = false;
|
||||
mixsrc_t idx;
|
||||
mixsrc_t idx = getSourceIndex(name, true);
|
||||
|
||||
for (idx = MIXSRC_NONE; idx <= MIXSRC_LAST_TELEM; idx++) {
|
||||
if (isSourceAvailable(idx)) {
|
||||
char srcName[maxSourceNameLength];
|
||||
getSourceString(srcName, idx);
|
||||
if (!strncasecmp(srcName, name)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
if (idx >= 0)
|
||||
lua_pushinteger(L, idx);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
|
||||
@@ -61,12 +61,6 @@ extern bool luaLcdAllowed;
|
||||
class BitmapBuffer;
|
||||
extern BitmapBuffer* luaLcdBuffer;
|
||||
|
||||
class LuaWidget;
|
||||
extern LuaWidget* runningFS;
|
||||
|
||||
class LuaLvglManager;
|
||||
extern LuaLvglManager* luaLvglManager;
|
||||
|
||||
extern uint32_t luaExtraMemoryUsage;
|
||||
void luaInitThemesAndWidgets();
|
||||
#endif
|
||||
|
||||
+306
-203
File diff suppressed because it is too large
Load Diff
@@ -24,6 +24,30 @@
|
||||
#define LVGL_METATABLE "LVGL*"
|
||||
#define LVGL_SIMPLEMETATABLE "LVGLSIMPLE*"
|
||||
|
||||
class LuaScriptManager;
|
||||
class LvglDialog;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct LvglParamFuncOrValue
|
||||
{
|
||||
public:
|
||||
enum ParamType {
|
||||
PVALUE,
|
||||
PTXT,
|
||||
};
|
||||
|
||||
int function;
|
||||
union {
|
||||
LcdFlags flags;
|
||||
coord_t coord;
|
||||
const char* txt;
|
||||
uint32_t value;
|
||||
};
|
||||
|
||||
void parse(lua_State *L, ParamType typ = PVALUE);
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class LvglWidgetObjectBase
|
||||
@@ -36,9 +60,6 @@ class LvglWidgetObjectBase
|
||||
void push(lua_State *L);
|
||||
void saveLvglObjectRef(int ref);
|
||||
|
||||
void getParams(lua_State *L, int index);
|
||||
|
||||
virtual void build(lua_State *L);
|
||||
virtual bool callRefs(lua_State *L);
|
||||
virtual void clearRefs(lua_State *L);
|
||||
void clearChildRefs(lua_State *L);
|
||||
@@ -47,12 +68,14 @@ class LvglWidgetObjectBase
|
||||
virtual void hide() = 0;
|
||||
virtual void enable() {};
|
||||
virtual void disable() {};
|
||||
virtual void close() {};
|
||||
|
||||
virtual void setColor(LcdFlags newColor) {}
|
||||
virtual void setOpacity(uint8_t newOpa) {}
|
||||
virtual void setPos(coord_t x, coord_t y) {}
|
||||
virtual void setSize(coord_t w, coord_t h) {}
|
||||
|
||||
void create(lua_State *L, int index);
|
||||
void update(lua_State *L);
|
||||
|
||||
virtual Window *getWindow() const = 0;
|
||||
@@ -66,21 +89,22 @@ class LvglWidgetObjectBase
|
||||
std::vector<int> lvglObjectRefs;
|
||||
const char* metatable = nullptr;
|
||||
bool clearRequest = false;
|
||||
LuaLvglManager *lvglManager = nullptr;
|
||||
LuaScriptManager *lvglManager = nullptr;
|
||||
coord_t x = 0, y = 0, w = LV_SIZE_CONTENT, h = LV_SIZE_CONTENT;
|
||||
LcdFlags color = COLOR2FLAGS(COLOR_THEME_SECONDARY1_INDEX);
|
||||
LcdFlags currentColor = -1;
|
||||
uint8_t opacity = LV_OPA_COVER;
|
||||
int getColorFunction = LUA_REFNIL;
|
||||
int getOpacityFunction = LUA_REFNIL;
|
||||
int getVisibleFunction = LUA_REFNIL;
|
||||
int getSizeFunction = LUA_REFNIL;
|
||||
int getPosFunction = LUA_REFNIL;
|
||||
LvglParamFuncOrValue color = { .function = LUA_REFNIL, .flags = COLOR2FLAGS(COLOR_THEME_SECONDARY1_INDEX)};
|
||||
LvglParamFuncOrValue opacity = { .function = LUA_REFNIL, .value = LV_OPA_COVER};
|
||||
|
||||
virtual void build(lua_State *L);
|
||||
virtual void refresh();
|
||||
|
||||
virtual void parseParam(lua_State *L, const char *key);
|
||||
|
||||
void getParams(lua_State *L, int index);
|
||||
|
||||
bool colorChanged(LcdFlags newColor);
|
||||
|
||||
void clearRef(lua_State *L, int& ref);
|
||||
@@ -128,26 +152,23 @@ class LvglWidgetLabel : public LvglSimpleWidgetObject
|
||||
void setFont(LcdFlags font);
|
||||
void setAlign(LcdFlags align);
|
||||
|
||||
void build(lua_State *L) override;
|
||||
bool callRefs(lua_State *L) override;
|
||||
void clearRefs(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
uint32_t textHash = -1;
|
||||
|
||||
const char *txt = "";
|
||||
LcdFlags font = FONT(STD);
|
||||
LcdFlags align = LEFT;
|
||||
int getTextFunction = LUA_REFNIL;
|
||||
int getFontFunction = LUA_REFNIL;
|
||||
int getAlignFunction = LUA_REFNIL;
|
||||
LvglParamFuncOrValue font = { .function = LUA_REFNIL, .flags = FONT(STD)};
|
||||
LvglParamFuncOrValue align = { .function = LUA_REFNIL, .flags = LEFT};
|
||||
LvglParamFuncOrValue txt = { .function = LUA_REFNIL, .txt = ""};
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
void refresh() override
|
||||
{
|
||||
setText(txt);
|
||||
setFont(font);
|
||||
setAlign(align);
|
||||
setText(txt.txt);
|
||||
setFont(font.flags);
|
||||
setAlign(align.flags);
|
||||
LvglSimpleWidgetObject::refresh();
|
||||
}
|
||||
};
|
||||
@@ -164,8 +185,6 @@ class LvglWidgetLineBase : public LvglSimpleWidgetObject
|
||||
void setPos(coord_t x, coord_t y) override;
|
||||
void setSize(coord_t w, coord_t h) override;
|
||||
|
||||
void build(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
bool rounded = false;
|
||||
int dashGap = 0;
|
||||
@@ -174,6 +193,7 @@ class LvglWidgetLineBase : public LvglSimpleWidgetObject
|
||||
|
||||
virtual void setLine() = 0;
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
void refresh() override;
|
||||
};
|
||||
@@ -205,24 +225,30 @@ class LvglWidgetVLine : public LvglWidgetLineBase
|
||||
class LvglWidgetLine : public LvglSimpleWidgetObject
|
||||
{
|
||||
public:
|
||||
LvglWidgetLine() : LvglSimpleWidgetObject() {}
|
||||
LvglWidgetLine();
|
||||
~LvglWidgetLine();
|
||||
|
||||
void setColor(LcdFlags newColor) override;
|
||||
void setOpacity(uint8_t newOpa) override;
|
||||
void setPos(coord_t x, coord_t y) override;
|
||||
void setSize(coord_t w, coord_t h) override;
|
||||
|
||||
void build(lua_State *L) override;
|
||||
bool callRefs(lua_State *L) override;
|
||||
void clearRefs(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
coord_t thickness = 1;
|
||||
bool rounded = false;
|
||||
size_t ptCnt = 0;
|
||||
lv_point_t* pts = nullptr;
|
||||
uint32_t ptsHash = -1;
|
||||
lv_obj_t* parent = nullptr;
|
||||
int getPointsFunction = LUA_REFNIL;
|
||||
|
||||
void setLine();
|
||||
|
||||
void getPt(lua_State* L, int n);
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
void refresh() override;
|
||||
};
|
||||
@@ -232,22 +258,27 @@ class LvglWidgetLine : public LvglSimpleWidgetObject
|
||||
class LvglWidgetTriangle : public LvglSimpleWidgetObject
|
||||
{
|
||||
public:
|
||||
LvglWidgetTriangle() : LvglSimpleWidgetObject() {}
|
||||
LvglWidgetTriangle();
|
||||
~LvglWidgetTriangle();
|
||||
|
||||
void setColor(LcdFlags newColor) override;
|
||||
void setSize(coord_t w, coord_t h) override;
|
||||
|
||||
void build(lua_State *L) override;
|
||||
bool callRefs(lua_State *L) override;
|
||||
void clearRefs(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
coord_t px[3] = {0}, py[3] = {0};
|
||||
lv_point_t pts[3] = {0};
|
||||
uint32_t ptsHash = -1;
|
||||
MaskBitmap* mask = nullptr;
|
||||
lv_obj_t* parent = nullptr;
|
||||
int getPointsFunction = LUA_REFNIL;
|
||||
|
||||
void fillTriangle();
|
||||
void fillLine(coord_t x1, coord_t x2, coord_t y);
|
||||
|
||||
void getPt(lua_State* L, int n);
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
void refresh() override;
|
||||
};
|
||||
@@ -290,9 +321,8 @@ class LvglWidgetBox : public LvglWidgetObject
|
||||
public:
|
||||
LvglWidgetBox() : LvglWidgetObject() {}
|
||||
|
||||
void build(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
void build(lua_State *L) override;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -302,11 +332,10 @@ class LvglWidgetSetting : public LvglWidgetObject
|
||||
public:
|
||||
LvglWidgetSetting() : LvglWidgetObject() {}
|
||||
|
||||
void build(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
const char *txt = "";
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
};
|
||||
|
||||
@@ -320,12 +349,11 @@ class LvglWidgetBorderedObject : public LvglWidgetObject
|
||||
void setColor(LcdFlags newColor) override;
|
||||
void setOpacity(uint8_t newOpa) override;
|
||||
|
||||
void build(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
coord_t thickness = 1;
|
||||
bool filled = false;
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
};
|
||||
|
||||
@@ -343,14 +371,12 @@ class LvglWidgetRoundObject : public LvglWidgetBorderedObject
|
||||
void clearRefs(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
coord_t radius = 0;
|
||||
|
||||
int getRadiusFunction = LUA_REFNIL;
|
||||
LvglParamFuncOrValue radius = { .function = LUA_REFNIL, .coord = 0};
|
||||
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
void refresh() override
|
||||
{
|
||||
setRadius(radius);
|
||||
setRadius(radius.coord);
|
||||
LvglWidgetObject::refresh();
|
||||
}
|
||||
};
|
||||
@@ -362,11 +388,10 @@ class LvglWidgetRectangle : public LvglWidgetBorderedObject
|
||||
public:
|
||||
LvglWidgetRectangle() : LvglWidgetBorderedObject() {}
|
||||
|
||||
void build(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
coord_t rounded = 0;
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
};
|
||||
|
||||
@@ -377,9 +402,8 @@ class LvglWidgetCircle : public LvglWidgetRoundObject
|
||||
public:
|
||||
LvglWidgetCircle() : LvglWidgetRoundObject() {}
|
||||
|
||||
void build(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
void build(lua_State *L) override;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -394,21 +418,19 @@ class LvglWidgetArc : public LvglWidgetRoundObject
|
||||
void setStartAngle(coord_t angle);
|
||||
void setEndAngle(coord_t angle);
|
||||
|
||||
void build(lua_State *L) override;
|
||||
bool callRefs(lua_State *L) override;
|
||||
void clearRefs(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
coord_t startAngle = 0, endAngle = 0;
|
||||
|
||||
int getStartAngleFunction = LUA_REFNIL;
|
||||
int getEndAngleFunction = LUA_REFNIL;
|
||||
LvglParamFuncOrValue startAngle = { .function = LUA_REFNIL, .coord = 0};
|
||||
LvglParamFuncOrValue endAngle = { .function = LUA_REFNIL, .coord = 0};
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
void refresh() override
|
||||
{
|
||||
setStartAngle(startAngle);
|
||||
setEndAngle(endAngle);
|
||||
setStartAngle(startAngle.coord);
|
||||
setEndAngle(endAngle.coord);
|
||||
LvglWidgetRoundObject::refresh();
|
||||
}
|
||||
};
|
||||
@@ -420,12 +442,11 @@ class LvglWidgetImage : public LvglWidgetObject
|
||||
public:
|
||||
LvglWidgetImage() : LvglWidgetObject(LVGL_SIMPLEMETATABLE) {}
|
||||
|
||||
void build(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
std::string filename;
|
||||
bool fillFrame = false;
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
};
|
||||
|
||||
@@ -436,12 +457,11 @@ class LvglWidgetQRCode : public LvglWidgetObject
|
||||
public:
|
||||
LvglWidgetQRCode() : LvglWidgetObject(LVGL_SIMPLEMETATABLE) {}
|
||||
|
||||
void build(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
std::string data;
|
||||
LcdFlags bgColor = COLOR2FLAGS(COLOR_THEME_SECONDARY3_INDEX);
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
};
|
||||
|
||||
@@ -452,7 +472,7 @@ class LvglWidgetTextButtonBase : public LvglWidgetObject
|
||||
public:
|
||||
LvglWidgetTextButtonBase() : LvglWidgetObject(LVGL_SIMPLEMETATABLE)
|
||||
{
|
||||
color = -1; // ignore unless overridden
|
||||
color.flags = -1; // ignore unless overridden
|
||||
}
|
||||
|
||||
void setText(const char *s);
|
||||
@@ -485,13 +505,13 @@ class LvglWidgetTextButton : public LvglWidgetTextButtonBase
|
||||
void setFont(LcdFlags font);
|
||||
void setChecked(bool check);
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void clearRefs(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
bool checked = false;
|
||||
int longPressFunction = LUA_REFNIL;
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
void refresh() override
|
||||
{
|
||||
@@ -509,12 +529,12 @@ class LvglWidgetMomentaryButton : public LvglWidgetTextButtonBase
|
||||
|
||||
void setFont(LcdFlags font);
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void clearRefs(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
int releaseFunction = LUA_REFNIL;
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
};
|
||||
|
||||
@@ -525,13 +545,13 @@ class LvglWidgetToggleSwitch : public LvglWidgetObject
|
||||
public:
|
||||
LvglWidgetToggleSwitch() : LvglWidgetObject(LVGL_SIMPLEMETATABLE) {}
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void clearRefs(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
int getStateFunction = LUA_REFNIL;
|
||||
int setStateFunction = LUA_REFNIL;
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
};
|
||||
|
||||
@@ -542,7 +562,6 @@ class LvglWidgetTextEdit : public LvglWidgetObject
|
||||
public:
|
||||
LvglWidgetTextEdit() : LvglWidgetObject(LVGL_SIMPLEMETATABLE) {}
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void clearRefs(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
@@ -552,6 +571,7 @@ class LvglWidgetTextEdit : public LvglWidgetObject
|
||||
|
||||
int setFunction = LUA_REFNIL;
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
};
|
||||
|
||||
@@ -562,7 +582,6 @@ class LvglWidgetNumberEdit : public LvglWidgetObject
|
||||
public:
|
||||
LvglWidgetNumberEdit() : LvglWidgetObject(LVGL_SIMPLEMETATABLE) {}
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void clearRefs(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
@@ -572,6 +591,7 @@ class LvglWidgetNumberEdit : public LvglWidgetObject
|
||||
int setFunction = LUA_REFNIL;
|
||||
int dispFunction = LUA_REFNIL;
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
};
|
||||
|
||||
@@ -582,7 +602,7 @@ class LvglWidgetSliderBase : public LvglWidgetObject
|
||||
public:
|
||||
LvglWidgetSliderBase() : LvglWidgetObject(LVGL_SIMPLEMETATABLE)
|
||||
{
|
||||
color = -1;
|
||||
color.flags = -1;
|
||||
}
|
||||
|
||||
void setColor(LcdFlags newColor) override;
|
||||
@@ -605,6 +625,7 @@ class LvglWidgetSlider : public LvglWidgetSliderBase
|
||||
public:
|
||||
LvglWidgetSlider() : LvglWidgetSliderBase() {}
|
||||
|
||||
protected:
|
||||
void build(lua_State *L) override;
|
||||
};
|
||||
|
||||
@@ -615,6 +636,7 @@ class LvglWidgetVerticalSlider : public LvglWidgetSliderBase
|
||||
public:
|
||||
LvglWidgetVerticalSlider() : LvglWidgetSliderBase() {}
|
||||
|
||||
protected:
|
||||
void build(lua_State *L) override;
|
||||
};
|
||||
|
||||
@@ -625,7 +647,6 @@ class LvglWidgetPage : public LvglWidgetObject
|
||||
public:
|
||||
LvglWidgetPage() : LvglWidgetObject() {}
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void clearRefs(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
@@ -635,6 +656,7 @@ class LvglWidgetPage : public LvglWidgetObject
|
||||
|
||||
int backActionFunction = LUA_REFNIL;
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
};
|
||||
|
||||
@@ -645,14 +667,16 @@ class LvglWidgetDialog : public LvglWidgetObject
|
||||
public:
|
||||
LvglWidgetDialog() : LvglWidgetObject() {}
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void clearRefs(lua_State *L) override;
|
||||
void close() override;
|
||||
|
||||
protected:
|
||||
const char *title = nullptr;
|
||||
LvglDialog* dialog = nullptr;
|
||||
|
||||
int closeFunction = LUA_REFNIL;
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
};
|
||||
|
||||
@@ -663,7 +687,6 @@ class LvglWidgetConfirmDialog : public LvglWidgetObject
|
||||
public:
|
||||
LvglWidgetConfirmDialog() : LvglWidgetObject(LVGL_SIMPLEMETATABLE) {}
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void clearRefs(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
@@ -673,6 +696,7 @@ class LvglWidgetConfirmDialog : public LvglWidgetObject
|
||||
int confirmFunction = LUA_REFNIL;
|
||||
int cancelFunction = LUA_REFNIL;
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
};
|
||||
|
||||
@@ -683,13 +707,12 @@ class LvglWidgetMessageDialog : public LvglWidgetObject
|
||||
public:
|
||||
LvglWidgetMessageDialog() : LvglWidgetObject(LVGL_SIMPLEMETATABLE) {}
|
||||
|
||||
void build(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
const char *title = nullptr;
|
||||
const char *message = nullptr;
|
||||
const char *details = nullptr;
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
};
|
||||
|
||||
@@ -716,12 +739,11 @@ class LvglWidgetChoice : public LvglWidgetPicker
|
||||
public:
|
||||
LvglWidgetChoice() : LvglWidgetPicker() {}
|
||||
|
||||
void build(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
std::string title;
|
||||
std::vector<std::string> values;
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
};
|
||||
|
||||
@@ -732,6 +754,7 @@ class LvglWidgetFontPicker : public LvglWidgetPicker
|
||||
public:
|
||||
LvglWidgetFontPicker() : LvglWidgetPicker() {}
|
||||
|
||||
protected:
|
||||
void build(lua_State *L) override;
|
||||
};
|
||||
|
||||
@@ -742,6 +765,7 @@ class LvglWidgetAlignPicker : public LvglWidgetPicker
|
||||
public:
|
||||
LvglWidgetAlignPicker() : LvglWidgetPicker() {}
|
||||
|
||||
protected:
|
||||
void build(lua_State *L) override;
|
||||
};
|
||||
|
||||
@@ -752,6 +776,7 @@ class LvglWidgetColorPicker : public LvglWidgetPicker
|
||||
public:
|
||||
LvglWidgetColorPicker() : LvglWidgetPicker() {}
|
||||
|
||||
protected:
|
||||
void build(lua_State *L) override;
|
||||
};
|
||||
|
||||
@@ -762,6 +787,7 @@ class LvglWidgetTimerPicker : public LvglWidgetPicker
|
||||
public:
|
||||
LvglWidgetTimerPicker() : LvglWidgetPicker() {}
|
||||
|
||||
protected:
|
||||
void build(lua_State *L) override;
|
||||
};
|
||||
|
||||
@@ -772,11 +798,10 @@ class LvglWidgetSwitchPicker : public LvglWidgetPicker
|
||||
public:
|
||||
LvglWidgetSwitchPicker() : LvglWidgetPicker() {}
|
||||
|
||||
void build(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
uint32_t filter = 0xFFFFFFFF;
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
};
|
||||
|
||||
@@ -787,11 +812,10 @@ class LvglWidgetSourcePicker : public LvglWidgetPicker
|
||||
public:
|
||||
LvglWidgetSourcePicker() : LvglWidgetPicker() {}
|
||||
|
||||
void build(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
uint32_t filter = 0xFFFFFFFF;
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
};
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
|
||||
#define MAX_INSTRUCTIONS (20000 / 100)
|
||||
|
||||
LuaScriptManager *luaScriptManager = nullptr;
|
||||
|
||||
#if defined(HARDWARE_TOUCH)
|
||||
uint32_t LuaEventHandler::downTime = 0;
|
||||
uint32_t LuaEventHandler::tapTime = 0;
|
||||
@@ -140,7 +142,7 @@ void LuaEventHandler::event_cb(lv_event_t* e)
|
||||
#endif
|
||||
}
|
||||
|
||||
void LuaEventHandler::onClicked()
|
||||
void LuaEventHandler::onClickedEvent()
|
||||
{
|
||||
#if defined(HARDWARE_TOUCH)
|
||||
auto click_source = lv_indev_get_act();
|
||||
@@ -167,7 +169,7 @@ void LuaEventHandler::onClicked()
|
||||
luaPushEvent(EVT_KEY_BREAK(KEY_ENTER));
|
||||
}
|
||||
|
||||
void LuaEventHandler::onCancel() {
|
||||
void LuaEventHandler::onCancelEvent() {
|
||||
luaPushEvent(EVT_KEY_BREAK(KEY_EXIT));
|
||||
}
|
||||
|
||||
@@ -217,18 +219,41 @@ void LuaWidget::redraw_cb(lv_event_t* e)
|
||||
buf.setClippingRect(clipping.x1 - a.x1, clipping.x2 + 1 - a.x1,
|
||||
clipping.y1 - a.y1, clipping.y2 + 1 - a.y1);
|
||||
|
||||
auto save = luaScriptManager;
|
||||
luaScriptManager = widget;
|
||||
widget->refresh(&buf);
|
||||
luaScriptManager = save;
|
||||
}
|
||||
}
|
||||
|
||||
LuaWidget::LuaWidget(const WidgetFactory* factory, Window* parent,
|
||||
const rect_t& rect, WidgetPersistentData* persistentData,
|
||||
int luaScriptContextRef, int zoneRectDataRef, int optionsDataRef) :
|
||||
int zoneRectDataRef, int optionsDataRef,
|
||||
int createFunctionRef, std::string path) :
|
||||
Widget(factory, parent, rect, persistentData),
|
||||
zoneRectDataRef(zoneRectDataRef), optionsDataRef(optionsDataRef),
|
||||
errorMessage(nullptr)
|
||||
{
|
||||
this->luaScriptContextRef = luaScriptContextRef;
|
||||
// Push create function
|
||||
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, createFunctionRef);
|
||||
// Push stored zone for 'create' call
|
||||
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, zoneRectDataRef);
|
||||
// Push stored options for 'create' call
|
||||
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, optionsDataRef);
|
||||
// Push widget folder path
|
||||
lua_pushstring(lsWidgets, path.c_str());
|
||||
|
||||
auto save = luaScriptManager;
|
||||
luaScriptManager = this;
|
||||
|
||||
if (lua_pcall(lsWidgets, 3, 1, 0) == LUA_OK) {
|
||||
luaScriptContextRef = luaL_ref(lsWidgets, LUA_REGISTRYINDEX);
|
||||
} else {
|
||||
luaScriptContextRef = LUA_NOREF;
|
||||
setErrorMessage("create()");
|
||||
}
|
||||
|
||||
luaScriptManager = save;
|
||||
|
||||
if (useLvglLayout()) {
|
||||
update();
|
||||
@@ -252,7 +277,7 @@ void LuaWidget::onClicked()
|
||||
return;
|
||||
}
|
||||
|
||||
LuaEventHandler::onClicked();
|
||||
LuaScriptManager::onClickedEvent();
|
||||
}
|
||||
|
||||
void LuaWidget::onCancel()
|
||||
@@ -262,7 +287,7 @@ void LuaWidget::onCancel()
|
||||
return;
|
||||
}
|
||||
|
||||
LuaEventHandler::onCancel();
|
||||
LuaScriptManager::onCancelEvent();
|
||||
}
|
||||
|
||||
void LuaWidget::checkEvents()
|
||||
@@ -286,8 +311,9 @@ void LuaWidget::checkEvents()
|
||||
lv_obj_get_coords(lvobj, &a);
|
||||
// Check widget is at least partially visible
|
||||
if (a.x2 >= 0 && a.x1 < LCD_W) {
|
||||
auto save = luaScriptManager;
|
||||
PROTECT_LUA() {
|
||||
luaLvglManager = this;
|
||||
luaScriptManager = this;
|
||||
refresh(nullptr);
|
||||
if (!errorMessage) {
|
||||
if (!callRefs(lsWidgets)) {
|
||||
@@ -298,7 +324,7 @@ void LuaWidget::checkEvents()
|
||||
} else {
|
||||
// TODO: error handling
|
||||
}
|
||||
luaLvglManager = nullptr;
|
||||
luaScriptManager = save;
|
||||
UNPROTECT_LUA();
|
||||
}
|
||||
}
|
||||
@@ -325,7 +351,7 @@ void LuaWidget::update()
|
||||
// Get options table and update values
|
||||
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, optionsDataRef);
|
||||
int i = 0;
|
||||
for (const ZoneOption* option = getOptions(); option->name; option++, i++) {
|
||||
for (const ZoneOption* option = getOptionDefinitions(); option->name; option++, i++) {
|
||||
auto optVal = getOptionValue(i);
|
||||
switch (option->type) {
|
||||
case ZoneOption::String:
|
||||
@@ -347,7 +373,7 @@ void LuaWidget::update()
|
||||
lua_setfield(lsWidgets, -2, option->name);
|
||||
}
|
||||
|
||||
if (useLvglLayout()) luaLvglManager = this;
|
||||
luaScriptManager = this;
|
||||
|
||||
if (lua_pcall(lsWidgets, 2, 0, 0) != 0)
|
||||
setErrorMessage("update()");
|
||||
@@ -370,7 +396,7 @@ void LuaWidget::update()
|
||||
}
|
||||
}
|
||||
|
||||
luaLvglManager = nullptr;
|
||||
luaScriptManager = nullptr;
|
||||
}
|
||||
|
||||
// Update table on top of Lua stack - set entry with name 'idx' to value 'val'
|
||||
@@ -499,12 +525,10 @@ void LuaWidget::refresh(BitmapBuffer* dc)
|
||||
// scripts
|
||||
bool lla = luaLcdAllowed;
|
||||
luaLcdAllowed = true;
|
||||
runningFS = this;
|
||||
|
||||
if (lua_pcall(lsWidgets, 3, 0, 0) != 0) {
|
||||
setErrorMessage("refresh()");
|
||||
}
|
||||
runningFS = nullptr;
|
||||
// Remove LCD
|
||||
luaLcdAllowed = lla;
|
||||
luaLcdBuffer = nullptr;
|
||||
@@ -521,18 +545,19 @@ void LuaWidget::background()
|
||||
luaSetInstructionsLimit(lsWidgets, MAX_INSTRUCTIONS);
|
||||
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, luaFactory()->backgroundFunction);
|
||||
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, luaScriptContextRef);
|
||||
runningFS = this;
|
||||
auto save = luaScriptManager;
|
||||
luaScriptManager = this;
|
||||
if (lua_pcall(lsWidgets, 1, 0, 0) != 0) {
|
||||
setErrorMessage("background()");
|
||||
}
|
||||
runningFS = nullptr;
|
||||
luaScriptManager = save;
|
||||
}
|
||||
}
|
||||
|
||||
void LuaWidget::onEvent(event_t event)
|
||||
{
|
||||
if (fullscreen) {
|
||||
LuaEventHandler::onLuaEvent(event);
|
||||
LuaScriptManager::onLuaEvent(event);
|
||||
}
|
||||
Widget::onEvent(event);
|
||||
}
|
||||
@@ -547,10 +572,10 @@ bool LuaWidget::useLvglLayout() const { return luaFactory()->useLvglLayout(); }
|
||||
|
||||
bool LuaWidget::isAppMode() const
|
||||
{
|
||||
return fullscreen && ViewMain::instance()->isAppMode();
|
||||
return ((WidgetsContainer*)parent)->isAppMode();
|
||||
}
|
||||
|
||||
void LuaLvglManager::saveLvglObjectRef(int ref)
|
||||
void LuaScriptManager::saveLvglObjectRef(int ref)
|
||||
{
|
||||
if (tempParent)
|
||||
tempParent->saveLvglObjectRef(ref);
|
||||
@@ -558,7 +583,7 @@ void LuaLvglManager::saveLvglObjectRef(int ref)
|
||||
lvglObjectRefs.push_back(ref);
|
||||
}
|
||||
|
||||
void LuaLvglManager::clearRefs(lua_State *L)
|
||||
void LuaScriptManager::clearRefs(lua_State *L)
|
||||
{
|
||||
for (size_t i = 0; i < lvglObjectRefs.size(); i += 1) {
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, lvglObjectRefs[i]);
|
||||
@@ -569,7 +594,7 @@ void LuaLvglManager::clearRefs(lua_State *L)
|
||||
lvglObjectRefs.clear();
|
||||
}
|
||||
|
||||
bool LuaLvglManager::callRefs(lua_State *L)
|
||||
bool LuaScriptManager::callRefs(lua_State *L)
|
||||
{
|
||||
for (size_t i = 0; i < lvglObjectRefs.size(); i += 1) {
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, lvglObjectRefs[i]);
|
||||
@@ -579,3 +604,20 @@ bool LuaLvglManager::callRefs(lua_State *L)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void LuaScriptManager::createTelemetryQueue()
|
||||
{
|
||||
if (luaInputTelemetryFifo == nullptr) {
|
||||
luaInputTelemetryFifo = new TelemetryQueue();
|
||||
registerTelemetryQueue(luaInputTelemetryFifo);
|
||||
}
|
||||
}
|
||||
|
||||
LuaScriptManager::~LuaScriptManager()
|
||||
{
|
||||
if (luaInputTelemetryFifo == nullptr) {
|
||||
deregisterTelemetryQueue(luaInputTelemetryFifo);
|
||||
delete luaInputTelemetryFifo;
|
||||
luaInputTelemetryFifo = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
+40
-30
@@ -28,6 +28,7 @@
|
||||
#include "lua_states.h"
|
||||
#include "lua_api.h"
|
||||
#include "lua_lvgl_widget.h"
|
||||
#include "telemetry/telemetry.h"
|
||||
|
||||
#include "edgetx_types.h"
|
||||
|
||||
@@ -35,10 +36,37 @@
|
||||
|
||||
class LuaWidgetFactory;
|
||||
|
||||
class LuaLvglManager
|
||||
class LuaEventHandler
|
||||
{
|
||||
public:
|
||||
LuaEventHandler() = default;
|
||||
void setupHandler(Window* w);
|
||||
void removeHandler(Window* w);
|
||||
|
||||
protected:
|
||||
#if defined(HARDWARE_TOUCH)
|
||||
// "tap" handling
|
||||
static uint32_t downTime;
|
||||
static uint32_t tapTime;
|
||||
static uint32_t tapCount;
|
||||
// "swipe" / "slide" handling
|
||||
static tmr10ms_t swipeTimeOut;
|
||||
static bool _sliding;
|
||||
static coord_t _startX;
|
||||
static coord_t _startY;
|
||||
#endif
|
||||
static void event_cb(lv_event_t* e);
|
||||
|
||||
void onClickedEvent();
|
||||
void onCancelEvent();
|
||||
void onLuaEvent(event_t event);
|
||||
};
|
||||
|
||||
class LuaScriptManager : public LuaEventHandler
|
||||
{
|
||||
public:
|
||||
LuaLvglManager() = default;
|
||||
LuaScriptManager() = default;
|
||||
~LuaScriptManager();
|
||||
|
||||
std::vector<int> getLvglObjectRefs() const { return lvglObjectRefs; }
|
||||
void saveLvglObjectRef(int ref);
|
||||
@@ -62,46 +90,26 @@ class LuaLvglManager
|
||||
|
||||
uint8_t refreshInstructionsPercent;
|
||||
|
||||
void createTelemetryQueue();
|
||||
TelemetryQueue* telemetryQueue() { return luaInputTelemetryFifo; }
|
||||
|
||||
protected:
|
||||
int luaScriptContextRef = 0;
|
||||
std::vector<int> lvglObjectRefs;
|
||||
LvglWidgetObjectBase* tempParent = nullptr;
|
||||
};
|
||||
|
||||
class LuaEventHandler
|
||||
{
|
||||
public:
|
||||
LuaEventHandler() = default;
|
||||
void setupHandler(Window* w);
|
||||
void removeHandler(Window* w);
|
||||
|
||||
protected:
|
||||
#if defined(HARDWARE_TOUCH)
|
||||
// "tap" handling
|
||||
static uint32_t downTime;
|
||||
static uint32_t tapTime;
|
||||
static uint32_t tapCount;
|
||||
// "swipe" / "slide" handling
|
||||
static tmr10ms_t swipeTimeOut;
|
||||
static bool _sliding;
|
||||
static coord_t _startX;
|
||||
static coord_t _startY;
|
||||
#if defined(LUA)
|
||||
TelemetryQueue* luaInputTelemetryFifo = nullptr;
|
||||
#endif
|
||||
static void event_cb(lv_event_t* e);
|
||||
|
||||
void onClicked();
|
||||
void onCancel();
|
||||
void onLuaEvent(event_t event);
|
||||
};
|
||||
|
||||
class LuaWidget : public Widget, public LuaEventHandler, public LuaLvglManager
|
||||
class LuaWidget : public Widget, public LuaScriptManager
|
||||
{
|
||||
friend class LuaWidgetFactory;
|
||||
|
||||
public:
|
||||
LuaWidget(const WidgetFactory* factory, Window* parent, const rect_t& rect,
|
||||
WidgetPersistentData* persistentData, int luaScriptContextRef, int zoneRectDataRef,
|
||||
int optionsDataRef);
|
||||
WidgetPersistentData* persistentData, int zoneRectDataRef,
|
||||
int optionsDataRef, int createFunctionRef, std::string path);
|
||||
~LuaWidget() override;
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
@@ -160,3 +168,5 @@ class LuaWidget : public Widget, public LuaEventHandler, public LuaLvglManager
|
||||
|
||||
static void redraw_cb(lv_event_t *e);
|
||||
};
|
||||
|
||||
extern LuaScriptManager* luaScriptManager;
|
||||
|
||||
@@ -24,18 +24,26 @@
|
||||
|
||||
#include "lua_api.h"
|
||||
#include "lua_states.h"
|
||||
#include "strhelpers.h"
|
||||
|
||||
#define MAX_INSTRUCTIONS (20000/100)
|
||||
|
||||
LuaWidgetFactory::LuaWidgetFactory(const char* name, ZoneOption* widgetOptions,
|
||||
int createFunction) :
|
||||
LuaWidgetFactory::LuaWidgetFactory(const char* name, ZoneOption* widgetOptions, int optionDefinitionsReference,
|
||||
int createFunction, int updateFunction, int refreshFunction,
|
||||
int backgroundFunction, int translateFunction, bool lvglLayout,
|
||||
const char* filename) :
|
||||
WidgetFactory(name, widgetOptions),
|
||||
optionDefinitionsReference(optionDefinitionsReference),
|
||||
createFunction(createFunction),
|
||||
updateFunction(0),
|
||||
refreshFunction(0),
|
||||
backgroundFunction(0),
|
||||
translateFunction(0)
|
||||
updateFunction(updateFunction),
|
||||
refreshFunction(refreshFunction),
|
||||
backgroundFunction(backgroundFunction),
|
||||
translateFunction(translateFunction),
|
||||
lvglLayout(lvglLayout),
|
||||
path(filename)
|
||||
{
|
||||
path = path.substr(0, path.rfind("/") + 1);
|
||||
translateOptions(widgetOptions);
|
||||
}
|
||||
|
||||
LuaWidgetFactory::~LuaWidgetFactory() {
|
||||
@@ -45,7 +53,7 @@ LuaWidgetFactory::~LuaWidgetFactory() {
|
||||
delete displayName;
|
||||
}
|
||||
|
||||
auto option = getOptions();
|
||||
auto option = getDefaultOptions();
|
||||
while (option && option->name != nullptr) {
|
||||
if (option->displayName) {
|
||||
delete option->displayName;
|
||||
@@ -62,7 +70,6 @@ Widget* LuaWidgetFactory::create(Window* parent, const rect_t& rect,
|
||||
initPersistentData(persistentData, init);
|
||||
|
||||
luaSetInstructionsLimit(lsWidgets, MAX_INSTRUCTIONS);
|
||||
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, createFunction);
|
||||
|
||||
// Make 'zone' table for 'create' call
|
||||
lua_newtable(lsWidgets);
|
||||
@@ -75,8 +82,6 @@ Widget* LuaWidgetFactory::create(Window* parent, const rect_t& rect,
|
||||
|
||||
// Store the zone data in registry for later updates
|
||||
int zoneRectDataRef = luaL_ref(lsWidgets, LUA_REGISTRYINDEX);
|
||||
// Push stored zone for 'create' call
|
||||
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, zoneRectDataRef);
|
||||
|
||||
// Create options table
|
||||
lua_newtable(lsWidgets);
|
||||
@@ -99,14 +104,8 @@ Widget* LuaWidgetFactory::create(Window* parent, const rect_t& rect,
|
||||
|
||||
// Store the options data in registry for later updates
|
||||
int optionsDataRef = luaL_ref(lsWidgets, LUA_REGISTRYINDEX);
|
||||
// Push stored options for 'create' call
|
||||
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, optionsDataRef);
|
||||
|
||||
bool err = lua_pcall(lsWidgets, 2, 1, 0);
|
||||
int widgetData = err ? LUA_NOREF : luaL_ref(lsWidgets, LUA_REGISTRYINDEX);
|
||||
LuaWidget* lw = new LuaWidget(this, parent, rect, persistentData, widgetData, zoneRectDataRef, optionsDataRef);
|
||||
if (err) lw->setErrorMessage("create()");
|
||||
return lw;
|
||||
return new LuaWidget(this, parent, rect, persistentData, zoneRectDataRef, optionsDataRef, createFunction, path);
|
||||
}
|
||||
|
||||
void LuaWidgetFactory::translateOptions(ZoneOption * options)
|
||||
@@ -144,3 +143,207 @@ void LuaWidgetFactory::translateOptions(ZoneOption * options)
|
||||
}
|
||||
lua_pop(lsWidgets, 1);
|
||||
}
|
||||
|
||||
static int switchValue()
|
||||
{
|
||||
int v = SWSRC_INVERT;
|
||||
if (lua_istable(lsWidgets, -1)) {
|
||||
// Find first available
|
||||
int t = lua_gettop(lsWidgets);
|
||||
for (lua_pushnil(lsWidgets); v == SWSRC_INVERT && lua_next(lsWidgets, -2); lua_pop(lsWidgets, 1)) {
|
||||
v = getSwitchIndex(luaL_checkstring(lsWidgets, -1), false);
|
||||
}
|
||||
lua_settop(lsWidgets, t);
|
||||
} else if (lua_type(lsWidgets, -1) == LUA_TSTRING) {
|
||||
v = getSwitchIndex(lua_tostring(lsWidgets, -1), true);
|
||||
} else {
|
||||
v = luaL_checkinteger(lsWidgets, -1);
|
||||
}
|
||||
if (v == SWSRC_INVERT) v = SWSRC_NONE;
|
||||
return v;
|
||||
}
|
||||
|
||||
static int sourceValue()
|
||||
{
|
||||
int v = -1;
|
||||
if (lua_istable(lsWidgets, -1)) {
|
||||
// Find first available
|
||||
int t = lua_gettop(lsWidgets);
|
||||
for (lua_pushnil(lsWidgets); v < 0 && lua_next(lsWidgets, -2); lua_pop(lsWidgets, 1)) {
|
||||
v = getSourceIndex(luaL_checkstring(lsWidgets, -1), false);
|
||||
}
|
||||
lua_settop(lsWidgets, t);
|
||||
} else if (lua_type(lsWidgets, -1) == LUA_TSTRING) {
|
||||
v = getSourceIndex(lua_tostring(lsWidgets, -1), true);
|
||||
} else {
|
||||
v = luaL_checkunsigned(lsWidgets, -1);
|
||||
}
|
||||
if (v == -1) v = MIXSRC_NONE;
|
||||
return v;
|
||||
}
|
||||
|
||||
// Parse the options table to get the default, min and max values
|
||||
// Called when the widget settings dialog is opened to get values
|
||||
// for current loaded model.
|
||||
const void LuaWidgetFactory::parseOptionDefaults() const
|
||||
{
|
||||
if (optionDefinitionsReference == LUA_REFNIL) {
|
||||
// TRACE("parseOptionDefaults() no options");
|
||||
return;
|
||||
}
|
||||
|
||||
PROTECT_LUA()
|
||||
{
|
||||
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, optionDefinitionsReference);
|
||||
ZoneOption *option = (ZoneOption*)options;
|
||||
for (lua_pushnil(lsWidgets); lua_next(lsWidgets, -2), option->name;
|
||||
lua_pop(lsWidgets, 1)) {
|
||||
// TRACE("parsing option %d", count);
|
||||
luaL_checktype(lsWidgets, -2, LUA_TNUMBER); // key is number
|
||||
luaL_checktype(lsWidgets, -1, LUA_TTABLE); // value is table
|
||||
uint8_t field = 0;
|
||||
for (lua_pushnil(lsWidgets); lua_next(lsWidgets, -2) && field < 5;
|
||||
lua_pop(lsWidgets, 1), field++) {
|
||||
luaL_checktype(lsWidgets, -2, LUA_TNUMBER); // key is number
|
||||
switch (field) {
|
||||
case 2:
|
||||
if (option->type == ZoneOption::Switch) {
|
||||
option->deflt.signedValue = switchValue();
|
||||
} else if (option->type == ZoneOption::Source) {
|
||||
option->deflt.unsignedValue = sourceValue();
|
||||
} else if (option->type == ZoneOption::Integer) {
|
||||
option->deflt.signedValue = luaL_checkinteger(lsWidgets, -1);
|
||||
} else if (option->type == ZoneOption::Bool) {
|
||||
option->deflt.boolValue = (luaL_checkunsigned(lsWidgets, -1) != 0);
|
||||
} else if (option->type == ZoneOption::String || option->type == ZoneOption::File) {
|
||||
strncpy(option->deflt.stringValue, luaL_checkstring(lsWidgets, -1),
|
||||
LEN_ZONE_OPTION_STRING);
|
||||
} else {
|
||||
option->deflt.unsignedValue = luaL_checkunsigned(lsWidgets, -1);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (option->type == ZoneOption::Switch) {
|
||||
option->min.signedValue = switchValue();
|
||||
} else if (option->type == ZoneOption::Source) {
|
||||
option->min.unsignedValue = sourceValue();
|
||||
} else if (option->type == ZoneOption::Integer || option->type == ZoneOption::Slider) {
|
||||
option->min.signedValue = luaL_checkinteger(lsWidgets, -1);
|
||||
} else if (option->type == ZoneOption::Choice) {
|
||||
luaL_checktype(lsWidgets, -1, LUA_TTABLE); // value is a table
|
||||
for (lua_pushnil(lsWidgets); lua_next(lsWidgets, -2); lua_pop(lsWidgets, 1)) {
|
||||
option->choiceValues.push_back(luaL_checkstring(lsWidgets, -1));
|
||||
}
|
||||
} else if (option->type == ZoneOption::File) {
|
||||
option->fileSelectPath = luaL_checkstring(lsWidgets, -1);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (option->type == ZoneOption::Switch) {
|
||||
option->max.signedValue = switchValue();
|
||||
} else if (option->type == ZoneOption::Source) {
|
||||
option->max.unsignedValue = sourceValue();
|
||||
} else if (option->type == ZoneOption::Integer || option->type == ZoneOption::Slider) {
|
||||
option->max.signedValue = luaL_checkinteger(lsWidgets, -1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
option++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("error in theme/widget options");
|
||||
}
|
||||
UNPROTECT_LUA();
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse options table to get name and type values.
|
||||
// Called on radio startup to build base data for all widgtes.
|
||||
ZoneOption* LuaWidgetFactory::parseOptionDefinitions(int reference)
|
||||
{
|
||||
if (reference == LUA_REFNIL) {
|
||||
// TRACE("parseOptionDefinitions() no options");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, reference);
|
||||
for (lua_pushnil(lsWidgets); lua_next(lsWidgets, -2); lua_pop(lsWidgets, 1)) {
|
||||
count++;
|
||||
}
|
||||
|
||||
// TRACE("we have %d options", count);
|
||||
if (count > MAX_WIDGET_OPTIONS) {
|
||||
count = MAX_WIDGET_OPTIONS;
|
||||
// TRACE("limited to %d options", count);
|
||||
}
|
||||
|
||||
ZoneOption *options = new ZoneOption[count + 1];
|
||||
if (!options) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PROTECT_LUA()
|
||||
{
|
||||
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, reference);
|
||||
ZoneOption *option = options;
|
||||
for (lua_pushnil(lsWidgets); lua_next(lsWidgets, -2), count-- > 0;
|
||||
lua_pop(lsWidgets, 1)) {
|
||||
// TRACE("parsing option %d", count);
|
||||
luaL_checktype(lsWidgets, -2, LUA_TNUMBER); // key is number
|
||||
luaL_checktype(lsWidgets, -1, LUA_TTABLE); // value is table
|
||||
uint8_t field = 0;
|
||||
for (lua_pushnil(lsWidgets); lua_next(lsWidgets, -2) && field < 5;
|
||||
lua_pop(lsWidgets, 1), field++) {
|
||||
luaL_checktype(lsWidgets, -2, LUA_TNUMBER); // key is number
|
||||
switch (field) {
|
||||
case 0:
|
||||
option->name = luaL_checkstring(lsWidgets, -1);
|
||||
option->displayName = nullptr;
|
||||
// TRACE("name = %s", option->name);
|
||||
break;
|
||||
case 1:
|
||||
option->type = (ZoneOption::Type)luaL_checkinteger(lsWidgets, -1);
|
||||
option->deflt.unsignedValue = 0;
|
||||
// set some sensible defaults
|
||||
if (option->type == ZoneOption::Integer) {
|
||||
option->min.signedValue = -100;
|
||||
option->max.signedValue = 100;
|
||||
} else if (option->type == ZoneOption::Switch) {
|
||||
option->min.signedValue = SWSRC_FIRST;
|
||||
option->max.signedValue = SWSRC_LAST;
|
||||
} else if (option->type == ZoneOption::Timer) {
|
||||
option->min.unsignedValue = 0;
|
||||
option->max.unsignedValue = MAX_TIMERS - 1;
|
||||
} else if (option->type == ZoneOption::TextSize) {
|
||||
option->min.unsignedValue = FONT_STD_INDEX;
|
||||
option->max.unsignedValue = FONTS_COUNT - 1;
|
||||
} else if (option->type == ZoneOption::String || option->type == ZoneOption::File) {
|
||||
option->deflt.stringValue[0] = 0;
|
||||
} else if (option->type == ZoneOption::Slider) {
|
||||
option->min.unsignedValue = 0;
|
||||
option->max.unsignedValue = 9;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
option++;
|
||||
}
|
||||
option->name = NULL; // sentinel
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("error in theme/widget options");
|
||||
delete[] options;
|
||||
return NULL;
|
||||
}
|
||||
UNPROTECT_LUA();
|
||||
return options;
|
||||
}
|
||||
|
||||
@@ -25,12 +25,13 @@
|
||||
|
||||
class LuaWidgetFactory : public WidgetFactory
|
||||
{
|
||||
friend void luaLoadWidgetCallback();
|
||||
friend class LuaWidget;
|
||||
|
||||
public:
|
||||
LuaWidgetFactory(const char* name, ZoneOption* widgetOptions,
|
||||
int createFunction);
|
||||
LuaWidgetFactory(const char* name, ZoneOption* widgetOptions, int optionDefinitionsReference,
|
||||
int createFunction, int updateFunction, int refreshFunction,
|
||||
int backgroundFunction, int translateFunction, bool lvgllayout,
|
||||
const char* filename);
|
||||
~LuaWidgetFactory();
|
||||
|
||||
Widget* create(Window* parent, const rect_t& rect,
|
||||
@@ -41,14 +42,18 @@ class LuaWidgetFactory : public WidgetFactory
|
||||
|
||||
bool useLvglLayout() const { return lvglLayout; }
|
||||
|
||||
static ZoneOption* parseOptionDefinitions(int reference);
|
||||
const void parseOptionDefaults() const override;
|
||||
|
||||
protected:
|
||||
void translateOptions(ZoneOption * options);
|
||||
|
||||
int optionDefinitionsReference;
|
||||
int createFunction;
|
||||
int updateFunction;
|
||||
int refreshFunction;
|
||||
int backgroundFunction;
|
||||
int translateFunction;
|
||||
int settingsFunction;
|
||||
bool lvglLayout;
|
||||
std::string path;
|
||||
};
|
||||
|
||||
+13
-133
@@ -98,123 +98,12 @@ void luaSetInstructionsLimit(lua_State * L, int count)
|
||||
#endif
|
||||
}
|
||||
|
||||
ZoneOption *createOptionsArray(int reference, uint8_t maxOptions)
|
||||
{
|
||||
if (reference == 0) {
|
||||
// TRACE("createOptionsArray() no options");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, reference);
|
||||
for (lua_pushnil(lsWidgets); lua_next(lsWidgets, -2); lua_pop(lsWidgets, 1)) {
|
||||
count++;
|
||||
}
|
||||
|
||||
// TRACE("we have %d options", count);
|
||||
if (count > maxOptions) {
|
||||
count = maxOptions;
|
||||
// TRACE("limited to %d options", count);
|
||||
}
|
||||
|
||||
ZoneOption *options = new ZoneOption[count + 1];
|
||||
if (!options) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PROTECT_LUA()
|
||||
{
|
||||
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, reference);
|
||||
ZoneOption *option = options;
|
||||
for (lua_pushnil(lsWidgets); lua_next(lsWidgets, -2), count-- > 0;
|
||||
lua_pop(lsWidgets, 1)) {
|
||||
// TRACE("parsing option %d", count);
|
||||
luaL_checktype(lsWidgets, -2, LUA_TNUMBER); // key is number
|
||||
luaL_checktype(lsWidgets, -1, LUA_TTABLE); // value is table
|
||||
uint8_t field = 0;
|
||||
for (lua_pushnil(lsWidgets); lua_next(lsWidgets, -2) && field < 5;
|
||||
lua_pop(lsWidgets, 1), field++) {
|
||||
luaL_checktype(lsWidgets, -2, LUA_TNUMBER); // key is number
|
||||
switch (field) {
|
||||
case 0:
|
||||
option->name = luaL_checkstring(lsWidgets, -1);
|
||||
option->displayName = nullptr;
|
||||
// TRACE("name = %s", option->name);
|
||||
break;
|
||||
case 1:
|
||||
option->type = (ZoneOption::Type)luaL_checkinteger(lsWidgets, -1);
|
||||
option->deflt.unsignedValue = 0;
|
||||
// set some sensible defaults
|
||||
if (option->type == ZoneOption::Integer) {
|
||||
option->min.signedValue = -100;
|
||||
option->max.signedValue = 100;
|
||||
} else if (option->type == ZoneOption::Switch) {
|
||||
option->min.signedValue = SWSRC_FIRST;
|
||||
option->max.signedValue = SWSRC_LAST;
|
||||
} else if (option->type == ZoneOption::Timer) {
|
||||
option->min.unsignedValue = 0;
|
||||
option->max.unsignedValue = MAX_TIMERS - 1;
|
||||
} else if (option->type == ZoneOption::TextSize) {
|
||||
option->min.unsignedValue = FONT_STD_INDEX;
|
||||
option->max.unsignedValue = FONTS_COUNT - 1;
|
||||
} else if (option->type == ZoneOption::String || option->type == ZoneOption::File) {
|
||||
option->deflt.stringValue[0] = 0;
|
||||
} else if (option->type == ZoneOption::Slider) {
|
||||
option->min.unsignedValue = 0;
|
||||
option->max.unsignedValue = 9;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (option->type == ZoneOption::Integer || option->type == ZoneOption::Switch) {
|
||||
option->deflt.signedValue = luaL_checkinteger(lsWidgets, -1);
|
||||
} else if (option->type == ZoneOption::Bool) {
|
||||
option->deflt.boolValue = (luaL_checkunsigned(lsWidgets, -1) != 0);
|
||||
} else if (option->type == ZoneOption::String || option->type == ZoneOption::File) {
|
||||
strncpy(option->deflt.stringValue, luaL_checkstring(lsWidgets, -1),
|
||||
LEN_ZONE_OPTION_STRING);
|
||||
} else {
|
||||
option->deflt.unsignedValue = luaL_checkunsigned(lsWidgets, -1);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (option->type == ZoneOption::Integer || option->type == ZoneOption::Switch || option->type == ZoneOption::Slider) {
|
||||
option->min.signedValue = luaL_checkinteger(lsWidgets, -1);
|
||||
} else if (option->type == ZoneOption::Choice) {
|
||||
luaL_checktype(lsWidgets, -1, LUA_TTABLE); // value is a table
|
||||
for (lua_pushnil(lsWidgets); lua_next(lsWidgets, -2); lua_pop(lsWidgets, 1)) {
|
||||
option->choiceValues.push_back(luaL_checkstring(lsWidgets, -1));
|
||||
}
|
||||
} else if (option->type == ZoneOption::File) {
|
||||
option->fileSelectPath = luaL_checkstring(lsWidgets, -1);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (option->type == ZoneOption::Integer || option->type == ZoneOption::Switch || option->type == ZoneOption::Slider) {
|
||||
option->max.signedValue = luaL_checkinteger(lsWidgets, -1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
option++;
|
||||
}
|
||||
option->name = NULL; // sentinel
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("error in theme/widget options");
|
||||
delete[] options;
|
||||
return NULL;
|
||||
}
|
||||
UNPROTECT_LUA();
|
||||
return options;
|
||||
}
|
||||
|
||||
void luaLoadWidgetCallback()
|
||||
void luaLoadWidgetCallback(const char* filename)
|
||||
{
|
||||
TRACE("luaLoadWidgetCallback()");
|
||||
const char * name=NULL;
|
||||
|
||||
int widgetOptions = 0, createFunction = 0, updateFunction = 0, settingsFunction = 0,
|
||||
int optionDefinitionsReference = LUA_REFNIL, createFunction = 0, updateFunction = 0,
|
||||
refreshFunction = 0, backgroundFunction = 0, translateFunction = 0;
|
||||
bool lvglLayout = false;
|
||||
|
||||
@@ -226,7 +115,7 @@ void luaLoadWidgetCallback()
|
||||
name = luaL_checkstring(lsWidgets, -1);
|
||||
}
|
||||
else if (!strcmp(key, "options")) {
|
||||
widgetOptions = luaL_ref(lsWidgets, LUA_REGISTRYINDEX);
|
||||
optionDefinitionsReference = luaL_ref(lsWidgets, LUA_REGISTRYINDEX);
|
||||
lua_pushnil(lsWidgets);
|
||||
}
|
||||
else if (!strcmp(key, "create")) {
|
||||
@@ -249,34 +138,25 @@ void luaLoadWidgetCallback()
|
||||
translateFunction = luaL_ref(lsWidgets, LUA_REGISTRYINDEX);
|
||||
lua_pushnil(lsWidgets);
|
||||
}
|
||||
else if (!strcmp(key, "settings")) {
|
||||
settingsFunction = luaL_ref(lsWidgets, LUA_REGISTRYINDEX);
|
||||
lua_pushnil(lsWidgets);
|
||||
}
|
||||
else if (!strcasecmp(key, "useLvgl")) {
|
||||
lvglLayout = lua_toboolean(lsWidgets, -1);
|
||||
}
|
||||
}
|
||||
|
||||
if (name && createFunction) {
|
||||
ZoneOption * options = createOptionsArray(widgetOptions, MAX_WIDGET_OPTIONS);
|
||||
ZoneOption * options = LuaWidgetFactory::parseOptionDefinitions(optionDefinitionsReference);
|
||||
if (options) {
|
||||
LuaWidgetFactory * factory = new LuaWidgetFactory(name, options, createFunction);
|
||||
factory->updateFunction = updateFunction;
|
||||
factory->refreshFunction = refreshFunction;
|
||||
factory->backgroundFunction = backgroundFunction;
|
||||
factory->translateFunction = translateFunction;
|
||||
factory->settingsFunction = settingsFunction;
|
||||
factory->translateOptions(options);
|
||||
factory->lvglLayout = lvglLayout;
|
||||
new LuaWidgetFactory(name, options, optionDefinitionsReference,
|
||||
createFunction, updateFunction, refreshFunction, backgroundFunction,
|
||||
translateFunction, lvglLayout, filename);
|
||||
TRACE("Loaded Lua widget %s", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void luaLoadFile(const char * filename, void (*callback)())
|
||||
static void luaLoadFile(const char * filename, std::function<void()> callback)
|
||||
{
|
||||
if (lsWidgets == NULL || callback == NULL)
|
||||
if (lsWidgets == NULL)
|
||||
return;
|
||||
|
||||
TRACE("luaLoadFile(%s)", filename);
|
||||
@@ -286,7 +166,7 @@ void luaLoadFile(const char * filename, void (*callback)())
|
||||
PROTECT_LUA() {
|
||||
if (luaLoadScriptFileToState(lsWidgets, filename, LUA_SCRIPT_LOAD_MODE) == SCRIPT_OK) {
|
||||
if (lua_pcall(lsWidgets, 0, 1, 0) == LUA_OK && lua_istable(lsWidgets, -1)) {
|
||||
(*callback)();
|
||||
callback();
|
||||
}
|
||||
else {
|
||||
TRACE("luaLoadFile(%s): Error parsing script: %s", filename, lua_tostring(lsWidgets, -1));
|
||||
@@ -301,7 +181,7 @@ void luaLoadFile(const char * filename, void (*callback)())
|
||||
UNPROTECT_LUA();
|
||||
}
|
||||
|
||||
void luaLoadFiles(const char * directory, void (*callback)())
|
||||
static void luaLoadFiles(const char * directory)
|
||||
{
|
||||
char path[LUA_FULLPATH_MAXLEN+1];
|
||||
FILINFO fno;
|
||||
@@ -324,7 +204,7 @@ void luaLoadFiles(const char * directory, void (*callback)())
|
||||
strcpy(&path[pathlen], fno.fname);
|
||||
strcat(&path[pathlen], LUA_WIDGET_FILENAME);
|
||||
if (isFileAvailable(path)) {
|
||||
luaLoadFile(path, callback);
|
||||
luaLoadFile(path, [=]() { luaLoadWidgetCallback(path); });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -374,7 +254,7 @@ void luaInitThemesAndWidgets()
|
||||
}
|
||||
UNPROTECT_LUA();
|
||||
TRACE("lsWidgets %p", lsWidgets);
|
||||
luaLoadFiles(WIDGETS_PATH, luaLoadWidgetCallback);
|
||||
luaLoadFiles(WIDGETS_PATH);
|
||||
luaDoGc(lsWidgets, true);
|
||||
}
|
||||
}
|
||||
|
||||
+102
-28
@@ -427,9 +427,9 @@ char *getCustomSwitchesGroupName(char *dest, uint8_t idx)
|
||||
return dest;
|
||||
}
|
||||
|
||||
char *getSwitchName(char *dest, uint8_t idx)
|
||||
char *getSwitchName(char *dest, uint8_t idx, bool defaultOnly)
|
||||
{
|
||||
if (switchHasCustomName(idx)) {
|
||||
if (!defaultOnly && switchHasCustomName(idx)) {
|
||||
dest = strAppend(dest, switchGetCustomName(idx), LEN_SWITCH_NAME);
|
||||
} else {
|
||||
dest = strAppend(dest, switchGetName(idx), LEN_SWITCH_NAME);
|
||||
@@ -464,7 +464,7 @@ const char *getSwitchPositionSymbol(uint8_t pos)
|
||||
return _switch_state_str[pos + 1];
|
||||
}
|
||||
|
||||
char *getSwitchPositionName(char *dest, swsrc_t idx)
|
||||
char *getSwitchPositionName(char *dest, swsrc_t idx, bool defaultOnly)
|
||||
{
|
||||
if (idx == SWSRC_NONE) {
|
||||
return strcpy(dest, STR_EMPTY);
|
||||
@@ -480,7 +480,7 @@ char *getSwitchPositionName(char *dest, swsrc_t idx)
|
||||
|
||||
if (idx <= SWSRC_LAST_SWITCH) {
|
||||
div_t swinfo = switchInfo(idx);
|
||||
s = getSwitchName(s, swinfo.quot);
|
||||
s = getSwitchName(s, swinfo.quot, defaultOnly);
|
||||
s = strAppend(s, getSwitchPositionSymbol(swinfo.rem), 2);
|
||||
*s = '\0';
|
||||
} else if (idx <= SWSRC_LAST_MULTIPOS_SWITCH) {
|
||||
@@ -522,9 +522,42 @@ char *getSwitchPositionName(char *dest, swsrc_t idx)
|
||||
return dest;
|
||||
}
|
||||
|
||||
const char *getAnalogLabel(uint8_t type, uint8_t idx)
|
||||
bool switchCanHaveCustomName(swsrc_t idx)
|
||||
{
|
||||
if (analogHasCustomLabel(type, idx)) return analogGetCustomLabel(type, idx);
|
||||
return (idx >= SWSRC_FIRST_SWITCH && idx <= SWSRC_LAST_SWITCH);
|
||||
}
|
||||
|
||||
int getSwitchIndex(const char* name, bool all)
|
||||
{
|
||||
bool negate = false;
|
||||
|
||||
if (name[0] == '!') {
|
||||
name++;
|
||||
negate = true;
|
||||
}
|
||||
|
||||
for (swsrc_t idx = SWSRC_NONE; idx < SWSRC_COUNT; idx++) {
|
||||
if (all || isSwitchAvailable(idx, ModelCustomFunctionsContext)) {
|
||||
char* s;
|
||||
if (switchCanHaveCustomName(idx)) {
|
||||
// Check default name
|
||||
s = getSwitchPositionName(idx, true);
|
||||
if (!strcasecmp(s, name))
|
||||
return negate ? -idx : idx;
|
||||
}
|
||||
s = getSwitchPositionName(idx);
|
||||
if (!strcasecmp(s, name))
|
||||
return negate ? -idx : idx;
|
||||
}
|
||||
}
|
||||
|
||||
return SWSRC_INVERT; // Not found
|
||||
}
|
||||
|
||||
const char *getAnalogLabel(uint8_t type, uint8_t idx, bool defaultOnly)
|
||||
{
|
||||
if (!defaultOnly && analogHasCustomLabel(type, idx))
|
||||
return analogGetCustomLabel(type, idx);
|
||||
|
||||
if (type == ADC_INPUT_MAIN) {
|
||||
// main controls: translated label is stored in "short label"
|
||||
@@ -566,15 +599,15 @@ const char *getAnalogShortLabel(uint8_t idx)
|
||||
return "";
|
||||
}
|
||||
|
||||
const char *getMainControlLabel(uint8_t idx)
|
||||
const char *getMainControlLabel(uint8_t idx, bool defaultOnly)
|
||||
{
|
||||
return getAnalogLabel(ADC_INPUT_MAIN, idx);
|
||||
return getAnalogLabel(ADC_INPUT_MAIN, idx, defaultOnly);
|
||||
}
|
||||
|
||||
const char *getTrimLabel(uint8_t idx)
|
||||
const char *getTrimLabel(uint8_t idx, bool defaultOnly)
|
||||
{
|
||||
if (idx < adcGetMaxInputs(ADC_INPUT_MAIN)) {
|
||||
return getMainControlLabel(idx);
|
||||
return getMainControlLabel(idx, defaultOnly);
|
||||
}
|
||||
|
||||
// TODO: replace with string from HW def
|
||||
@@ -595,15 +628,15 @@ const char *getTrimSourceLabel(uint16_t src_raw, int8_t trim_src)
|
||||
}
|
||||
}
|
||||
|
||||
const char *getPotLabel(uint8_t idx)
|
||||
const char *getPotLabel(uint8_t idx, bool defaultOnly)
|
||||
{
|
||||
return getAnalogLabel(ADC_INPUT_FLEX, idx);
|
||||
return getAnalogLabel(ADC_INPUT_FLEX, idx, defaultOnly);
|
||||
}
|
||||
|
||||
// this should be declared in header, but it used so much foreign symbols that
|
||||
// we declare it in cpp-file and pre-instantiate it for the uses
|
||||
template <size_t L>
|
||||
char *getSourceString(char (&destRef)[L], mixsrc_t idx)
|
||||
char *getSourceString(char (&destRef)[L], mixsrc_t idx, bool defaultOnly)
|
||||
{
|
||||
size_t dest_len = L;
|
||||
char* dest = destRef;
|
||||
@@ -622,7 +655,7 @@ char *getSourceString(char (&destRef)[L], mixsrc_t idx)
|
||||
static_assert(L > sizeof(STR_CHAR_INPUT) - 1, "dest string too small");
|
||||
dest_len -= sizeof(STR_CHAR_INPUT) - 1;
|
||||
char *pos = strAppend(dest, STR_CHAR_INPUT, sizeof(STR_CHAR_INPUT) - 1);
|
||||
if (g_model.inputNames[idx][0] != '\0' &&
|
||||
if (!defaultOnly && g_model.inputNames[idx][0] != '\0' &&
|
||||
(dest_len > sizeof(g_model.inputNames[idx]))) {
|
||||
memset(pos, 0, sizeof(g_model.inputNames[idx]) + 1);
|
||||
size_t input_len =
|
||||
@@ -669,7 +702,7 @@ char *getSourceString(char (&destRef)[L], mixsrc_t idx)
|
||||
if (idx < MAX_STICKS) {
|
||||
pos = strAppend(pos, STR_CHAR_STICK, sizeof(STR_CHAR_STICK) - 1);
|
||||
dest_len -= sizeof(STR_CHAR_STICK) - 1;
|
||||
name = getMainControlLabel(idx);
|
||||
name = getMainControlLabel(idx, defaultOnly);
|
||||
} else {
|
||||
idx -= MAX_STICKS;
|
||||
if (IS_SLIDER(idx)) {
|
||||
@@ -680,7 +713,7 @@ char *getSourceString(char (&destRef)[L], mixsrc_t idx)
|
||||
dest_len -= sizeof(STR_CHAR_POT) - 1;
|
||||
}
|
||||
// TODO: AXIS / SWITCH ???
|
||||
name = getPotLabel(idx);
|
||||
name = getPotLabel(idx, defaultOnly);
|
||||
}
|
||||
strncpy(pos, name, dest_len - 1);
|
||||
pos[dest_len - 1] = '\0';
|
||||
@@ -707,11 +740,11 @@ char *getSourceString(char (&destRef)[L], mixsrc_t idx)
|
||||
} else if (idx <= MIXSRC_LAST_TRIM) {
|
||||
idx -= MIXSRC_FIRST_TRIM;
|
||||
char *pos = strAppend(dest, STR_CHAR_TRIM, sizeof(STR_CHAR_TRIM) - 1);
|
||||
strAppend(pos, getTrimLabel(idx));
|
||||
strAppend(pos, getTrimLabel(idx, defaultOnly));
|
||||
} else if (idx <= MIXSRC_LAST_SWITCH) {
|
||||
idx -= MIXSRC_FIRST_SWITCH;
|
||||
char *pos = strAppend(dest, STR_CHAR_SWITCH, sizeof(STR_CHAR_SWITCH) - 1);
|
||||
getSwitchName(pos, idx);
|
||||
getSwitchName(pos, idx, defaultOnly);
|
||||
#if defined(FUNCTION_SWITCHES)
|
||||
} else if (idx <= MIXSRC_LAST_CUSTOMSWITCH_GROUP) {
|
||||
idx -= MIXSRC_FIRST_CUSTOMSWITCH_GROUP;
|
||||
@@ -719,15 +752,14 @@ char *getSourceString(char (&destRef)[L], mixsrc_t idx)
|
||||
getCustomSwitchesGroupName(pos, idx);
|
||||
#endif
|
||||
} else if (idx <= MIXSRC_LAST_LOGICAL_SWITCH) {
|
||||
// TODO: unnecessary, use the direct way instead
|
||||
idx -= MIXSRC_FIRST_LOGICAL_SWITCH;
|
||||
getSwitchPositionName(dest, idx + SWSRC_FIRST_LOGICAL_SWITCH);
|
||||
getSwitchPositionName(dest, idx + SWSRC_FIRST_LOGICAL_SWITCH, defaultOnly);
|
||||
} else if (idx <= MIXSRC_LAST_TRAINER) {
|
||||
idx -= MIXSRC_FIRST_TRAINER;
|
||||
strAppendStringWithIndex(dest, STR_PPM_TRAINER, idx + 1);
|
||||
} else if (idx <= MIXSRC_LAST_CH) {
|
||||
auto ch = idx - MIXSRC_FIRST_CH;
|
||||
if (g_model.limitData[ch].name[0] != '\0') {
|
||||
if (!defaultOnly && g_model.limitData[ch].name[0] != '\0') {
|
||||
strAppend(dest, g_model.limitData[ch].name, LEN_CHANNEL_NAME);
|
||||
} else {
|
||||
strAppendStringWithIndex(dest, STR_CH, ch + 1);
|
||||
@@ -736,7 +768,7 @@ char *getSourceString(char (&destRef)[L], mixsrc_t idx)
|
||||
idx -= MIXSRC_FIRST_GVAR;
|
||||
#if defined(LIBOPENUI)
|
||||
char *s = strAppendStringWithIndex(dest, STR_GV, idx + 1);
|
||||
if (g_model.gvars[idx].name[0]) {
|
||||
if (!defaultOnly && g_model.gvars[idx].name[0]) {
|
||||
s = strAppend(s, ":");
|
||||
getGVarString(s, idx);
|
||||
}
|
||||
@@ -763,7 +795,7 @@ char *getSourceString(char (&destRef)[L], mixsrc_t idx)
|
||||
strncpy(dest, src_str, dest_len - 1);
|
||||
} else if (idx <= MIXSRC_LAST_TIMER) {
|
||||
idx -= MIXSRC_FIRST_TIMER;
|
||||
if (g_model.timers[idx].name[0] != '\0') {
|
||||
if (!defaultOnly && g_model.timers[idx].name[0] != '\0') {
|
||||
strAppend(dest, g_model.timers[idx].name, LEN_TIMER_NAME);
|
||||
} else {
|
||||
strAppendStringWithIndex(dest, STR_SRC_TIMER, idx + 1);
|
||||
@@ -781,13 +813,53 @@ char *getSourceString(char (&destRef)[L], mixsrc_t idx)
|
||||
return destRef;
|
||||
}
|
||||
|
||||
bool sourceCanHaveCustomName(mixsrc_t idx)
|
||||
{
|
||||
return (idx >= MIXSRC_FIRST_INPUT && idx <= MIXSRC_LAST_INPUT) ||
|
||||
(idx >= MIXSRC_FIRST_STICK && idx <= MIXSRC_LAST_STICK) ||
|
||||
(idx >= MIXSRC_FIRST_POT && idx <= MIXSRC_LAST_POT) ||
|
||||
(idx >= MIXSRC_FIRST_TRIM && idx <= MIXSRC_LAST_TRIM) ||
|
||||
(idx >= MIXSRC_FIRST_SWITCH && idx <= MIXSRC_LAST_SWITCH) ||
|
||||
(idx >= MIXSRC_FIRST_CH && idx <= MIXSRC_LAST_CH) ||
|
||||
(idx >= MIXSRC_FIRST_GVAR && idx <= MIXSRC_LAST_GVAR) ||
|
||||
(idx >= MIXSRC_FIRST_TIMER && idx <= MIXSRC_LAST_TIMER);
|
||||
}
|
||||
|
||||
bool matchSource(const char* name, mixsrc_t idx, bool defaultOnly)
|
||||
{
|
||||
char *s = getSourceString(idx, defaultOnly);
|
||||
if (strcasecmp(s, name) == 0)
|
||||
return true;
|
||||
// Check for names starting with CHAR_xxx symbol strings
|
||||
if (s[0] == '\302' && (strcasecmp(s + 2, name) == 0))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
int getSourceIndex(const char* name, bool all)
|
||||
{
|
||||
for (mixsrc_t idx = MIXSRC_NONE; idx <= MIXSRC_LAST_TELEM; idx++) {
|
||||
if (all || isSourceAvailable(idx)) {
|
||||
if (sourceCanHaveCustomName(idx)) {
|
||||
// Check default name
|
||||
if (matchSource(name, idx, true))
|
||||
return idx;
|
||||
}
|
||||
if (matchSource(name, idx, false))
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// pre-instantiate for use from external
|
||||
// all other instantiations are done from this file
|
||||
template char *getSourceString<16>(char (&dest)[16], mixsrc_t idx);
|
||||
template char *getSourceString<16>(char (&dest)[16], mixsrc_t idx, bool defaultOnly);
|
||||
|
||||
char *getSourceString(mixsrc_t idx)
|
||||
char *getSourceString(mixsrc_t idx, bool defaultOnly)
|
||||
{
|
||||
return getSourceString(_static_str_buffer, idx);
|
||||
return getSourceString(_static_str_buffer, idx, defaultOnly);
|
||||
}
|
||||
|
||||
char *getCurveString(int idx)
|
||||
@@ -805,9 +877,9 @@ char *getTimerString(char *dest, int32_t tme, TimerOptions timerOptions)
|
||||
return getFormattedTimerString(dest, tme, timerOptions);
|
||||
}
|
||||
|
||||
char *getSwitchPositionName(swsrc_t idx)
|
||||
char *getSwitchPositionName(swsrc_t idx, bool defaultOnly)
|
||||
{
|
||||
return getSwitchPositionName(_static_str_buffer, idx);
|
||||
return getSwitchPositionName(_static_str_buffer, idx, defaultOnly);
|
||||
}
|
||||
|
||||
char *getGVarString(int idx) { return getGVarString(_static_str_buffer, idx); }
|
||||
@@ -1102,6 +1174,8 @@ char *strAppendSigned(char *dest, int32_t value, uint8_t digits, uint8_t radix)
|
||||
|
||||
char *strAppend(char *dest, const char *source, int len)
|
||||
{
|
||||
if (source == nullptr) { *dest = '\0'; return dest; }
|
||||
|
||||
while ((*dest++ = *source++)) {
|
||||
if (--len == 0) {
|
||||
*dest = '\0';
|
||||
|
||||
+16
-14
@@ -110,9 +110,11 @@ char *strAppendStringWithIndex(char *dest, const char *s, int idx);
|
||||
#define LEN_TIMER_STRING 10 // "-00:00:00"
|
||||
char *getTimerString(char *dest, int32_t tme,
|
||||
TimerOptions timerOptions = {.options = 0});
|
||||
char *getTimerString(int32_t tme, TimerOptions timerOptions = {.options = 0});
|
||||
char *getFormattedTimerString(char *dest, int32_t tme,
|
||||
TimerOptions timerOptions);
|
||||
char *getCurveString(char *dest, int idx);
|
||||
char *getCurveString(int idx);
|
||||
char *getGVarString(char *dest, int idx);
|
||||
char *getGVarString(int idx);
|
||||
char *getValueOrGVarString(char *dest, size_t len, gvar_t value, gvar_t vmin,
|
||||
@@ -123,33 +125,33 @@ char *getValueOrSrcVarString(char *dest, size_t len, gvar_t value, gvar_t vmin,
|
||||
const char *suffix = nullptr, gvar_t offset = 0, bool usePPMUnit = false);
|
||||
const char *getSwitchWarnSymbol(uint8_t pos);
|
||||
const char *getSwitchPositionSymbol(uint8_t pos);
|
||||
char *getSwitchPositionName(char *dest, swsrc_t idx);
|
||||
char *getSwitchName(char *dest, uint8_t idx);
|
||||
char *getSwitchPositionName(char *dest, swsrc_t idx, bool defaultOnly = false);
|
||||
char *getSwitchPositionName(swsrc_t idx, bool defaultOnly = false);
|
||||
char *getSwitchName(char *dest, uint8_t idx, bool defaultOnly = false);
|
||||
int getSwitchIndex(const char* name, bool all);
|
||||
int getSourceIndex(const char* name, bool all);
|
||||
|
||||
const char *getAnalogLabel(uint8_t type, uint8_t idx);
|
||||
const char *getAnalogLabel(uint8_t type, uint8_t idx, bool defaultOnly = false);
|
||||
const char *getAnalogShortLabel(uint8_t idx);
|
||||
const char *getMainControlLabel(uint8_t idx);
|
||||
const char *getTrimLabel(uint8_t idx);
|
||||
const char *getMainControlLabel(uint8_t idx, bool defaultOnly = false);
|
||||
const char *getTrimLabel(uint8_t idx, bool defaultOnly = false);
|
||||
const char *getTrimSourceLabel(uint16_t src_raw, int8_t trim_src);
|
||||
const char *getPotLabel(uint8_t idx);
|
||||
const char *getPotLabel(uint8_t idx, bool defaultOnly = false);
|
||||
char *getCustomSwitchesGroupName(char *dest, uint8_t idx);
|
||||
|
||||
template <size_t L>
|
||||
char *getSourceString(char (&dest)[L], mixsrc_t idx);
|
||||
char *getSourceString(char (&dest)[L], mixsrc_t idx, bool defaultOnly = false);
|
||||
char *getSourceString(mixsrc_t idx, bool defaultOnly = false);
|
||||
|
||||
template <size_t L>
|
||||
char *getSourceCustomValueString(char (&dest)[L], mixsrc_t source, int32_t val,
|
||||
LcdFlags flags);
|
||||
|
||||
#endif
|
||||
char *getSourceCustomValueString(mixsrc_t source, int32_t val, LcdFlags flags);
|
||||
|
||||
char *getFlightModeString(char *dest, int8_t idx);
|
||||
|
||||
char *getSourceString(mixsrc_t idx);
|
||||
char *getSourceCustomValueString(mixsrc_t source, int32_t val, LcdFlags flags);
|
||||
char *getSwitchPositionName(swsrc_t idx);
|
||||
char *getCurveString(int idx);
|
||||
char *getTimerString(int32_t tme, TimerOptions timerOptions = {.options = 0});
|
||||
#endif
|
||||
|
||||
void splitTimer(char *s0, char *s1, char *s2, char *s3, int tme,
|
||||
bool bLowercase = true);
|
||||
|
||||
|
||||
@@ -311,12 +311,8 @@ void processCrossfireTelemetryFrame(uint8_t module, uint8_t* rxBuffer,
|
||||
crossfireModuleStatus[module].queryCompleted = true;
|
||||
}
|
||||
|
||||
if (luaInputTelemetryFifo && luaInputTelemetryFifo->hasSpace(rxBufferCount - 2)) {
|
||||
for (uint8_t i = 1; i < rxBufferCount - 1; i++) {
|
||||
// destination address and CRC are skipped
|
||||
luaInputTelemetryFifo->push(rxBuffer[i]);
|
||||
}
|
||||
}
|
||||
// destination address and CRC are skipped
|
||||
pushTelemetryDataToQueues(rxBuffer + 1, rxBufferCount - 2);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -391,18 +391,12 @@ void sportProcessTelemetryPacketWithoutCrc(uint8_t module, uint8_t origin, const
|
||||
}
|
||||
else if (dataId >= DIY_STREAM_FIRST_ID && dataId <= DIY_STREAM_LAST_ID) {
|
||||
#if defined(LUA)
|
||||
if (luaInputTelemetryFifo &&
|
||||
luaInputTelemetryFifo->hasSpace(sizeof(SportTelemetryPacket))) {
|
||||
|
||||
SportTelemetryPacket luaPacket;
|
||||
luaPacket.physicalId = physicalId;
|
||||
luaPacket.primId = primId;
|
||||
luaPacket.dataId = dataId;
|
||||
luaPacket.value = data;
|
||||
for (uint8_t i=0; i<sizeof(SportTelemetryPacket); i++) {
|
||||
luaInputTelemetryFifo->push(luaPacket.raw[i]);
|
||||
}
|
||||
}
|
||||
SportTelemetryPacket luaPacket;
|
||||
luaPacket.physicalId = physicalId;
|
||||
luaPacket.primId = primId;
|
||||
luaPacket.dataId = dataId;
|
||||
luaPacket.value = data;
|
||||
pushTelemetryDataToQueues(luaPacket.raw, sizeof(SportTelemetryPacket));
|
||||
#endif
|
||||
}
|
||||
else if (dataId >= RB3040_CH1_2_FIRST_ID && dataId <= RB3040_CH7_8_LAST_ID) {
|
||||
@@ -433,16 +427,12 @@ void sportProcessTelemetryPacketWithoutCrc(uint8_t module, uint8_t origin, const
|
||||
}
|
||||
#if defined(LUA)
|
||||
else if (primId == 0x32) {
|
||||
if (luaInputTelemetryFifo && luaInputTelemetryFifo->hasSpace(sizeof(SportTelemetryPacket))) {
|
||||
SportTelemetryPacket luaPacket;
|
||||
luaPacket.physicalId = physicalId;
|
||||
luaPacket.primId = primId;
|
||||
luaPacket.dataId = dataId;
|
||||
luaPacket.value = data;
|
||||
for (uint8_t i=0; i<sizeof(SportTelemetryPacket); i++) {
|
||||
luaInputTelemetryFifo->push(luaPacket.raw[i]);
|
||||
}
|
||||
}
|
||||
SportTelemetryPacket luaPacket;
|
||||
luaPacket.physicalId = physicalId;
|
||||
luaPacket.primId = primId;
|
||||
luaPacket.dataId = dataId;
|
||||
luaPacket.value = data;
|
||||
pushTelemetryDataToQueues(luaPacket.raw, sizeof(SportTelemetryPacket));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -315,11 +315,7 @@ void processGhostTelemetryFrame(uint8_t module, uint8_t* buffer, uint32_t length
|
||||
#if defined(LUA)
|
||||
default:
|
||||
// destination address and CRC are skipped
|
||||
if (luaInputTelemetryFifo && luaInputTelemetryFifo->hasSpace(length - 2) ) {
|
||||
for (uint8_t i = 1; i < length - 1; i++) {
|
||||
luaInputTelemetryFifo->push(buffer[i]);
|
||||
}
|
||||
}
|
||||
pushTelemetryDataToQueues(buffer + 1, length - 2);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -468,7 +468,38 @@ void logTelemetryWriteByte(uint8_t data)
|
||||
OutputTelemetryBuffer outputTelemetryBuffer __DMA_NO_CACHE;
|
||||
|
||||
#if defined(LUA)
|
||||
Fifo<uint8_t, LUA_TELEMETRY_INPUT_FIFO_SIZE> * luaInputTelemetryFifo = NULL;
|
||||
TelemetryQueue* luaInputTelemetryFifo = nullptr;
|
||||
#if defined(COLORLCD)
|
||||
std::list<TelemetryQueue*> telemetryQueues;
|
||||
|
||||
void registerTelemetryQueue(TelemetryQueue* queue)
|
||||
{
|
||||
telemetryQueues.emplace_back(queue);
|
||||
}
|
||||
|
||||
void deregisterTelemetryQueue(TelemetryQueue* queue)
|
||||
{
|
||||
telemetryQueues.remove(queue);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void pushDataToQueue(TelemetryQueue* queue, uint8_t* data, int length)
|
||||
{
|
||||
if (queue && queue->hasSpace(length)) {
|
||||
for (uint8_t i = 0; i < length; i += 1) {
|
||||
queue->push(data[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pushTelemetryDataToQueues(uint8_t* data, int length)
|
||||
{
|
||||
#if defined(COLORLCD)
|
||||
for (auto it = telemetryQueues.cbegin(); it != telemetryQueues.cend(); ++it)
|
||||
pushDataToQueue(*it, data, length);
|
||||
#endif
|
||||
pushDataToQueue(luaInputTelemetryFifo, data, length);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HARDWARE_INTERNAL_MODULE)
|
||||
|
||||
@@ -236,7 +236,11 @@ extern OutputTelemetryBuffer outputTelemetryBuffer __DMA_NO_CACHE;
|
||||
#if defined(LUA)
|
||||
#include "fifo.h"
|
||||
#define LUA_TELEMETRY_INPUT_FIFO_SIZE 256
|
||||
extern Fifo<uint8_t, LUA_TELEMETRY_INPUT_FIFO_SIZE> * luaInputTelemetryFifo;
|
||||
typedef Fifo<uint8_t, LUA_TELEMETRY_INPUT_FIFO_SIZE> TelemetryQueue;
|
||||
extern TelemetryQueue* luaInputTelemetryFifo;
|
||||
void registerTelemetryQueue(TelemetryQueue*);
|
||||
void deregisterTelemetryQueue(TelemetryQueue*);
|
||||
void pushTelemetryDataToQueues(uint8_t* data, int length);
|
||||
#endif
|
||||
|
||||
void processPXX2Frame(uint8_t idx, const uint8_t* frame,
|
||||
|
||||
@@ -61,8 +61,7 @@ struct crsf_frame_test {
|
||||
{
|
||||
ctx = CrossfireDriver.init(EXTERNAL_MODULE);
|
||||
if (!luaInputTelemetryFifo) {
|
||||
luaInputTelemetryFifo =
|
||||
new Fifo<uint8_t, LUA_TELEMETRY_INPUT_FIFO_SIZE>();
|
||||
luaInputTelemetryFifo = new TelemetryQueue();
|
||||
assert(luaInputTelemetryFifo != nullptr);
|
||||
} else {
|
||||
luaInputTelemetryFifo->clear();
|
||||
|
||||
Reference in New Issue
Block a user