Subscribe a button to trigger some function dynamically in C++? - c++

I'm trying to make a button class (abstract) so I can set what function is that button going to trigger when clicked dynamically when my program load.
I want to construct all my buttons by reading XML files, this is to avoid code replication so having only 1 "generic" button class is really useful for me.
I was wondering if you could dynamically pass the necessary information about a method, like a pointer to the method's owner and method in question name, or even better the direct pointer to the method, for a button to call that function/method when clicked ?

Since pointer to function is a runtime artifact you cannot store that in the offline configuration. I see two solutions that might fit what you describe:
put your functions into a dynamic library and load them by name - that way your configuration would map a button to library path/function name pair,
build a "registry" of named function pointers at startup, probably some hash table, so the configuration would map a button to the hash key.
From experience though I would say that building such facilities are usually overkill, and the configuration quickly becomes heavier then the app itself.
Some additional pointers: Boost.Signals, QT Signals, Command and Chain of Responsibility design patterns.

You can create a SetFunctor method in your generic Button class, which accepts a function object as a parameter. Then you create a Call method that calls the function wrapped inside the function object. Something like this:
template<typename FUNC>
class Functor
{
typedef FUNC (*FC)();
FC func;
public:
Functor( FC f ) : func(f) {}
~Functor() {}
FUNC Call() { return func(); }
FUNC operator()() const { return Call(); }
};
class Button
{
std::auto_ptr<Functor<void> > pfunc;
public:
Button() {}
~Button() {}
void SetFunctor( void(*fc)() )
{
pfunc.reset( new Functor<void>( fc ) ); // now owns ptr;
}
void Call()
{
pfunc->Call();
}
};
...
void changeColor()
{
// do work
}
Button obj;
obj.SetFunctor( changeColor );
obj.Call();
Of course I could've used better smart pointers and or better techniques, but this should give you a gist of what I was hinting at. Also note, that this Functor object can only accept functions that have no parameters. You can change this to your liking. I hope it helps!
UPDATE: A few fixes added. Sorry about that!

You are looking for the signal/slot pattern.
In C++ two popular options are boost signals and sigc.

There are a couple of ways to link a button to a function in C++ - you can use function pointers (which are somewhat scary), or a signals and slots pattern which provides the functionality of function pointer with more type safety.
As far as wiring up the function pointers or signals and slots at run time based on a config file, to do this elegantly will require reflection, which C++ doesn't provide for you. I suspect this will be the ugly part.

Related

How can I create a C++ class that accepts function pointers with different signatures?

