Skip to content

Commit 925cdc0

Browse files
authored
Merge pull request #1204 from joto/refactor-funcs-calling-lua
Refactor functions calling back into Lua code
2 parents e42621e + 5cf798a commit 925cdc0

File tree

2 files changed

+84
-46
lines changed

2 files changed

+84
-46
lines changed

src/output-flex.cpp

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,25 @@ TRAMPOLINE(table_tostring, __tostring)
6868
static char const osm2pgsql_table_name[] = "osm2pgsql.table";
6969
static char const osm2pgsql_object_metatable[] = "osm2pgsql.object_metatable";
7070

71+
prepared_lua_function_t::prepared_lua_function_t(lua_State *lua_state,
72+
char const *name)
73+
{
74+
int const index = lua_gettop(lua_state);
75+
76+
lua_getfield(lua_state, 1, name);
77+
78+
if (lua_type(lua_state, -1) == LUA_TFUNCTION) {
79+
m_index = index;
80+
return;
81+
}
82+
83+
if (lua_type(lua_state, -1) == LUA_TNIL) {
84+
return;
85+
}
86+
87+
throw std::runtime_error{"osm2pgsql.{} must be a function"_format(name)};
88+
}
89+
7190
static void push_osm_object_to_lua_stack(lua_State *lua_state,
7291
osmium::OSMObject const &object,
7392
bool with_attributes)
@@ -988,14 +1007,12 @@ void output_flex_t::add_row(table_connection_t *table_connection,
9881007
}
9891008
}
9901009

