#ifndef SCRIPTARGUMENTS_H #define SCRIPTARGUMENTS_H #include #include #include #include "scripting/interface/ScriptObject.h" class IScriptFunction; namespace detail { template inline void invalidateBinding(T val) { } template inline void invalidateBinding(IScriptObject* val) { // Decrease reference for wrapped objects val->decreaseReference(); } template inline void validateBinding(T val) { } template inline void validateBinding(IScriptObject* val) { // Increase reference for wrapped objects val->increaseReference(); } }; // namespace detail class IScriptArguments { public: IScriptArguments() = default; virtual ~IScriptArguments() = default; virtual bool invoke(IScriptFunction* func, bool catchExceptions = false) = 0; }; template class ScriptArguments : public IScriptArguments { public: template ScriptArguments(Args&&... An) : IScriptArguments(), m_resolved(false), m_tuple(std::forward(An)...) { validateArgs(std::index_sequence_for{}); } virtual ~ScriptArguments() { if (!m_resolved) { invalidateArgs(std::index_sequence_for{}); } } virtual bool invoke(IScriptFunction* func, bool catchExceptions = false) = 0; inline size_t count() const { return m_argc; } inline const std::tuple& args() const { return m_tuple; } protected: static constexpr int m_argc = (sizeof...(Ts)); bool m_resolved; std::tuple m_tuple; private: template inline void invalidateArgs(std::index_sequence) { if constexpr (sizeof...(Is) > 0) { int unused[] = { ((detail::invalidateBinding(std::get(m_tuple))), void(), 0)... }; static_cast(unused); // Avoid warning for unused variable } } template inline void validateArgs(std::index_sequence) { if constexpr (sizeof...(Is) > 0) { int unused[] = { ((detail::validateBinding(std::get(m_tuple))), void(), 0)... }; static_cast(unused); // Avoid warning for unused variable } } }; #endif