Add a RAII-friendly DI wrapper for driver instances

custom
jacqueline 2 years ago
parent 84f45e6045
commit 464a4bf527
  1. 43
      src/drivers/driver_cache.cpp
  2. 54
      src/drivers/include/driver_cache.hpp

@ -0,0 +1,43 @@
#include "driver_cache.hpp"
#include <memory>
#include <mutex>
#include "display.hpp"
#include "display_init.hpp"
#include "storage.hpp"
#include "touchwheel.hpp"
namespace drivers {
DriverCache::DriverCache() : gpios_(std::make_unique<GpioExpander>()) {}
DriverCache::~DriverCache() {}
auto DriverCache::AcquireGpios() -> GpioExpander* {
return gpios_.get();
}
auto DriverCache::AcquireDac() -> std::shared_ptr<AudioDac> {
return Acquire(dac_, [&]() -> AudioDac* {
return AudioDac::create(AcquireGpios()).value_or(nullptr);
});
}
auto DriverCache::AcquireDisplay() -> std::shared_ptr<Display> {
return Acquire(display_, [&]() -> Display* {
return Display::create(AcquireGpios(), displays::kST7735R);
});
}
auto DriverCache::AcquireStorage() -> std::shared_ptr<SdStorage> {
return Acquire(storage_, [&]() -> SdStorage* {
return SdStorage::create(AcquireGpios()).value_or(nullptr);
});
}
auto DriverCache::AcquireTouchWheel() -> std::shared_ptr<TouchWheel> {
return Acquire(touchwheel_,
[&]() -> TouchWheel* { return new TouchWheel(); });
}
} // namespace drivers

@ -0,0 +1,54 @@
#pragma once
#include <memory>
#include <mutex>
#include "dac.hpp"
#include "display.hpp"
#include "gpio_expander.hpp"
#include "storage.hpp"
#include "touchwheel.hpp"
namespace drivers {
class DriverCache {
private:
std::unique_ptr<GpioExpander> gpios_;
std::weak_ptr<AudioDac> dac_;
std::weak_ptr<Display> display_;
std::weak_ptr<SdStorage> storage_;
std::weak_ptr<TouchWheel> touchwheel_;
// TODO(jacqueline): Haptics, samd
std::mutex mutex_;
template <typename T, typename F>
auto Acquire(std::weak_ptr<T> ptr, F factory) -> std::shared_ptr<T> {
std::shared_ptr<T> acquired = ptr.lock();
if (acquired) {
return acquired;
}
std::lock_guard<std::mutex> lock(mutex_);
acquired = ptr.lock();
if (acquired) {
return acquired;
}
acquired.reset(factory());
ptr = acquired;
return acquired;
}
public:
DriverCache();
~DriverCache();
auto AcquireGpios() -> GpioExpander*;
auto AcquireDac() -> std::shared_ptr<AudioDac>;
auto AcquireDisplay() -> std::shared_ptr<Display>;
auto AcquireStorage() -> std::shared_ptr<SdStorage>;
auto AcquireTouchWheel() -> std::shared_ptr<TouchWheel>;
};
} // namespace drivers
Loading…
Cancel
Save