From previous part, we may not know if a company conform to the APIs it used to design the camera driver. In such a case, we need to use adapter pattern. Adapter pattern bridges the gap of uneven APIs to a set of consistent APIs. Abstraction leads us to tread the device driver consistently.
#include "stdafx.h"
#include <iostream>
#include <thread>
#include <vector>
#include <string>
#include <functional>
#include <algorithm>
#include <mutex>
#include <Windows.h>
using namespace std;
using namespace std::placeholders;
class CameraDeviceDriver_company2 {
// It will have its own event class
// Its own start method and name
};
class CameraDeviceDriver_company1 {
// Nested
template<class TSignature>
class Event {
private:
vector<function<TSignature>> eventHandlers;
mutex sync;
public:
void operator += (const function<TSignature>& eventHandler) {
lock_guard<mutex> gaurd1(sync);
eventHandlers.push_back(eventHandler);
}
void operator -= (const function<TSignature>& eventHandler) {
lock_guard<mutex> gaurd2(sync);
/*compare_func = [&eventHandler](const function<TSignature>& eh) {
return eh == eventHandler;
}
eventHandlers.erase(find_if(begin(eventHandlers), end(eventHandlers), compare_func), end(eventHandlers));*/
//TODO: remove event handlers
}
template<class... TArgs>
void raiseNotification(TArgs... args) {
lock_guard<mutex> gaurd3(sync);
for(const function<Tsignature>& eventHandler : eventHandlers) {
eventHandler(forward<TArgs>(args)...);
}
}
};
private:
thread t;
public:
Event<void(CameraDeviceDriver_company1*, int)> VideoFeed;
Event<void(CameraDeviceDriver_company1*)> Error;
void Start(/*this*/)
{
thread t([this]() {
int count = 1;
while(true)
{
count++;
this->VideoFeed.raiseNotification(count);
Sleep(2000);
} });
this->t = move(t);
}
};
// Abstraction
// Below cannot be created because device driver company does not conform to it.
// So we need adapter
class CameraDeviceDriver
{
};
// Adapter pattern - create one layer to solve the problem
class Comapny1Adapter : public CameraDeviceDriver
{
private:
CameraDeviceDriver_company1 c1dd;
public:
// Fire the event using inherited Event objects
// Specific work with the device drivers will be done in this class
};
// Adapter pattern - create one layer to solve the problem
class Comapny2Adapter : public CameraDeviceDriver {
private:
CameraDeviceDriver_company2 c1dd;
public:
// Fire the event using inherited Event objects
// Specific work with the device drivers will be done in this class
};
// CameraFeedReciever is the client of CameraDeviceDriver abstraction
class CameraFeedReceiver {
private:
vector<CameraDeviceDriver*> Cameras; // Have to work with pointers for polymorphism
CameraFeedReceiver()
{
}
public:
CameraFeedReceiver(const CameraFeedReceiver&) = delete;
CameraFeedReceiver& operator=(const CameraFeedReceiver&) = delete;
static CameraFeedReceiver cfr;
static CameraFeedReceiver& get() {
return cfr;
}
void feedReceiver(CameraDeviceDriver* sender, int count)
{
//TODO: Check which device driver the object it is by comparing which sender it is
// can be done using find_if()
}
void addCamera(CameraDeviceDriver* cdd)
{
cdd.VideoFeed += bind(&CameraFeedReceiver::feedReceiver, this, _1, _2);
Cameras.push_back(cdd);
}
void removeCamera(CameraDeviceDriver* cdd) {
cdd.VideoFeed -= bind(&CameraFeedReceiver::feedReceiver, this, _1, _2);
}
};
class HDD
{
};
class alarm
{
};
int main()
{
CameraDeviceDriver cdd1, cdd2;
cdd1.Start();
cdd2.Start();
CameraFeedReceiver &cfr1 = CameraFeedReceiver::get();
cfr1.addCamera(cdd1);
cfr1.addCamera(cdd2);
while(1){
// System never stops.
}
return 0;
}