Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions library/LuaApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1320,11 +1320,21 @@ static void OpenModule(lua_State *state, const char *mname, const luaL_Reg *reg2
lua_pop(state, 1);
}

#define WRAPM(module, function) { #function, df::wrap_function(module::function,true) }
#define WRAP(function) { #function, df::wrap_function(function,true) }
#define WRAPN(name, function) { #name, df::wrap_function(function,true) }
#define WRAPM(module, function) { #function, df::wrap_function(module::function, #function, true) }
#define WRAP(function) { #function, df::wrap_function(function, #function, true) }
#define WRAPN(name, function) { #name, df::wrap_function(function, #function, true) }
#define CWRAP(name, function) { #name, &Lua::CallWithCatchWrapper<function> }

// The _D variants are used to indicate that a wrapped function is deprecated.
// Deprecated functions will still function but will emit a warning to the DFHack console.
// This warning is displayed only once for each distinct appearance in a script (by script path and line number).
// The additional "message" argument is displayed with the warning; it is recommended that this message
// indicate the recommended replacement or substitution. The message must not be empty.

#define WRAPM_D(module, function, message) { #function, df::wrap_function(module::function, #function, true, message) }
#define WRAP_D(function, message) { #function, df::wrap_function(function, #function, true, message) }
#define WRAPN_D(name, function, message) { #name, df::wrap_function(function, #function, true, message) }

/***** DFHack module *****/

static string getOSType()
Expand Down
52 changes: 52 additions & 0 deletions library/LuaWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ distribution.
// must be last due to MS stupidity
#include "DataDefs.h"
#include "DataIdentity.h"
#include "Debug.h"
#include "HashUtil.h"
#include "LuaWrapper.h"
#include "LuaTools.h"

Expand All @@ -46,6 +48,11 @@ distribution.
using namespace DFHack;
using namespace DFHack::LuaWrapper;

namespace DFHack
{
DBG_DECLARE(lua, deprecation, DebugCategory::LWARNING);
}

/**
* Report an error while accessing a field (index = field name).
*/
Expand Down Expand Up @@ -1869,6 +1876,51 @@ void LuaWrapper::AttachDFGlobals(lua_State *state)
lua_pop(state, 1);
}

namespace
{
struct deprecation_notification
{
std::string name;
std::string source;
int line;

bool operator==(const deprecation_notification& other) const = default;

struct hash
{
std::size_t operator()(const deprecation_notification& n) const noexcept
{
return hash_value(n.name, n.source, n.line);
}
};
};

static std::unordered_set<deprecation_notification, deprecation_notification::hash> deprecation_notification_history;
}

void LuaWrapper::notify_deprecated(lua_State* state, std::string_view name, std::string_view message)
{
lua_Debug ar;
std::optional<deprecation_notification> notify;

for (int depth = 0; lua_getstack(state, depth, &ar); depth++)
{
if (lua_getinfo(state, "nSl", &ar) && std::strcmp(ar.what, "Lua") == 0)
{
notify = deprecation_notification{std::string(name),ar.short_src,ar.currentline};
break;
}
}

if (!notify) return;

if (!deprecation_notification_history.contains(*notify))
{
WARN(deprecation).print("Deprecated function {} called from {} at line {}: {}\n", notify->name, notify->source, notify->line, message);
deprecation_notification_history.insert(*notify);
}
}

namespace DFHack { namespace LuaWrapper {
struct LuaToken { int reserved; };

Expand Down
22 changes: 17 additions & 5 deletions library/include/DataFuncs.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,21 +174,33 @@ namespace df {
template<typename T>
class function_identity : public function_identity_base {
T ptr;
const std::string name;
const bool depr;
const std::string depr_message;

public:
using wrapper = function_wrapper<T>;

function_identity(T ptr, bool vararg)
: function_identity_base(wrapper::num_args, vararg), ptr(ptr) {};
function_identity(T ptr, std::string_view name, bool vararg, std::string_view depr = {})
: function_identity_base(wrapper::num_args, vararg), ptr(ptr), name(name), depr(!depr.empty()), depr_message(depr)
{};

virtual void invoke(lua_State *state, int base) const { wrapper::execute(state, base, ptr); }
virtual void invoke(lua_State *state, int base) const
{
if (depr)
{
DFHack::LuaWrapper::notify_deprecated(state, name, depr_message);
}
wrapper::execute(state, base, ptr);
}
};

template<typename T>
inline function_identity_base *wrap_function(T ptr, bool vararg = false) {
inline function_identity_base* wrap_function(T ptr, std::string_view name = {}, bool vararg = false, std::string_view depr = {})
{
using RT = return_type<T>::type;
if constexpr (isPrimitive<RT>)
return new function_identity<T>(ptr, vararg);
return new function_identity<T>(ptr, name, vararg, depr);
else
return nullptr;
}}
2 changes: 2 additions & 0 deletions library/include/LuaWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,4 +237,6 @@ namespace LuaWrapper {
void IndexStatics(lua_State *state, int meta_idx, int ftable_idx, struct_identity *pstruct);

void AttachDFGlobals(lua_State *state);

DFHACK_EXPORT void notify_deprecated(lua_State* state, std::string_view name, std::string_view message);
}}
2 changes: 1 addition & 1 deletion library/include/PluginLua.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
DFhackCExport const DFHack::EventReg plugin_lua_events[] =

#define DFHACK_LUA_COMMAND(name) { #name, name }
#define DFHACK_LUA_FUNCTION(name) { #name, df::wrap_function(name,true) }
#define DFHACK_LUA_FUNCTION(name) { #name, df::wrap_function(name,#name,true) }
#define DFHACK_LUA_EVENT(name) { #name, &name##_event }
#define DFHACK_LUA_END { NULL, NULL }
Loading