I originally posted this in "Beginners", but maybe it would be better fit to be here. That and "Beginners" is getting flooded with some guy making tons of spam accounts.
I apologize if this is a stupid question or something that I should be able to do easily.
I'm working on something where I have a collection of objects (of different types, but all derived from the same virtual base class).
It sort of has this structure:
1) Object in collection receives some input it can't handle
2) Object sends a "signal" to the containing object
3) Containing object handles "signal"
4) Containing object informs the sending object of either a solution or failure to solve
I'm stuck at 4. Right now, the object have in them a function pointer, which takes a "signal" to send to the containing object. Really, it's just passing a pointer to its own internal storage of a "signal", since there's something about using function pointers with arguments that I don't understand.
The signals are sent up and handled properly, but I can't send them back down. When the containing object receives a signal, it does via a function pointer (std::function), the sole argument being a pointer to the signal sent. The declaration is:
|
void ReceiveSignal(Signal::Signal *);
|
When this object is added to the containing object's list, this is the code that does it:
|
element->sendSignal = std::bind(&Parent::ReceiveSignal, this, element->sig);
|
When the signal gets sent, it looks like this:
1 2
|
*sig = Signal::Error; //change interval signal value
sendSignal(sig); //Send pointer to internal signal value - I know this is bad
|
element is a pointer to the object being added. "sendSignal" is a std::function stored in the sending object; It is initially bound to a no-action function, but that's just because I wan't to be safe.
I know there are multiple things wrong with what I just did.
Using "element->sig", which is a pointer to a "signal" inside of the sending object, as a placeholder when binding is not the right way to handle sending parameters in std::function. Without doing that, every call to this bound function outputs the same value, regardless of what value I actually put in the parenthesis.
I guess my main question is:
What is the best, safest way to do 2-way callbacks? It might seem a little counter-intuitive.
I want the containing object to send the "signal" to the containing object. That containing object takes some action and sends a resolution "signal" back to the object that originally sent that message.
The way I did it feels very "hacky", and it doesn't seem like good programming practice. I could just use function pointers in C, but they don't quite achieve what I'm going for, as the collection of object can be a collection of any number of different types of items, but they're all derived from the same base class. That base class has the "sendSignal" function pointer in it, as a public variable. The containing object won't know anything about the properties of the derived version that is actually in the container, as it is a list of pointers of the base class object type, but that's how I designed it.
Basically, I need a callback registered for each object in both directions. But the way I designed it was that the main object doesn't know anything about the object in the container except that it at least has everything that the virtual base class does.
Perhaps it would help if I gave a UML diagram.
https://i.imgur.com/5dLgeMN.jpg
Of course, I don't need someone to write all of the code for me. I'd really like some feedback on how to keep the class structure I've develop must establish some way for the Main Object to somehow remember which of its contained objects sent the signal. When each object is added to the Main Object's list, their "sendSignal" function is bound to MainObject, so every single one of the contained objects will call the same function when they send a signal.
This bad programming practice of mine must be eliminated.