Skip to content

Instantly share code, notes, and snippets.

@motters
Last active August 29, 2018 18:10
Show Gist options
  • Save motters/a6f1782e0995b5a988f072d395c6e3c2 to your computer and use it in GitHub Desktop.
Save motters/a6f1782e0995b5a988f072d395c6e3c2 to your computer and use it in GitHub Desktop.
Factory to create, retrieve and delete instances of sensors
#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