c++ 11 lambda usage as delegate with std::function - c++

I have a Button class which have an onClick std::function typed field and "setClickListener" method sets any lambda function to this std::function field as follows :
#include <functional>
class Button {
public:
void doSomething() {
if(onClick) {
onClick();
}
}
typedef std::function<void()> OnClickListener;
OnClickListener onClick;
void setClickListener(OnClickListener onClickCallBack) {
onClick = onClickCallBack;
}
};
In my application code, I am creating a lambda function and setting to onClick function of button as seen below :
#include "Button.h"
void onAnEventOccured() {
button->setClickListener([this]()->void {
// Do something
memberFunction();
anotherMemberFunction();
// etc...
});
}
void memberFunction() {
// Do some work...
}
void anotherMemberFunction() {
// Do some work...
}
Now, the critical section is that onAnEventOccured method called many times during the application's life cycle and the lambda function is set again and again. I am runnning on Visual Studio 2015 and putting debug trace point on the deconstructor of std::function class and can see it hits to tracepoint while setting setClickListener. I guess this is the deconstructor of lambda function which has been destroyed while leaving the scope of onAnEventOccured function and copy version of this lambda stored in Button instance as expected.
Am I correct on this? Is there any memory leak on this architecture?

Can't you call:
button->setClickListener([this]()->void {
// Do something
memberFunction();
anotherMemberFunction();
// etc...
});
in the constructor or during any other initialization method that you have on your Application code?
Also, your code could get an rvalue reference.
void setClickListener(OnClickListener&& callback);

Related

Is it possible to create a thread that calls a function from a different class?