I am relatively new to C++ and I am working on a personal project for practicing where I need to create a class that can take function pointers with different signatures.
The idea is that each instance of the class will store a pointer to a specific function and can call that function whenever I want.
To give a better idea of what I want, let me explain with a little bit more detail what I am trying to do. The project I am working on is a very basic console game and the object I am trying to create is an object that would store details on each location the player can access in the game.
(DISCLAIMER: I know that most of what I describe later is probably an overkill for a basic console game. I can easily make the whole game in a couple of files using just simple functions and I know how to do that. But the idea here is that I wanted to practice more advanced C++ techniques without having to figure out a complex project. So, since I know how to make a basic console game, I thought it would be a good idea to try and figure out how to achieve the same result but with more advanced techniques)
One of the details that I think should be stored is what happens in each location, basically the text that is output to the screen describing what happens and prompting the user to take action.
Since this would be different for each location, I can't just declare and implement a function in the class.
One way of solving this issue is to create a base class with a virtual function and then implement this function in a series of derived classes, each defining a new location.
The problem I have with this approach is that it makes each location a class that can be inherited further and instanced, which I don't need as I will only have 1 instance of each location.
I can of course just create 1 instance of the class, but I wanted to see if there is a way to avoid having to create separate classes for each location.
This why I started thinking of function pointers.
Now, I know I can declare a function pointer and initialise it in a class like that:
class Test
{
public:
Test(void (*p)())
: print{p}
{}
private:
void (*print)();
};
That works fine as long as the function returns void and accepts no arguments.
So, I thought maybe I can do that with a template:
template <typename Function>
class Test
{
public:
Test(Function *p)
: print{p}
{}
Function *print;
};
This actually works well. I can now have a class that accepts different functions with different return types.
I can create instances of the class in the following way:
void print();
Test<void ()> a {print};
However, I have one problem with this approach. Because it is a class template, I can't have a pointer that I want to use to point to instances of Test class regardless of the function that is passed to them.
For instance, if I declare the following pointer:
Test<void ()> *b = &a;
There is no way to re-assign that pointer to another instance of Test class unless the function pointer passed to it also returns void and accepts no arguments. Otherwise, I have to create a new pointer.
Is there a way to avoid that? Is there a better way of achieving what I am looking for than using function pointers?
Thank you very much and sorry for the long message.
There is no way to re-assign that pointer to another instance of Test class unless the function pointer passed to it also returns void and accepts no arguments.
And how would you expect that to work? Each Test has a different signature for its print method. In the example below, if you assigned action2 to action1, then how would it know what to pass to the print function?
void fun1() {}
void fun2(int) {}
void test() {
Test<void()> action1= &fun1;
action1.print();
Test<void(int)> action2= &fun2;
action2.print(42);
}
What you want is really simple, thanks to improvements in C++11: std::function<void()>.
Whenever you need to pass some arguments to the function, you'd use a lambda, potentially with captures:
#include <functional>
void fun1() {}
void fun2(int) {}
using Action = std::function<void()>;
int main() {
class MyObject { public: void doSomething() {} } obj;
Action action1;
action1 = fun1;
action1 = []{ fun2(42); };
action1 = [&obj]{ obj.doSomething(); }; // obj captured by reference
}
So that's pretty much what you should do.
Now of course you may ask "hey, but what if I wanted to implement something like std::function myself"? It's not a trivial task, if you want to get full functionality of std::function, including small object optimization (i.e. std::function usually doesn't allocate unless the functor it wraps is "big").
I wanted to see what can I do if I had a reason to have the each game location using a function that have different return types.
You chose to use a common abstraction, i.e. some class (like Action) that you can always call the same way, and get to do various things. So, what would you like the following code to do?
Action someAction;
int result = someAction();
std::string result = someAction();
Now suppose that e.g. someAction has captured a void() function. What should the code that assigns the "result" to an integer or a string do? And how would you protect from mistakes, e.g. if you really wanted someAction() to return an int, but you accidentally used one that returns nothing?
Remember that the compiler has to generate code for all of the sites where you call someAction, so it needs to know what to do ahead of time, even if you may otherwise ensure that no "incorrect" calls are made.
You could implement a custom Action class on top of std::function that could support std::optional<ResultType> instead of ResultType. That way, if the actual result of the functor wrapped in Action was convertible to that ResultType, you'd get a non-null optional, otherwise the optional would be null. And the list of supported result types would need to be pre-determined, i.e. the compiler wouldn't be able to dynamically add them, but adding a new type should amount to passing an additional type as a template argument, so it'd be easy to support quite many types.

Determining type of parent form in Qt

