lundi 3 juillet 2017

How to implement event driven logic between two interfaces?

I'm stuck on how to tie my different objects together with an event driven logic. I'm trying to build an app which will take status signals from a driver and then send a message (upon change) to an MQTT broker. The different drivers are for local I/O handling or high-level interface towards another device etc.

So far I have done following:

  • Configuration setup through Singleton (command line + JSON config).
  • Driver is loaded through factory pattern (simulator or Raspberry pi I/O). Returned as a shared_ptr.
  • MQTT connection is setup through a wrapper of the Mosquitto library (which implements its own thread).

Translated to:

class Mqtt* mqtt = new Mqtt();
auto hwio = DriverFactory::createDriver(Config::Instance()->getPlatform());

Then I thought a clean way to keep it all separated would be to create an additional interface class, where the constructor takes the mqtt&driver. Then in that class have a run() function with an endless loop, which will perform various signal manipulation before sending it off to the MQTT broker.

IoInterface iointerface(mqtt, hwio);
iointerface.run();

The driver class has always the same signals (X, Y, Z...). The driver class would also have a run() function running in a separate thread, to handle signal changes. Initiated in main loop before (or after?) the interface class.

std::thread t1 = hwio->run();

Driver class:

class SimulatorDriver : public Driver
{
public:
    std::thread run(); // Returns simulator()

    int getXMode();
    int getYMode();
    int getZMode();

private:
    void simulator();
    int X;
    int Y;
    int Z;
};

Interface class:

class IoInterface
{
public:
    IoInterface(Mqtt* mqtt, std::shared_ptr<Driver> hwio);
    bool run();
...

private:
    virtual void send(std::string data); // Send message through MQTT

    int m_x = 0;
    int m_y = 0;
    int m_z = 0;
};

Now I have resorted a simple polling logic. Driver update its own local signal variables, then interface is comparing through a getter against another own local variable whether any change (and if yes, send a message).

I find this polling logic not so nice, it is also hard to implement in a clean way. Not to mention that I also need a relatively low polling frequency (200ms), yet it may be minutes/hours between signal changes (but once signals starts changing it is in groups of ~10 which need response within ~500-800ms) .

My question is, have I approached this in the "right" way? How can I implement an event driven logic?

I have been reading a lot about the new C++ features for event handling but have had a hard time to apply it to my setup. Any comments are appreciated, thanks!

Aucun commentaire:

Enregistrer un commentaire