I am working on a C++11 multithreated GUI program.
So I have the DevTools and MainWindow classes. I want to call a function that belongs to DevTools from a MainWindow clicked() event function. (All object definitions are created on the classes' definitions).
Function on MainWindow calls Obtain_XY_Thread:
void MainWindow::on_obtain_xy_clicked()
{
DevTools.Obtain_XY_Thread();
}
So DevTools::Obtain_XY_Thread() is called and it creates a thread of Obtain_XY but what I really want is directly call Obtain_XY:
void DevTools::Obtain_XY_Thread()
{
thread obtain_xy(&DevTools::Obtain_XY, *this);
obtain_xy.detach();
}
void DevTools::Obtain_XY()
{
for(int i=0;i<500;i++){
//does something
}
}
This works, but I don't think it's the correct approach. Is there any way to call Obtain_XY without having to create another function? How could I create the thread on MainWindow::on_obtain_xy_clicked() directly?
This was simply fixed by adding std::thread:
void MainWindow::on_obtain_xy_clicked()
{
std::thread obtain_xy(&DevTools::Obtain_XY, &DevTools);
obtain_xy.detach();
}

Pass argument to function taking parent class argument without casting argument to parent class

I am building a Boost state machine. My state has a pointer to its own backend (fsm) to process events. All events of my state machine are children of an MySatetMachineEvent class (with an example child like EventChild). State transitions are only defined for children like EventChild of MySTateMachineEvent.
To clean up my code I want to create a function processEvent(MySatetMachineEvent event) taking all possible events. This class should then call the process_event() function with the passed event.
For example:
processEvent(MyStateMachineEvent event)
{
fsm.process_event(event);
}
processEvent(EventCild());
should case a call of
fsm.process_event(EventChild());
Creating such a function causes the error that fsm.process_event() is called with an instance of MyStateMachineEvent. As written above there are no state transitions defined for this case.
This hinders my state machine from working in a proper manner, obviously.
So my question is if there is a way to pass any EventChild or other child of MyStateMachineEvent to my processEvent(MySTateMachineEvent event) function without casting the passed Object to MyStateMachineEvent.
I am aware of the solution to overlode my function like
processEvent(EventChild event) {
fsm.process_event(event);
}
This would cause may functions (with the exact same line of code inside) in my case, thus i am looking for a cleaner and more fancy solution.
You can use a function template:
template <typename Event>
void processEvent(Event event)
{
fsm.process_event(event);
}
Every instantiation will preserve the exact type of the event argument that was passed in.
Albeit I like Vittorio Romeo's template approach, it might not be suitable if you e. g. have some kind of event queue holding arbitrary events. A polymorphic approach could be more suitable then:
class MyStateMachineEvent
{
public:
virtual ~MyStateMachineEvent() { }
virtual void doOrGetSomething() = 0;
};
class EventChild : public MyStateMachineEvent
{
public:
void doOrGetSomething() override;
};
Now your processEvent function might accept a reference, just as would the fsm's variant as well:
void processEvent(MyStateMachineEvent& event)
{
fsm.processEvent(event);
}
void FSM::processEvent(MyStateMachineEvent& event)
{
// ...
event.doOrGetSomething();
// ...
}
And usage might look like this:
std::queue<std::unique_ptr<MyStateMachineEvent>> events;
events.emplace(new EventChild());
processEvent(**events.front());
events.pop();

QtConcurrent: Inform another function that result is ready

I'm new to the C++ and QT world. I need to do some modifications on an existing console application.
I have the following problem: I'm running some functions (which take some time) concurrently and show a wait indicator during this time. The setup looks like this:
QFuture<void> doStuff = QtConcurrent::run(longCalc, param1, param2);
showWaitIndicator(&doStuff);
// ....
void showWaitIndicator(QFuture<void> *future)
{
while (future->isRunning()) {
// Show some nice indicator and so on.
}
}
This setup works just fine, but now I want to run some other tasks concurrently which have another return type and I need to access the result. Instead of QFuture<void>these are mostly QFuture<double>, QFuture<int>, etc: QFuture<double> doStuff = QtConcurrent::run(doubleCalc);
I also want to display my nice wait indicator, but the different return types mean I can't use my current showWaitIndicator() function.
Is there a good way to improve this "setup"? I'm new to C++, so I'm pretty sure there must be a way. My first idea was function overloading but this didn't work because the parameters have the same type (QFuture).
TL;DR: I need to inform my showWaitIndicator() function that QFuture finished.
You can emit a custom signal from the function that runs concurrently, or use a QFutureWatcher as a source of such signal.
E.g. when longCalc is in the same class:
MyClass::MyClass() {
Q_OBJECT
Q_SIGNAL void longCalcDone();
connect(this, &MyClass::longCalcDone, this, [this]{
...
});
}
void MyClass::longCalc(int arg1, int arg2) {
...
emit MyClass::longCalcDone();
}
E.g. when longCalc is a free function or is in another class:
void longCalc(int, int);
MyClass::MyClass() {
Q_OBJECT
Q_SIGNAL void longCalcDone();
connect(this, &MyClass::longCalcDone, this, [this]{
...
});
void doStuff() {
QtConcurrent::run([=]{
longCalc(param1, param2);
emit longCalcDone();
});
}
}
E.g. with a future watcher instead:
class MyClass : public QObject {
QFutureWatcher watcher;
MyClass() {
connect(&watcher, &QFutureWatcher::finished, this, [this]{
...
});
}
void doStuff() {
auto future = QtConcurrent::run(longCalc, this, param1, param2);
watcher.setFuture(&future);
}
};
The while (future->isRunning()) synchronous code is an anti-pattern. Presumably you invoke QCoreApplication::processEvents within that loop. The problem is - the world is not like that, you can't take the locus of control away from the event loop and pretend that the world revolves around you. Instead, invert the control flow and have your code (a slot, a method or a functor) invoked when the future finishes.
See also this question.

Storing Lua callback functions

I have a game I am integrating with Lua scripting in order to allow customization.
I am using a C++ Lua wrapper:
https://github.com/tomaka/luawrapper
In my Lua script I am calling something like this:
function sprite_factory()
local sprite = sprite_new() -- register_new_sprite(name)
sprite:RegisterCallback("on_activate", function ()
sprite:SetState("closed")
end)
end
In my C++ code I have built a Sprite class and I'm using registerFunction to make the member methods available to Lua e.g. RegisterCallback is called on the sprite object returned by sprite_new()
bool RegisterCallback(const std::string hook, const std::function<void()> callback) {
callback();
mCallback = callback;
return true;
}
If I do the callback inside the RegisterCallback method, it works fine. However, I want to store the callback to be used as a raised event.
When I call this method later in my code:
void DoCallback() {
mCallback(); //raises exception
}
I get an exception:
libc++abi.dylib: terminating with uncaught exception of type
std::__1::bad_function_call: std::exception
I am declaring mCallback as a private:
std::function<void()> mCallback = NULL;
I'm not sure what is going on here.
I would suspect that there is an issue with the way mCallback is declared.

C++ Passing a member function as a callback

I am trying to create a very simple event system to be used in a game. I have a EventManager class that looks something like this:
typedef std::function<void(IEvent* event)> CallbackType;
class EventManager
{
public:
void AddListener(const std::string eventName, IEventListener* listener)
{
CallbackType callback = std::bind(&IEventListener::HandleEvent, listener, std::placeholders::_1);
listeners[eventName].push_back(callback);
}
void AddListener(const std::string eventName, CallbackType callback)
{
// ...
}
void TriggerEvent(IEvent* event)
{
for (CallbackType callback : listeners[event->GetName()])
{
callback(event);
}
}
private:
std::map<std::string, std::vector<CallbackType>> listeners;
}
The 1st AddListener function works perfectly. The TriggerEvent function calls the HandleEvent function, which is implemented by each class that extends my IEventListener interface.
I would really like to be able to pass a callback to the 2nd AddListener function. This callback would then get called in the TriggerEvent function as before. I can pass in a callback constructed using std::bind and this works. For example:
eventManager->AddListener("WindowResize", std::bind(&MyClass::MemberFunction, this, std::placeholders::_1));
where MyClass extends the IEventListener interface. However, I'd really like to be able to just pass a simple function pointer instead:
eventManager->AddListener("WindowResize", this, &MyClass::MemberFunction);
Is this possible?
Edit
For anyone interested, I wrote a couple of macros that I think makes things a little cleaner.
#define MEMBER_CALLBACK(funPtr) \
std::bind(&funPtr, this, std::placeholders::_1)
#define MEMBER_CALLBACK_WITH_INSTANCE(funPtr, instancePtr) \
std::bind(&funPtr, instancePtr, std::placeholders::_1)
Now I can subscribe to an event by:
eventManager->AddListener("EventName", MEMBER_CALLBACK(MyClass::MemberFunction));
You can't pass a simple function pointer because MyClass::MemberFunction isn't a simple function. The std::bind() works because it associates an instance of MyClass with the reference to the member function. Without that information, the member function would not have access to the instance's data.