Last active
August 29, 2018 18:10
-
-
Save motters/a6f1782e0995b5a988f072d395c6e3c2 to your computer and use it in GitHub Desktop.
Factory to create, retrieve and delete instances of sensors
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <utility> | |
#include <memory> | |
#include <string> | |
#include <map> | |
#include <stdexcept> | |
#include <iostream> | |
/** | |
* Parent class for sensors to inherit | |
*/ | |
class Chip | |
{ | |
public: | |
Chip() | |
{ | |
std::cout << "Created Chip" << std::endl; | |
} | |
~Chip() | |
{ | |
std::cout << "Deleting CHIP" << std::endl; | |
} | |
}; | |
/** | |
* Example sensor MPU6050 | |
*/ | |
class MPU6050 : public Chip | |
{ | |
public: | |
MPU6050() | |
{ | |
std::cout << "Created MPU6050" << std::endl; | |
} | |
~MPU6050() | |
{ | |
std::cout << "Deleting MPU6050" << std::endl; | |
} | |
void setup(int gforceRange) { | |
} | |
int read() | |
{ | |
std::cout << "Reading MPU6050" << std::endl; | |
return 1937; | |
} | |
}; | |
/** | |
* Example sensor MPU9250 | |
*/ | |
class MPU9250 : public Chip | |
{ | |
public: | |
MPU9250() | |
{ | |
std::cout << "Created MPU9250" << std::endl; | |
} | |
~MPU9250() | |
{ | |
std::cout << "Deleting MPU9250" << std::endl; | |
} | |
void setup(int gforceRange, int resolution) { | |
} | |
double read() | |
{ | |
std::cout << "Reading MPU9250" << std::endl; | |
return 1093.0282; | |
} | |
}; | |
/** | |
* Sensor Factory | |
* | |
*/ | |
class SensorsFactory | |
{ | |
public: | |
// Supported sensor types | |
enum class Type { | |
IMU, | |
GPS, | |
Barometer, | |
Temperature | |
}; | |
/** | |
* Create a new sensor instance | |
* | |
* @author Sam Mottley | |
*/ | |
template<typename T> | |
int create(Type type) | |
{ | |
// Increment one from catergory size | |
int count = m_sensors[type].size() + 1; | |
// Create sensors as specified | |
auto i = std::make_shared<T>(); | |
m_sensors[type][count] = i; | |
// Return the instance referance | |
return count; | |
} | |
/** | |
* Destroy an instance of an sensor | |
* | |
* @author Sam Mottley | |
*/ | |
void destroy(Type type, int id) | |
{ | |
// Check exists | |
exists(type, id); | |
// Erase the entry | |
m_sensors[type].erase(id); | |
} | |
/** | |
* Return a sensors object | |
* | |
* @author Sam Mottley | |
* @param Type type supported sensor type | |
* @param int i id of the sensor | |
* @return T sensor class | |
*/ | |
template<typename T> | |
std::shared_ptr<T> get(Type type, int id) | |
{ | |
// Check exists | |
exists(type, id); | |
// Turn sensor | |
return std::static_pointer_cast<T>(m_sensors[type][id]); | |
} | |
/** | |
* Setup the sensor with the correct number of parameters | |
* | |
* @author Sam Mottley | |
*/ | |
template<typename T, typename... Args> | |
void setup(Type type, int id, Args... args) | |
{ | |
// Check exists | |
exists(type, id); | |
// Get sensor | |
std::shared_ptr<T> i = get<T>(type, id); | |
// Setup sensor | |
i->setup(args...); | |
} | |
/** | |
* Creates and sets up instance of sensor | |
* | |
* @author Sam Mottley | |
*/ | |
template<typename T, typename... Args> | |
int build(Type type, Args... args) | |
{ | |
// Create sensor | |
int id = create<T>(type); | |
// Setup sensor | |
setup<T>(type, id, args...); | |
// Return id | |
return id; | |
} | |
private: | |
// Container for all our sensors | |
std::map<Type, std::map<int, std::shared_ptr<Chip>>> m_sensors; | |
/** | |
* Check ID exists | |
* | |
* @author Sam Mottley | |
*/ | |
void exists(Type type, int id) | |
{ | |
auto container = m_sensors[type]; | |
if (container.find(id) == container.end()) | |
{ | |
throw std::range_error("Sensor ID does not exists"); | |
} | |
} | |
}; | |
int main() | |
{ | |
// Create sensors factory | |
SensorsFactory sensors; | |
// Create and setup a sensor | |
int instanceAcc1 = sensors.build<MPU6050>(SensorsFactory::Type::IMU, 1); | |
int instanceAcc2 = sensors.build<MPU9250>(SensorsFactory::Type::IMU, 1, 8876); | |
// Read sensors | |
{ | |
// Retrieve sensors from factory via there catergory and referance | |
auto accel1 = sensors.get<MPU6050>(SensorsFactory::Type::IMU, instanceAcc1); | |
auto accel2 = sensors.get<MPU9250>(SensorsFactory::Type::IMU, instanceAcc2); | |
// Get values from sensors | |
accel1->read(); | |
accel2->read(); | |
} | |
// Delete a sensor | |
sensors.destroy(SensorsFactory::Type::IMU, 1); | |
// Try to delere something that does not exist | |
try | |
{ | |
// Attempt delete | |
sensors.destroy(SensorsFactory::Type::IMU, 25); | |
} | |
catch (const std::runtime_error& e) | |
{ | |
// Show error | |
std::cout << "Error deleting sensor: " << " " << e.what() << std::endl; | |
} | |
while (true) {} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment