C++ Boost Signals connecting two functions from two different classes in template - c++

I'm trying to make a connection between a function in one class so that I can call it in another class. The answers I've found are either too specific or maybe I'm missing something because I cannot for the life of me figure out what I'm doing wrong. Also, I'm a bit new to the boost library so please excuse any dumb questions I may ask.
The setup for my workflow is basically this...
class MyClass : public BaseClass {
void setup();
void myFunc(datatype);
OtherClass myOtherClass;
}
void setup()
{
OtherNamespace::addListener(this, myOtherClass);
}
namespace OtherNamespace {
class OtherClass {
signals::signal<void (datatype)> myConnection;
}
template<class A, class B>
void addListener(A * app, B & connection)
{
connection.myConnection.connect( 'I don't know what to do here' );
}
}
Basically, the addlistener function won't make the connection between the signal and the function. I know that where I don't know what to do I'm doing something wrong but I just can't figure out what about it is wrong. I'm making this as a helper function so that I can pass functions from one class to another then call them when they're attached. I'm trying to create a domino event from a websocket connection and I am clearly missing something very important. Any help would be truly appreciated.
I'm on xcode and boost and macbook pro.

You should connect to the signal a matching slot, which is a callable having the appropriate signature. The best solution is to leave the slot creation to the caller of your addListener function (the following is your code, in SSCCE form):
#include <boost/signals2.hpp>
typedef int datatype;
class BaseClass
{};
namespace OtherNamespace
{
class OtherClass
{
public:
boost::signals2::signal<void (datatype)> myConnection;
};
template<class A, class B>
void addListener(A app, B & connection)
{
connection.myConnection.connect(app);
}
}
class MyClass : public BaseClass
{
public:
void setup();
void myFunc(datatype)
{}
OtherNamespace::OtherClass myOtherClass;
};
void MyClass::setup()
{
// let the caller decide how to make the slot
OtherNamespace::addListener(boost::bind(&MyClass::myFunc, this, _1), myOtherClass);
}

Related

Calling functions implicitly from derived classes

In my main.cpp I have something similar to the following:
void OnEventStart(int id)
{
// Do some stuff
}
This function is a callback, it is only triggered (by the main sdk that this is from) when an event has occured.
I now have this class:
class SomeClass {
public:
void OnEventStart(int id);
};
void SomeClass::OnEventStart(int id)
{
// Do some other stuff
}
Now I want to trigger void SomeClass::OnEventStart(int id) without doing something like this:
SomeClass class;
void OnEventStart(int id)
{
// Do some stuff
class.OnEventStart(id);
// AnotherClass.OnEventStart(id);
// Another.OnEventStart(id);
}
As you can imagine, using a method like this can easily clutter up the inital function/callback.
Your question is not very clear, but I'll assume the following:
You have some sort of callback handler that takes a void(*)(int).
In that case, if SomeClass is stateless, you can simply use a lambda wrapper:
my_framework_callback([]{ SomeClass{}.OnEventStart(id); });
If I misunderstood what you were asking, here's a different assumption:
SomeClass and similar types are stateless.
You're annoyed by having to instantiate SomeClass just to call one of its methods.
If that's the case, you can create a temporary instance of SomeClass on the spot:
void OnEventStart(int id)
{
SomeClass{}.OnEventStart(id);
AnotherClass{}.OnEventStart(id);
Another{}.OnEventStart(id);
}
If your question is instead...
"I have various classes with the same interface, and I want to call a function on all of them."
...then one possible solution would be using an abstract base class that provides .OnEventStart() = 0 and store an std::vector of pointers to that base class.
std::vector<std::unique_ptr<MyAbstractClass>> handlers;
void OnEventStart(int id)
{
for(auto& h : handlers)
h->OnEventStart(id);
}

Opaque Pointer (pimpl) and signals and slots

I am getting more and more into the Pimpl idiom (private opaque pointer to real class implementation). But I still have an issue which bothers me.
How does this idiom\design pattern deal with signals in the public class (like boost or qt signals)?
class my_class : public QObject
{
Q_OBJECT
public:
void monitorstuff();
signal:
void needupdate();
private:
class impl; unique_ptr<impl> pimpl; // opaque type here
};
class my_class::impl {
void reallymonitorstuff();
};
my_class::impl::reallymonitorstuff()
{
...
//update required here
...
}
void my_class::monitorstuff()
{
pimpl->reallymonitorstuff();
}
Do I replicate all signals in the pimpl, connect with signals of the outer class? A bit annoying to have twice as much signals as what is publicly available, also annoying when I need to swap instances.
Do I pass the public instance as parameter to the private instance which calls directly the public signals
Another design mechanism in conjuction I didn't heard of?
In general, I don't really see the problem. The public class should forward all calls to the impl including calls to connect a slot. The impl contains the signal, not the public class. E.g here using Boost.Signals2:
#include <memory>
#include <boost/signals2.hpp>
#include <iostream>
using signal_type = boost::signals2::signal<void()>;
using slot_type = signal_type::slot_type;
class my_class {
public:
my_class();
void monitorstuff();
void connect(const slot_type& slot);
private:
struct impl; std::unique_ptr<impl> pimpl;
};
struct my_class::impl {
signal_type signal;
void reallymonitorstuff();
void connect(const slot_type& slot){ signal.connect(slot); }
};
void
my_class::impl::reallymonitorstuff() {
//...
signal();
//...
}
void my_class::monitorstuff() {
pimpl->reallymonitorstuff();
}
void my_class::connect(const slot_type& slot) {
pimpl->connect(slot);
}
my_class::my_class() : pimpl(std::make_unique<my_class::impl>()){}
int main() {
my_class mc;
auto slot = []{ std::cout << "Notified!\n"; };
mc.connect(slot);
mc.monitorstuff();
}
Live demo.
I wonder if your problem is more specific to Qt.
Do I replicate all signals in the pimpl, connect with signals of the outer class? A bit annoying to have twice as much signals as what is publicly available, also annoying when I need to swap instances.
No, you don't need to do that.
Do I pass the public instance as parameter to the private instance which calls directly the public signals
That is not necessary either.
Another design mechanism in conjuction I didn't heard of?
That is not necessary either.
Assuming my_class::monitorstuff is supposed raise a signal, I think all you need is:
void my_class::monitorstuff()
{
pimpl->reallymonitorstuff();
emit <<Details of signal>>;
}
pimpl does not need to be concerned with signals or slots.

Understanding unused typedef of empty inherited class

I'm just trying to understand some tutorial code I'm going through. I'm trying to learn some Dx11 code and the tutorial I'm going through has classes that are designed as event details to be passed to functions when an event occurs, e.g. a mouse button being pressed. There's an empty base class EventArgs defined as follows:
class EventArgs
{
public:
EventArgs() {};
}
Which is the inherited by other event like classes. So for example they have a key pressed event args class as follows:
class KeyEventArgs : public EventArgs
{
public:
typedef EventArgs base;
KeyEventArgs(/**/)
{ }
// Rest of the class
}
I understand the premise that all the events are inheriting a base to say "they are an event type" but I don't understand the typedef base which is in every event class but isn't used by them directly. It seems as if a function that takes a KeyEventArgs parameter uses this base typedef to pass the event on to it's own base class but I don't understand how that works. The example they give is:
class Game
{
virtual void onKeyRelease(KeyEventArgs &e);
}
class Tutorial : public Game
{
void onKeyRelease(KeyEventArgs &e)
{
base::onKeyRelease(e);
/* Above calls Game::onKeyRelease(e) */
}
}
If anyone could shed any light on why/how the above works I'd be very grateful.
Thanks in advance.
The word base is not a keyword so in the class Tutorial example, the line base::onKeyRelease(e); will not compile. Now, if you saw it somewhere and it does compile, you must know that it must be define by a typedef or a using statement somewhere.
The purpose of the using such a typedef is to add another level of abstraction to help people change code safely. Considering the Tutorial example you could just as well write Game::onKeyRelease(e); Let's consider the following example:
class Game
{
virtual void onKeyRelease(KeyEventArgs &e);
}
class AwsomeGame : public Game
{
virtual void onKeyRelease(KeyEventArgs &e);
}
class Tutorial : public Game
{
typedef Game base;
void onKeyRelease(KeyEventArgs &e)
{
base::onKeyRelease(e);
//equivalent to Game::onKeyRelease(e);
}
}
If you change Tutorial base class from Game to AwsomeGame and the typedef also you have successfully changed the code without any bad side effects.
Not using a typedef would force you to write explicit calls to Game, and when the base class changes, you will have to change it in all the places you have used it. Now, if you consider the above example and you change Game to AwsomeGame without changing the typedef the code is valid, but you might run into a logical error later:
class Tutorial : public AwsomeGame //,public Game
{
void onKeyRelease(KeyEventArgs &e)
{
Game::onKeyRelease(e);
//code is valid, but you probably want AwsomeGame::onKeyRelease(e);
}
}
There is nothing magic here. Some other languages will provide a base, or similar, keyword to access the base class.
Obviously the programmers here like that, and simulate this by providing their own base. They could very well have written
class Tutorial : public Game
{
void onKeyRelease(KeyEventArgs &e)
{
Game::onKeyRelease(e);
/* Above calls Game::onKeyRelease(e) */
}
}
and avoided confusion (and a comment on what the code does).

How to access class member and methods from static method(signal handler)

I have one problem. I am writing my program on C++ language. I have one problem. I need to set signal handler for my process. As the signal is related with the process on system level I have faced the problem.
My program consists of several classes. They are connected together. But it doesn't matter in this case.
The problem is that I need access to member and methods of the class from my signal handler. For instance, I have a class named Foo at it has some members and methods.
So from my handler I need to call its function and change members.
I understand that compiler should know that this class instances will exist during all program execution.
I have tried to set static member class Foo instance in another class , but this didn't solve the problem.
I have no idea what is the correct approach for doing this. Please explain how to correctly implement signal handling in such case.
Here is an example of my code:
class MyContainer
{
private:
std::vector<Foo> container;
public:
int removeFromContainer(Foo* aFoo) {
// DO some stuff
return RESULT_CODE;
}
int addToContainer(Foo* aFoo) {
// DO some stuff
return RESULT_CODE;
}
};
Here is my Main class
class MainClass
{
private:
int member;
public:
void mainLoop(char* args) {
signal(SIGCHLD, &signalHandler);
}
};
Here is my function for signal handling
void static signalHandler_child(int p)
{
this->myContainerInstance->addToContainer(new Foo);
}
A static method is not so different from a global function. If you need to access instance members of a class, your signal handler should take an instance pointer/reference as argument.
Something like this
class Foo
{
private:
int member;
public:
static int Handler(Foo* aFoo) { return aFoo->member; }
};

Registering derived classes in central list

I have a central list of implementations of an interface and would like for derived classes to be able to register themselves in that list without having to add them in some central place. For example:
// interface.h
struct MyInterface;
std::vector<MyInterface*>& InterfaceList();
struct MyInterface {
MyInterface() {
InterfaceList().push_back(this);
}
virtual ~MyInterface() {}
// ...
};
// derived.cpp
#include "interface.h"
class MyImplementation: public MyInterface {
public:
MyImplementation() {
}
// ...
};
MyImplementation impl;
This doesn't seem to work. For reasons I don't understand, the constructor of MyInterface never gets called - I would have thought that the instance of the derived class would call it at startup. I know it's possible to do something along these lines since I've seen other libraries doing it - but haven't managed to figure out what it is that I'm doing wrong.
Thanks :)
Edit: Sorry, missed a pair of braces and a reference. InterfaceList() is a function that returns a reference to a vector.
Edit part 2: Have now got it working in a reduced example, but can't get it to work in the files for the derived implementations - but that technique is working in another project. There must be something slightly different in those files which is causing it to fail - but it appears the problem isn't in the code I posted. Don't really want to post big chunks of my employer's projects though so I guess I'll have to keep fiddling myself. Thanks for the suggestions so far though :)
You example does not compile under VS2008. What compiler are you using? When you change the second line in interface.h to
std::vector<MyInterface*> InterfaceList;
it works correctly. Just drop the braces.
I had a similar problem recently, and found that the simplest solution was to create a templated base class that was responsible for registering all of my implementations.
The base class contains a static variable, of templated type T, and this is registered with the central list. At runtime, each implementation would create its own static object and in the process of creating itself would register with the central list.
#include <iostream>
#include <vector>
class ITestInterface
{
public:
virtual void Execute() = 0;
};
std::vector<ITestInterface *> InterfaceList;
template <class T> class BaseClass :
public ITestInterface
{
public:
virtual void Execute() = 0;
protected:
BaseClass()
{
InterfaceList.push_back(&s_thing);
}
private:
static T s_thing;
};
template <class T> T BaseClass<T>::s_thing;
class ImplementationOne :
public BaseClass<ImplementationOne>
{
public :
ImplementationOne():
BaseClass()
{
;
}
void Execute()
{
std::cout << "ImplementationOne Execute\r\n";
}
};
class ImplementationTwo :
public BaseClass<ImplementationTwo>
{
public :
ImplementationTwo():
BaseClass()
{
;
}
void Execute()
{
std::cout << "ImplementationTwo Execute\r\n";
}
};
int _tmain(int argc, _TCHAR* argv[])
{
std::vector<ITestInterface *>::iterator it = InterfaceList.begin();
for(; it != InterfaceList.end(); it++)
{
(*it)->Execute();
}
}
The thing to remember with this code is that the line
static T s_thing;
does not result in a single s_thing, rather because a template is a type-generator there is one static s_thing for each derived class.
The output is
ImplementationOne Execute
ImplementationTwo Execute
This code works in VS2010.
This is the issue:
std::vector<MyInterface*> InterfaceList();
should be
std::vector<MyInterface*> InterfaceList;
Following definition of InterfaceList is a kind of function declaration which returns std::vector
std::vector<MyInterface*> InterfaceList();
Change this to
std::vector<MyInterface*> InterfaceList;