mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-02-02 14:08:45 -04:00
AP_Scripting: move singleton method bindings to flash
This commit is contained in:
parent
c2c94631e8
commit
da352163ee
@ -1944,7 +1944,7 @@ void emit_operators(struct userdata *data) {
|
||||
}
|
||||
}
|
||||
|
||||
void emit_userdata_methods(struct userdata *node) {
|
||||
void emit_methods(struct userdata *node) {
|
||||
while(node) {
|
||||
// methods
|
||||
struct method *method = node->methods;
|
||||
@ -1995,10 +1995,22 @@ void emit_userdata_metatables(void) {
|
||||
}
|
||||
}
|
||||
|
||||
void emit_singleton_metatables(struct userdata *head) {
|
||||
void emit_enum(struct userdata * data) {
|
||||
fprintf(source, "struct userdata_enum %s_enums[] = {\n", data->sanatized_name);
|
||||
struct userdata_enum *ud_enum = data->enums;
|
||||
while (ud_enum != NULL) {
|
||||
fprintf(source, " {\"%s\", %s::%s},\n", ud_enum->name, data->name, ud_enum->name);
|
||||
ud_enum = ud_enum->next;
|
||||
}
|
||||
fprintf(source, "};\n\n");
|
||||
}
|
||||
|
||||
void emit_index(struct userdata *head) {
|
||||
|
||||
struct userdata * node = head;
|
||||
while(node) {
|
||||
start_dependency(source, node->dependency);
|
||||
|
||||
fprintf(source, "const luaL_Reg %s_meta[] = {\n", node->sanatized_name);
|
||||
|
||||
struct method *method = node->methods;
|
||||
@ -2013,41 +2025,61 @@ void emit_singleton_metatables(struct userdata *head) {
|
||||
field = field->next;
|
||||
}
|
||||
|
||||
fprintf(source, " {NULL, NULL}\n");
|
||||
fprintf(source, "};\n");
|
||||
fprintf(source, "};\n\n");
|
||||
|
||||
if (node->operations) {
|
||||
fprintf(source, "const luaL_Reg %s_operators[] = {\n", node->sanatized_name);
|
||||
for (uint32_t i = 1; i < OP_LAST; i = (i << 1)) {
|
||||
const char * op_name = get_name_for_operation((node->operations) & i);
|
||||
if (op_name == NULL) {
|
||||
continue;
|
||||
}
|
||||
fprintf(source, " {\"%s\", %s_%s},\n", op_name, node->sanatized_name, op_name);
|
||||
}
|
||||
fprintf(source, " {NULL, NULL},\n");
|
||||
fprintf(source, "};\n\n");
|
||||
}
|
||||
|
||||
if (node->enums != NULL) {
|
||||
emit_enum(node);
|
||||
}
|
||||
|
||||
fprintf(source, "static int %s_index(lua_State *L) {\n", node->sanatized_name);
|
||||
fprintf(source, " const char * name = luaL_checkstring(L, 2);\n");
|
||||
fprintf(source, " if (load_function(L,%s_meta,ARRAY_SIZE(%s_meta),name)",node->sanatized_name,node->sanatized_name);
|
||||
if (node->enums != NULL) {
|
||||
fprintf(source, " || load_enum(L,%s_enums,ARRAY_SIZE(%s_enums),name)",node->sanatized_name,node->sanatized_name);
|
||||
}
|
||||
fprintf(source, ") {\n");
|
||||
fprintf(source, " return 1;\n");
|
||||
fprintf(source, " }\n");
|
||||
fprintf(source, " return 0;\n");
|
||||
fprintf(source, "}\n");
|
||||
end_dependency(source, node->dependency);
|
||||
fprintf(source, "\n");
|
||||
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
||||
void emit_enums(struct userdata * data) {
|
||||
void emit_type_index(struct userdata * data, char * meta_name) {
|
||||
fprintf(source, "const struct luaL_Reg %s_fun[] = {\n", meta_name);
|
||||
while (data) {
|
||||
if (data->enums != NULL) {
|
||||
start_dependency(source, data->dependency);
|
||||
fprintf(source, "struct userdata_enum %s_enums[] = {\n", data->sanatized_name);
|
||||
struct userdata_enum *ud_enum = data->enums;
|
||||
while (ud_enum != NULL) {
|
||||
fprintf(source, " {\"%s\", %s::%s},\n", ud_enum->name, data->name, ud_enum->name);
|
||||
ud_enum = ud_enum->next;
|
||||
}
|
||||
fprintf(source, " {NULL, 0}};\n");
|
||||
fprintf(source, " {\"%s\", %s_index},\n", data->alias ? data->alias : data->name, data->sanatized_name);
|
||||
end_dependency(source, data->dependency);
|
||||
fprintf(source, "\n");
|
||||
}
|
||||
data = data->next;
|
||||
}
|
||||
fprintf(source, "};\n\n");
|
||||
}
|
||||
|
||||
void emit_metas(struct userdata * data, char * meta_name) {
|
||||
void emit_type_index_with_operators(struct userdata * data, char * meta_name) {
|
||||
fprintf(source, "const struct userdata_meta %s_fun[] = {\n", meta_name);
|
||||
while (data) {
|
||||
start_dependency(source, data->dependency);
|
||||
if (data->enums) {
|
||||
fprintf(source, " {\"%s\", %s_meta, %s_enums},\n", data->alias ? data->alias : data->name, data->name, data->sanatized_name);
|
||||
if (data->operations == 0) {
|
||||
fprintf(source, " {\"%s\", %s_index, nullptr},\n", data->alias ? data->alias : data->name, data->sanatized_name);
|
||||
} else {
|
||||
fprintf(source, " {\"%s\", %s_meta, NULL},\n", data->alias ? data->alias : data->name, data->sanatized_name);
|
||||
fprintf(source, " {\"%s\", %s_index, %s_operators},\n", data->alias ? data->alias : data->name, data->sanatized_name, data->sanatized_name);
|
||||
}
|
||||
end_dependency(source, data->dependency);
|
||||
data = data->next;
|
||||
@ -2056,66 +2088,61 @@ void emit_metas(struct userdata * data, char * meta_name) {
|
||||
}
|
||||
|
||||
void emit_loaders(void) {
|
||||
// emit the enum header
|
||||
fprintf(source, "struct userdata_enum {\n");
|
||||
fprintf(source, " const char *name;\n");
|
||||
fprintf(source, " int value;\n");
|
||||
fprintf(source, "};\n\n");
|
||||
emit_enums(parsed_userdata);
|
||||
emit_enums(parsed_singletons);
|
||||
|
||||
// emit the meta table header
|
||||
fprintf(source, "struct userdata_meta {\n");
|
||||
fprintf(source, " const char *name;\n");
|
||||
fprintf(source, " const luaL_Reg *reg;\n");
|
||||
fprintf(source, " const struct userdata_enum *enums;\n");
|
||||
fprintf(source, "};\n\n");
|
||||
emit_metas(parsed_userdata, "userdata");
|
||||
emit_metas(parsed_singletons, "singleton");
|
||||
emit_metas(parsed_ap_objects, "ap_object");
|
||||
emit_type_index_with_operators(parsed_userdata, "userdata");
|
||||
emit_type_index(parsed_singletons, "singleton");
|
||||
emit_type_index(parsed_ap_objects, "ap_object");
|
||||
|
||||
fprintf(source, "void load_generated_bindings(lua_State *L) {\n");
|
||||
fprintf(source, " luaL_checkstack(L, 5, \"Out of stack\");\n"); // this is more stack space then we need, but should never fail
|
||||
fprintf(source, " // userdata metatables\n");
|
||||
fprintf(source, " for (uint32_t i = 0; i < ARRAY_SIZE(userdata_fun); i++) {\n");
|
||||
fprintf(source, " luaL_newmetatable(L, userdata_fun[i].name);\n");
|
||||
fprintf(source, " luaL_setfuncs(L, userdata_fun[i].reg, 0);\n");
|
||||
fprintf(source, " lua_pushstring(L, \"__index\");\n");
|
||||
fprintf(source, " lua_pushcclosure(L, userdata_fun[i].func, 0);\n");
|
||||
fprintf(source, " lua_setfield(L, -2, \"__index\");\n");
|
||||
|
||||
fprintf(source, " if (userdata_fun[i].operators != nullptr) {\n");
|
||||
fprintf(source, " luaL_setfuncs(L, userdata_fun[i].operators, 0);\n");
|
||||
fprintf(source, " }\n");
|
||||
|
||||
fprintf(source, " lua_pushstring(L, \"__call\");\n");
|
||||
fprintf(source, " lua_pushvalue(L, -2);\n");
|
||||
fprintf(source, " lua_settable(L, -3);\n");
|
||||
|
||||
fprintf(source, " lua_pop(L, 1);\n");
|
||||
fprintf(source, " lua_newuserdata(L, 0);\n");
|
||||
fprintf(source, " luaL_getmetatable(L, userdata_fun[i].name);\n");
|
||||
fprintf(source, " lua_setmetatable(L, -2);\n");
|
||||
fprintf(source, " lua_setglobal(L, userdata_fun[i].name);\n");
|
||||
fprintf(source, " }\n");
|
||||
fprintf(source, "\n");
|
||||
|
||||
fprintf(source, " // ap object metatables\n");
|
||||
fprintf(source, " for (uint32_t i = 0; i < ARRAY_SIZE(ap_object_fun); i++) {\n");
|
||||
fprintf(source, " luaL_newmetatable(L, ap_object_fun[i].name);\n");
|
||||
fprintf(source, " luaL_setfuncs(L, ap_object_fun[i].reg, 0);\n");
|
||||
fprintf(source, " lua_pushstring(L, \"__index\");\n");
|
||||
fprintf(source, " lua_pushcclosure(L, ap_object_fun[i].func, 0);\n");
|
||||
fprintf(source, " lua_setfield(L, -2, \"__index\");\n");
|
||||
fprintf(source, " lua_pushstring(L, \"__call\");\n");
|
||||
fprintf(source, " lua_pushvalue(L, -2);\n");
|
||||
fprintf(source, " lua_settable(L, -3);\n");
|
||||
|
||||
fprintf(source, " lua_pop(L, 1);\n");
|
||||
fprintf(source, " lua_newuserdata(L, 0);\n");
|
||||
fprintf(source, " luaL_getmetatable(L, ap_object_fun[i].name);\n");
|
||||
fprintf(source, " lua_setmetatable(L, -2);\n");
|
||||
fprintf(source, " lua_setglobal(L, ap_object_fun[i].name);\n");
|
||||
fprintf(source, " }\n");
|
||||
fprintf(source, "\n");
|
||||
|
||||
fprintf(source, " // singleton metatables\n");
|
||||
fprintf(source, " for (uint32_t i = 0; i < ARRAY_SIZE(singleton_fun); i++) {\n");
|
||||
fprintf(source, " luaL_newmetatable(L, singleton_fun[i].name);\n");
|
||||
fprintf(source, " luaL_setfuncs(L, singleton_fun[i].reg, 0);\n");
|
||||
fprintf(source, " lua_pushstring(L, \"__index\");\n");
|
||||
fprintf(source, " lua_pushcclosure(L, singleton_fun[i].func, 0);\n");
|
||||
fprintf(source, " lua_setfield(L, -2, \"__index\");\n");
|
||||
fprintf(source, " lua_pushstring(L, \"__call\");\n");
|
||||
fprintf(source, " lua_pushvalue(L, -2);\n");
|
||||
fprintf(source, " lua_settable(L, -3);\n");
|
||||
|
||||
fprintf(source, " if (singleton_fun[i].enums != nullptr) {\n");
|
||||
fprintf(source, " int j = 0;\n");
|
||||
fprintf(source, " while (singleton_fun[i].enums[j].name != NULL) {\n");
|
||||
fprintf(source, " lua_pushstring(L, singleton_fun[i].enums[j].name);\n");
|
||||
fprintf(source, " lua_pushinteger(L, singleton_fun[i].enums[j].value);\n");
|
||||
fprintf(source, " lua_settable(L, -3);\n");
|
||||
fprintf(source, " j++;\n");
|
||||
fprintf(source, " }\n");
|
||||
fprintf(source, " }\n");
|
||||
|
||||
fprintf(source, " lua_pop(L, 1);\n");
|
||||
fprintf(source, " lua_newuserdata(L, 0);\n");
|
||||
fprintf(source, " luaL_getmetatable(L, singleton_fun[i].name);\n");
|
||||
@ -2130,16 +2157,6 @@ void emit_loaders(void) {
|
||||
}
|
||||
|
||||
void emit_sandbox(void) {
|
||||
struct userdata *single = parsed_singletons;
|
||||
fprintf(source, "const char *singletons[] = {\n");
|
||||
while (single) {
|
||||
start_dependency(source, single->dependency);
|
||||
fprintf(source, " \"%s\",\n", single->alias ? single->alias : single->sanatized_name);
|
||||
end_dependency(source, single->dependency);
|
||||
single = single->next;
|
||||
}
|
||||
fprintf(source, "};\n\n");
|
||||
|
||||
struct userdata *data = parsed_userdata;
|
||||
fprintf(source, "const struct userdata {\n");
|
||||
fprintf(source, " const char *name;\n");
|
||||
@ -2162,9 +2179,9 @@ void emit_sandbox(void) {
|
||||
|
||||
fprintf(source, "void load_generated_sandbox(lua_State *L) {\n");
|
||||
// load the singletons
|
||||
fprintf(source, " for (uint32_t i = 0; i < ARRAY_SIZE(singletons); i++) {\n");
|
||||
fprintf(source, " lua_pushstring(L, singletons[i]);\n");
|
||||
fprintf(source, " lua_getglobal(L, singletons[i]);\n");
|
||||
fprintf(source, " for (uint32_t i = 0; i < ARRAY_SIZE(singleton_fun); i++) {\n");
|
||||
fprintf(source, " lua_pushstring(L, singleton_fun[i].name);\n");
|
||||
fprintf(source, " lua_getglobal(L, singleton_fun[i].name);\n");
|
||||
fprintf(source, " lua_settable(L, -3);\n");
|
||||
fprintf(source, " }\n");
|
||||
|
||||
@ -2379,6 +2396,43 @@ void emit_docs(struct userdata *node, int is_userdata, int emit_creation) {
|
||||
}
|
||||
|
||||
|
||||
void emit_index_helpers(void) {
|
||||
fprintf(source, "static bool load_function(lua_State *L, const luaL_Reg *list, const uint8_t length, const char* name) {\n");
|
||||
fprintf(source, " for (uint8_t i = 0; i < length; i++) {\n");
|
||||
fprintf(source, " if (strcmp(name,list[i].name) == 0) {\n");
|
||||
fprintf(source, " lua_pushcfunction(L, list[i].func);\n");
|
||||
fprintf(source, " return true;\n");
|
||||
fprintf(source, " }\n");
|
||||
fprintf(source, " }\n");
|
||||
fprintf(source, " return false;\n");
|
||||
fprintf(source, "}\n\n");
|
||||
|
||||
fprintf(source, "static bool load_enum(lua_State *L, const userdata_enum *list, const uint8_t length, const char* name) {\n");
|
||||
fprintf(source, " for (uint8_t i = 0; i < length; i++) {\n");
|
||||
fprintf(source, " if (strcmp(name,list[i].name) == 0) {\n");
|
||||
fprintf(source, " lua_pushinteger(L, list[i].value);\n");
|
||||
fprintf(source, " return true;\n");
|
||||
fprintf(source, " }\n");
|
||||
fprintf(source, " }\n");
|
||||
fprintf(source, " return false;\n");
|
||||
fprintf(source, "}\n\n");
|
||||
}
|
||||
|
||||
void emit_structs(void) {
|
||||
// emit the enum header
|
||||
fprintf(source, "struct userdata_enum {\n");
|
||||
fprintf(source, " const char *name;\n");
|
||||
fprintf(source, " int value;\n");
|
||||
fprintf(source, "};\n\n");
|
||||
|
||||
// emit the meta table header
|
||||
fprintf(source, "struct userdata_meta {\n");
|
||||
fprintf(source, " const char *name;\n");
|
||||
fprintf(source, " lua_CFunction func;\n");
|
||||
fprintf(source, " const luaL_Reg *operators;\n");
|
||||
fprintf(source, "};\n\n");
|
||||
}
|
||||
|
||||
char * output_path = NULL;
|
||||
char * docs_path = NULL;
|
||||
|
||||
@ -2476,6 +2530,10 @@ int main(int argc, char **argv) {
|
||||
|
||||
emit_not_supported_helper();
|
||||
|
||||
emit_structs();
|
||||
|
||||
emit_index_helpers();
|
||||
|
||||
emit_userdata_allocators();
|
||||
|
||||
emit_userdata_checkers();
|
||||
@ -2484,21 +2542,20 @@ int main(int argc, char **argv) {
|
||||
|
||||
emit_ap_object_checkers();
|
||||
|
||||
emit_userdata_fields();
|
||||
|
||||
emit_userdata_methods(parsed_userdata);
|
||||
|
||||
emit_userdata_metatables();
|
||||
|
||||
emit_singleton_fields();
|
||||
emit_methods(parsed_singletons);
|
||||
emit_index(parsed_singletons);
|
||||
|
||||
emit_userdata_methods(parsed_singletons);
|
||||
emit_userdata_fields();
|
||||
emit_methods(parsed_userdata);
|
||||
emit_index(parsed_userdata);
|
||||
|
||||
emit_singleton_metatables(parsed_singletons);
|
||||
|
||||
emit_userdata_methods(parsed_ap_objects);
|
||||
emit_methods(parsed_ap_objects);
|
||||
emit_index(parsed_ap_objects);
|
||||
|
||||
emit_singleton_metatables(parsed_ap_objects);
|
||||
|
||||
emit_loaders();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user