991-
void output_flex_t::call_process_function(int index,
992-
osmium::OSMObject const &object)
1010+
void output_flex_t::call_lua_function(prepared_lua_function_t func,
1011+
osmium::OSMObject const &object)
9931012
{
9941013
std::lock_guard<std::mutex> guard{lua_mutex};
9951014

996-
assert(lua_gettop(lua_state()) == 3);
997-
998-
lua_pushvalue(lua_state(), index); // the function to call
1015+
lua_pushvalue(lua_state(), func.index()); // the function to call
9991016
push_osm_object_to_lua_stack(
10001017
lua_state(), object,
10011018
get_options()->extra_attributes); // the single argument
@@ -1009,7 +1026,7 @@ void output_flex_t::call_process_function(int index,
10091026

10101027
void output_flex_t::pending_way(osmid_t id)
10111028
{
1012-
if (!m_has_process_way) {
1029+
if (!m_process_way) {
10131030
return;
10141031
}
10151032

@@ -1023,15 +1040,15 @@ void output_flex_t::pending_way(osmid_t id)
10231040
auto &way = m_buffer.get<osmium::Way>(0);
10241041

10251042
m_context_way = &way;
1026-
call_process_function(2, way);
1043+
call_lua_function(m_process_way, way);
10271044
m_context_way = nullptr;
10281045
m_num_way_nodes = std::numeric_limits<std::size_t>::max();
10291046
m_buffer.clear();
10301047
}
10311048

10321049
void output_flex_t::pending_relation(osmid_t id)
10331050
{
1034-
if (!m_has_process_relation) {
1051+
if (!m_process_relation) {
10351052
return;
10361053
}
10371054

@@ -1048,7 +1065,7 @@ void output_flex_t::pending_relation(osmid_t id)
10481065
auto const &relation = m_rels_buffer.get<osmium::Relation>(0);
10491066

10501067
m_context_relation = &relation;
1051-
call_process_function(3, relation);
1068+
call_lua_function(m_process_relation, relation);
10521069
m_context_relation = nullptr;
10531070
m_rels_buffer.clear();
10541071
}
@@ -1076,37 +1093,37 @@ void output_flex_t::stop(osmium::thread::Pool *pool)
10761093

10771094
void output_flex_t::node_add(osmium::Node const &node)
10781095
{
1079-
if (!m_has_process_node) {
1096+
if (!m_process_node) {
10801097
return;
10811098
}
10821099

10831100
m_context_node = &node;
1084-
call_process_function(1, node);
1101+
call_lua_function(m_process_node, node);
10851102
m_context_node = nullptr;
10861103
}
10871104

10881105
void output_flex_t::way_add(osmium::Way *way)
10891106
{
10901107
assert(way);
10911108

1092-
if (!m_has_process_way) {
1109+
if (!m_process_way) {
10931110
return;
10941111
}
10951112

10961113
m_context_way = way;
1097-
call_process_function(2, *way);
1114+
call_lua_function(m_process_way, *way);
10981115
m_context_way = nullptr;
10991116
m_num_way_nodes = std::numeric_limits<std::size_t>::max();
11001117
}
11011118

11021119
void output_flex_t::relation_add(osmium::Relation const &relation)
11031120
{
1104-
if (!m_has_process_relation) {
1121+
if (!m_process_relation) {
11051122
return;
11061123
}
11071124

11081125
m_context_relation = &relation;
1109-
call_process_function(3, relation);
1126+
call_lua_function(m_process_relation, relation);
11101127
m_context_relation = nullptr;
11111128
}
11121129

@@ -1195,16 +1212,17 @@ output_flex_t::clone(std::shared_ptr<middle_query_t> const &mid,
11951212
std::shared_ptr<db_copy_thread_t> const &copy_thread) const
11961213
{
11971214
return std::make_shared<output_flex_t>(
1198-
mid, *get_options(), copy_thread, true, m_lua_state, m_has_process_node,
1199-
m_has_process_way, m_has_process_relation, m_tables,
1215+
mid, *get_options(), copy_thread, true, m_lua_state, m_process_node,
1216+
m_process_way, m_process_relation, m_tables,
12001217
m_stage2_ways_tracker, m_stage2_rels_tracker);
12011218
}
12021219

12031220
output_flex_t::output_flex_t(
12041221
std::shared_ptr<middle_query_t> const &mid, options_t const &o,
12051222
std::shared_ptr<db_copy_thread_t> const &copy_thread, bool is_clone,
1206-
std::shared_ptr<lua_State> lua_state, bool has_process_node,
1207-
bool has_process_way, bool has_process_relation,
1223+
std::shared_ptr<lua_State> lua_state, prepared_lua_function_t process_node,
1224+
prepared_lua_function_t process_way,
1225+
prepared_lua_function_t process_relation,
12081226
std::shared_ptr<std::vector<flex_table_t>> tables,
12091227
std::shared_ptr<id_tracker> ways_tracker,
12101228
std::shared_ptr<id_tracker> rels_tracker)
@@ -1215,8 +1233,8 @@ output_flex_t::output_flex_t(
12151233
m_expire(o.expire_tiles_zoom, o.expire_tiles_max_bbox, o.projection),
12161234
m_buffer(32768, osmium::memory::Buffer::auto_grow::yes),
12171235
m_rels_buffer(1024, osmium::memory::Buffer::auto_grow::yes),
1218-
m_has_process_node(has_process_node), m_has_process_way(has_process_way),
1219-
m_has_process_relation(has_process_relation)
1236+
m_process_node(process_node), m_process_way(process_way),
1237+
m_process_relation(process_relation)
12201238
{
12211239
assert(copy_thread);
12221240

@@ -1234,21 +1252,6 @@ output_flex_t::output_flex_t(
12341252
}
12351253
}
12361254

1237-
static bool prepare_process_function(lua_State *lua_state, char const *name)
1238-
{
1239-
lua_getfield(lua_state, 1, name);
1240-
1241-
if (lua_type(lua_state, -1) == LUA_TFUNCTION) {
1242-
return true;
1243-
}
1244-
1245-
if (lua_type(lua_state, -1) == LUA_TNIL) {
1246-
return false;
1247-
}
1248-
1249-
throw std::runtime_error{"osm2pgsql.{} must be a function"_format(name)};
1250-
}
1251-
12521255
void output_flex_t::init_lua(std::string const &filename)
12531256
{
12541257
m_lua_state.reset(luaL_newstate(),
@@ -1320,10 +1323,10 @@ void output_flex_t::init_lua(std::string const &filename)
13201323
// Check whether the process_* functions are available and store them on
13211324
// the Lua stack for fast access later
13221325
lua_getglobal(lua_state(), "osm2pgsql");
1323-
m_has_process_node = prepare_process_function(lua_state(), "process_node");
1324-
m_has_process_way = prepare_process_function(lua_state(), "process_way");
1325-
m_has_process_relation =
1326-
prepare_process_function(lua_state(), "process_relation");
1326+
m_process_node = prepared_lua_function_t{lua_state(), "process_node"};
1327+
m_process_way = prepared_lua_function_t{lua_state(), "process_way"};
1328+
m_process_relation =
1329+
prepared_lua_function_t{lua_state(), "process_relation"};
13271330

13281331
lua_remove(lua_state(), 1); // global "osm2pgsql"
13291332
}

src/output-flex.hpp

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,46 @@ extern "C"
2626
#include <utility>
2727
#include <vector>
2828

29+
/**
30+
* The flex output calls several user-defined Lua functions. They are
31+
* "prepared" by putting the function pointers on the Lua stack. Objects
32+
* of the class prepared_lua_function_t are used to hold the stack position
33+
* of the function which allows them to be called later using a symbolic
34+
* name.
35+
*/
36+
class prepared_lua_function_t
37+
{
38+
public:
39+
prepared_lua_function_t() noexcept = default;
40+
41+
/**
42+
* Get function with the name "osm2pgsql.name" from Lua and put pointer
43+
* to it on the Lua stack.
44+
*/
45+
prepared_lua_function_t(lua_State *lua_state, const char *name);
46+
47+
/// Return the index of the function on the Lua stack.
48+
int index() const noexcept { return m_index; }
49+
50+
/// Is this function defined in the users Lua code?
51+
operator bool() const noexcept { return m_index != 0; }
52+
53+
private:
54+
int m_index = 0;
55+
};
56+
2957
class output_flex_t : public output_t
3058
{
59+
3160
public:
3261
output_flex_t(std::shared_ptr<middle_query_t> const &mid,
3362
options_t const &options,
3463
std::shared_ptr<db_copy_thread_t> const &copy_thread,
3564
bool is_clone = false,
3665
std::shared_ptr<lua_State> lua_state = nullptr,
37-
bool has_process_node = false, bool has_process_way = false,
38-
bool has_process_relation = false,
66+
prepared_lua_function_t process_node = {},
67+
prepared_lua_function_t process_way = {},
68+
prepared_lua_function_t process_relation = {},
3969
std::shared_ptr<std::vector<flex_table_t>> tables =
4070
std::make_shared<std::vector<flex_table_t>>(),
4171
std::shared_ptr<id_tracker> ways_tracker =
@@ -91,7 +121,12 @@ class output_flex_t : public output_t
91121
private:
92122
void init_clone();
93123

94-
void call_process_function(int index, osmium::OSMObject const &object);
124+
/**
125+
* Call a Lua function that was "prepared" earlier with the OSMObject
126+
* as its only parameter.
127+
*/
128+
void call_lua_function(prepared_lua_function_t func,
129+
osmium::OSMObject const &object);
95130

96131
void init_lua(std::string const &filename);
97132

@@ -151,9 +186,9 @@ class output_flex_t : public output_t
151186
std::size_t m_num_way_nodes = std::numeric_limits<std::size_t>::max();
152187

153188
bool m_in_stage2 = false;
154-
bool m_has_process_node = false;
155-
bool m_has_process_way = false;
156-
bool m_has_process_relation = false;
189+
prepared_lua_function_t m_process_node;
190+
prepared_lua_function_t m_process_way;
191+
prepared_lua_function_t m_process_relation;
157192
};
158193

159194
#endif // OSM2PGSQL_OUTPUT_FLEX_HPP

0 commit comments

Comments
 (0)