Hello,
is it possibly to write a templated class whos template decides which member variable of the class to being used? My problem is as follows: I have a gui with slots of signals, which is just a templated class. There are signals like for release, click, hover, etc... These are all generic for that special case, e.g. the release signal returns not values to the caller function. However, often I would like to hand over additional data, e.g. the number of the button that has just been pressed from a specific key-bar in game. I don't want to make this part of the gui widgets themselfs, so I wrote a wrapper-class:
template<typename Data, typename WidgetType=Widget>
class DataContainer
{
public:
DataContainer(void) : m_data(Data()), m_pWidget(nullptr)
{
}
DataContainer(WidgetType& widget, Data data) : m_data(data), m_pWidget(&widget)
{
widget.SigReleased.Connect(this, &DataContainer::OnAccessData);
}
DataContainer(const DataContainer<Data, WidgetType>& container): m_data(container.m_data), m_pWidget(container.m_pWidget),
SigAccess(container.SigAccess)
{
m_pWidget->SigReleased.Connect(this, &DataContainer::OnAccessData);
}
DataContainer(DataContainer<Data, WidgetType>&& container) : m_data(container.m_data), m_pWidget(container.m_pWidget),
SigAccess(std::move(container.SigAccess))
{
m_pWidget->SigReleased.Disconnect(&container, &DataContainer::OnAccessData);
m_pWidget->SigReleased.Connect(this, &DataContainer::OnAccessData);
container.m_pWidget = nullptr;
}
~DataContainer(void)
{
if(m_pWidget)
m_pWidget->SigReleased.Disconnect(this, &DataContainer::OnAccessData);
}
void SetWidget(WidgetType* pWidget)
{
if(m_pWidget && pWidget != m_pWidget)
m_pWidget->SigReleased.Disconnect(this, &DataContainer::OnAccessData);
if(pWidget)
pWidget->SigReleased.Connect(this, &DataContainer::OnAccessData);
m_pWidget = pWidget;
}
WidgetType* GetWidget(void) const
{
return m_pWidget;
}
WidgetType* operator->(void) const
{
return m_pWidget;
}
DataContainer<Data>& operator=(const DataContainer<Data> container)
{
m_data = container.m_data;
m_pWidget = container.m_pWidget;
SigAccess = container.SigAccess;
m_pWidget->SigReleased.Connect(this, &DataContainer::OnAccessData);
}
void OnAccessData(void)
{
SigAccess(m_data);
}
core::Signal<Data> SigAccess;
private:
Data m_data;
WidgetType* m_pWidget;
};
This allows me to instead hook the SigAccess, which will return some user-defined data. The problem is, that this class only works for the SigRelease, and I would have to rewrite it for every other signal that there possibly is.
To come back to my question, is there any possiblity to solve this using templates? I want to be able to do e.g.
gui::DataContainer<SigClicked, UserData, Window> container(*pWindow); // SigClicked => name of the signal to being clicked in the widget class, always a spezialization of "core::Signal<Args...>"