how to setup a proper callback to retrieve data - c++

I have the following situation, I have two classes. I pass an instance of class 1 to an instance of class two through a callback function. Ultimately the goal is to connect to something (say sql server) and retrieve some datasets maybe every x number of minutes. How would I amend the below so that after passing an object of class 1 to the object of class 2, I can somehow get the object 1 to do all the work. Essentially I need the implementation of connecting to SQl and getting data to be in the work() function of class foo. and more importantly how do I relay the result set back to the user in main();
Does that make sense at all? Is the correct? The ultimate goal is to latch onto a sql server and grab a dataset every 5 minutes and generate some statistics to be returned to the user, should this be modified at all? Should the connection be handled by the foo class or the bar class
class foo{
public:
void work(int id, &result){}
};
class bar{
private:
foo* foo_
public:
void callback(foo* tempfoo){
foo_ = tempfoo;
}
void work();
};
int main(){
foo send;
bar receive;
receive.callback(&send);
//do a bunch of stuff with the receive object to get the result
bar.work(//some parameters that are needed to generate the result);
}
Thanks a lot guys.

The class that wants to call a callback should take a function pointer and then call that pointer when appropriate (when work is done).
There are a couple of options as to how exactly to pass a function pointer. You could use Lambda (as in the example code below), or you could use std::bind with a member function.
Example below:
class foo(){
public:
foo()
~foo()
work(int id, &result){
//do work
//call callback with some params
callback(PARAMS);
}
void setCallback(std::function<void(PARAMETERS)> cb){
callback = cb;
}
private:
std::function<void(PARAMETERS)> callback = nullptr;
}
class bar(){
private:
foo* foo_
public:
bar()
~bar()
work();
}
int main(){
foo send;
bar receive;
receive.setCallback([](PARAMETERS){
//your callback code in lambda
//send and receive are not captured here
//if you wish to capture send and receive
//you should somehow maintain their existence in memory
//until the callback is called, otherwise you'll get bad access error
//due to those guys already destroyed
//to capture send and receive you should put them into [] of lambda declaration.
//Append & if you want to capture by reference.
});
receive.work(//some parameters that are needed to generate the result);
}

Related

how to call a function when an asynchronous task is already done?

I have a set of classes look like this:
class A {
public:
std::unique_ptr<B> b;
void triggerAsynchronously() {
// this work is submitted to a queue.
b->getC()->signalAsync();
}
};
class B {
public:
std::shared_ptr<C> c;
std::shared_ptr<C> getC() const {
return c;
}
void doSomethingWithSignalFromClassC() {}
};
class C {
public:
void signalAsync() {
// This function is submitted to a queue, and wait until its turn to be executed.
// I want to trigger A::b::doSomethingWithSignalFromC() once this function is done (aka end of this block)
}
}
C::signalAsync() is triggered by A::triggerSignalCAsynchronously(). Note that A::triggerSignalCAsynchronously() returns immediately after submitting works to the queue, but C::signalAsync() is not executed immediately. Once C::signalAsync() is executed and done with its work, it should notify A::b::doSomethingWithSignalFromClassC().
My question is: how to notify B when C::signalAsync() has already finished? From A, we can get a shared_pointer<C>. Therefore, natural approach is to store weak_ptr<B> inside C. However, this does not work as b is a unique pointer. I also think about storing a raw pointer of B inside C, but that seems to go against the unique_ptr design.
Also, storing a raw pointer to A in C seems to be bad:
class A {
void setA() {
b->getC()->setA(this);
}
}
I have the feeling that something is wrong with my design. If it were you to solve this problem, which directions would you try?
You need to be very precise with what you are asking for. You say
Once C::signalAsync() is executed and done with its work, it should notify A::b::doSomethingWithSignalFromClassC()
'Notify' implies that a thread is waiting somewhere to be woken up to do something - this is complex
But you could also mean, I want singalAsync to call a method on an instance of B. This is simple.
Not knowing the constraints on these calls (do you wont then all or are some in libraries that you cant change etc) makes it harder.
Here is what I would do for the callback case
class C {
std::shared_ptr<B> callback_;
public:
C(std::shared_ptr<B> &cb){
callback_ = cb;
}
void signalAsync() {
// noodle noodle noodle
callback_->doSomethingWithSignalFromClassC();
}
}
ie when I construct a C object tell it the obbject to call back on.
Alternatively you could pass that as an arg to signalAsync but maybe thats not possible
Another idea would be to pass a std::function in the constructor so you dont have to hard code whcih method gets called at the end of signalAsync
According to pm100's answer, the usage of std::function actually works. I want to write down what I do in the end, just in case anyone might need it. A little bit more details, in my case, C's header file cannot include B's header file because B already includes C in its header (forward declaration not work). C also could not include A because A is designed to be an Implementation class (Pointer to Implementation idiom); therefore, A header is inside src folder and should not be included anywhere (except for A.cc)
What I did in the end:
class A {
public:
std::unique_ptr<B> b;
void triggerAsynchronously() {
// this work is submitted to a queue.
b->getC()->signalAsync();
}
void setFunctionToC() {
// This happens before triggerAsynchronously()
auto do_something_when_finished = [&b = b]() {
b->doSomethingWithSignalFromClassC();
}
b->getC()->setFunctionToC(do_something_when_finished);
}
};
class C {
std::function<void()> call_on_finished;
public:
void setFunctionToC(std::function<void()> f) {
call_on_finished = f;
}
void signalAsync() {
// This function is submitted to a queue, and wait until its turn to be executed.
// I want to trigger A::b::doSomethingWithSignalFromC() once this function is done (aka end of this block)
call_on_finished();
}
}

c++ - access pointer to call method (using callbacks etc)

I am trying to figure out how to do this.
I have 2 classes -
class Caller(){
//constructs Callee
void onEventFired(){
//need to call a function on an obj
//which I dont have access to here
//objptr->funcA
}
};
class Callee(){
//it has access to an instance of caller object
private:
void setup(){
std::unique_ptr objptr = make_unique<SampleClass>....
//create unique ptr of obj
//can pass the objptr to Caller through a
//separate function but probably not clean ??
}
};
Chain of events -
Caller creates the callee instance during its own construction, – later, callee's setup function is called which creates SampleClass pointer. at some point later, the periodic event starts to fire up thats when I want call SampleClass's funcA from within Caller
One way is to pass the raw SampleClass pointer to the Caller class through a separate function but ideally I don't want the class Caller to have access to that.
Is there a way using some callbacks which I can do this cleanly.
Your question is a little weak in motivation, so let's beef it up just a tad.
Suppose that Caller accepts registrations for things that want to be called back whenever EVENT_FIRED happens. So, the system has something like this:
//... initialize all callees
//... wait for event
switch (event) {
//...
case EVENT_FIRED:
//...
//callback all interested callees
Caller::instance().onEventFired();
break;
//...
default:
//...
break;
};
Typically, you will want the callees to register themselves with the Caller instance, so that they get notification of the event via their registered callback.
In order to accept registrations, you would use some kind of container in the caller to track them.
class Caller {
public:
struct Callback {
virtual ~Callback () = default;
virtual void fire () = 0;
};
static Caller & instance () {
static Caller one;
return one;
}
template <typename CALLBACK, int EVENT>
void subscribe () {
std::unique_ptr<Callback> cb(std::make_unique<CALLBACK>());
callbacks_[EVENT].push_back(std::move(cb));
}
//...
void onEventFired () {
for (auto &cb : callbacks_[EVENT_FIRED]) cb->fire();
}
private:
typedef std::list<std::unique_ptr<Callback>> CallbackList;
std::unordered_map<int, CallbackList> callbacks_;
Caller () = default;
Caller (const Caller &) = delete;
Caller & operator = (Caller) = delete;
~Caller () = default;
};
The Caller now implements the Callback interface, and makes its registration during setup.
class Callee : public Caller::Callback {
public:
static void setup () {
Caller::instance().subscribe<Callee, EVENT_FIRED>();
}
void fire () { std::cout << "You're fired!\n"; }
};
Try it online!
Here are 2 references may be what you're looking for.
The Attorney-Client idiom, and pass-key pattern.
The Attorney-Client idiom is a method that add a proxy class.
The proxy class is a friend of the class which needs access.
[Callee] - [Proxy] - [Caller] relationship is built.
Pass-Key pattern is a relatively simple method to solve the problem.
The main idea is same that uses friend keyword.
However, it's using class template, rooted in template meta programming.
For more sophisticated usage, take a look at this version. (the last answer)

Anonymous inner class in C++ (Java-style listener)

My C/C++ skills are a bit rusty, and I've mostly been working in Java for the past few years. Now I just started playing around with Arduino, and made a simple button class. I want to add an event listener, so I did something like this:
class MyButton{
public:
MyButton(byte pin);
bool isPressed();
bool wasToggled();
bool wasPressed();
void eventLoop();
inline void setListener(MyButtonListener* listener) { _listener = listener; }
private:
byte _pin;
boolean _lastToggledState = false;
MyButtonListener* _listener;
};
class MyButtonListener{
public:
virtual void onPressed() = 0;
private:
};
The eventLoop() method (which is intended to be called from the Arduino loop() function ), invokes the onPressed() method in the listener class:
void MyButton::eventLoop(){
if( wasPressed() && _listener ){
_listener->onPressed();
}
}
So far, things are okay. But I can't figure out how to actually assign and use the listener in the main Arduino file. Coming from Java, I'm used to just doing something like
myBtn.setListener( new MyButtonListener(){
void onPressed(){
Serial.println("Pressed");
toggleLed(); // toggleLed() is a method in the main Arduino file
}
});
I got it to work in a very convoluted way, by declaring a new class which takes the toggleLed() method as an argument (because it can't be accessed from within the new class otherwise):
class BtnListener : public MyButtonListener{
public:
BtnListener(void* toggleFunction) : _toggleFunction(toggleFunction){ };
private:
void (*_toggleFunction)();
void onPressed(){
Serial.println("Pressed");
_toggleFunction();
};
};
myBtn.setListener( new BtnListener(toggleLed) );
Surely there must be a more convenient way of doing something like this in C++? It's doable (but ugly) with one listener - I can't even imagine the horror of having 10 buttons which all need different listener implementations...
In your case, one or the simplest methods would be to store the listener as a std::function<void()> and don't have an actual class to model the buttonlistener at all (you can still have that if you really want to encapsulate that, but it's not neccesary). Then use a lambda function to the setListener call, something like this:
myBtn.setListener( [this]{
Serial.println("Pressed");
toggleLed(); // toggleLed() is a method in the main Arduino file
});
Since the Arduino IDE by default doesn't seem to include <functional.h>, I wasn't able to use the answer using std::function<void()>. However, after some experimenting I realized there was an easier way, which also has the benefit of being able to model the listener.
The listener class simply contains function pointers to each listener callback function, and a constructor that takes an argument for each callback. Then it's very convenient to just create a new instance of the listener class and pass each callback as a lambda.
class MyButton{
public:
inline void setListener(MyButtonListener* listener) { _listener = listener; }
private:
MyButtonListener* _listener;
}
class MyButtonListener{
public:
MyButtonListener(void* onPressed, void* onToggled) : onPressed(onPressed), onToggled(onToggled) {};
void (*onPressed)();
void (*onToggled)();
};
void MyButton::eventLoop(){
if( _listener ){
if( wasPressed() ){
_listener->onPressed();
}
if( wasToggled() ){
_listener->onToggled();
}
}
}
myBtn.setListener(
new MyButtonListener(
// onPressed
[](){
Serial.println("Pressed");
toggleLed();
},
// onToggled
[](){
Serial.println("Toggled");
}
)
);
Not sure if there are any drawbacks with this solution, but it works, is readable and is fit for use on Arduino.

How to pass a Function pointer without exposing class details

I'm creating a library that needs to allow the user to set a callback function.
The interface of this library is as below:
// Viewer Class Interface Exposed to user
/////////////////////////////
#include "dataType_1.h"
#include "dataType_2.h"
class Viewer
{
void SetCallbackFuntion( dataType_1* (Func) (dataType_2* ) );
private:
dataType_1* (*CallbackFunction) (dataType_2* );
}
In a typical usage, the user needs to access an object of dataType_3 within the callback.
However, this object is only known only to his program, like below.
// User usage
#include "Viewer.h"
#include "dataType_3.h"
// Global Declaration needed
dataType_3* objectDataType3;
dataType_1* aFunction( dataType_2* a)
{
// An operation on object of type dataType_3
objectDataType3->DoSomething();
}
main()
{
Viewer* myViewer;
myViewer->SetCallbackFunction( &aFunction );
}
My Question is as follows:
How do I avoid using an ugly global variable for objectDataType3 ?
(objectDataType3 is part of libraryFoo and all the other objects dataType_1, dataType_2 & Viewer are part of libraryFooBar) Hence I would like them to remain as separate as possible.
Don't use C in C++.
Use an interface to represent the fact you want a notification.
If you want objects of type dataType_3 to be notified of an event that happens in the viewer then just make this type implement the interface then you can register the object directly with the viewer for notification.
// The interface
// Very close to your function pointer definition.
class Listener
{
public: virtual dataType_1* notify(dataType_2* param) = 0;
};
// Updated viewer to use the interface defineition rather than a pointer.
// Note: In the old days of C when you registered a callback you normally
// also registered some data that was passed to the callback
// (see pthread_create for example)
class Viewer
{
// Set (or Add) a listener.
void SetNotifier(Listener* l) { listener = l; }
// Now you can just inform all objects that are listening
// directly via the interface. (remember to check for NULL listener)
void NotifyList(dataType_2* data) { if (listener) { listener->notify(data); }
private:
Listener* listener;
};
int main()
{
dataType_3 objectDataType3; // must implement the Listener interface
Viewer viewer;
viewer.SetNotifier(&objectDataType3);
}
Use Boost.Function:
class Viewer
{
void SetCallbackFuntion(boost::function<datatype_1* (dataType_2*)> func);
private:
boost::function<datatype_1* (dataType_2*)> CallbackFunction;
}
Then use Boost.Bind to pass the member function pointer together with your object as the function.
If you don't want or can't use boost, the typical pattern around callback functions like this is that you can pass a "user data" value (mostly declared as void*) when registering the callback. This value is then passed to the callback function.
The usage then looks like this:
dataType_1* aFunction( dataType_2* a, void* user_ptr )
{
// Cast user_ptr to datatype_3
// We know it works because we passed it during set callback
datatype_3* objectDataType3 = reinterpret_cast<datatype_3*>(user_ptr);
// An operation on object of type dataType_3
objectDataType3->DoSomething();
}
main()
{
Viewer* myViewer;
dataType_3 objectDataType3; // No longer needs to be global
myViewer->SetCallbackFunction( &aFunction, &objectDataType3 );
}
The implementation on the other side only requires to save the void* along with the function pointer:
class Viewer
{
void SetCallbackFuntion( dataType_1* (Func) (dataType_2*, void*), void* user_ptr );
private:
dataType_1* (*CallbackFunction) (dataType_2*, void*);
void* user_ptr;
}
boost::/std:: function is the solution here. You can bind member functions to them, and in addition functors and lambdas, if you have a lambda compiler.
struct local {
datatype3* object;
local(datatype3* ptr)
: object(ptr) {}
void operator()() {
object->func();
}
};
boost::function<void()> func;
func = local(object);
func(); // calls object->func() by magic.
Something like this is simple to do:
class Callback
{
public:
virtual operator()()=0;
};
template<class T>
class ClassCallback
{
T* _classPtr;
typedef void(T::*fncb)();
fncb _cbProc;
public:
ClassCallback(T* classPtr,fncb cbProc):_classPtr(classPtr),_cbProc(cbProc){}
virtual operator()(){
_classPtr->*_cbProc();
}
};
Your Viewer class would take a callback, and call it using the easy syntax:
class Viewer
{
void SetCallbackFuntion( Callback* );
void OnCallCallback(){
m_cb->operator()();
}
}
Some other class would register the callback with the viewer by using the ClassCallback template specialization:
// User usage
#include "Viewer.h"
#include "dataType_3.h"
main()
{
Viewer* myViewer;
dataType_3 objectDataType3;
myViewer->SetCallbackFunction( new ClassCallback<dataType_3>(&objectDataType3,&dataType_3::DoSomething));
}
You're asking several questions mixed up in here and this is going to cause you lots of confusion in your answers.
I'm going to focus on your issue with dataType_3.
You state:
I would like to avoid declaring or
including dataType_3 in my library as
it has huge dependencies.
What you need to do is make an interface class for dataType_3 that gives the operations -- the footprint -- of dataType_3 without defining everything in it. You'll find tips on how to do that in this article (among other places). This will allow you to comfortably include a header that gives the footprint for dataType_3 without bringing in all of its dependencies. (If you've got dependencies in the public API you may have to reuse that trick for all of those as well. This can get tedious, but this is the price of having a poorly-designed API.)
Once you've got that, instead of passing in a function for callback consider having your "callback" instead be a class implementing a known interface. There are several advantages to doing this which you can find in the literature, but for your specific example there's a further advantage. You can inherit that interface complete with an instantiated dataType_3 object in the base class. This means that you only have to #include the dataType_3 interface specification and then use the dataType_3 instance provided for you by the "callback" framework.
If you have the option of forcing some form of constraints on Viewer, I would simply template that, i.e.
template <typename CallBackType>
class Viewer
{
public:
void SetCallbackFunctor(CallBackType& callback) { _callee = callback; }
void OnCallback()
{
if (_callee) (*_callee)(...);
}
private:
// I like references, but you can use pointers
boost::optional<CallBackType&> _callee;
};
Then in your dataType_3 implement the operator() to do as needed, to use.
int main(void)
{
dataType_3 objectDataType3;
// IMHO, I would construct with the objectDataType3, rather than separate method
// if you did that, you can hold a direct reference rather than pointer or boost::optional!
Viewer<dataType_3> viewer;
viewer.SetCallbackFunctor(objectDataType3);
}
No need for other interfaces, void* etc.

What's a good safe way to initialise memory for types I don't yet know about?

I started thinking about this after receiving an answer for this question. This is a bit tricky to explain, but I'll do my best.
I'm building a small(ish) 2D game engine. There are certain requirements that I need to satisfy, since this engine has to "work" with existing code that others have written for a different engine. Some change to existing code is inevitable, but I want to minimise it.
Users of my engine need to define entities called "gadgets". These are basically structs containing shapes and other state variables. These "gadgets" fall into classes, e.g. they may decide to define an icon gadget or a button gadget - or whatever.
They will also define a message handler for that class of gadgets.
E.g.
typedef struct
{
shape shapelist[5];
int num_options;
}interface;
static void interface_message_handler( interface * myself, message * msg )
{
switch( msg->type )
{
case NEW_MSG:
{
interface_descriptor * desc = msg->desc;
// initialize myself with contents of this message.
...
}
break;
....
}
}
Users have already given me the corresponding message handler function and also the number of bytes in a interface object. And they can then ask the engine to create new instances of their gadgets via IDs e.g:
engine->CreateNewGadget( interface_gadget_class_ID, welcome_interface_ID );
where interface_gadget_class_ID is the ID for that class of gadgets and welcome_interface_ID is the instance ID. At some point during CreateNewGadget I need to a) allocate memory to hold a new gadget and then call the gadget class's message handler on it, with a NEW_MSG so that it can initialize itself.
The problem is, if all I'm doing is allocating memory - that memory is uninitialized (and that means all the struct members are uninitialized - so if interface contains a vector, for example, then I'm going to get some wierd results if the message handler does anything with it ).
To avoid wierd results caused by doing stuff to unintialized memory, I really need to call a constructor for that memory as well before passing it to the gadget's message handler function.
e.g in the case of interface:
pfunc(new (memory) interface);
But my question is, if I have no knowledge of the types that users are creating, how can I do that?
// We create a typedef that refers to a function pointer
// which is a function that returns an interface pointer
typedef interface * (*GadgetFactory)(void);
// we'll actually create these functions by using this template function
// Different version of this function will produce different classes.
template<typename T>
interface * create_object()
{
return new T;
}
// This function takes care of setting everything up.
template<typename T>
void RegisterGadgetType(int gadget_type_id)
{
// Get outselves a copy of a pointer to the function that will make the object
GadgetFactory factory = create_object<T>;
// store factory somewhere
}
interface * CreateGadget(int gadget_type_id)
{
// get factory
GadgetFactory factory;
// factory will give me the actual object type I need.
return (*factory)();
}
RegisterGadgetType<S>(2);
CreateGadget(2);
as i see it, you always know because interface_gadget_class_ID defines the type to create.
you create a base c++ class: (corresponds to class interface in your example). this base class contains all of data members which are used by every interface subclass (that is, every gadget).
the base class also declares all methods common to every gadget. example: each gadget is able to receive a call handleMessage. handleMessage is pure virtual, because this method is the subclasses' role to fulfill.
then you extend/subclass to support the stuff you have to do with each gadget's specialization. at this point, you add the members and methods specific to each gadget subclass.
CreateNewGadget serves as a factory for all your subclasses, where the arguments determine which class you will create.
from there, c++ will handle construction/destruction, allocation sizes, etc..
if you're allowing plugins with their own factories in your engine, then you'll need another level, where third parties register their custom types and inherit from your base(s).
here's a simple layout of the interfaces (in non-compiled pseudo code):
namespace MONGadgets {
class t_interface {
protected:
t_interface(/* ... */);
public:
virtual ~t_interface();
/* each subclass must override handleMessage */
virtual t_result handleMessage(const t_message& message) = 0;
};
namespace InterfaceSubclasses {
class t_gadget1 : public t_interface {
public:
t_gadget1(const welcome_interface_ID& welcome);
virtual ~t_gadget1();
virtual t_result handleMessage(const t_message& message) {
std::cout << "t_gadget1\n";
}
/* gadget1 has no specific instance variables or methods to declare */
};
class t_gadget2 : public t_interface {
public:
t_gadget2(const welcome_interface_ID& welcome);
virtual ~t_gadget2();
virtual t_result handleMessage(const t_message& message) {
std::cout << "t_gadget2\n";
}
private:
/* here is an example of a method specific to gadget2: */
void drawShape(const unsigned& idx);
private:
/* here is gadget2's unique data: */
shape shapelist[5];
int num_options;
};
namespace ClassID {
enum { Gadget1 = 1, Gadget2 = 2 };
}
}
/* replaced by virtual t_result t_interface::handleMessage(const t_message&)
- static void interface_message_handler( interface * myself, message * msg );
*/
class t_gadget_factory {
public:
t_interface* CreateNewGadget(const interface_gadget_class_ID& classID, const welcome_interface_ID& welcome) {
switch (classID) {
case InterfaceSubclasses::ClassID::Gadget1 :
return new InterfaceSubclasses::gadget1(welcome);
case InterfaceSubclasses::ClassID::Gadget2 :
return new InterfaceSubclasses::gadget2(welcome);
/* ... */
}
}
};
}
Example code (ignoring my other suggestion, about factories and virtual functions):
typedef struct
{
shape shapelist[5];
int num_options;
} interface;
static void interface_message_handler( void * myself, message * msg )
{
switch( msg->type )
{
case NEW_MSG:
{
interface *self = new (myself) interface;
interface_descriptor * desc = msg->desc;
// initialize myself with contents of this message.
...
}
break;
case OTHER_MSG:
{
interface *self = static_cast<interface*>(myself);
...
}
break;
....
}
}
Then your CreateNewGadget code does:
void *ptr = malloc(some_amount);
msg newmsg;
newmsg.type = NEW_MSG;
// other fields
some_message_handler(ptr, &msg);
// now we have an initialized object, that we can add to our tree or whatever.
The less horrible version is more like this:
struct gadgetinterface {
virtual ~gadgetinterface() {}
virtual void handle_message(msg *) = 0;
};
struct mygadget : gadgetinterface {
void handle_message(msg *m) {
// no need for NEW_MSG, just do other messages
}
};
gadgetinterface *mygadget_factory(some parameters) {
// use some parameters, either passed to constructor or afterwards
return new mygadget();
}
Then we register a pointer to mygadget_factory with the gadget manager, and CreateNewGadget does this:
gadgetinterface *some_factory(some parameters); // that's it!
Where some_factory is the function pointer that was registered, so in the case of this gadget type, it points to mygadget_factory.