#pragma once
#include "IDevice.hpp"
#include "IDeviceManager.hpp"
#include <memory>
#include <map>
#include <atomic>
namespace libobsensor {
class Context;
class DeviceBase : public IDevice {
private:
struct ComponentItem {
DeviceComponentId compId = OB_DEV_COMPONENT_UNKNOWN;
std::shared_ptr<IDeviceComponent> component; std::function<std::shared_ptr<IDeviceComponent>()> creator; bool initialized = false;
bool lockRequired = false;
};
public:
DeviceBase(const std::shared_ptr<const IDeviceEnumInfo> &info);
DeviceBase();
virtual ~DeviceBase() noexcept override;
void reset() override;
void reboot() override;
void deactivate() override;
std::shared_ptr<const DeviceInfo> getInfo() const override;
bool isDeactivated() const override;
const std::string &getExtensionInfo(const std::string &infoKey) const override;
bool isExtensionInfoExists(const std::string &infoKey) const override;
uint64_t getDeviceErrorState() const override;
void fetchDeviceErrorState() override;
void registerComponent(DeviceComponentId compId, std::function<std::shared_ptr<IDeviceComponent>()> creator, bool lockRequired = false);
void registerComponent(DeviceComponentId compId, std::shared_ptr<IDeviceComponent> component, bool lockRequired = false);
void deregisterComponent(DeviceComponentId compId);
bool isComponentExists(DeviceComponentId compId) const override;
bool isComponentCreated(DeviceComponentId compId) const override; DeviceComponentPtr<IDeviceComponent> getComponent(DeviceComponentId compId, bool throwExIfNotFound = true) override;
void registerSensorPortInfo(OBSensorType type, std::shared_ptr<const SourcePortInfo> sourcePortInfo);
void deregisterSensor(OBSensorType type);
const std::shared_ptr<const SourcePortInfo> &getSensorPortInfo(OBSensorType type) const;
bool isSensorExists(OBSensorType type) const override;
bool isSensorCreated(OBSensorType type) const override; DeviceComponentPtr<ISensor> getSensor(OBSensorType type) override;
std::vector<OBSensorType> getSensorTypeList() const override;
bool hasAnySensorStreamActivated() override;
std::vector<std::shared_ptr<IFilter>> createRecommendedPostProcessingFilters(OBSensorType type) override;
std::shared_ptr<IFilter> getSensorFrameFilter(const std::string &name, OBSensorType type, bool throwIfNotFound = true) override;
DeviceComponentPtr<IPropertyServer> getPropertyServer() override;
void updateFirmware(const std::vector<uint8_t> &firmware, DeviceFwUpdateCallback updateCallback, bool async) override;
void setFirmwareUpdateState(bool isUpdating) override;
bool isFirmwareUpdating() const override;
void updateOptionalDepthPresets(const char filePathList[][OB_PATH_MAX], uint8_t pathCount, DeviceFwUpdateCallback updateCallback) override;
static std::map<std::string, std::string> parseExtensionInfo(std::string extensionInfo);
void activateDeviceAccessor() override;
int getFirmwareVersionInt() override;
protected:
virtual void fetchDeviceInfo();
virtual void fetchExtensionInfo();
DeviceComponentLock tryLockResource();
std::shared_ptr<ISourcePort> getSourcePort(std::shared_ptr<const SourcePortInfo> sourcePortInfo) const;
void checkAndStartHeartbeat();
protected:
const std::shared_ptr<const IDeviceEnumInfo> enumInfo_;
std::shared_ptr<DeviceInfo> deviceInfo_;
std::map<std::string, std::string> extensionInfo_;
uint64_t deviceErrorState_ = 0;
private:
std::shared_ptr<Context> ctx_;
std::recursive_timed_mutex resourceMutex_;
mutable std::recursive_mutex componentsMutex_;
std::vector<ComponentItem> components_;
std::atomic<bool> isDeactivated_;
std::map<OBSensorType, std::shared_ptr<const SourcePortInfo>> sensorPortInfos_;
std::map<OBSensorType, std::shared_ptr<IFilter>> sensorFrameFilters_;
std::atomic<bool> isFirmwareUpdating_;
};
}