Friday, 19 October 2012

2000 Reads and Quick Guide to connecting Boost Signals

Well to say I only started this blog in summer, I'm pretty impressed to reach 2000 reads. Atleast someone must find my writing useful. Further work continues on refining the structure of the CAM module. Things are going reasonably well and each piece of the jigsaw is coming together.

I also stumbled on a little GEM on the forums after I was having problems creating the Document Objects that have children, for example like this hierarchy below...



If we delete ToolPaths using the GUI, ideally we want the children (TPGFeature) to be delete accordingly. Inheriting from a App::DocumentObject we do not get such a luxury.

Solution - Using Boost::Signals:

We need to set up an signal/slot mechanism using the Boost Libraries to observe when a document object is deleted.These are pretty simple to use and remove the need for having to use QT and it's signal/slot mechanism that requires inheriting from QObject and run through the MOC preprocessor. This is fine in context of the GUI interface, but isn't necessary in the rest of the application.

Boost signals are pretty straightforward to use:

In the class header file we need to include these. Essentially the typedef is just a typing shortcut to make the syntax less cumbersome to write.
#include <boost/signals.hpp>
typedef boost::signals::connection Connection;
In the class declaration we need a Connection member delObjConnection and this slot function that will be called when a signal is intercepted. In our case, when the signalDeletedObject is made within our slot function onDelete we need to have a App::DocumentObject as parameter. This slot function has to be public.
public:
    ///SLOTS
    void onDelete(const App::DocumentObject &docObj);
protected:
    ///Connections
    Connection delObjConnection;
In the class definition, we now need to set up our connection and also implement our slot. The function onSettingDocument overrides the implementation in App::DocumentObject. This is called just after the CamFeature object has been constructed and has a document assigned to it. (This was only recently added in the GIT master)

CamFeature::~CamFeature()
{
    delObjConnection.disconnect();
}

void CamFeature::onSettingDocument()
{
    //Create a signal to observe slot if this item is deleted
    delObjConnection = getDocument()->signalDeletedObject.connect(boost::bind(&Cam::CamFeature::onDelete, this, _1));
}

That's pretty much it. Now we can delete child objects in the onDelete slot we have made!