// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp #include #include // Functions args bool NzLuaImplQueryArg(NzLuaInstance& instance, unsigned int index, NzTypeTag) { return instance.CheckBoolean(index); } double NzLuaImplQueryArg(NzLuaInstance& instance, unsigned int index, NzTypeTag) { return instance.CheckNumber(index); } float NzLuaImplQueryArg(NzLuaInstance& instance, unsigned int index, NzTypeTag) { return static_cast(instance.CheckNumber(index)); } int NzLuaImplQueryArg(NzLuaInstance& instance, unsigned int index, NzTypeTag) { return static_cast(instance.CheckInteger(index)); } std::string NzLuaImplQueryArg(NzLuaInstance& instance, unsigned int index, NzTypeTag) { std::size_t strLength = 0; const char* str = instance.CheckString(index, &strLength); return std::string(str, strLength); } NzString NzLuaImplQueryArg(NzLuaInstance& instance, unsigned int index, NzTypeTag) { std::size_t strLength = 0; const char* str = instance.CheckString(index, &strLength); return NzString(str, strLength); } template T NzLuaImplQueryArg(NzLuaInstance& instance, unsigned int index, NzTypeTag) { return NzLuaImplQueryArg(instance, index, NzTypeTag()); } template std::enable_if_t::value, T> NzLuaImplQueryArg(NzLuaInstance& instance, unsigned int index, NzTypeTag) { return static_cast(NzLuaImplQueryArg(instance, index, NzTypeTag::type>())); } // Function returns int NzLuaImplReplyVal(NzLuaInstance& instance, bool&& val, NzTypeTag) { instance.PushBoolean(val); return 1; } int NzLuaImplReplyVal(NzLuaInstance& instance, double&& val, NzTypeTag) { instance.PushNumber(val); return 1; } int NzLuaImplReplyVal(NzLuaInstance& instance, float&& val, NzTypeTag) { instance.PushNumber(val); return 1; } int NzLuaImplReplyVal(NzLuaInstance& instance, int&& val, NzTypeTag) { instance.PushInteger(val); return 1; } int NzLuaImplReplyVal(NzLuaInstance& instance, std::string&& val, NzTypeTag) { instance.PushString(val.c_str(), val.size()); return 1; } int NzLuaImplReplyVal(NzLuaInstance& instance, NzString&& val, NzTypeTag) { instance.PushString(std::move(val)); return 1; } template int NzLuaImplReplyVal(NzLuaInstance& instance, std::pair&& val, NzTypeTag>) { int retVal = 0; retVal += NzLuaImplReplyVal(instance, std::move(val.first), NzTypeTag()); retVal += NzLuaImplReplyVal(instance, std::move(val.second), NzTypeTag()); return retVal; } template std::enable_if_t::value, int> NzLuaImplReplyVal(NzLuaInstance& instance, T&& val, NzTypeTag) { using SignedT = typename std::make_signed::type; return NzLuaImplReplyVal(instance, val, NzTypeTag()); } template class NzLuaImplFunctionProxy { public: NzLuaImplFunctionProxy(NzLuaInstance& instance) : m_instance(instance) { } template void ProcessArgs() { std::get(m_args) = std::move(NzLuaImplQueryArg(m_instance, N+1, NzTypeTag())); } template void ProcessArgs() { ProcessArgs(); ProcessArgs(); } void ProcessArgs() { ProcessArgs<0, Args...>(); } int Invoke(void (*func)(Args...)) { NzApply(func, m_args); return 0; } template int Invoke(Ret (*func)(Args...)) { return NzLuaImplReplyVal(m_instance, std::move(NzApply(func, m_args)), NzTypeTag()); } private: NzLuaInstance& m_instance; std::tuple m_args; }; template void NzLuaInstance::PushFunction(R(*func)(Args...)) { PushFunction([func](NzLuaInstance& instance) -> int { NzLuaImplFunctionProxy handler(instance); handler.ProcessArgs(); return handler.Invoke(func); }); }