Added experimental extension to the signal system

0.8
Bruno Van de Velde 2017-08-29 00:21:29 +02:00
parent 4bd6b662bb
commit 8e87c02919
2 changed files with 328 additions and 43 deletions

View File

@ -32,9 +32,11 @@
#include <SFML/System/String.hpp>
#include <SFML/System/Vector2.hpp>
#include <functional>
#include <typeindex>
#include <cstddef>
#include <memory>
#include <vector>
#include <deque>
#include <map>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -43,6 +45,33 @@ namespace tgui
{
class Widget;
class ChildWindow;
class SignalWidgetBase;
namespace internal_signal
{
extern std::deque<const void*> parameters;
// The dereference function turns the void* elements in the parameters list back into its original type right before calling the signal handler
#ifdef TGUI_ENABLE_SIGNAL_EXTENSION
template <typename Type>
auto dereference(const void* obj)
{
if constexpr (std::is_same_v<Type, std::string>)
{
// Signal handlers are allowed to have std::string parameters while the signal sends sf::String
return static_cast<std::string>(*static_cast<const sf::String*>(obj));
}
else
return *static_cast<const Type*>(obj);
}
#else
template <typename Type>
const Type& dereference(const void* obj)
{
return *static_cast<const Type*>(obj);
}
#endif
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -65,8 +94,8 @@ namespace tgui
Signal(std::string&& name, std::size_t extraParameters = 0) :
m_name{std::move(name)}
{
if (1 + extraParameters > m_parameters.size())
m_parameters.resize(1 + extraParameters);
if (1 + extraParameters > internal_signal::parameters.size())
internal_signal::parameters.resize(1 + extraParameters);
}
@ -142,7 +171,7 @@ namespace tgui
if (m_handlers.empty())
return false;
m_parameters[0] = static_cast<const void*>(&widget);
internal_signal::parameters[0] = static_cast<const void*>(&widget);
for (auto& handler : m_handlers)
handler.second();
@ -162,6 +191,14 @@ namespace tgui
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/// @brief Checks whether the unbound parameters match with this signal
/// @return The index in the parameters list where the parameters will be stored
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual unsigned int validateTypes(std::initializer_list<std::type_index> unboundParameters);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
protected:
@ -177,15 +214,12 @@ namespace tgui
std::string m_name;
std::map<unsigned int, std::function<void()>> m_handlers;
static std::vector<const void*> m_parameters;
};
#define TGUI_SIGNAL_VALUE_DECLARATION(TypeName, Type) \
/**************************************************************************************************************************** \
* @brief Signal to which the user can subscribe to get callbacks from
*
****************************************************************************************************************************/ \
class TGUI_API Signal##TypeName : public Signal \
{ \
@ -196,7 +230,6 @@ namespace tgui
\
/************************************************************************************************************************ \
* @brief Constructor
*
************************************************************************************************************************/ \
Signal##TypeName(std::string&& name) : \
Signal{std::move(name), 1} \
@ -209,7 +242,6 @@ namespace tgui
* @param handler Callback function that is given a Vector2f as argument
*
* @return Unique id of the connection
*
************************************************************************************************************************/ \
unsigned int connect(const Delegate##TypeName& handler); \
\
@ -219,23 +251,28 @@ namespace tgui
* @param handler Callback function that is given a pointer to the widget, the name of the signal and a Vector2f as arguments
*
* @return Unique id of the connection
*
************************************************************************************************************************/ \
unsigned int connect(const Delegate##TypeName##Ex& handler); \
\
/************************************************************************************************************************ \
* @internal
* @brief Call all connected signal handlers
*
************************************************************************************************************************/ \
bool emit(const Widget* widget, Type strParam) \
{ \
if (m_handlers.empty()) \
return false; \
\
m_parameters[1] = static_cast<const void*>(&strParam); \
internal_signal::parameters[1] = static_cast<const void*>(&strParam); \
return Signal::emit(widget); \
} \
\
/************************************************************************************************************************ \
* @internal
* @brief Checks whether the unbound parameters match with this signal
* @return The index in the parameters list where the parameters will be stored
************************************************************************************************************************/ \
unsigned int validateTypes(std::initializer_list<std::type_index> unboundParameters) override; \
};
@ -296,6 +333,14 @@ namespace tgui
bool emit(const Widget* widget, int value1, int value2);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/// @brief Checks whether the unbound parameters match with this signal
/// @return The index in the parameters list where the parameters will be stored
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int validateTypes(std::initializer_list<std::type_index> unboundParameters) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
};
@ -349,6 +394,14 @@ namespace tgui
bool emit(const ChildWindow* param);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/// @brief Checks whether the unbound parameters match with this signal
/// @return The index in the parameters list where the parameters will be stored
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int validateTypes(std::initializer_list<std::type_index> unboundParameters) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
};
@ -426,11 +479,20 @@ namespace tgui
if (m_handlers.empty())
return false;
m_parameters[1] = static_cast<const void*>(&item);
m_parameters[2] = static_cast<const void*>(&id);
internal_signal::parameters[1] = static_cast<const void*>(&item);
internal_signal::parameters[2] = static_cast<const void*>(&id);
return Signal::emit(widget);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/// @brief Checks whether the unbound parameters match with this signal
/// @return The index in the parameters list where the parameters will be stored
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int validateTypes(std::initializer_list<std::type_index> unboundParameters) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
};
@ -508,15 +570,77 @@ namespace tgui
if (m_handlers.empty())
return false;
m_parameters[1] = static_cast<const void*>(&item);
m_parameters[2] = static_cast<const void*>(&fullItem);
internal_signal::parameters[1] = static_cast<const void*>(&item);
internal_signal::parameters[2] = static_cast<const void*>(&fullItem);
return Signal::emit(widget);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/// @brief Checks whether the unbound parameters match with this signal
/// @return The index in the parameters list where the parameters will be stored
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int validateTypes(std::initializer_list<std::type_index> unboundParameters) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
};
#ifdef TGUI_ENABLE_SIGNAL_EXTENSION
namespace internal_signals
{
// Type to pass a list of template types
template <typename...>
struct TypeSet;
// Used for static_assert errors inside template functions
template <typename...>
struct always_false : std::false_type {};
// If the argument is a bind expression then call the bound function and pass the return value, otherwise just pass the argument
template <typename Arg>
auto unbind(Arg&& arg)
{
if constexpr (std::is_bind_expression_v<Arg>)
return arg();
else
return std::forward<Arg>(arg);
}
// The binder will figure out the unbound parameters and bind them if they correspond to what the signal sends
template <typename... Args>
struct binder;
template <typename Arg, typename... AllArgs, typename BoundArg, typename... BoundArgs>
struct binder<TypeSet<Arg, AllArgs...>, TypeSet<BoundArg, BoundArgs...>>
: binder<TypeSet<AllArgs...>, TypeSet<BoundArgs...>>
{
};
template <typename... UnboundArgs>
struct binder<TypeSet<UnboundArgs...>, TypeSet<>>
{
template <typename... Args, typename... BoundArgs>
static auto bind(Signal& signal, std::function<void(Args...)>&& handler, BoundArgs&&... args)
{
return bindImpl(std::index_sequence_for<UnboundArgs...>{}, signal, std::forward<std::function<void(Args...)>>(handler), std::forward<BoundArgs>(args)...);
}
private:
template <typename... Args, typename... BoundArgs, std::size_t... Indices>
static auto bindImpl(std::index_sequence<Indices...>, Signal& signal, std::function<void(Args...)>&& handler, BoundArgs&&... args)
{
const std::size_t offset = signal.validateTypes({typeid(UnboundArgs)...});
return [=](){ std::invoke(handler, unbind(std::forward<BoundArgs>(args))..., internal_signal::dereference<UnboundArgs>(internal_signal::parameters[offset + Indices])...); };
}
};
}
#endif // TGUI_ENABLE_SIGNAL_EXTENSION
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Base class for Widget which provides functionality to connect signals based on their name
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -589,6 +713,60 @@ namespace tgui
}
#ifdef TGUI_ENABLE_SIGNAL_EXTENSION
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Connects a signal handler that will be called when this signal is emitted
///
/// @param signalName Name of the signal
/// @param handler Callback function
/// @param args Optional extra arguments to pass to the signal handler when the signal is emitted
///
/// @return Unique id of the connection
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename Func, typename... BoundArgs, typename std::enable_if_t<!std::is_function_v<decltype(std::function(std::declval<Func>()))>
&& !std::is_convertible_v<Func, std::function<void(const BoundArgs&...)>>
&& !std::is_convertible_v<Func, std::function<void(const BoundArgs&..., std::shared_ptr<Widget>, const std::string&)>>>* = nullptr>
unsigned int connect(std::string signalName, Func&& handler, const BoundArgs&... args)
{
return connectWithUnboundParameters(std::move(signalName), std::function(std::forward<Func>(handler)), args...);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Connects a signal handler that will be called when this signal is emitted
///
/// @param signalName Name of the signal
/// @param handler Callback function
/// @param args Optional extra arguments to pass to the signal handler when the signal is emitted
///
/// @return Unique id of the connection
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename Class, typename... Args, typename... BoundArgs, typename std::enable_if_t<!std::is_convertible_v<void(Class::*)(Args...), std::function<void(const BoundArgs&...)>>
&& !std::is_convertible_v<void(Class::*)(Args...), std::function<void(const BoundArgs&..., std::shared_ptr<Widget>, const std::string&)>>>* = nullptr>
unsigned int connect(std::string signalName, void(Class::*handler)(Args...), const BoundArgs&... args)
{
return connectWithUnboundParameters(std::move(signalName), std::function<void(Class*, Args...)>(handler), args...);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Connects a signal handler that will be called when this signal is emitted
///
/// @param signalName Name of the signal
/// @param handler Callback function
/// @param args Optional extra arguments to pass to the signal handler when the signal is emitted
///
/// @return Unique id of the connection
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename Class, typename... Args, typename... BoundArgs, typename std::enable_if_t<!std::is_convertible_v<void(Class::*)(Args...) const, std::function<void(const BoundArgs&...)>>
&& !std::is_convertible_v<void(Class::*)(Args...) const, std::function<void(const BoundArgs&..., std::shared_ptr<Widget>, const std::string&)>>>* = nullptr>
unsigned int connect(std::string signalName, void(Class::*handler)(Args...) const, const BoundArgs&... args)
{
return connectWithUnboundParameters(std::move(signalName), std::function<void(const Class*, Args...)>(handler), args...);
}
#endif // TGUI_ENABLE_SIGNAL_EXTENSION
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Connect a signal handler to multiple signals
///
@ -602,8 +780,8 @@ namespace tgui
unsigned int connect(std::initializer_list<std::string> signalNames, Func&& handler, const Args&... args)
{
unsigned int lastId = 0;
for (const auto& signalName : signalNames)
lastId = connect(signalName, handler, args...);
for (auto& signalName : signalNames)
lastId = connect(std::move(signalName), handler, args...);
return lastId;
}
@ -641,6 +819,23 @@ namespace tgui
/// @brief Retrieves a signal based on its name
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual Signal& getSignal(std::string&& signalName) = 0;
#ifdef TGUI_ENABLE_SIGNAL_EXTENSION
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private:
template <typename... Args, typename... BoundArgs>
unsigned int connectWithUnboundParameters(std::string&& signalName, std::function<void(Args...)>&& func, BoundArgs&&... args)
{
if constexpr (sizeof...(Args) < sizeof...(BoundArgs))
static_assert(internal_signals::always_false<Args..., BoundArgs...>::value, "TGUI Error: Too many parameters passed to connect, signal handler does not have so many parameters!");
else
{
Signal& signal = getSignal(toLower(std::move(signalName)));
return signal.connect(internal_signals::binder<internal_signals::TypeSet<Args...>, internal_signals::TypeSet<BoundArgs...>>::bind(signal, std::forward<std::function<void(Args...)>>(func), std::forward<BoundArgs>(args)...));
}
}
#endif // TGUI_ENABLE_SIGNAL_EXTENSION
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -39,19 +39,16 @@ namespace
{
return ++lastId;
}
template <typename Type>
const Type& dereference(const void* obj)
{
return *static_cast<const Type*>(obj);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace tgui
{
std::vector<const void*> Signal::m_parameters(3, nullptr);
namespace internal_signal
{
std::deque<const void*> parameters;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -110,7 +107,17 @@ namespace tgui
tgui::Widget::Ptr Signal::getWidget()
{
return dereference<Widget*>(m_parameters[0])->shared_from_this();
return internal_signal::dereference<Widget*>(internal_signal::parameters[0])->shared_from_this();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int Signal::validateTypes(std::initializer_list<std::type_index> unboundParameters)
{
if (unboundParameters.size() == 0)
return 0;
else
throw Exception{"Signal '" + m_name + "' could not provide data for unbound parameters."};
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -119,30 +126,65 @@ namespace tgui
unsigned int Signal##TypeName::connect(const Delegate##TypeName& handler) \
{ \
const auto id = generateUniqueId(); \
m_handlers[id] = [handler](){ handler(dereference<Type>(m_parameters[1])); }; \
m_handlers[id] = [handler](){ handler(internal_signal::dereference<Type>(internal_signal::parameters[1])); }; \
return id; \
} \
\
unsigned int Signal##TypeName::connect(const Delegate##TypeName##Ex& handler) \
{ \
const auto id = generateUniqueId(); \
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, dereference<Type>(m_parameters[1])); }; \
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, internal_signal::dereference<Type>(internal_signal::parameters[1])); }; \
return id; \
} \
\
unsigned int Signal##TypeName::validateTypes(std::initializer_list<std::type_index> unboundParameters) \
{ \
if ((unboundParameters.size() == 1) && (*unboundParameters.begin() == typeid(Type))) \
return 1; \
else \
return Signal::validateTypes(unboundParameters); \
}
TGUI_SIGNAL_VALUE_CONNECT_DEFINITION(Int, int)
TGUI_SIGNAL_VALUE_CONNECT_DEFINITION(UInt, unsigned int)
TGUI_SIGNAL_VALUE_CONNECT_DEFINITION(Bool, bool)
TGUI_SIGNAL_VALUE_CONNECT_DEFINITION(Float, float)
TGUI_SIGNAL_VALUE_CONNECT_DEFINITION(String, sf::String)
TGUI_SIGNAL_VALUE_CONNECT_DEFINITION(Vector2f, sf::Vector2f)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int SignalString::connect(const DelegateString& handler)
{
const auto id = generateUniqueId();
m_handlers[id] = [handler](){ handler(internal_signal::dereference<sf::String>(internal_signal::parameters[1])); };
return id;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int SignalString::connect(const DelegateStringEx& handler)
{
const auto id = generateUniqueId();
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, internal_signal::dereference<sf::String>(internal_signal::parameters[1])); };
return id;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int SignalString::validateTypes(std::initializer_list<std::type_index> unboundParameters)
{
if ((unboundParameters.size() == 1) && ((*unboundParameters.begin() == typeid(std::string)) || (*unboundParameters.begin() == typeid(sf::String))))
return 1;
else
return Signal::validateTypes(unboundParameters);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int SignalRange::connect(const DelegateRange& handler)
{
const auto id = generateUniqueId();
m_handlers[id] = [handler](){ handler(dereference<int>(m_parameters[1]), dereference<int>(m_parameters[2])); };
m_handlers[id] = [handler](){ handler(internal_signal::dereference<int>(internal_signal::parameters[1]), internal_signal::dereference<int>(internal_signal::parameters[2])); };
return id;
}
@ -151,7 +193,7 @@ namespace tgui
unsigned int SignalRange::connect(const DelegateRangeEx& handler)
{
const auto id = generateUniqueId();
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, dereference<int>(m_parameters[1]), dereference<int>(m_parameters[2])); };
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, internal_signal::dereference<int>(internal_signal::parameters[1]), internal_signal::dereference<int>(internal_signal::parameters[2])); };
return id;
}
@ -162,17 +204,27 @@ namespace tgui
if (m_handlers.empty())
return false;
m_parameters[1] = static_cast<const void*>(&start);
m_parameters[2] = static_cast<const void*>(&end);
internal_signal::parameters[1] = static_cast<const void*>(&start);
internal_signal::parameters[2] = static_cast<const void*>(&end);
return Signal::emit(widget);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int SignalRange::validateTypes(std::initializer_list<std::type_index> unboundParameters)
{
if ((unboundParameters.size() == 2) && (*unboundParameters.begin() == typeid(int)) && (*(unboundParameters.begin()+1) == typeid(int)))
return 1;
else
return Signal::validateTypes(unboundParameters);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int SignalChildWindow::connect(const DelegateChildWindow& handler)
{
const auto id = generateUniqueId();
m_handlers[id] = [handler](){ handler(std::static_pointer_cast<ChildWindow>(dereference<ChildWindow*>(m_parameters[1])->shared_from_this())); };
m_handlers[id] = [handler](){ handler(std::static_pointer_cast<ChildWindow>(internal_signal::dereference<ChildWindow*>(internal_signal::parameters[1])->shared_from_this())); };
return id;
}
@ -181,7 +233,7 @@ namespace tgui
unsigned int SignalChildWindow::connect(const DelegateChildWindowEx& handler)
{
const auto id = generateUniqueId();
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, std::static_pointer_cast<ChildWindow>(dereference<ChildWindow*>(m_parameters[1])->shared_from_this())); };
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, std::static_pointer_cast<ChildWindow>(internal_signal::dereference<ChildWindow*>(internal_signal::parameters[1])->shared_from_this())); };
return id;
}
@ -192,16 +244,26 @@ namespace tgui
if (m_handlers.empty())
return false;
m_parameters[1] = static_cast<const void*>(&childWindow);
internal_signal::parameters[1] = static_cast<const void*>(&childWindow);
return Signal::emit(childWindow);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int SignalChildWindow::validateTypes(std::initializer_list<std::type_index> unboundParameters)
{
if ((unboundParameters.size() == 1) && (*unboundParameters.begin() == typeid(ChildWindow*)))
return 1;
else
return Signal::validateTypes(unboundParameters);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int SignalItem::connect(const DelegateItem& handler)
{
const auto id = generateUniqueId();
m_handlers[id] = [handler](){ handler(dereference<sf::String>(m_parameters[1])); };
m_handlers[id] = [handler](){ handler(internal_signal::dereference<sf::String>(internal_signal::parameters[1])); };
return id;
}
@ -210,7 +272,7 @@ namespace tgui
unsigned int SignalItem::connect(const DelegateItemEx& handler)
{
const auto id = generateUniqueId();
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, dereference<sf::String>(m_parameters[1])); };
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, internal_signal::dereference<sf::String>(internal_signal::parameters[1])); };
return id;
}
@ -219,7 +281,7 @@ namespace tgui
unsigned int SignalItem::connect(const DelegateItemAndId& handler)
{
const auto id = generateUniqueId();
m_handlers[id] = [handler](){ handler(dereference<sf::String>(m_parameters[1]), dereference<sf::String>(m_parameters[2])); };
m_handlers[id] = [handler](){ handler(internal_signal::dereference<sf::String>(internal_signal::parameters[1]), internal_signal::dereference<sf::String>(internal_signal::parameters[2])); };
return id;
}
@ -228,16 +290,32 @@ namespace tgui
unsigned int SignalItem::connect(const DelegateItemAndIdEx& handler)
{
const auto id = generateUniqueId();
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, dereference<sf::String>(m_parameters[1]), dereference<sf::String>(m_parameters[2])); };
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, internal_signal::dereference<sf::String>(internal_signal::parameters[1]), internal_signal::dereference<sf::String>(internal_signal::parameters[2])); };
return id;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int SignalItem::validateTypes(std::initializer_list<std::type_index> unboundParameters)
{
if ((unboundParameters.size() == 1) && ((*unboundParameters.begin() == typeid(std::string)) || (*unboundParameters.begin() == typeid(sf::String))))
return 1;
else if ((unboundParameters.size() == 2)
&& ((*unboundParameters.begin() == typeid(std::string)) || (*unboundParameters.begin() == typeid(sf::String)))
&& ((*(unboundParameters.begin()+1) == typeid(std::string)) || (*(unboundParameters.begin()+1) == typeid(sf::String))))
{
return 1;
}
else
return Signal::validateTypes(unboundParameters);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int SignalMenuItem::connect(const DelegateMenuItem& handler)
{
const auto id = generateUniqueId();
m_handlers[id] = [handler](){ handler(dereference<sf::String>(m_parameters[1])); };
m_handlers[id] = [handler](){ handler(internal_signal::dereference<sf::String>(internal_signal::parameters[1])); };
return id;
}
@ -246,7 +324,7 @@ namespace tgui
unsigned int SignalMenuItem::connect(const DelegateMenuItemEx& handler)
{
const auto id = generateUniqueId();
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, dereference<sf::String>(m_parameters[1])); };
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, internal_signal::dereference<sf::String>(internal_signal::parameters[1])); };
return id;
}
@ -255,7 +333,7 @@ namespace tgui
unsigned int SignalMenuItem::connect(const DelegateMenuItemFull& handler)
{
const auto id = generateUniqueId();
m_handlers[id] = [handler](){ handler(dereference<std::vector<sf::String>>(m_parameters[2])); };
m_handlers[id] = [handler](){ handler(internal_signal::dereference<std::vector<sf::String>>(internal_signal::parameters[2])); };
return id;
}
@ -264,11 +342,23 @@ namespace tgui
unsigned int SignalMenuItem::connect(const DelegateMenuItemFullEx& handler)
{
const auto id = generateUniqueId();
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, dereference<std::vector<sf::String>>(m_parameters[2])); };
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, internal_signal::dereference<std::vector<sf::String>>(internal_signal::parameters[2])); };
return id;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int SignalMenuItem::validateTypes(std::initializer_list<std::type_index> unboundParameters)
{
if ((unboundParameters.size() == 1) && ((*unboundParameters.begin() == typeid(std::string)) || (*unboundParameters.begin() == typeid(sf::String))))
return 1;
else if ((unboundParameters.size() == 1) && (*unboundParameters.begin() == typeid(std::vector<sf::String>)))
return 2;
else
return Signal::validateTypes(unboundParameters);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////