Fixes #1480: How to handle the increasing number of Lua constants
This commit is contained in:
+153
-68
@@ -34,6 +34,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "opentx.h"
|
||||
#include "stamp-opentx.h"
|
||||
|
||||
@@ -47,6 +48,8 @@ extern "C" {
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "lua_exports.cpp" //this line must be after lua headers
|
||||
|
||||
#define lua_registernumber(L, n, i) (lua_pushnumber(L, (i)), lua_setglobal(L, (n)))
|
||||
#define lua_registerint(L, n, i) (lua_pushinteger(L, (i)), lua_setglobal(L, (n)))
|
||||
#define lua_pushtablenil(L, k) (lua_pushstring(L, (k)), lua_pushnil(L), lua_settable(L, -3))
|
||||
@@ -97,14 +100,17 @@ static int luaGetTime(lua_State *L)
|
||||
|
||||
static void luaGetValueAndPush(int src)
|
||||
{
|
||||
/*
|
||||
Hint about dividers are taken from putsTelemetryChannel()
|
||||
*/
|
||||
if (!TELEMETRY_STREAMING() && src>=MIXSRC_FIRST_TELEM && src<=MIXSRC_LAST_TELEM) {
|
||||
//telemetry not working, return zero for telemetry sources
|
||||
lua_pushinteger(L, (int)0);
|
||||
return;
|
||||
if (src >= MIXSRC_FIRST_TELEM && src <= MIXSRC_LAST_TELEM) {
|
||||
// telemetry values
|
||||
if ((src != MIXSRC_FIRST_TELEM-1+TELEM_TX_VOLTAGE) && !TELEMETRY_STREAMING() ) {
|
||||
// telemetry not working, return zero for telemetry sources
|
||||
// except for "tx voltage"
|
||||
lua_pushinteger(L, (int)0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int idx = src;
|
||||
switch (src) {
|
||||
case MIXSRC_FIRST_TELEM-1+TELEM_TX_VOLTAGE:
|
||||
case MIXSRC_FIRST_TELEM-1+TELEM_VFAS:
|
||||
@@ -113,21 +119,24 @@ static void luaGetValueAndPush(int src)
|
||||
case MIXSRC_FIRST_TELEM-1+TELEM_MIN_CELLS_SUM:
|
||||
case MIXSRC_FIRST_TELEM-1+TELEM_CURRENT:
|
||||
case MIXSRC_FIRST_TELEM-1+TELEM_MAX_CURRENT:
|
||||
case MIXSRC_FIRST_TELEM-1+TELEM_VSPEED:
|
||||
case MIXSRC_FIRST_TELEM-1+TELEM_ASPEED:
|
||||
//theese need to be divided by 10
|
||||
lua_pushnumber(L, getValue(src)/10.0);
|
||||
break;
|
||||
|
||||
case MIXSRC_FIRST_TELEM-1+TELEM_A1:
|
||||
case MIXSRC_FIRST_TELEM-1+TELEM_A2:
|
||||
//convert raw A1/2 values to calibrated values
|
||||
lua_pushnumber(L, applyChannelRatio(src-(MIXSRC_FIRST_TELEM-1+TELEM_A1), getValue(src))/100.0);
|
||||
break;
|
||||
|
||||
case MIXSRC_FIRST_TELEM-1+TELEM_MIN_A1:
|
||||
case MIXSRC_FIRST_TELEM-1+TELEM_MIN_A2:
|
||||
//convert raw A1/2 values to calibrated values
|
||||
lua_pushnumber(L, applyChannelRatio(src-(MIXSRC_FIRST_TELEM-1+TELEM_MIN_A1), getValue(src))/100.0);
|
||||
case MIXSRC_FIRST_TELEM-1+TELEM_MIN_A3:
|
||||
case MIXSRC_FIRST_TELEM-1+TELEM_MIN_A4:
|
||||
idx -= TELEM_MIN_A1-TELEM_A1;
|
||||
// no break
|
||||
case MIXSRC_FIRST_TELEM-1+TELEM_A1:
|
||||
case MIXSRC_FIRST_TELEM-1+TELEM_A2:
|
||||
case MIXSRC_FIRST_TELEM-1+TELEM_A3:
|
||||
case MIXSRC_FIRST_TELEM-1+TELEM_A4:
|
||||
//convert raw Ax values to calibrated values
|
||||
idx -= (MIXSRC_FIRST_TELEM+TELEM_A1-1);
|
||||
lua_pushnumber(L, applyChannelRatio(idx, getValue(src))/100.0);
|
||||
break;
|
||||
|
||||
case MIXSRC_FIRST_TELEM-1+TELEM_CELL:
|
||||
@@ -136,6 +145,7 @@ static void luaGetValueAndPush(int src)
|
||||
case MIXSRC_FIRST_TELEM-1+TELEM_ACCx:
|
||||
case MIXSRC_FIRST_TELEM-1+TELEM_ACCy:
|
||||
case MIXSRC_FIRST_TELEM-1+TELEM_ACCz:
|
||||
case MIXSRC_FIRST_TELEM-1+TELEM_VSPEED:
|
||||
//theese need to be divided by 100
|
||||
lua_pushnumber(L, getValue(src)/100.0);
|
||||
break;
|
||||
@@ -147,62 +157,136 @@ static void luaGetValueAndPush(int src)
|
||||
}
|
||||
}
|
||||
|
||||
struct LuaField {
|
||||
const char * name;
|
||||
const uint8_t id;
|
||||
const uint8_t attr;
|
||||
};
|
||||
//these are used when returning fields that are defined as multiples
|
||||
static char foundName[10];
|
||||
static char foundDesc[50];
|
||||
static LuaField foundField = {0, foundName, foundDesc};
|
||||
|
||||
const LuaField luaFields[] = {
|
||||
{ "altitude-max", MIXSRC_FIRST_TELEM+TELEM_MAX_ALT-1, 0 },
|
||||
{ "altitude", MIXSRC_FIRST_TELEM+TELEM_ALT-1, PREC2 },
|
||||
{ "vario", MIXSRC_FIRST_TELEM+TELEM_VSPEED-1, PREC2 },
|
||||
{ "tx-voltage", MIXSRC_FIRST_TELEM+TELEM_TX_VOLTAGE-1, PREC1 },
|
||||
{ "rpm", MIXSRC_FIRST_TELEM+TELEM_RPM-1, 0 },
|
||||
{ NULL, 0, 0 },
|
||||
};
|
||||
/**
|
||||
Return filed data for a given field name
|
||||
|
||||
Note: function is non-reentrant
|
||||
*/
|
||||
const LuaField * luaFindFieldByName(const char * name)
|
||||
{
|
||||
// TODO better search method (binary lookup)
|
||||
for(int n = 0; n < (int)DIM(luaFields); ++n) {
|
||||
if (!strcmp(name, luaFields[n].name)) {
|
||||
return &luaFields[n];
|
||||
}
|
||||
}
|
||||
//search in multiples
|
||||
for(int n = 0; n < (int)DIM(luaMultipleFields); ++n) {
|
||||
for(int i = luaMultipleFields[n].start; i < luaMultipleFields[n].end; i++){
|
||||
//char buf[10];
|
||||
snprintf(foundName, sizeof(foundName), luaMultipleFields[n].name, i);
|
||||
// TRACE("luaFindFieldByName(): %s", foundName);
|
||||
if (!strcmp(name, foundName)) {
|
||||
snprintf(foundDesc, sizeof(foundDesc), luaMultipleFields[n].desc, i);
|
||||
foundField.id = luaMultipleFields[n].id+i-1;
|
||||
return &foundField;
|
||||
}
|
||||
}
|
||||
}
|
||||
// search in lua script outputs
|
||||
// TODO
|
||||
return 0; // not found
|
||||
}
|
||||
|
||||
/**
|
||||
Return filed data for a given field id
|
||||
|
||||
Note: function is non-reentrant
|
||||
*/
|
||||
const LuaField * luaFindFieldById(int id)
|
||||
{
|
||||
for(int n = 0; n < (int)DIM(luaFields); ++n) {
|
||||
if (id == luaFields[n].id) {
|
||||
return &luaFields[n];
|
||||
}
|
||||
}
|
||||
//search in multiples
|
||||
for(int n = 0; n < (int)DIM(luaMultipleFields); ++n) {
|
||||
if ((id >= luaMultipleFields[n].id) && (id <= luaMultipleFields[n].id+luaMultipleFields[n].end-luaMultipleFields[n].start)) {
|
||||
int i = id - luaMultipleFields[n].id + luaMultipleFields[n].start;
|
||||
snprintf(foundName, sizeof(foundName), luaMultipleFields[n].name, i);
|
||||
snprintf(foundDesc, sizeof(foundDesc), luaMultipleFields[n].desc, i);
|
||||
foundField.id = id;
|
||||
return &foundField;
|
||||
}
|
||||
}
|
||||
// search in lua script outputs
|
||||
// TODO
|
||||
return 0; // not found
|
||||
}
|
||||
|
||||
// TODO this could be removed and luaGetFieldInfo() used instead
|
||||
// get a filed ids for one or more fields
|
||||
static int luaGetFields(lua_State *L)
|
||||
{
|
||||
// get number of arguments
|
||||
int n = lua_gettop(L);
|
||||
// return requested filed ids as multiple return values
|
||||
for (int i = 1; i <= n; i++)
|
||||
{
|
||||
const char * what = luaL_checkstring(L, i);
|
||||
TRACE("luaGetFields(): %s", what);
|
||||
const LuaField * field = luaFindFieldByName(what);
|
||||
if (field) {
|
||||
lua_pushinteger(L, field->id);
|
||||
}
|
||||
else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
//get a detailed info about particular field
|
||||
static int luaGetFieldInfo(lua_State *L)
|
||||
{
|
||||
const LuaField * field;
|
||||
if (lua_isnumber(L, 1)) {
|
||||
int id = luaL_checkinteger(L, 1);
|
||||
// TRACE("luaGetFieldInfo(): int %d", id);
|
||||
field = luaFindFieldById(id);
|
||||
}
|
||||
else {
|
||||
const char * what = luaL_checkstring(L, 1);
|
||||
// TRACE("luaGetFieldInfo(): str %s", what);
|
||||
field = luaFindFieldByName(what);
|
||||
}
|
||||
if (field) {
|
||||
lua_newtable(L);
|
||||
lua_pushtableinteger(L, "id", field->id);
|
||||
lua_pushstring(L, "name"); lua_pushstring(L, field->name); lua_settable(L, -3);
|
||||
lua_pushstring(L, "desc"); lua_pushstring(L, field->desc); lua_settable(L, -3);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int luaGetValue(lua_State *L)
|
||||
{
|
||||
int src = 0;
|
||||
if (lua_isnumber(L, 1)) {
|
||||
int src = luaL_checkinteger(L, 1);
|
||||
luaGetValueAndPush(src);
|
||||
return 1;
|
||||
src = luaL_checkinteger(L, 1);
|
||||
}
|
||||
else {
|
||||
const char *what = luaL_checkstring(L, 1);
|
||||
for (const LuaField * field = &luaFields[0]; field->name; field++) {
|
||||
if (!strcmp(what, field->name)) {
|
||||
getvalue_t value = getValue(field->id);
|
||||
if (field->attr == PREC1)
|
||||
lua_pushnumber(L, double(value)/10);
|
||||
else if (field->attr == PREC2)
|
||||
lua_pushnumber(L, double(value)/100);
|
||||
else
|
||||
lua_pushnumber(L, value);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (frskyData.hub.gpsFix) {
|
||||
if (!strcmp(what, "latitude")) {
|
||||
lua_pushnumber(L, gpsToDouble(frskyData.hub.gpsLatitudeNS=='S', frskyData.hub.gpsLatitude_bp, frskyData.hub.gpsLatitude_ap));
|
||||
return 1;
|
||||
}
|
||||
else if (!strcmp(what, "longitude")) {
|
||||
lua_pushnumber(L, gpsToDouble(frskyData.hub.gpsLongitudeEW=='W', frskyData.hub.gpsLongitude_bp, frskyData.hub.gpsLongitude_ap));
|
||||
return 1;
|
||||
}
|
||||
else if (!strcmp(what, "pilot-latitude")) {
|
||||
lua_pushnumber(L, pilotLatitude);
|
||||
return 1;
|
||||
}
|
||||
else if (!strcmp(what, "pilot-longitude")) {
|
||||
lua_pushnumber(L, pilotLongitude);
|
||||
return 1;
|
||||
}
|
||||
// convert from filed name to its id
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
const LuaField * field = luaFindFieldByName(name);
|
||||
if (field) {
|
||||
// TRACE("luaGetValue(): %d", field->id);
|
||||
src = field->id;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
if (src >= EXTRA_FIRST ) {
|
||||
// one of the extra fields
|
||||
return luaGetExtraValue(src);
|
||||
}
|
||||
luaGetValueAndPush(src);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int luaPlayFile(lua_State *L)
|
||||
@@ -314,11 +398,9 @@ static int luaLcdDrawChannel(lua_State *L)
|
||||
}
|
||||
else {
|
||||
const char *what = luaL_checkstring(L, 3);
|
||||
for (const LuaField * field = &luaFields[0]; field->name; field++) {
|
||||
if (!strcmp(what, field->name)) {
|
||||
channel = field->id;
|
||||
break;
|
||||
}
|
||||
const LuaField * field = luaFindFieldByName(what);
|
||||
if (field) {
|
||||
channel = field->id;
|
||||
}
|
||||
}
|
||||
int att = luaL_checkinteger(L, 4);
|
||||
@@ -1182,6 +1264,9 @@ void luaInit()
|
||||
lua_register(L, "getVersion", luaGetVersion);
|
||||
lua_register(L, "getGeneralSettings", luaGetGeneralSettings);
|
||||
lua_register(L, "getValue", luaGetValue);
|
||||
lua_register(L, "getFields", luaGetFields);
|
||||
lua_register(L, "getFieldInfo", luaGetFieldInfo);
|
||||
|
||||
lua_register(L, "playFile", luaPlayFile);
|
||||
lua_register(L, "playNumber", luaPlayNumber);
|
||||
lua_register(L, "popupInput", luaPopupInput);
|
||||
|
||||
Reference in New Issue
Block a user