I have a database with table X: let's call it clients. I also have a form related to editing table X contents. It may open it on it's own (to browse/edit) as well as from other forms when it is necessary to "pick" a record from table X.
How do I go about telling the parent that a particular QModelIndex has been picked straight out of on_tableView_doubleClicked(const QModelIndex &index) signal handler?
Currently, I had only one "dad" form, so I knew which type of pointer to put in child form (so it can hold a pointer to parent) and just casted a pointer of it's type.
if (parent) daddy = qobject_cast<InvoiceEd*>(parent);
Now I want to add a call from another form, I realized that I have to cast different pointer out of QWidget* pointer, and I don't know how to determine what's "in disguise" under QWidget* parent pointer. How can I do that?
I suggest using an interface and dynamic_cast to pass the information about the selected item:
InvoiceEdInterface.hpp:
class InvoiceEdInterface {
public:
virtual void SetSelectedItem (SelectedItemClass i_selected_item) = 0;
};
InvoiceEd.hpp:
class InvoiceEd: public InvoiceEdInterface {
public:
void SetSelectedItem (SelectedItemClass i_selected_item) override {
// Process setting selected item.
}
};
DataForm.hpp
class DataForm {
...
void on_tableView_doubleClicked(const QModelIndex &index) {
auto invoice_ed {dynamic_cast< InvoiceEdInterface* >(parent ())};
if (invoice_ed) {
invoice_ed->SetSelectedItem (...);
}
}
...
};
The idea behind the solution is pretty simple: if the parent widget implements the specified interface, that the SetSelectedItem() is called. Otherwise, nothing happens.
Note, however, that the proposed solution may not be Qt-ish. With Qt, you may add a signal that informs about the selected item. When the DataForm object is created in parent widget to select some item, the parent widget should establish a signal-slot connection. This solution is more flexible than the one, proposed above because it lets any object in the program get information about the selected item.
Both of the proposed solution work dynamically without the limitations of the template-based solution.
There is a code in some existing method implementation to resolve the widget type:
// dataform.cpp
void DataForm::myEdit()
{
///
if (parent()) daddy = qobject_cast<InvoiceEd*>(parent());
}
and the author wants to make it more flexible e.g. specifically cast to certain widget type depending on the caller. That can be done. Let's pass the desired type to it:
class DataForm
{
public:
// was void myEdit()
template <typename T = InvoiceEd> // defaults to InvoiceEd
void myEdit()
{
///
T* daddy = qobject_cast<T*>(parent());
// now we operate with the proper pointer so that
// exact instance does virtual function calls etc.
}
///
};
pDataForm->myEdit(); // default case
pDataForm->myEdit<MutatedInvoiceEd>(); // specified case
P.S. The above is without criticizing the design which is questionable. In OOP we don't usually want to know the context the method was called from or the objects don't want to identify each other. You should in this case create two different methods for different uses or maybe provide an additional parameter (maybe with default value void myEdit(bool insideOfContainerEdit = true) so that the code knows about some principal use case. There a number of ways to handle that but we cannot see the entire code of yours.
But of course the very existence of templates in C++ makes us able to solve the problem to degree. I myself find help in templates to sometimes avoid writing more code or derive from the type etc. but overuse of such approach leads to a lot of headache. We ideally should either rely on inheritance with polymorphism or handle such cases entirely via templates with parameter types.

Data Driven Design in native C++

So I am writing a game engine that utilizes data driven design to instantiate various actors from xml files. I recently finished coding the event management system and everything fires off the events and the handlers catch them correctly. No easy task considering I used member function pointers and templates. The issue I am having now is that I would like to be able to do something like this in the xml file:
<InputComponent>
<Event EventName="GainedFocus" OnEvent="Initialize"/>
</InputComponent>
The problem should be pretty obvious. C++ has no form of reflection and therefore cannot, as far as I know, get the address for the Initialize function from the string "Initialize". This means that for slightly different input components I have derive from the class and register the events specific to that instance and add the functions. Also, it should be known that this is different than the way I am handling typical input:
<InputComponent>
<Mapping Type="MousePress" Button=1 Command="RotateCamera"/>
</InputComponent>
In this instance mapping is an element specific to input components and commands are themselves objects that are created with a factory. I cannot really do this with generic events though. Commands are specific items that perform the exact same operations on different objects whereas objects or components themselves often need to handle individual events differently. Has anyone done anything like this before? Genuinely curious as to how someone could go about doing something like this so that events that need to be registered to an object dont have to be hard coded into the class itself.
EDIT: Let me word it this way. Different INSTANCES of the same type of components need to react differently to events. This will be application specific and as such should be separate from the engine code (I shouldn't have to modify the components). The user should be able to supply functions that can then be called upon reaction to an event. Both the function and event should be able to be bound in XML. I am starting to think this might just be impossible in unmanaged C++ because there is no form of metadata to look up the functions supplied by the user based on a string of the same name.
You could use a map that associates strings with function pointers.
Or if the function signatures differ you can use a Factory pattern with an if-else-if ladder.
Edit 1: Example
// Typedef for event functions
typedef void (*Event_Function_Pointer)(const Event& e);
typedef std::map<std::string, Event_Function_Pointer> Event_Function_Container;
//...
Event_Function_Container events;
events["Gained Focus"] = Initialize;
There's also an option of having lookup table since the text and the function pointers are constant data:
struct Event_Function_Entry
{
char * const * event_name;
Event_Function_Pointer event_function;
};
Event_Function_Entry events[] =
{
{"Gained Focus", Initialize},
};
Your components could all inherit from a same base, that provindes the interface for basic operations that your commands will invoque:
class Component {
public:
virtual void initialize();
virtual void rotate(int x, int y);
...
};
class Monster : public Component {
virtual void initialize(); // concrete implementation for a Monster
virtual void rotate(int x, int y);
};
You may then consider the "command" design pattern. The general idea would be:
class Command { // generic interface for commands
Component *receiver;
public:
Command(Component *receiver);
virtual ~Command();
virtual void execute();
};
class InitializeCommand : Command { // a specific command
public:
InitializeCommand (Component *receiver /* + additional command specific parameters */); // specific constructor with all needed parameters
void execute() {
// use the parameters and do the common operations
receiver->initialize(); // polymorphically call the object operations
// ...
}
};
The rest depends of your global design.
You could for example design a factory that would create the commands based on the events that are processed and execute these:
if (event==...) {
// todo: find object pointed to by the object
Command c = myfactory_for_event (object, parameters);
c.execute();
}
Of if your xml file is meant to configure an object, then you read the file, create specific commands, and store them in an event map that associates an event name to a concrete command:
map<string,Command*> commands;
In this case, the event processing would be something like:
myobject["initialize"]->execute();
So no one knows if there is any way to do this? Obviously there are hack ways. Multiple integration, multiple factories etc. I could ONLY have responses to events done as Command objects but that seems like a weird solution...because there is no runtime information available I have to encapsulate each INDIVIDUAL function in its own class..waste of memory if you ask me...Just realized how weird that sounds. Basically what I meant is for each funtion I wanted to map to an event I would have to create an entire new class (same as the command pattern I am already using to map keys). Would be much easier if I could just provide a function address instead of allocating and deallocating memory for ever individual action but no one seems to have an answer.

Problem using abstract factory

I am using an abstract factory to create user interface components such as dialogs. The abstract factory used is returned from a currently selected generic "INode" which is the base class for several different types of node. So for instance, if I want to add a new node of the same type as the selected node, the scenario goes something like this:
(please note this is semi-pseudo code)
User clicks node and the node gets stored for later use:
void onTreeNodeSelected(INode *node)
{
selectedNode = node;
}
User clicks "add" on the user interface:
void onAddClicked()
{
IFactory *factory = selectedNode->getFactory();
Dialog *dialog = factory->createAddDialog(parentWidget);
dialog->show();
}
Which all seems fine. The problem comes when I want to edit the selected node:
void onEditClicked()
{
IFactory *factory = selectedNode->getFactory();
Dialog *dialog = factory->createEditDialog(selectedNode, parentWidget);
dialog->show();
}
Oh dear.. I'm passing in an INode object. At some point I'm going to have to downcast that to the correct node type so the dialog can use it properly.
I've studied the "PostgreSQL Admin 3" source code, and they do something similar to this. They get round it by doing something like this:
FooObjectFactoryClass::createDialog(IObject *object)
{
FooObjectDialog *dialog = new FooObjectDialog((FooObject*)object);
}
Yeck.. cast!
The only way I can think around it and still able to use my factories is to inject the node itself into the factory before it is returned:
FooNode : INode
{
FooNodeFactory* FooNode::getFactory()
{
fooNodeFactory->setFooNode(this);
return fooNodeFactory;
}
}
So then my edit event can do this:
void onEditClicked()
{
IFactory *factory = selectedNode->getFactory();
Dialog *dialog = factory->createEditDialog(parentWidget);
dialog->show();
}
And it will use the injected node for context.
I suppose if there is no injected code, the createEditDialog could assert false or something.
Any thoughts?
Thanks!
A common solution is "double-dispatch", where you call a virtual function on one object, which in turn calls a virtual function on the other, passing this, which now has the correct static type. So, in your case, the factory can contain "create" functions for the various types of dialogues:
class IFactory
{
public:
....
virtual Dialog* createEditDialog(ThisNode*, IWidget*);
virtual Dialog* createEditDialog(ThatNode*, IWidget*);
virtual Dialog* createEditDialog(TheOtherNode*, IWidget*);
....
};
then each type of node has a virtual createEditDialog that dispatches to the correct factory function:
class INode
{
public:
....
virtual Dialog* createEditDialog(IWidget* parent) = 0;
....
};
class ThisNode : public INode
{
public:
....
virtual Dialog* ThisNode::createEditDialog(IWidget* parent)
{
return getFactory()->createEditDialog(this, parent);
}
....
};
Then you can create the correct dialogue as
void onEditClicked()
{
Dialog *dialog = selectedNode->createEditDialog(parentWidget);
dialog->show();
}
In my opinion, using C-style casts (although C++ style would be preferred) is perfectly acceptable as long as your code is properly commented.
I'm not a big fan of DI (dependency injection) because it makes some code hard to follow and, in your case, I would rather look at a dynamic_cast<>() or something than try to follow injected code over multiple source files.
I would sugest two things.
First: there is nothing wrong with casting. If you want to be safe, you could use RTTI (type_id stuff) or some virtual functions in the INode class which could return some info which would let you know if it is safe to cast.
Second: you could check to see what the createEditDialog function needs, and put those in virtual functions in either INode, or an inherited class which would be the type createDialog expects.
In general, I see nothing really wrong with the problem you describe, and it is hard to give more suggestions without seeing the whole code, which I assume is unfeasible.
Your approach of injecting the node into the factory is generally a pattern I've found useful, but there are often times when you don't have a reference to the target object when you're creating the factory like you do here. So this might work fine for you in this case and it's simpler than handling this kind of problem in the general case.
For the more general case, you need to work with the notion of interfaces and establish a mechanism by which your INode object can publish which interfaces it supports and provide access to those interfaces for clients. Doing this completely dynamically leads to a COM-like approach that requires dynamic registration and casting. But you can also do this in a statically typed manner if you have a relatively stable set of interfaces you want to expose and can afford to edit the INode interface when you need to add a new component interface.
So this would be an example of how to do the simple statically typed approach:
struct INode
{
virtual INodeSize* getNodeSizeInterface() = 0;
virtual INodeProperties* getNodePropertiesInterface() = 0;
virtual INodeColor* getNodeColorInterface() = 0;
... // etc
}
Now each INode implementation can return some or all of these component interfaces (it would just return NULL if it didn't implemen them). Then your dialogs operate on the component interfaces to do their work instead of trying to figure out which actual implementation of INode was passed in. This will make for much more flexible mapping between dialogs and node implementations. A dialog can quickly determine whether it has a "compatible" INode object by verifying that it returns a valid object for each interface that the dialog is interested in.
I think a cast inside createEditDialog is not a bad thing in this case, even though you give up compile time checks. If the type of the node does not change at runtime, you could use templates instead of an abstract INode-class.
Otherwise, your proposed solution is the one that I would think of as well. I would, however, rename the Method to something like "getSelectedNodeDialogFactory" (i know, long name) so that it is clear that the factory returned is specific to that node. Are there other dialogs that need to know the concrete type of the INode object? Does createAddDialog need a parent or a predecessor node, maybe? Those could all go in the factory-with-selected-node class.

Templates vs. Action Hierarchy

I'm creating a button class and am having a hard time deciding between 2 solutions.
1) Templatize the Button class and have it take a function object in its constructor to call when the button is pressed. The guy I'm coding with is worried that this will lead to code bloat/thrashing.
2) Create a ButtonAction base class, and there will be a different ButtonAction for each button. Thus the Button class takes a ButtonAction in its constructor to call when the button is pressed.
We've also considered the use of function pointers, but haven't thought it through that thoroughly.
You could use boost::function<> objects for your actions. This way you don't need any templates and the button class becomes very flexible:
struct Button {
typedef boost::function<void ()> action_t;
action_t action;
Button(const action_t &a_action) : action(a_action) {
}
void click() {
action();
}
};
This way the class is easy to use with function pointers, functor objects or things like boost::bind:
void dosomething();
Button b1 = Button(&dosomething);
struct SomeAction {
void operator()() {}
};
Button b2 = Button(SomeAction());
I'd enumerate the consequences of each alternative, and then decide which option is best for the particular case at hand.
If the template option might (premature worry?) bloat object code, then the polymorphism alternative might make the source code unnecessarily complex.
In the case of templates the compiler will create another Button class for each function object you instantiate it with. This means the product object code will be larger than if you have a single Button class that accepts various action objects through a subclass.
In the case of polymorphism the compiler will generate a single Button class but you will now have another base class to maintain, and you will be forced to subclass it for any new action you add to your collection. In particular you will not be able to use actions that were written before you created the base action class unless you can modify them so they derive from that action class.
The template alternative allows you to use anything at all that conforms to the template's interface. So if you use the template parameter as a function then you can accept anything at all that can be called like a function. This implies you don't even need to consider the alternative of function pointers, since templates allow you to accept function pointers -- and much more.
The polymorphism option implies the compiler knows more about what you're trying to do. In other words, templates come with templates errors.
You can ease some of the template issues if you can find a way to only template Button member-functions, rather than the entire Button class. Take as function parameter an instance of the template so you don't need to explicitly instantiate the template function. Then you win both on some of the template benefits as well as some of the polymorphism benefits.