mirror of https://github.com/ArduPilot/ardupilot
AP_Scripting: Add alias suppport to the scripting generator
This commit is contained in:
parent
746240ebe3
commit
e4035bd7e8
|
@ -29,8 +29,8 @@ An example script is given below:
|
|||
```lua
|
||||
function update () -- periodic function that will be called
|
||||
current_pos = Location()
|
||||
AP_AHRS:get_position(current_pos)
|
||||
distance = current_pos:get_distance(AP_AHRS:get_home()) -- calculate the distance from home
|
||||
ahrs:get_position(current_pos)
|
||||
distance = current_pos:get_distance(ahrs:get_home()) -- calculate the distance from home
|
||||
if distance > 1000 then -- if more then 1000 meters away
|
||||
distance = 1000; -- clamp the distance to 1000 meters
|
||||
end
|
||||
|
|
|
@ -15,6 +15,7 @@ userdata Location method get_vector_from_origin_NEU boolean Vector3f
|
|||
|
||||
include AP_AHRS/AP_AHRS.h
|
||||
|
||||
singleton AP_AHRS alias ahrs
|
||||
singleton AP_AHRS method get_position boolean Location
|
||||
singleton AP_AHRS method get_home Location
|
||||
|
||||
|
@ -25,7 +26,9 @@ userdata Vector3f field y float read write -FLT_MAX FLT_MAX
|
|||
userdata Vector3f field z float read write -FLT_MAX FLT_MAX
|
||||
|
||||
include AP_Notify/AP_Notify.h
|
||||
singleton notify alias notify
|
||||
singleton AP_Notify method play_tune void string
|
||||
|
||||
include AP_RangeFinder/AP_RangeFinder.h
|
||||
singleton RangeFinder alias rangefinder
|
||||
singleton RangeFinder method num_sensors uint8_t
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
char keyword_alias[] = "alias";
|
||||
char keyword_comment[] = "--";
|
||||
char keyword_field[] = "field";
|
||||
char keyword_include[] = "include";
|
||||
|
@ -505,7 +506,8 @@ void handle_userdata(void) {
|
|||
|
||||
struct singleton {
|
||||
struct singleton *next;
|
||||
char *name;
|
||||
char *name; // name of the C++ singleton
|
||||
char *alias; // (optional) used for scripting access
|
||||
struct method * methods;
|
||||
};
|
||||
|
||||
|
@ -538,12 +540,28 @@ void handle_singleton(void) {
|
|||
if (type == NULL) {
|
||||
error(ERROR_SINGLETON, "Expected an access type for userdata %s", name);
|
||||
}
|
||||
if (strcmp(type, keyword_method) != 0) {
|
||||
error(ERROR_SINGLETON, "Singletons only support method access types (got %s)", type);
|
||||
}
|
||||
|
||||
// method name
|
||||
handle_method(TRACE_USERDATA, node->name, &(node->methods));
|
||||
if (strcmp(type, keyword_alias) == 0) {
|
||||
if (node->alias != NULL) {
|
||||
error(ERROR_SINGLETON, "Alias of %s was already declared for %s", node->alias, node->name);
|
||||
}
|
||||
const char *alias = next_token();
|
||||
if (alias == NULL) {
|
||||
error(ERROR_SINGLETON, "Missing the name of the alias for %s", node->name);
|
||||
}
|
||||
node->alias = (char *)allocate(strlen(alias) + 1);
|
||||
strcpy(node->alias, alias);
|
||||
|
||||
// ensure no more tokens on the line
|
||||
if (next_token()) {
|
||||
error(ERROR_HEADER, "Singleton contained an unexpected extra token: %s", state.token);
|
||||
}
|
||||
return;
|
||||
} else if (strcmp(type, keyword_method) == 0) {
|
||||
handle_method(TRACE_USERDATA, node->name, &(node->methods));
|
||||
} else {
|
||||
error(ERROR_SINGLETON, "Singletons only support methods or aliases (got %s)", type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -841,6 +859,8 @@ void emit_singleton_method(const struct singleton *data, const struct method *me
|
|||
arg = arg->next;
|
||||
}
|
||||
|
||||
const char *access_name = data->alias ? data->alias : data->name;
|
||||
|
||||
fprintf(source, "int %s_%s(lua_State *L) {\n", data->name, method->name);
|
||||
fprintf(source, " const int args = lua_gettop(L);\n");
|
||||
fprintf(source, " if (args > %d) {\n", arg_count);
|
||||
|
@ -848,12 +868,12 @@ void emit_singleton_method(const struct singleton *data, const struct method *me
|
|||
fprintf(source, " } else if (args < %d) {\n", arg_count);
|
||||
fprintf(source, " return luaL_argerror(L, args, \"too few arguments\");\n");
|
||||
fprintf(source, " }\n\n");
|
||||
fprintf(source, " luaL_checkudata(L, 1, \"%s\");\n\n", data->name);
|
||||
fprintf(source, " luaL_checkudata(L, 1, \"%s\");\n\n", access_name);
|
||||
|
||||
// fetch and check the singleton pointer
|
||||
fprintf(source, " %s *singleton = %s::get_singleton();", data->name, data->name);
|
||||
fprintf(source, " %s *singleton = %s::get_singleton();\n", data->name, data->name);
|
||||
fprintf(source, " if (singleton == nullptr) {\n");
|
||||
fprintf(source, " return luaL_argerror(L, args, \"%s not supported on this firmware\");\n", data->name);
|
||||
fprintf(source, " return luaL_argerror(L, args, \"%s not supported on this firmware\");\n", access_name);
|
||||
fprintf(source, " }\n\n");
|
||||
|
||||
// extract the arguments
|
||||
|
@ -1016,7 +1036,7 @@ void emit_loaders(void) {
|
|||
fprintf(source, "} singleton_fun[] = {\n");
|
||||
struct singleton * single = parsed_singletons;
|
||||
while (single) {
|
||||
fprintf(source, " {\"%s\", %s_meta},\n", single->name, single->name);
|
||||
fprintf(source, " {\"%s\", %s_meta},\n", single->alias ? single->alias : single->name, single->name);
|
||||
single = single->next;
|
||||
}
|
||||
fprintf(source, "};\n\n");
|
||||
|
@ -1054,7 +1074,7 @@ void emit_sandbox(void) {
|
|||
struct singleton *single = parsed_singletons;
|
||||
fprintf(source, "const char *singletons[] = {\n");
|
||||
while (single) {
|
||||
fprintf(source, " \"%s\",\n", single->name);
|
||||
fprintf(source, " \"%s\",\n", single->alias ? single->alias : single->name);
|
||||
single = single->next;
|
||||
}
|
||||
fprintf(source, "};\n\n");
|
||||
|
|
|
@ -264,10 +264,11 @@ int RangeFinder_num_sensors(lua_State *L) {
|
|||
return luaL_argerror(L, args, "too few arguments");
|
||||
}
|
||||
|
||||
luaL_checkudata(L, 1, "RangeFinder");
|
||||
luaL_checkudata(L, 1, "rangefinder");
|
||||
|
||||
RangeFinder *singleton = RangeFinder::get_singleton(); if (singleton == nullptr) {
|
||||
return luaL_argerror(L, args, "RangeFinder not supported on this firmware");
|
||||
RangeFinder *singleton = RangeFinder::get_singleton();
|
||||
if (singleton == nullptr) {
|
||||
return luaL_argerror(L, args, "rangefinder not supported on this firmware");
|
||||
}
|
||||
|
||||
const uint8_t data = singleton->num_sensors(
|
||||
|
@ -287,7 +288,8 @@ int AP_Notify_play_tune(lua_State *L) {
|
|||
|
||||
luaL_checkudata(L, 1, "AP_Notify");
|
||||
|
||||
AP_Notify *singleton = AP_Notify::get_singleton(); if (singleton == nullptr) {
|
||||
AP_Notify *singleton = AP_Notify::get_singleton();
|
||||
if (singleton == nullptr) {
|
||||
return luaL_argerror(L, args, "AP_Notify not supported on this firmware");
|
||||
}
|
||||
|
||||
|
@ -306,10 +308,11 @@ int AP_AHRS_get_home(lua_State *L) {
|
|||
return luaL_argerror(L, args, "too few arguments");
|
||||
}
|
||||
|
||||
luaL_checkudata(L, 1, "AP_AHRS");
|
||||
luaL_checkudata(L, 1, "ahrs");
|
||||
|
||||
AP_AHRS *singleton = AP_AHRS::get_singleton(); if (singleton == nullptr) {
|
||||
return luaL_argerror(L, args, "AP_AHRS not supported on this firmware");
|
||||
AP_AHRS *singleton = AP_AHRS::get_singleton();
|
||||
if (singleton == nullptr) {
|
||||
return luaL_argerror(L, args, "ahrs not supported on this firmware");
|
||||
}
|
||||
|
||||
const Location &data = singleton->get_home(
|
||||
|
@ -328,10 +331,11 @@ int AP_AHRS_get_position(lua_State *L) {
|
|||
return luaL_argerror(L, args, "too few arguments");
|
||||
}
|
||||
|
||||
luaL_checkudata(L, 1, "AP_AHRS");
|
||||
luaL_checkudata(L, 1, "ahrs");
|
||||
|
||||
AP_AHRS *singleton = AP_AHRS::get_singleton(); if (singleton == nullptr) {
|
||||
return luaL_argerror(L, args, "AP_AHRS not supported on this firmware");
|
||||
AP_AHRS *singleton = AP_AHRS::get_singleton();
|
||||
if (singleton == nullptr) {
|
||||
return luaL_argerror(L, args, "ahrs not supported on this firmware");
|
||||
}
|
||||
|
||||
Location & data_2 = *check_Location(L, 2);
|
||||
|
@ -352,6 +356,10 @@ const luaL_Reg AP_Notify_meta[] = {
|
|||
{NULL, NULL}
|
||||
};
|
||||
|
||||
const luaL_Reg notify_meta[] = {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
const luaL_Reg AP_AHRS_meta[] = {
|
||||
{"get_home", AP_AHRS_get_home},
|
||||
{"get_position", AP_AHRS_get_position},
|
||||
|
@ -370,9 +378,10 @@ const struct singleton_fun {
|
|||
const char *name;
|
||||
const luaL_Reg *reg;
|
||||
} singleton_fun[] = {
|
||||
{"RangeFinder", RangeFinder_meta},
|
||||
{"rangefinder", RangeFinder_meta},
|
||||
{"AP_Notify", AP_Notify_meta},
|
||||
{"AP_AHRS", AP_AHRS_meta},
|
||||
{"notify", notify_meta},
|
||||
{"ahrs", AP_AHRS_meta},
|
||||
};
|
||||
|
||||
void load_generated_bindings(lua_State *L) {
|
||||
|
@ -402,9 +411,10 @@ void load_generated_bindings(lua_State *L) {
|
|||
}
|
||||
|
||||
const char *singletons[] = {
|
||||
"RangeFinder",
|
||||
"rangefinder",
|
||||
"AP_Notify",
|
||||
"AP_AHRS",
|
||||
"notify",
|
||||
"ahrs",
|
||||
};
|
||||
|
||||
const struct userdata {
|
||||
|
|
Loading…
Reference in New Issue