Skip to content

Commit 5cf798a

Browse files
committed
Refactor functions calling back into Lua code
The flex output calls several user-defined Lua functions. They are "prepared" by putting the function pointers on the Lua stack and later called. This change gets rid of magic numbers and uses more generic names for the functions doing the preparing and calling.
1 parent e42621e commit 5cf798a

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)