Fixes #1480: How to handle the increasing number of Lua constants

This commit is contained in:
Damjan Adamic
2014-07-18 08:59:38 +02:00
parent ce6d0807fa
commit fb3e615008
6 changed files with 479 additions and 159 deletions
+153 -68
View File
@@ -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);