Skip to content

Instantly share code, notes, and snippets.

@vishal-keshav
Last active January 26, 2019 12:29
Show Gist options
  • Save vishal-keshav/f0fb44f4f77e06c57190a698ef0b49a6 to your computer and use it in GitHub Desktop.
Save vishal-keshav/f0fb44f4f77e06c57190a698ef0b49a6 to your computer and use it in GitHub Desktop.
On Object oriented programming and design patterns in C++ part 5 (complete)

Design Principles Part 5 (final)

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.

Implementation

#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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment